Skip to content

Commit

Permalink
DEV9: Return sender IP alongside payload
Browse files Browse the repository at this point in the history
Also return payload in a unique_ptr,
  • Loading branch information
TheLastRar authored and refractionpcsx2 committed Jun 25, 2024
1 parent fbac331 commit baec86e
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 87 deletions.
9 changes: 8 additions & 1 deletion pcsx2/DEV9/Sessions/BaseSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "DEV9/PacketReader/IP/IP_Packet.h"
#include <functional>
#include <optional>
#include <vector>

namespace Sessions
Expand All @@ -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:
Expand All @@ -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;

Expand Down
19 changes: 9 additions & 10 deletions pcsx2/DEV9/Sessions/ICMP_Session/ICMP_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -732,7 +731,7 @@ namespace Sessions
}

lock.unlock();
return nullptr;
return std::nullopt;
}

bool ICMP_Session::Send(PacketReader::IP::IP_Payload* payload)
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/DEV9/Sessions/ICMP_Session/ICMP_Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
16 changes: 7 additions & 9 deletions pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
16 changes: 8 additions & 8 deletions pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -77,16 +77,16 @@ 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();

virtual ~TCP_Session();

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);
Expand All @@ -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);

Expand All @@ -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);

/*
Expand All @@ -132,15 +132,15 @@ 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);

// Error on sending data
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();
};
Expand Down
54 changes: 27 additions & 27 deletions pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -153,43 +153,43 @@ 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);
iRet->SetPSH(true);

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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Loading

0 comments on commit baec86e

Please sign in to comment.