From eb561bb0c2e0e343670f91735dbdd3ec6470f24e Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 1 Apr 2022 15:09:35 -0400 Subject: [PATCH] handle Ack ranges --- libi2pd/SSU2.cpp | 27 +++++++++++++++++++++++---- libi2pd/SSU2.h | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index efdd54bc..98ab2f1b 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -794,17 +794,36 @@ namespace transport void SSU2Session::HandleAck (const uint8_t * buf, size_t len) { if (m_SentPackets.empty ()) return; + if (len < 5) return; + // acnt uint32_t ackThrough = bufbe32toh (buf); - uint32_t firstPacketNum = ackThrough > buf[4] ? ackThrough - buf[4] : 0; // acnt + uint32_t firstPacketNum = ackThrough > buf[4] ? ackThrough - buf[4] : 0; + HandleAckRange (firstPacketNum, ackThrough); // acnt + // ranges + len -= 5; + const uint8_t * ranges = buf + 5; + while (len > 0 && firstPacketNum) + { + uint32_t lastPacketNum = firstPacketNum - 1; + if (*ranges > lastPacketNum) break; + lastPacketNum -= *ranges; ranges++; // nacks + if (*ranges > lastPacketNum) break; + firstPacketNum -= *ranges; ranges++; // acks + len -= 2; + HandleAckRange (firstPacketNum, lastPacketNum); + } + } + + void SSU2Session::HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum) + { auto it = m_SentPackets.begin (); while (it != m_SentPackets.end () && it->first < firstPacketNum) it++; // find first acked packet if (it == m_SentPackets.end ()) return; // not found auto it1 = it; - while (it1 != m_SentPackets.end () && it1->first <= ackThrough) it1++; + while (it1 != m_SentPackets.end () && it1->first <= lastPacketNum) it1++; it1--; m_SentPackets.erase (it, it1); - // TODO: handle ranges - } + } bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) { diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h index f50aa7b4..f7f73ec2 100644 --- a/libi2pd/SSU2.h +++ b/libi2pd/SSU2.h @@ -153,6 +153,7 @@ namespace transport bool HandlePayload (const uint8_t * buf, size_t len); // returns true is contains data void HandleAck (const uint8_t * buf, size_t len); + void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum); bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep); std::shared_ptr ExtractRouterInfo (const uint8_t * buf, size_t size); void CreateNonce (uint64_t seqn, uint8_t * nonce);