send and receive sequence number in UDP tunnels
Some checks are pending
Build Debian packages / bookworm (push) Waiting to run
Build Debian packages / bullseye (push) Waiting to run
Build Debian packages / trixie (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=no (push) Waiting to run
Build on OSX / With USE_UPNP=yes (push) Waiting to run
Build on Windows / clang-x86_64 (push) Waiting to run
Build on Windows / i686 (push) Waiting to run
Build on Windows / ucrt-x86_64 (push) Waiting to run
Build on Windows / x86_64 (push) Waiting to run
Build on Windows / CMake clang-x86_64 (push) Waiting to run
Build on Windows / CMake i686 (push) Waiting to run
Build on Windows / CMake ucrt-x86_64 (push) Waiting to run
Build on Windows / CMake x86_64 (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=no (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=yes (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Waiting to run
Build containers / Building container for linux/amd64 (push) Waiting to run
Build containers / Building container for linux/arm64 (push) Waiting to run
Build containers / Building container for linux/arm/v7 (push) Waiting to run
Build containers / Building container for linux/386 (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions

This commit is contained in:
orignal 2025-10-01 22:06:57 -04:00
parent dd029793e1
commit fffb68c5e0
5 changed files with 46 additions and 18 deletions

View file

@ -226,10 +226,10 @@ namespace datagram
}
}
}
uint16_t flags = bufbe16toh (buf + identityLen);
const uint8_t * flags = buf + identityLen;
size_t offset = identityLen + 2;
bool isOptions = false;
if (flags & DATAGRAM2_FLAG_OPTIONS)
if (flags[1] & DATAGRAM2_FLAG_OPTIONS)
{
isOptions = true;
m_Options.CleanUp ();
@ -250,7 +250,7 @@ namespace datagram
if (!verified)
{
std::shared_ptr<i2p::crypto::Verifier> transientVerifier;
if (flags & DATAGRAM2_FLAG_OFFLINE_SIGNATURE)
if (flags[1] & DATAGRAM2_FLAG_OFFLINE_SIGNATURE)
{
transientVerifier = i2p::data::ProcessOfflineSignature (&identity, buf, len, offset);
if (!transientVerifier)
@ -308,10 +308,10 @@ namespace datagram
auto r = FindReceiver(toPort);
if (r)
{
uint16_t flags = bufbe16toh (buf + 32);
const uint8_t * flags = buf + 32;
size_t offset = 34;
bool isOptions = false;
if (flags & DATAGRAM3_FLAG_OPTIONS)
if (flags[1] & DATAGRAM3_FLAG_OPTIONS)
{
isOptions = true;
m_Options.CleanUp ();

View file

@ -53,9 +53,9 @@ namespace datagram
eDatagramV3 = 3,
};
constexpr uint16_t DATAGRAM2_FLAG_OPTIONS = 0x10;
constexpr uint16_t DATAGRAM2_FLAG_OFFLINE_SIGNATURE = 0x20;
constexpr uint16_t DATAGRAM3_FLAG_OPTIONS = 0x10;
constexpr uint8_t DATAGRAM2_FLAG_OPTIONS = 0x10;
constexpr uint8_t DATAGRAM2_FLAG_OFFLINE_SIGNATURE = 0x20;
constexpr uint8_t DATAGRAM3_FLAG_OPTIONS = 0x10;
class DatagramSession : public std::enable_shared_from_this<DatagramSession>
{

View file

@ -247,12 +247,12 @@ namespace util
static size_t WriteOption (std::string_view param, std::string_view value, uint8_t * buf, size_t len);
template<typename T>
bool Get(std::string_view param, T& value)
bool Get(std::string_view param, T& value) const
{
auto s = (*this)[param];
if (s.empty ()) return false;
auto res = std::from_chars(s.data(), s.data() + s.size(), value);
return res.ec != std::errc();
return res.ec == std::errc();
}
template<typename T>
bool Put (std::string_view param, T value)

View file

@ -6,6 +6,7 @@
* See full license text in LICENSE file at top of project tree
*/
#include <string_view>
#include "Log.h"
#include "util.h"
#include "ClientContext.h"
@ -16,6 +17,9 @@ namespace i2p
{
namespace client
{
constexpr std::string_view UDP_SESSION_SEQN { "seqn" };
constexpr std::string_view UDP_SESSION_ACKED { "acked" };
void I2PUDPServerTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
const uint8_t * buf, size_t len, const i2p::util::Mapping * options)
{
@ -27,6 +31,15 @@ namespace client
m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch();
else
LogPrint (eLogInfo, "UDP Server: Send exception: ", ec.message (), " to ", m_RemoteEndpoint);
if (options)
{
uint32_t seqn = 0;
if (options->Get (UDP_SESSION_SEQN, seqn) && seqn > m_LastSession->m_LastReceivedPacketNum)
{
m_LastSession->m_LastReceivedPacketNum = seqn;
LogPrint (eLogDebug, "UDP Server: Received packet with seqn ", seqn);
}
}
}
void I2PUDPServerTunnel::HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
@ -123,11 +136,9 @@ namespace client
const boost::asio::ip::udp::endpoint& endpoint, const i2p::data::IdentHash& to,
uint16_t ourPort, uint16_t theirPort) :
m_Destination(localDestination->GetDatagramDestination()),
IPSocket(localDestination->GetService(), localEndpoint),
Identity (to), SendEndpoint(endpoint),
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
LocalPort(ourPort),
RemotePort(theirPort)
IPSocket(localDestination->GetService(), localEndpoint), Identity (to),
SendEndpoint(endpoint), LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
LocalPort(ourPort), RemotePort(theirPort), m_NextSendPacketNum (1), m_LastReceivedPacketNum (0)
{
IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU ));
IPSocket.non_blocking (true);
@ -149,7 +160,13 @@ namespace client
auto ts = i2p::util::GetMillisecondsSinceEpoch();
auto session = m_Destination->GetSession (Identity);
if (ts > LastActivity + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort);
{
i2p::util::Mapping options;
options.Put (UDP_SESSION_SEQN, m_NextSendPacketNum);
if (m_LastReceivedPacketNum > 0)
options.Put (UDP_SESSION_ACKED, m_LastReceivedPacketNum);
m_Destination->SendDatagram(session, m_Buffer, len, LocalPort, RemotePort, &options);
}
else
m_Destination->SendRawDatagram(session, m_Buffer, len, LocalPort, RemotePort);
size_t numPackets = 0;
@ -164,6 +181,7 @@ namespace client
}
if (numPackets > 0)
LogPrint(eLogDebug, "UDPSession: Forward more ", numPackets, "packets B from ", FromEndpoint);
m_NextSendPacketNum += numPackets + 1;
m_Destination->FlushSendQueue (session);
LastActivity = ts;
Receive();
@ -238,7 +256,8 @@ namespace client
uint16_t remotePort, bool gzip, i2p::datagram::DatagramVersion datagramVersion) :
m_Name (name), m_RemoteDest (remoteDest), m_LocalDest (localDestination), m_LocalEndpoint (localEndpoint),
m_ResolveThread (nullptr), m_LocalSocket (nullptr), RemotePort (remotePort),
m_LastPort (0), m_cancel_resolve (false), m_Gzip (gzip), m_DatagramVersion (datagramVersion)
m_LastPort (0), m_cancel_resolve (false), m_Gzip (gzip), m_DatagramVersion (datagramVersion),
m_NextSendPacketNum (1), m_LastReceivedPacketNum (0)
{
}
@ -339,7 +358,13 @@ namespace client
LogPrint (eLogDebug, "UDP Client: Send ", transferred, " to ", m_RemoteAddr->identHash.ToBase32 (), ":", RemotePort);
auto session = m_LocalDest->GetDatagramDestination ()->GetSession (m_RemoteAddr->identHash);
if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
m_LocalDest->GetDatagramDestination ()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
{
i2p::util::Mapping options;
options.Put (UDP_SESSION_SEQN, m_NextSendPacketNum);
if (m_LastReceivedPacketNum > 0)
options.Put (UDP_SESSION_ACKED, m_LastReceivedPacketNum);
m_LocalDest->GetDatagramDestination ()->SendDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort, &options);
}
else
m_LocalDest->GetDatagramDestination ()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
size_t numPackets = 0;
@ -356,6 +381,7 @@ namespace client
}
if (numPackets)
LogPrint (eLogDebug, "UDP Client: Sent ", numPackets, " more packets to ", m_RemoteAddr->identHash.ToBase32 ());
m_NextSendPacketNum += numPackets + 1;
m_LocalDest->GetDatagramDestination ()->FlushSendQueue (session);
// mark convo as active

View file

@ -46,6 +46,7 @@ namespace client
uint16_t RemotePort;
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
uint32_t m_NextSendPacketNum, m_LastReceivedPacketNum;
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
@ -180,6 +181,7 @@ namespace client
bool m_Gzip;
i2p::datagram::DatagramVersion m_DatagramVersion;
std::shared_ptr<UDPConvo> m_LastSession;
uint32_t m_NextSendPacketNum, m_LastReceivedPacketNum;
public: