mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-10-17 09:10:21 +01:00
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
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:
parent
dd029793e1
commit
fffb68c5e0
5 changed files with 46 additions and 18 deletions
|
@ -226,10 +226,10 @@ namespace datagram
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint16_t flags = bufbe16toh (buf + identityLen);
|
const uint8_t * flags = buf + identityLen;
|
||||||
size_t offset = identityLen + 2;
|
size_t offset = identityLen + 2;
|
||||||
bool isOptions = false;
|
bool isOptions = false;
|
||||||
if (flags & DATAGRAM2_FLAG_OPTIONS)
|
if (flags[1] & DATAGRAM2_FLAG_OPTIONS)
|
||||||
{
|
{
|
||||||
isOptions = true;
|
isOptions = true;
|
||||||
m_Options.CleanUp ();
|
m_Options.CleanUp ();
|
||||||
|
@ -250,7 +250,7 @@ namespace datagram
|
||||||
if (!verified)
|
if (!verified)
|
||||||
{
|
{
|
||||||
std::shared_ptr<i2p::crypto::Verifier> transientVerifier;
|
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);
|
transientVerifier = i2p::data::ProcessOfflineSignature (&identity, buf, len, offset);
|
||||||
if (!transientVerifier)
|
if (!transientVerifier)
|
||||||
|
@ -308,10 +308,10 @@ namespace datagram
|
||||||
auto r = FindReceiver(toPort);
|
auto r = FindReceiver(toPort);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
uint16_t flags = bufbe16toh (buf + 32);
|
const uint8_t * flags = buf + 32;
|
||||||
size_t offset = 34;
|
size_t offset = 34;
|
||||||
bool isOptions = false;
|
bool isOptions = false;
|
||||||
if (flags & DATAGRAM3_FLAG_OPTIONS)
|
if (flags[1] & DATAGRAM3_FLAG_OPTIONS)
|
||||||
{
|
{
|
||||||
isOptions = true;
|
isOptions = true;
|
||||||
m_Options.CleanUp ();
|
m_Options.CleanUp ();
|
||||||
|
|
|
@ -53,9 +53,9 @@ namespace datagram
|
||||||
eDatagramV3 = 3,
|
eDatagramV3 = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint16_t DATAGRAM2_FLAG_OPTIONS = 0x10;
|
constexpr uint8_t DATAGRAM2_FLAG_OPTIONS = 0x10;
|
||||||
constexpr uint16_t DATAGRAM2_FLAG_OFFLINE_SIGNATURE = 0x20;
|
constexpr uint8_t DATAGRAM2_FLAG_OFFLINE_SIGNATURE = 0x20;
|
||||||
constexpr uint16_t DATAGRAM3_FLAG_OPTIONS = 0x10;
|
constexpr uint8_t DATAGRAM3_FLAG_OPTIONS = 0x10;
|
||||||
|
|
||||||
class DatagramSession : public std::enable_shared_from_this<DatagramSession>
|
class DatagramSession : public std::enable_shared_from_this<DatagramSession>
|
||||||
{
|
{
|
||||||
|
|
|
@ -247,12 +247,12 @@ namespace util
|
||||||
static size_t WriteOption (std::string_view param, std::string_view value, uint8_t * buf, size_t len);
|
static size_t WriteOption (std::string_view param, std::string_view value, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool Get(std::string_view param, T& value)
|
bool Get(std::string_view param, T& value) const
|
||||||
{
|
{
|
||||||
auto s = (*this)[param];
|
auto s = (*this)[param];
|
||||||
if (s.empty ()) return false;
|
if (s.empty ()) return false;
|
||||||
auto res = std::from_chars(s.data(), s.data() + s.size(), value);
|
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>
|
template<typename T>
|
||||||
bool Put (std::string_view param, T value)
|
bool Put (std::string_view param, T value)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
|
@ -16,6 +17,9 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace client
|
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,
|
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)
|
const uint8_t * buf, size_t len, const i2p::util::Mapping * options)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +31,15 @@ namespace client
|
||||||
m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
m_LastSession->LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
else
|
else
|
||||||
LogPrint (eLogInfo, "UDP Server: Send exception: ", ec.message (), " to ", m_RemoteEndpoint);
|
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)
|
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,
|
const boost::asio::ip::udp::endpoint& endpoint, const i2p::data::IdentHash& to,
|
||||||
uint16_t ourPort, uint16_t theirPort) :
|
uint16_t ourPort, uint16_t theirPort) :
|
||||||
m_Destination(localDestination->GetDatagramDestination()),
|
m_Destination(localDestination->GetDatagramDestination()),
|
||||||
IPSocket(localDestination->GetService(), localEndpoint),
|
IPSocket(localDestination->GetService(), localEndpoint), Identity (to),
|
||||||
Identity (to), SendEndpoint(endpoint),
|
SendEndpoint(endpoint), LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
||||||
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
LocalPort(ourPort), RemotePort(theirPort), m_NextSendPacketNum (1), m_LastReceivedPacketNum (0)
|
||||||
LocalPort(ourPort),
|
|
||||||
RemotePort(theirPort)
|
|
||||||
{
|
{
|
||||||
IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU ));
|
IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU ));
|
||||||
IPSocket.non_blocking (true);
|
IPSocket.non_blocking (true);
|
||||||
|
@ -149,7 +160,13 @@ namespace client
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
auto session = m_Destination->GetSession (Identity);
|
auto session = m_Destination->GetSession (Identity);
|
||||||
if (ts > LastActivity + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
|
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
|
else
|
||||||
m_Destination->SendRawDatagram(session, m_Buffer, len, LocalPort, RemotePort);
|
m_Destination->SendRawDatagram(session, m_Buffer, len, LocalPort, RemotePort);
|
||||||
size_t numPackets = 0;
|
size_t numPackets = 0;
|
||||||
|
@ -164,6 +181,7 @@ namespace client
|
||||||
}
|
}
|
||||||
if (numPackets > 0)
|
if (numPackets > 0)
|
||||||
LogPrint(eLogDebug, "UDPSession: Forward more ", numPackets, "packets B from ", FromEndpoint);
|
LogPrint(eLogDebug, "UDPSession: Forward more ", numPackets, "packets B from ", FromEndpoint);
|
||||||
|
m_NextSendPacketNum += numPackets + 1;
|
||||||
m_Destination->FlushSendQueue (session);
|
m_Destination->FlushSendQueue (session);
|
||||||
LastActivity = ts;
|
LastActivity = ts;
|
||||||
Receive();
|
Receive();
|
||||||
|
@ -238,7 +256,8 @@ namespace client
|
||||||
uint16_t remotePort, bool gzip, i2p::datagram::DatagramVersion datagramVersion) :
|
uint16_t remotePort, bool gzip, i2p::datagram::DatagramVersion datagramVersion) :
|
||||||
m_Name (name), m_RemoteDest (remoteDest), m_LocalDest (localDestination), m_LocalEndpoint (localEndpoint),
|
m_Name (name), m_RemoteDest (remoteDest), m_LocalDest (localDestination), m_LocalEndpoint (localEndpoint),
|
||||||
m_ResolveThread (nullptr), m_LocalSocket (nullptr), RemotePort (remotePort),
|
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);
|
LogPrint (eLogDebug, "UDP Client: Send ", transferred, " to ", m_RemoteAddr->identHash.ToBase32 (), ":", RemotePort);
|
||||||
auto session = m_LocalDest->GetDatagramDestination ()->GetSession (m_RemoteAddr->identHash);
|
auto session = m_LocalDest->GetDatagramDestination ()->GetSession (m_RemoteAddr->identHash);
|
||||||
if (ts > m_LastSession->second + I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL)
|
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
|
else
|
||||||
m_LocalDest->GetDatagramDestination ()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
|
m_LocalDest->GetDatagramDestination ()->SendRawDatagram (session, m_RecvBuff, transferred, remotePort, RemotePort);
|
||||||
size_t numPackets = 0;
|
size_t numPackets = 0;
|
||||||
|
@ -356,6 +381,7 @@ namespace client
|
||||||
}
|
}
|
||||||
if (numPackets)
|
if (numPackets)
|
||||||
LogPrint (eLogDebug, "UDP Client: Sent ", numPackets, " more packets to ", m_RemoteAddr->identHash.ToBase32 ());
|
LogPrint (eLogDebug, "UDP Client: Sent ", numPackets, " more packets to ", m_RemoteAddr->identHash.ToBase32 ());
|
||||||
|
m_NextSendPacketNum += numPackets + 1;
|
||||||
m_LocalDest->GetDatagramDestination ()->FlushSendQueue (session);
|
m_LocalDest->GetDatagramDestination ()->FlushSendQueue (session);
|
||||||
|
|
||||||
// mark convo as active
|
// mark convo as active
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace client
|
||||||
uint16_t RemotePort;
|
uint16_t RemotePort;
|
||||||
|
|
||||||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||||
|
uint32_t m_NextSendPacketNum, m_LastReceivedPacketNum;
|
||||||
|
|
||||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
|
@ -180,6 +181,7 @@ namespace client
|
||||||
bool m_Gzip;
|
bool m_Gzip;
|
||||||
i2p::datagram::DatagramVersion m_DatagramVersion;
|
i2p::datagram::DatagramVersion m_DatagramVersion;
|
||||||
std::shared_ptr<UDPConvo> m_LastSession;
|
std::shared_ptr<UDPConvo> m_LastSession;
|
||||||
|
uint32_t m_NextSendPacketNum, m_LastReceivedPacketNum;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue