DEV9: Return sender IP alongside payload

Also return payload in a unique_ptr,
This commit is contained in:
TheLastRar 2024-06-19 23:31:10 +01:00 committed by refractionpcsx2
parent fbac331528
commit baec86e39b
12 changed files with 90 additions and 87 deletions

View File

@ -5,6 +5,7 @@
#include "DEV9/PacketReader/IP/IP_Packet.h"
#include <functional>
#include <optional>
#include <vector>
namespace Sessions
@ -24,6 +25,12 @@ namespace Sessions
bool operator!=(const ConnectionKey& other) const;
};
struct ReceivedPayload
{
PacketReader::IP::IP_Address sourceIP;
std::unique_ptr<PacketReader::IP::IP_Payload> payload;
};
class BaseSession
{
public:
@ -42,7 +49,7 @@ namespace Sessions
void AddConnectionClosedHandler(ConnectionClosedEventHandler handler);
virtual PacketReader::IP::IP_Payload* Recv() = 0;
virtual std::optional<ReceivedPayload> Recv() = 0;
virtual bool Send(PacketReader::IP::IP_Payload* payload) = 0;
virtual void Reset() = 0;

View File

@ -659,7 +659,7 @@ namespace Sessions
connections = parConnections;
}
IP_Payload* ICMP_Session::Recv()
std::optional<ReceivedPayload> ICMP_Session::Recv()
{
std::unique_lock lock(ping_mutex);
@ -675,7 +675,7 @@ namespace Sessions
lock.unlock();
//Create return ICMP packet
ICMP_Packet* ret = nullptr;
std::optional<ReceivedPayload> ret;
if (pingRet->type >= 0)
{
PayloadData* data;
@ -704,13 +704,12 @@ namespace Sessions
delete[] temp;
}
ret = new ICMP_Packet(data);
ret->type = pingRet->type;
ret->code = pingRet->code;
memcpy(ret->headerData, ping->headerData, 4);
std::unique_ptr<ICMP_Packet> pRet = std::make_unique<ICMP_Packet>(data);
pRet->type = pingRet->type;
pRet->code = pingRet->code;
memcpy(pRet->headerData, ping->headerData, 4);
if (destIP != pingRet->address)
destIP = pingRet->address;
ret = {pingRet->address, std::move(pRet)};
}
else if (pingRet->type == -1)
Console.Error("DEV9: ICMP: Unexpected ICMP status %d", pingRet->code);
@ -723,7 +722,7 @@ namespace Sessions
if (--open == 0)
RaiseEventConnectionClosed();
if (ret != nullptr)
if (ret.has_value())
DevCon.WriteLn("DEV9: ICMP: Return Ping");
//Return packet
@ -732,7 +731,7 @@ namespace Sessions
}
lock.unlock();
return nullptr;
return std::nullopt;
}
bool ICMP_Session::Send(PacketReader::IP::IP_Payload* payload)

View File

@ -78,7 +78,7 @@ namespace Sessions
public:
ICMP_Session(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP, ThreadSafeMap<Sessions::ConnectionKey, Sessions::BaseSession*>* parConnections);
virtual PacketReader::IP::IP_Payload* Recv();
virtual std::optional<ReceivedPayload> Recv();
virtual bool Send(PacketReader::IP::IP_Payload* payload);
bool Send(PacketReader::IP::IP_Payload* payload, PacketReader::IP::IP_Packet* packet);
virtual void Reset();

View File

