DEV9: Adjust comments in UDP_Session

This commit is contained in:
TheLastRar 2024-05-01 21:21:04 +01:00 committed by Connor McLaughlin
parent c6e7e15599
commit cf3ad3f855
3 changed files with 41 additions and 29 deletions

View File

@ -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<const char*>(&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<const char*>(&broadcastEnable), sizeof(broadcastEnable));
if (ret == SOCKET_ERROR)
@ -141,7 +158,7 @@ namespace Sessions
sockaddr_in endpoint{};
// FIONREAD returns total size of all available messages
//but we will read one message at a time
// however, we only read one message at a time
#ifdef _WIN32
ret = ioctlsocket(client, FIONREAD, &available);
#elif defined(__POSIX__)

View File

@ -31,9 +31,7 @@ using namespace std::chrono_literals;
namespace Sessions
{
const std::chrono::duration<std::chrono::steady_clock::rep, std::chrono::steady_clock::period>
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)
@ -126,7 +124,7 @@ namespace Sessions
sockaddr_in endpoint{};
// FIONREAD returns total size of all available messages
//but we will read one message at a time
// 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,7 +206,7 @@ namespace Sessions
}
else
{
//create client
// Create client
destPort = udp.destinationPort;
srcPort = udp.sourcePort;
@ -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<const char*>(&reuseAddress), sizeof(reuseAddress));
if (ret == SOCKET_ERROR)
@ -289,7 +286,7 @@ namespace Sessions
PayloadPtr* udpPayload = static_cast<PayloadPtr*>(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<const char*>(udpPayload->data), udpPayload->GetLength(), 0, reinterpret_cast<const sockaddr*>(&endpoint), sizeof(endpoint));
}
else
//Do we need to clear the error somehow?
ret = send(client, reinterpret_cast<const char*>(udpPayload->data), udpPayload->GetLength(), 0);
if (ret == SOCKET_ERROR)
@ -387,7 +384,6 @@ namespace Sessions
void UDP_Session::Reset()
{
//CloseSocket();
RaiseEventConnectionClosed();
}

View File

@ -28,11 +28,10 @@ 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<std::chrono::steady_clock::time_point> deathClockStart;
const static std::chrono::duration<std::chrono::steady_clock::rep, std::chrono::steady_clock::period> MAX_IDLE;