From 5df0b543dea42b0147c06319df23fa7aba8e7b6e Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Fri, 5 Apr 2024 16:43:10 +0100 Subject: [PATCH 1/5] DEV9: Increase number of tracked sent SEQ number --- pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h index 04b6b44301cd1..1437e50356ff9 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h @@ -68,7 +68,7 @@ namespace Sessions std::vector receivedPS2SeqNumbers; //Accesed By Out Thread Only std::mutex myNumberSentry; - const int oldMyNumCount = 2; + const int oldMyNumCount = 64; u32 _MySequenceNumber = 1; std::vector _OldMyNumbers; std::atomic myNumberACKed{true}; From 4c056e703f9af8e09f86cbdd1381a4016e248dbf Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sat, 6 Apr 2024 17:23:19 +0100 Subject: [PATCH 2/5] DEV9: Correct Console Logs --- .../DEV9/Sessions/TCP_Session/TCP_Session.cpp | 4 ++-- .../Sessions/TCP_Session/TCP_Session_In.cpp | 6 +++-- .../Sessions/TCP_Session/TCP_Session_Out.cpp | 24 +++++++++---------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp index 3c1d8965cb657..ee57d04867dea 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp @@ -81,9 +81,9 @@ namespace Sessions ret->destinationPort = srcPort; ret->sequenceNumber = GetMyNumber(); - //DevCon.WriteLn("With MySeq: %d", ret->sequenceNumber); + //DevCon.WriteLn("With MySeq: %u", ret->sequenceNumber); ret->acknowledgementNumber = expectedSeqNumber; - //DevCon.WriteLn("With MyAck: %d", ret->acknowledgementNumber); + //DevCon.WriteLn("With MyAck: %u", ret->acknowledgementNumber); ret->windowSize = 2 * maxSegmentSize; diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp index 138ab13c0efbd..4fce5d68c2e98 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp @@ -80,7 +80,9 @@ namespace Sessions int err = 0; int recived; - unsigned long available; + //FIONREAD uses unsigned long on windows and int on linux + //Zero init so we don't have bad data on any unused bytes + unsigned long available = 0; #ifdef _WIN32 err = ioctlsocket(client, FIONREAD, &available); #elif defined(__POSIX__) @@ -89,7 +91,7 @@ namespace Sessions if (err != SOCKET_ERROR) { if (available > maxSize) - Console.WriteLn("DEV9: TCP: Got a lot of data: %d Using: %d", available, maxSize); + Console.WriteLn("DEV9: TCP: Got a lot of data: %lu Using: %d", available, maxSize); buffer = std::make_unique(maxSize); recived = recv(client, (char*)buffer.get(), maxSize, 0); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp index bebfab067e693..db1fce3168566 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp @@ -361,7 +361,7 @@ namespace Sessions //Done send } //ACK data - //DevCon.WriteLn("[SRV] ACK Data: %d", expectedSeqNumber); + //DevCon.WriteLn("[SRV] ACK Data: %u", expectedSeqNumber); TCP_Packet* ret = CreateBasePacket(); ret->SetACK(true); @@ -402,11 +402,11 @@ namespace Sessions TCP_Session::NumCheckResult TCP_Session::CheckRepeatSYNNumbers(TCP_Packet* tcp) { //DevCon.WriteLn("DEV9: TCP: CHECK_REPEAT_SYN_NUMBERS"); - //DevCon.WriteLn("DEV9: TCP: [SRV]CurrAckNumber = %d [PS2]Seq Number = %d", expectedSeqNumber, tcp->sequenceNumber); + //DevCon.WriteLn("DEV9: TCP: [SRV] CurrAckNumber = %u [PS2] Seq Number = %u", expectedSeqNumber, tcp->sequenceNumber); if (tcp->sequenceNumber != expectedSeqNumber - 1) { - Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From Repeated SYN Packet, Got %d Expected %d", tcp->sequenceNumber, (expectedSeqNumber - 1)); + Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From Repeated SYN Packet, Got %u Expected %u", tcp->sequenceNumber, (expectedSeqNumber - 1)); return NumCheckResult::Bad; } return NumCheckResult::OK; @@ -419,24 +419,24 @@ namespace Sessions std::tie(seqNum, oldSeqNums) = GetAllMyNumbers(); //DevCon.WriteLn("DEV9: TCP: CHECK_NUMBERS"); - //DevCon.WriteLn("DEV9: TCP: [SRV]CurrSeqNumber = %d [PS2]Ack Number = %d", seqNum, tcp->acknowledgementNumber); - //DevCon.WriteLn("DEV9: TCP: [SRV]CurrAckNumber = %d [PS2]Seq Number = %d", expectedSeqNumber, tcp->sequenceNumber); - //DevCon.WriteLn("DEV9: TCP: [PS2]Data Length = %d", tcp->GetPayload()->GetLength()); + //DevCon.WriteLn("DEV9: TCP: [SRV] CurrSeqNumber = %u [PS2] Ack Number = %u", seqNum, tcp->acknowledgementNumber); + //DevCon.WriteLn("DEV9: TCP: [SRV] CurrAckNumber = %u [PS2] Seq Number = %u", expectedSeqNumber, tcp->sequenceNumber); + //DevCon.WriteLn("DEV9: TCP: [PS2] Data Length = %u", tcp->GetPayload()->GetLength()); if (tcp->acknowledgementNumber != seqNum) { - //DevCon.WriteLn("DEV9: TCP: [PS2]Sent Outdated Acknowledgement Number, Got %d Expected %d", tcp->acknowledgementNumber, seqNum); + //DevCon.WriteLn("DEV9: TCP: [PS2] Sent Outdated Acknowledgement Number, Got %u Expected %u", tcp->acknowledgementNumber, seqNum); //Check if oldSeqNums contains tcp->acknowledgementNumber if (std::find(oldSeqNums.begin(), oldSeqNums.end(), tcp->acknowledgementNumber) == oldSeqNums.end()) { - Console.Error("DEV9: TCP: [PS2] Sent Unexpected Acknowledgement Number, did not Match Old Numbers, Got %d Expected %d", tcp->acknowledgementNumber, seqNum); + Console.Error("DEV9: TCP: [PS2] Sent Unexpected Acknowledgement Number, did not Match Old Numbers, Got %u Expected %u", tcp->acknowledgementNumber, seqNum); return NumCheckResult::Bad; } } else { - //DevCon.WriteLn("[PS2]CurrSeqNumber Acknowleged By PS2"); + //DevCon.WriteLn("[PS2] CurrSeqNumber Acknowleged By PS2"); myNumberACKed.store(true); } @@ -444,19 +444,19 @@ namespace Sessions { if (tcp->GetPayload()->GetLength() == 0) { - Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From ACK Packet, Got %d Expected %d", tcp->sequenceNumber, expectedSeqNumber); + Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From ACK Packet, Got %u Expected %u", tcp->sequenceNumber, expectedSeqNumber); } else { //Check if receivedPS2SeqNumbers contains tcp->sequenceNumber if (std::find(receivedPS2SeqNumbers.begin(), receivedPS2SeqNumbers.end(), tcp->sequenceNumber) == receivedPS2SeqNumbers.end()) { - Console.Error("DEV9: TCP: [PS2] Sent an Old Seq Number on an Data packet, Got %d Expected %d", tcp->sequenceNumber, expectedSeqNumber); + Console.Error("DEV9: TCP: [PS2] Sent an Old Seq Number on an Data packet, Got %u Expected %u", tcp->sequenceNumber, expectedSeqNumber); return NumCheckResult::GotOldData; } else { - Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From Data Packet, Got %d Expected %d", tcp->sequenceNumber, expectedSeqNumber); + Console.Error("DEV9: TCP: [PS2] Sent Unexpected Sequence Number From Data Packet, Got %u Expected %u", tcp->sequenceNumber, expectedSeqNumber); return NumCheckResult::Bad; } } From ad5d237b672d7da8befae1ede8fb7bd57ee175ec Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sat, 6 Apr 2024 19:16:32 +0100 Subject: [PATCH 3/5] DEV9: Move and fix GetDelta Function --- .../DEV9/Sessions/TCP_Session/TCP_Session.cpp | 18 ++++++++++++++++++ pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h | 2 +- .../Sessions/TCP_Session/TCP_Session_Out.cpp | 13 ++----------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp index ee57d04867dea..2185ab9a1427c 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp @@ -68,6 +68,24 @@ namespace Sessions { } + s32 TCP_Session::GetDelta(u32 a, u32 b) + { + s64 delta = static_cast(a) - static_cast(b); + if (delta > 0.5 * UINT_MAX) + { + delta = -static_cast(UINT_MAX) + a - b - 1; + Console.Error("DEV9: TCP: [PS2] SequenceNumber Overflow Detected"); + Console.Error("DEV9: TCP: [PS2] New Data Offset: %d bytes", delta); + } + if (delta < -0.5 * UINT_MAX) + { + delta = UINT_MAX - b + a + 1; + Console.Error("DEV9: TCP: [PS2] SequenceNumber Overflow Detected"); + Console.Error("DEV9: TCP: [PS2] New Data Offset: %d bytes", delta); + } + return delta; + } + TCP_Packet* TCP_Session::CreateBasePacket(PayloadData* data) { //DevCon.WriteLn("Creating Base Packet"); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h index 1437e50356ff9..765574fdca696 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h @@ -95,7 +95,7 @@ namespace Sessions NumCheckResult CheckRepeatSYNNumbers(PacketReader::IP::TCP::TCP_Packet* tcp); NumCheckResult CheckNumbers(PacketReader::IP::TCP::TCP_Packet* tcp); - u32 GetDelta(u32 parExpectedSeq, u32 parGotSeq); + s32 GetDelta(u32 a, u32 b); //Returns a - b //Returns true if errored bool ErrorOnNonEmptyPacket(PacketReader::IP::TCP::TCP_Packet* tcp); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp index db1fce3168566..9eed93ca2748d 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp @@ -308,7 +308,9 @@ namespace Sessions windowSize.store(tcp->windowSize << windowScale); const NumCheckResult Result = CheckNumbers(tcp); + //Check if we already have some of the data sent const uint delta = GetDelta(expectedSeqNumber, tcp->sequenceNumber); + pxAssert(delta >= 0); //if (Result == NumCheckResult::GotOldData) //{ // DevCon.WriteLn("[PS2] New Data Offset: %d bytes", delta); @@ -464,17 +466,6 @@ namespace Sessions return NumCheckResult::OK; } - u32 TCP_Session::GetDelta(u32 parExpectedSeq, u32 parGotSeq) - { - u32 delta = parExpectedSeq - parGotSeq; - if (delta > 0.5 * UINT_MAX) - { - delta = UINT_MAX - parExpectedSeq + parGotSeq; - Console.Error("DEV9: TCP: [PS2] SequenceNumber Overflow Detected"); - Console.Error("DEV9: TCP: [PS2] New Data Offset: %d bytes", delta); - } - return delta; - } bool TCP_Session::ErrorOnNonEmptyPacket(TCP_Packet* tcp) { NumCheckResult ResultFIN = CheckNumbers(tcp); From 5ad89af31d5648cfc1fecdc41ab6279c35c09ee7 Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sat, 6 Apr 2024 20:36:37 +0100 Subject: [PATCH 4/5] DEV9: Improve tracking of acknowledged data --- pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp | 11 +++++++++++ pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h | 3 +++ .../DEV9/Sessions/TCP_Session/TCP_Session_In.cpp | 15 ++++++++++----- .../DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp index 2185ab9a1427c..f86d2c3cd2c08 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp @@ -39,11 +39,22 @@ namespace Sessions _MySequenceNumber += amount; } + void TCP_Session::UpdateReceivedAckNumber(u32 ack) + { + std::lock_guard numberlock(myNumberSentry); + if (GetDelta(ack, _ReceivedAckNumber) > 0) + _ReceivedAckNumber = ack; + } u32 TCP_Session::GetMyNumber() { std::lock_guard numberlock(myNumberSentry); return _MySequenceNumber; } + u32 TCP_Session::GetOutstandingSequenceLength() + { + std::lock_guard numberlock(myNumberSentry); + return GetDelta(_MySequenceNumber, _ReceivedAckNumber); + } std::tuple> TCP_Session::GetAllMyNumbers() { std::lock_guard numberlock(myNumberSentry); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h index 765574fdca696..800466d2197a5 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h @@ -71,6 +71,7 @@ namespace Sessions const int oldMyNumCount = 64; u32 _MySequenceNumber = 1; std::vector _OldMyNumbers; + u32 _ReceivedAckNumber = 1; std::atomic myNumberACKed{true}; public: @@ -89,7 +90,9 @@ namespace Sessions PacketReader::IP::TCP::TCP_Packet* PopRecvBuff(); void IncrementMyNumber(u32 amount); + void UpdateReceivedAckNumber(u32 ack); u32 GetMyNumber(); + u32 GetOutstandingSequenceLength(); std::tuple> GetAllMyNumbers(); void ResetMyNumbers(); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp index 4fce5d68c2e98..fde4339d29795 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp @@ -67,13 +67,18 @@ namespace Sessions return nullptr; } - uint maxSize = 0; + + //Note, windowSize will be updated before _ReceivedAckNumber, potential race condition + //in practice, we just get a smaller or -ve maxSize + const u32 outstanding = GetOutstandingSequenceLength(); + + int maxSize = 0; if (sendTimeStamps) - maxSize = std::min(maxSegmentSize - 12, windowSize.load()); + maxSize = std::min(maxSegmentSize - 12, windowSize.load() - outstanding); else - maxSize = std::min(maxSegmentSize, windowSize.load()); + maxSize = std::min(maxSegmentSize, windowSize.load() - outstanding); - if (maxSize != 0 && + if (maxSize > 0 && myNumberACKed.load()) { std::unique_ptr buffer; @@ -90,7 +95,7 @@ namespace Sessions #endif if (err != SOCKET_ERROR) { - if (available > maxSize) + if (available > static_cast(maxSize)) Console.WriteLn("DEV9: TCP: Got a lot of data: %lu Using: %d", available, maxSize); buffer = std::make_unique(maxSize); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp index 9eed93ca2748d..e67b31b0052b4 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_Out.cpp @@ -442,6 +442,8 @@ namespace Sessions myNumberACKed.store(true); } + UpdateReceivedAckNumber(tcp->acknowledgementNumber); + if (tcp->sequenceNumber != expectedSeqNumber) { if (tcp->GetPayload()->GetLength() == 0) From 6fe2cd35e3a5e30e9716ff0c06b722bb59a7d66c Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sat, 6 Apr 2024 20:41:51 +0100 Subject: [PATCH 5/5] DEV9: Increase allowed number of to be ACKed tcp packets --- pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp | 5 +++++ pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h | 1 + pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp index f86d2c3cd2c08..2a08eae80d11a 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.cpp @@ -55,6 +55,11 @@ namespace Sessions std::lock_guard numberlock(myNumberSentry); return GetDelta(_MySequenceNumber, _ReceivedAckNumber); } + bool TCP_Session::ShouldWaitForAck() + { + std::lock_guard numberlock(myNumberSentry); + return _OldMyNumbers[0] == _ReceivedAckNumber; + } std::tuple> TCP_Session::GetAllMyNumbers() { std::lock_guard numberlock(myNumberSentry); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h index 800466d2197a5..09109af5c8278 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session.h @@ -93,6 +93,7 @@ namespace Sessions void UpdateReceivedAckNumber(u32 ack); u32 GetMyNumber(); u32 GetOutstandingSequenceLength(); + bool ShouldWaitForAck(); std::tuple> GetAllMyNumbers(); void ResetMyNumbers(); diff --git a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp index fde4339d29795..8a8eeb50c5af7 100644 --- a/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp +++ b/pcsx2/DEV9/Sessions/TCP_Session/TCP_Session_In.cpp @@ -67,6 +67,8 @@ namespace Sessions return nullptr; } + if (ShouldWaitForAck()) + return nullptr; //Note, windowSize will be updated before _ReceivedAckNumber, potential race condition //in practice, we just get a smaller or -ve maxSize @@ -78,8 +80,7 @@ namespace Sessions else maxSize = std::min(maxSegmentSize, windowSize.load() - outstanding); - if (maxSize > 0 && - myNumberACKed.load()) + if (maxSize > 0) { std::unique_ptr buffer; int err = 0;