@ -18,13 +18,13 @@ using namespace PacketReader::IP::TCP;
namespace Sessions
{
void TCP_Session::PushRecvBuff(TCP_Packet* tcp)
void TCP_Session::PushRecvBuff(std::unique_ptr<TCP_Packet> tcp)
{
_recvBuff.Enqueue(tcp);
_recvBuff.Enqueue(std::move(tcp));
}
TCP_Packet* TCP_Session::PopRecvBuff()
std::unique_ptr<TCP_Packet> TCP_Session::PopRecvBuff()
{
TCP_Packet* ret;
std::unique_ptr<TCP_Packet> ret;
if (_recvBuff.Dequeue(&ret))
return ret;
else
@ -102,13 +102,13 @@ namespace Sessions
return delta;
}
TCP_Packet* TCP_Session::CreateBasePacket(PayloadData* data)
std::unique_ptr<TCP_Packet> TCP_Session::CreateBasePacket(PayloadData* data)
{
//DevCon.WriteLn("Creating base packet");
if (data == nullptr)
data = new PayloadData(0);
TCP_Packet* ret = new TCP_Packet(data);
std::unique_ptr<TCP_Packet> ret = std::make_unique<TCP_Packet>(data);
// Setup common packet infomation
ret->sourcePort = destPort;
@ -159,15 +159,13 @@ namespace Sessions
// Clear out _recvBuff
while (!_recvBuff.IsQueueEmpty())
{
TCP_Packet* retPay;
std::unique_ptr<TCP_Packet> retPay;
if (!_recvBuff.Dequeue(&retPay))
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(1ms);
continue;
}
delete retPay;
}
}
} // namespace Sessions

View File

@ -42,7 +42,7 @@ namespace Sessions
Bad
};
SimpleQueue<PacketReader::IP::TCP::TCP_Packet*> _recvBuff;
SimpleQueue<std::unique_ptr<PacketReader::IP::TCP::TCP_Packet>> _recvBuff;
#ifdef _WIN32
SOCKET client = INVALID_SOCKET;
@ -77,7 +77,7 @@ namespace Sessions
public:
TCP_Session(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP);
virtual PacketReader::IP::IP_Payload* Recv();
virtual std::optional<ReceivedPayload> Recv();
virtual bool Send(PacketReader::IP::IP_Payload* payload);
virtual void Reset();
@ -85,8 +85,8 @@ namespace Sessions
private:
// Async functions
void PushRecvBuff(PacketReader::IP::TCP::TCP_Packet* tcp);
PacketReader::IP::TCP::TCP_Packet* PopRecvBuff();
void PushRecvBuff(std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> tcp);
std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> PopRecvBuff();
void IncrementMyNumber(u32 amount);
void UpdateReceivedAckNumber(u32 ack);
@ -104,7 +104,7 @@ namespace Sessions
bool ValidateEmptyPacket(PacketReader::IP::TCP::TCP_Packet* tcp, bool ignoreOld = true);
// PS2 sent SYN
PacketReader::IP::TCP::TCP_Packet* ConnectTCPComplete(bool success);
std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> ConnectTCPComplete(bool success);
bool SendConnect(PacketReader::IP::TCP::TCP_Packet* tcp);
bool SendConnected(PacketReader::IP::TCP::TCP_Packet* tcp);
@ -120,7 +120,7 @@ namespace Sessions
* S4: PS2 then Sends ACK
*/
bool CloseByPS2Stage1_2(PacketReader::IP::TCP::TCP_Packet* tcp);
PacketReader::IP::TCP::TCP_Packet* CloseByPS2Stage3();
std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> CloseByPS2Stage3();
bool CloseByPS2Stage4(PacketReader::IP::TCP::TCP_Packet* tcp);
/*
@ -132,7 +132,7 @@ namespace Sessions
* Closing_ClosedByRemoteThenPS2_WaitingForAck
* we then check if S3 has been completed
*/
PacketReader::IP::TCP::TCP_Packet* CloseByRemoteStage1();
std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> CloseByRemoteStage1();
bool CloseByRemoteStage2_ButAfter4(PacketReader::IP::TCP::TCP_Packet* tcp);
bool CloseByRemoteStage3_4(PacketReader::IP::TCP::TCP_Packet* tcp);
@ -140,7 +140,7 @@ namespace Sessions
void CloseByRemoteRST();
// Returned TCP_Packet takes ownership of data
PacketReader::IP::TCP::TCP_Packet* CreateBasePacket(PacketReader::PayloadData* data = nullptr);
std::unique_ptr<PacketReader::IP::TCP::TCP_Packet> CreateBasePacket(PacketReader::PayloadData* data = nullptr);
void CloseSocket();
};

