From cf3ad3f855659789df22a2521bafd14441133a1d Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Wed, 1 May 2024 21:21:04 +0100 Subject: [PATCH] DEV9: Adjust comments in UDP_Session --- .../Sessions/UDP_Session/UDP_FixedPort.cpp | 27 +++++++++++++--- .../DEV9/Sessions/UDP_Session/UDP_Session.cpp | 32 ++++++++----------- pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.h | 11 +++---- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/pcsx2/DEV9/Sessions/UDP_Session/UDP_FixedPort.cpp b/pcsx2/DEV9/Sessions/UDP_Session/UDP_FixedPort.cpp index 838768f065..eee6729a9a 100644 --- a/pcsx2/DEV9/Sessions/UDP_Session/UDP_FixedPort.cpp +++ b/pcsx2/DEV9/Sessions/UDP_Session/UDP_FixedPort.cpp @@ -30,6 +30,19 @@ using namespace PacketReader::IP::UDP; namespace Sessions { + /* + * The default UDP_Session backend don't bind to the src port the PS2 uses. + * Some games, however, sends the response to a set port, rather than the message source port + * A set of heuristics are used to determine when we should bind the port, these are; + * Any broadcast & multicast packet, and any packet where the src and dst ports are close to each other + * UDP_FixedPort manages the lifetime of socket bound to a specific port, and shares that socket + * with any UDP_Sessions created from it. + * For a UDP_Session with a parent UDP_FixedPort, packets are sent from the UDP_Session, but received + * by the UDP_FixedPort, with the UDP_FixedPort asking each UDP_Session associated with it whether + * it can accept the received packet, broadcast/multicast will accept eveything, while unicast sessions + * only accept packets from the address it sent to + */ + UDP_FixedPort::UDP_FixedPort(ConnectionKey parKey, IP_Address parAdapterIP, u16 parPort) : BaseSession(parKey, parAdapterIP) , client{socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)} @@ -44,11 +57,15 @@ namespace Sessions #elif defined(__POSIX__) errno); #endif - //RaiseEventConnectionClosed(); //TODO + /* + * TODO: Currently error is not correctly handled here + * We would need to call RaiseEventConnectionClosed() + * and also deal with the follow up call to NewClientSession() + */ return; } - const int reuseAddress = true; //BOOL + const int reuseAddress = true; // BOOL on Windows ret = setsockopt(client, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&reuseAddress), sizeof(reuseAddress)); if (ret == SOCKET_ERROR) @@ -59,7 +76,7 @@ namespace Sessions errno); #endif - const int broadcastEnable = true; //BOOL + const int broadcastEnable = true; // BOOL on Windows ret = setsockopt(client, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&broadcastEnable), sizeof(broadcastEnable)); if (ret == SOCKET_ERROR) @@ -140,8 +157,8 @@ namespace Sessions std::unique_ptr buffer; sockaddr_in endpoint{}; - //FIONREAD returns total size of all available messages - //but we will read one message at a time + // FIONREAD returns total size of all available messages + // however, we only read one message at a time #ifdef _WIN32 ret = ioctlsocket(client, FIONREAD, &available); #elif defined(__POSIX__) diff --git a/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.cpp b/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.cpp index 8bdcd9a71f..82cedf4c99 100644 --- a/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.cpp +++ b/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.cpp @@ -31,9 +31,7 @@ using namespace std::chrono_literals; namespace Sessions { const std::chrono::duration - UDP_Session::MAX_IDLE = 120s; //See RFC 4787 Section 4.3 - - //TODO, figure out handling of multicast + UDP_Session::MAX_IDLE = 120s; // See RFC 4787 section 4.3 UDP_Session::UDP_Session(ConnectionKey parKey, IP_Address parAdapterIP) : UDP_BaseSession(parKey, parAdapterIP) @@ -125,8 +123,8 @@ namespace Sessions std::unique_ptr buffer; sockaddr_in endpoint{}; - //FIONREAD returns total size of all available messages - //but we will read one message at a time + // FIONREAD returns total size of all available messages + // however, we only read one message at a time #ifdef _WIN32 ret = ioctlsocket(client, FIONREAD, &available); #elif defined(__POSIX__) @@ -170,7 +168,6 @@ namespace Sessions if (std::chrono::steady_clock::now() - deathClockStart.load() > MAX_IDLE) { - //CloseSocket(); Console.WriteLn("DEV9: UDP: Max idle reached"); RaiseEventConnectionClosed(); } @@ -200,7 +197,7 @@ namespace Sessions if (destPort != 0) { - //client already created + // Already created client!? if (!(udp.destinationPort == destPort && udp.sourcePort == srcPort)) { Console.Error("DEV9: UDP: Packet invalid for current session (duplicate key?)"); @@ -209,11 +206,11 @@ namespace Sessions } else { - //create client + // Create client destPort = udp.destinationPort; srcPort = udp.sourcePort; - //Multicast address start with 0b1110 + // Multicast address start with 0b1110 if ((destIP.bytes[0] & 0xF0) == 0xE0) { isMulticast = true; @@ -234,7 +231,7 @@ namespace Sessions return false; } - const int reuseAddress = true; //BOOL + const int reuseAddress = true; // BOOL on Windows ret = setsockopt(client, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&reuseAddress), sizeof(reuseAddress)); if (ret == SOCKET_ERROR) @@ -289,7 +286,7 @@ namespace Sessions PayloadPtr* udpPayload = static_cast(udp.GetPayload()); - //Send + // Send Packet int ret = SOCKET_ERROR; if (isBroadcast) { @@ -321,11 +318,12 @@ namespace Sessions #endif Console.Error("DEV9: UDP: Send error %d", ret); - //We can recive an ICMP Port Unreacable error, which can get raised in send (and maybe sendto?) - //On Windows this an WSAECONNRESET error, although I've not been able to reproduce in testing - //On Linux this is an ECONNREFUSED error (Testing needed to confirm full behaviour) - - //The decision to ignore the error and retry was made to allow R&C Deadlock ressurection team to packet capture eveything + /* + * We can receive an ICMP Port Unreacable error, which can get raised in send (and maybe sendto?) + * On Windows this is an WSAECONNRESET error, although I've not been able to reproduce in testing + * On Linux this is an ECONNREFUSED error (Testing needed to confirm full behaviour) + * We ignore the error and resend to allow packet capture (i.e. wireshark) for server resurrection projects + */ #ifdef _WIN32 if (ret == WSAECONNRESET) #elif defined(__POSIX__) @@ -343,7 +341,6 @@ namespace Sessions ret = sendto(client, reinterpret_cast(udpPayload->data), udpPayload->GetLength(), 0, reinterpret_cast(&endpoint), sizeof(endpoint)); } else - //Do we need to clear the error somehow? ret = send(client, reinterpret_cast(udpPayload->data), udpPayload->GetLength(), 0); if (ret == SOCKET_ERROR) @@ -387,7 +384,6 @@ namespace Sessions void UDP_Session::Reset() { - //CloseSocket(); RaiseEventConnectionClosed(); } diff --git a/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.h b/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.h index d25d6839ae..20b9688c03 100644 --- a/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.h +++ b/pcsx2/DEV9/Sessions/UDP_Session/UDP_Session.h @@ -28,19 +28,18 @@ namespace Sessions u16 srcPort = 0; u16 destPort = 0; - //Broadcast - const bool isBroadcast; // = false; + // UDP_Session flags + const bool isBroadcast; bool isMulticast = false; - const bool isFixedPort; // = false; - //EndBroadcast + const bool isFixedPort; std::atomic deathClockStart; const static std::chrono::duration MAX_IDLE; public: - //Normal Port + // Normal Port UDP_Session(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP); - //Fixed Port + // Fixed Port #ifdef _WIN32 UDP_Session(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP, bool parIsBroadcast, bool parIsMulticast, SOCKET parClient); #elif defined(__POSIX__)