DEV9: Better error handling on UDP_FixedPort creation

This commit is contained in:
TheLastRar 2024-05-04 15:02:06 +01:00 committed by Connor McLaughlin
parent d7101c3be5
commit 85888a9a81
3 changed files with 31 additions and 9 deletions

View File

@ -45,10 +45,14 @@ namespace Sessions
UDP_FixedPort::UDP_FixedPort(ConnectionKey parKey, IP_Address parAdapterIP, u16 parPort) UDP_FixedPort::UDP_FixedPort(ConnectionKey parKey, IP_Address parAdapterIP, u16 parPort)
: BaseSession(parKey, parAdapterIP) : BaseSession(parKey, parAdapterIP)
, client{socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)} , port{parPort}
, port(parPort) {
}
void UDP_FixedPort::Init()
{ {
int ret; int ret;
client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (client == INVALID_SOCKET) if (client == INVALID_SOCKET)
{ {
Console.Error("DEV9: UDP: Failed to open socket. Error: %d", Console.Error("DEV9: UDP: Failed to open socket. Error: %d",
@ -57,11 +61,7 @@ namespace Sessions
#elif defined(__POSIX__) #elif defined(__POSIX__)
errno); errno);
#endif #endif
/* RaiseEventConnectionClosed();
* 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; return;
} }
@ -90,17 +90,23 @@ namespace Sessions
sockaddr_in endpoint{}; sockaddr_in endpoint{};
endpoint.sin_family = AF_INET; endpoint.sin_family = AF_INET;
endpoint.sin_addr = std::bit_cast<in_addr>(adapterIP); endpoint.sin_addr = std::bit_cast<in_addr>(adapterIP);
endpoint.sin_port = htons(parPort); endpoint.sin_port = htons(port);
ret = bind(client, reinterpret_cast<const sockaddr*>(&endpoint), sizeof(endpoint)); ret = bind(client, reinterpret_cast<const sockaddr*>(&endpoint), sizeof(endpoint));
if (ret == SOCKET_ERROR) if (ret == SOCKET_ERROR)
{
Console.Error("DEV9: UDP: Failed to bind socket. Error: %d", Console.Error("DEV9: UDP: Failed to bind socket. Error: %d",
#ifdef _WIN32 #ifdef _WIN32
WSAGetLastError()); WSAGetLastError());
#elif defined(__POSIX__) #elif defined(__POSIX__)
errno); errno);
#endif #endif
RaiseEventConnectionClosed();
return;
}
open.store(true);
} }
IP_Payload* UDP_FixedPort::Recv() IP_Payload* UDP_FixedPort::Recv()
@ -228,6 +234,9 @@ namespace Sessions
UDP_Session* UDP_FixedPort::NewClientSession(ConnectionKey parNewKey, bool parIsBrodcast, bool parIsMulticast) UDP_Session* UDP_FixedPort::NewClientSession(ConnectionKey parNewKey, bool parIsBrodcast, bool parIsMulticast)
{ {
if (!open.load())
return nullptr;
UDP_Session* s = new UDP_Session(parNewKey, adapterIP, parIsBrodcast, parIsMulticast, client); UDP_Session* s = new UDP_Session(parNewKey, adapterIP, parIsBrodcast, parIsMulticast, client);
s->AddConnectionClosedHandler([&](BaseSession* session) { HandleChildConnectionClosed(session); }); s->AddConnectionClosedHandler([&](BaseSession* session) { HandleChildConnectionClosed(session); });
@ -247,7 +256,10 @@ namespace Sessions
{ {
connections.erase(index); connections.erase(index);
if (connections.size() == 0) if (connections.size() == 0)
{
open.store(false);
RaiseEventConnectionClosed(); RaiseEventConnectionClosed();
}
} }
} }

View File

@ -20,7 +20,7 @@ namespace Sessions
class UDP_FixedPort : public BaseSession class UDP_FixedPort : public BaseSession
{ {
private: private:
std::atomic<bool> open{true}; std::atomic<bool> open{false};
#ifdef _WIN32 #ifdef _WIN32
SOCKET client = INVALID_SOCKET; SOCKET client = INVALID_SOCKET;
@ -38,6 +38,8 @@ namespace Sessions
public: public:
UDP_FixedPort(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP, u16 parPort); UDP_FixedPort(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP, u16 parPort);
void Init();
virtual PacketReader::IP::IP_Payload* Recv(); virtual PacketReader::IP::IP_Payload* Recv();
virtual bool Send(PacketReader::IP::IP_Payload* payload); virtual bool Send(PacketReader::IP::IP_Payload* payload);
virtual void Reset(); virtual void Reset();

View File

@ -531,12 +531,20 @@ bool SocketAdapter::SendUDP(ConnectionKey Key, IP_Packet* ipPkt)
connections.Add(fKey, fPort); connections.Add(fKey, fPort);
fixedUDPPorts.Add(udp.sourcePort, fPort); fixedUDPPorts.Add(udp.sourcePort, fPort);
fPort->Init();
} }
Console.WriteLn("DEV9: Socket: Creating New UDP Connection from FixedPort %d to %d", udp.sourcePort, udp.destinationPort); Console.WriteLn("DEV9: Socket: Creating New UDP Connection from FixedPort %d to %d", udp.sourcePort, udp.destinationPort);
s = fPort->NewClientSession(Key, s = fPort->NewClientSession(Key,
ipPkt->destinationIP == dhcpServer.broadcastIP || ipPkt->destinationIP == IP_Address{{{255, 255, 255, 255}}}, ipPkt->destinationIP == dhcpServer.broadcastIP || ipPkt->destinationIP == IP_Address{{{255, 255, 255, 255}}},
(ipPkt->destinationIP.bytes[0] & 0xF0) == 0xE0); (ipPkt->destinationIP.bytes[0] & 0xF0) == 0xE0);
if (s == nullptr)
{
Console.Error("DEV9: Socket: Failed to Create New UDP Connection from FixedPort");
return false;
}
} }
else else
{ {