View File

@ -20,11 +20,11 @@ using namespace PacketReader::IP::TCP;
namespace Sessions
{
PacketReader::IP::IP_Payload* TCP_Session::Recv()
std::optional<ReceivedPayload> TCP_Session::Recv()
{
TCP_Packet* ret = PopRecvBuff();
std::unique_ptr<TCP_Packet> ret = PopRecvBuff();
if (ret != nullptr)
return ret;
return ReceivedPayload{destIP, std::move(ret)};
switch (state)
{
@ -43,15 +43,15 @@ namespace Sessions
select(client + 1, nullptr, &writeSet, &exceptSet, &nowait);
if (FD_ISSET(client, &writeSet))
return ConnectTCPComplete(true);
return ReceivedPayload{destIP, ConnectTCPComplete(true)};
if (FD_ISSET(client, &exceptSet))
return ConnectTCPComplete(false);
return ReceivedPayload{destIP, ConnectTCPComplete(false)};
return nullptr;
return std::nullopt;
}
case TCP_State::SentSYN_ACK:
// Don't read data untill PS2 ACKs connection
return nullptr;
return std::nullopt;
case TCP_State::CloseCompletedFlushBuffer:
/*
* When TCP connection is closed by the server
@ -60,17 +60,17 @@ namespace Sessions
*/
state = TCP_State::CloseCompleted;
RaiseEventConnectionClosed();
return nullptr;
return std::nullopt;
case TCP_State::Connected:
case TCP_State::Closing_ClosedByPS2:
// Only accept data in above two states
break;
default:
return nullptr;
return std::nullopt;
}
if (ShouldWaitForAck())
return nullptr;
return std::nullopt;
// Note, windowSize will be updated before _ReceivedAckNumber, potential race condition
// in practice, we just get a smaller or -ve maxSize
@ -118,24 +118,24 @@ namespace Sessions
// In theory, this should only occur when the PS2 has RST the connection
// and the call to TCPSession.Recv() occurs at just the right time.
//Console.WriteLn("DEV9: TCP: Recv() on shutdown socket");
return nullptr;
return std::nullopt;
case WSAEWOULDBLOCK:
return nullptr;
return std::nullopt;
#elif defined(__POSIX__)
case EINVAL:
case ESHUTDOWN:
// See WSAESHUTDOWN
//Console.WriteLn("DEV9: TCP: Recv() on shutdown socket");
return nullptr;
return std::nullopt;
case EWOULDBLOCK:
return nullptr;
return std::nullopt;
#endif
case 0:
break;
default:
CloseByRemoteRST();
Console.Error("DEV9: TCP: Recv error: %d", err);
return nullptr;
return std::nullopt;
}
// Server closed the Socket
@ -153,22 +153,22 @@ namespace Sessions
switch (state)
{
case TCP_State::Connected:
return CloseByRemoteStage1();
return ReceivedPayload{destIP, CloseByRemoteStage1()};
case TCP_State::Closing_ClosedByPS2:
return CloseByPS2Stage3();
return ReceivedPayload{destIP, CloseByPS2Stage3()};
default:
CloseByRemoteRST();
Console.Error("DEV9: TCP: Remote close occured with invalid TCP state");
break;
}
return nullptr;
return std::nullopt;
}
DevCon.WriteLn("DEV9: TCP: [SRV] Sending %d bytes", recived);
PayloadData* recivedData = new PayloadData(recived);
memcpy(recivedData->data.get(), buffer.get(), recived);
TCP_Packet* iRet = CreateBasePacket(recivedData);
std::unique_ptr<TCP_Packet> iRet = CreateBasePacket(recivedData);
IncrementMyNumber((u32)recived);
iRet->SetACK(true);
@ -176,20 +176,20 @@ namespace Sessions
myNumberACKed.store(false);
//DevCon.WriteLn("DEV9: TCP: myNumberACKed reset");
return iRet;
return ReceivedPayload{destIP, std::move(iRet)};
}
}
return nullptr;
return std::nullopt;
}
TCP_Packet* TCP_Session::ConnectTCPComplete(bool success)
std::unique_ptr<TCP_Packet> TCP_Session::ConnectTCPComplete(bool success)
{
if (success)
{
state = TCP_State::SentSYN_ACK;
TCP_Packet* ret = new TCP_Packet(new PayloadData(0));
std::unique_ptr<TCP_Packet> ret = std::make_unique<TCP_Packet>(new PayloadData(0));
// Send packet to say we connected
ret->sourcePort = destPort;
ret->destinationPort = srcPort;
@ -240,11 +240,11 @@ namespace Sessions
}
}
PacketReader::IP::TCP::TCP_Packet* TCP_Session::CloseByPS2Stage3()
std::unique_ptr<TCP_Packet> TCP_Session::CloseByPS2Stage3()
{
//Console.WriteLn("DEV9: TCP: Remote has closed connection after PS2");
TCP_Packet* ret = CreateBasePacket();
std::unique_ptr ret = CreateBasePacket();
IncrementMyNumber(1);
ret->SetACK(true);
@ -257,11 +257,11 @@ namespace Sessions
return ret;
}
PacketReader::IP::TCP::TCP_Packet* TCP_Session::CloseByRemoteStage1()
std::unique_ptr<TCP_Packet> TCP_Session::CloseByRemoteStage1()
{
//Console.WriteLn("DEV9: TCP: Remote has closed connection");
TCP_Packet* ret = CreateBasePacket();
std::unique_ptr<TCP_Packet> ret = CreateBasePacket();
IncrementMyNumber(1);
ret->SetACK(true);

View File

@ -363,10 +363,10 @@ namespace Sessions
}
// ACK data
//DevCon.WriteLn("[SRV] ACK data: %u", expectedSeqNumber);
TCP_Packet* ret = CreateBasePacket();
std::unique_ptr<TCP_Packet> ret = CreateBasePacket();
ret->SetACK(true);
PushRecvBuff(ret);
PushRecvBuff(std::move(ret));
}
return true;
}
@ -521,10 +521,10 @@ namespace Sessions
#endif
// Connection close part 2, send ACK to PS2
TCP_Packet* ret = CreateBasePacket();
std::unique_ptr<TCP_Packet> ret = CreateBasePacket();
ret->SetACK(true);
PushRecvBuff(ret);
PushRecvBuff(std::move(ret));
return true;
}
@ -587,11 +587,11 @@ namespace Sessions
errno);
#endif
TCP_Packet* ret = CreateBasePacket();
std::unique_ptr<TCP_Packet> ret = CreateBasePacket();
ret->SetACK(true);
PushRecvBuff(ret);
PushRecvBuff(std::move(ret));
if (myNumberACKed.load())
{
@ -609,9 +609,9 @@ namespace Sessions
// Error on sending data
void TCP_Session::CloseByRemoteRST()
{
TCP_Packet* reterr = CreateBasePacket();
std::unique_ptr<TCP_Packet> reterr = CreateBasePacket();
reterr->SetRST(true);
PushRecvBuff(reterr);
PushRecvBuff(std::move(reterr));
CloseSocket();
state = TCP_State::CloseCompletedFlushBuffer;

View File

@ -109,10 +109,10 @@ namespace Sessions
open.store(true);
}
IP_Payload* UDP_FixedPort::Recv()
std::optional<ReceivedPayload> UDP_FixedPort::Recv()
{
if (!open.load())
return nullptr;
return std::nullopt;
int ret;
fd_set sReady;
@ -191,31 +191,30 @@ namespace Sessions
errno);
#endif
RaiseEventConnectionClosed();
return nullptr;
return std::nullopt;
}
recived = new PayloadData(ret);
memcpy(recived->data.get(), buffer.get(), ret);
UDP_Packet* iRet = new UDP_Packet(recived);
std::unique_ptr<UDP_Packet> iRet = std::make_unique<UDP_Packet>(recived);
iRet->destinationPort = port;
destIP = std::bit_cast<IP_Address>(endpoint.sin_addr);
iRet->sourcePort = ntohs(endpoint.sin_port);
IP_Address srvIP = std::bit_cast<IP_Address>(endpoint.sin_addr);
{
std::lock_guard numberlock(connectionSentry);
for (size_t i = 0; i < connections.size(); i++)
{
UDP_BaseSession* s = connections[i];
if (s->WillRecive(destIP))
return iRet;
if (s->WillRecive(srvIP))
return ReceivedPayload{srvIP, std::move(iRet)};
}
}
Console.Error("DEV9: UDP: Unexpected packet, dropping");
delete iRet;
}
return nullptr;
return std::nullopt;
}
bool UDP_FixedPort::Send(PacketReader::IP::IP_Payload* payload)

View File

@ -40,7 +40,7 @@ namespace Sessions
void Init();
virtual PacketReader::IP::IP_Payload* Recv();
virtual std::optional<ReceivedPayload> Recv();
virtual bool Send(PacketReader::IP::IP_Payload* payload);
virtual void Reset();

View File

@ -59,10 +59,10 @@ namespace Sessions
{
}
IP_Payload* UDP_Session::Recv()
std::optional<ReceivedPayload> UDP_Session::Recv()
{
if (!open.load())
return nullptr;
return std::nullopt;
if (isFixedPort)
{
@ -72,7 +72,7 @@ namespace Sessions
open.store(false);
RaiseEventConnectionClosed();
}
return nullptr;
return std::nullopt;
}
int ret;
@ -152,19 +152,19 @@ namespace Sessions
errno);
#endif
RaiseEventConnectionClosed();
return nullptr;
return std::nullopt;
}
recived = new PayloadData(ret);
memcpy(recived->data.get(), buffer.get(), ret);
UDP_Packet* iRet = new UDP_Packet(recived);
std::unique_ptr<UDP_Packet> iRet = std::make_unique<UDP_Packet>(recived);
iRet->destinationPort = srcPort;
iRet->sourcePort = destPort;
deathClockStart.store(std::chrono::steady_clock::now());
return iRet;
return ReceivedPayload{destIP, std::move(iRet)};
}
if (std::chrono::steady_clock::now() - deathClockStart.load() > MAX_IDLE)
@ -173,7 +173,7 @@ namespace Sessions
RaiseEventConnectionClosed();
}
return nullptr;
return std::nullopt;
}
bool UDP_Session::WillRecive(IP_Address parDestIP)

View File

@ -46,7 +46,7 @@ namespace Sessions
UDP_Session(ConnectionKey parKey, PacketReader::IP::IP_Address parAdapterIP, bool parIsBroadcast, bool parIsMulticast, int parClient);
#endif
virtual PacketReader::IP::IP_Payload* Recv();
virtual std::optional<ReceivedPayload> Recv();
virtual bool WillRecive(PacketReader::IP::IP_Address parDestIP);
virtual bool Send(PacketReader::IP::IP_Payload* payload);
virtual void Reset();

View File

@ -220,13 +220,13 @@ bool SocketAdapter::recv(NetPacket* pkt)
if (!connections.TryGetValue(key, &session))
continue;
IP_Payload* pl = session->Recv();
std::optional<ReceivedPayload> pl = session->Recv();
if (pl != nullptr)
if (pl.has_value())
{
IP_Packet* ipPkt = new IP_Packet(pl);
IP_Packet* ipPkt = new IP_Packet(pl->payload.release());
ipPkt->destinationIP = session->sourceIP;
ipPkt->sourceIP = session->destIP;
ipPkt->sourceIP = pl->sourceIP;
EthernetFrame frame(ipPkt);
frame.sourceMAC = internalMAC;