mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-05-24 08:05:31 +00:00
moved datagram destination and session to UDPConnection
Build Debian packages / bookworm (push) Failing after 13s
Build on FreeBSD / with UPnP (push) Failing after 3m28s
Build Debian packages / trixie (push) Failing after 9s
Build Debian packages / bullseye (push) Failing after 1m4s
Build containers / Building container for linux/386 (push) Failing after 30s
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Failing after 3h11m1s
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Failing after 3h13m14s
Build containers / Building container for linux/amd64 (push) Failing after 4m29s
Build containers / Pushing merged manifest (push) Has been skipped
Build on Ubuntu / Make with USE_UPNP=no (push) Failing after 3h13m47s
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Failing after 30s
Build containers / Building container for linux/arm/v7 (push) Failing after 29s
Build on Ubuntu / Make with USE_UPNP=yes (push) Failing after 3h11m2s
Build on OSX / Build on ARM64 (push) Has been cancelled
Build on OSX / Build on Intel x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
Build Debian packages / bookworm (push) Failing after 13s
Build on FreeBSD / with UPnP (push) Failing after 3m28s
Build Debian packages / trixie (push) Failing after 9s
Build Debian packages / bullseye (push) Failing after 1m4s
Build containers / Building container for linux/386 (push) Failing after 30s
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Failing after 3h11m1s
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Failing after 3h13m14s
Build containers / Building container for linux/amd64 (push) Failing after 4m29s
Build containers / Pushing merged manifest (push) Has been skipped
Build on Ubuntu / Make with USE_UPNP=no (push) Failing after 3h13m47s
Build on Windows / clang-x86_64 (push) Has been cancelled
Build on Windows / i686 (push) Has been cancelled
Build on Windows / ucrt-x86_64 (push) Has been cancelled
Build on Windows / x86_64 (push) Has been cancelled
Build on Windows / CMake i686 (push) Has been cancelled
Build on Windows / CMake ucrt-x86_64 (push) Has been cancelled
Build on Windows / CMake x86_64 (push) Has been cancelled
Build on Windows / XP (push) Has been cancelled
Build containers / Building container for linux/arm64 (push) Failing after 30s
Build containers / Building container for linux/arm/v7 (push) Failing after 29s
Build on Ubuntu / Make with USE_UPNP=yes (push) Failing after 3h11m2s
Build on OSX / Build on ARM64 (push) Has been cancelled
Build on OSX / Build on Intel x86_64 (push) Has been cancelled
Build on Windows / CMake clang-x86_64 (push) Has been cancelled
This commit is contained in:
@@ -208,7 +208,7 @@ namespace client
|
||||
options.Put (UDP_SESSION_FLAGS, UDP_SESSION_FLAG_RESET_PATH | UDP_SESSION_FLAG_ACK_REQUESTED);
|
||||
auto session = GetDatagramSession ();
|
||||
session->DropSharedRoutingPath ();
|
||||
GetDatagramDestination ()->SendDatagram (session, nullptr, 0, 0, 0, &options);
|
||||
m_Destination->SendDatagram (session, nullptr, 0, 0, 0, &options);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -227,16 +227,27 @@ namespace client
|
||||
m_UnackedDatagrams.erase (m_UnackedDatagrams.begin (), it);
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> UDPConnection::GetDatagramSession ()
|
||||
{
|
||||
auto session = m_LastDatagramSession.lock ();
|
||||
if (!session && isIdentity)
|
||||
{
|
||||
session = m_Destination->GetSession (Identity);
|
||||
m_LastDatagramSession = session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||
const boost::asio::ip::udp::endpoint& endpoint, const i2p::data::IdentHash& to,
|
||||
uint16_t ourPort, uint16_t theirPort) :
|
||||
UDPConnection (localDestination->GetService()),
|
||||
m_Destination(localDestination->GetDatagramDestination()),
|
||||
IPSocket(localDestination->GetService(), localEndpoint), Identity (to),
|
||||
UDPConnection (localDestination->GetService(), localDestination->GetDatagramDestination()),
|
||||
IPSocket(localDestination->GetService(), localEndpoint),
|
||||
SendEndpoint(endpoint), LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
||||
LastRepliableDatagramTime (0), LocalPort(ourPort), RemotePort(theirPort)
|
||||
{
|
||||
SetIdentity (to);
|
||||
Start ();
|
||||
IPSocket.set_option (boost::asio::socket_base::receive_buffer_size (I2P_UDP_MAX_MTU ));
|
||||
IPSocket.non_blocking (true);
|
||||
@@ -313,17 +324,6 @@ namespace client
|
||||
LogPrint(eLogError, "UDPSession: ", ecode.message());
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> UDPSession::GetDatagramSession ()
|
||||
{
|
||||
auto session = m_LastDatagramSession.lock ();
|
||||
if (!session)
|
||||
{
|
||||
session = m_Destination->GetSession (Identity);
|
||||
m_LastDatagramSession = session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
I2PUDPServerTunnel::I2PUDPServerTunnel (const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
const boost::asio::ip::address& localAddress, const boost::asio::ip::udp::endpoint& forwardTo, uint16_t inPort, bool gzip) :
|
||||
m_IsUniqueLocal (true), m_Name (name), m_LocalAddress (localAddress),
|
||||
@@ -389,7 +389,7 @@ namespace client
|
||||
const boost::asio::ip::udp::endpoint& localEndpoint,
|
||||
std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
uint16_t remotePort, bool gzip, i2p::datagram::DatagramVersion datagramVersion) :
|
||||
UDPConnection (localDestination->GetService ()),
|
||||
UDPConnection (localDestination->GetService (), localDestination->GetDatagramDestination ()),
|
||||
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),
|
||||
@@ -414,6 +414,7 @@ namespace client
|
||||
m_LocalSocket->non_blocking (true);
|
||||
|
||||
auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip, m_DatagramVersion);
|
||||
m_Destination = dgram;
|
||||
dgram->SetReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2P, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4,
|
||||
@@ -451,7 +452,6 @@ namespace client
|
||||
delete m_ResolveThread;
|
||||
m_ResolveThread = nullptr;
|
||||
}
|
||||
m_RemoteAddr = nullptr;
|
||||
UDPConnection::Stop ();
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ namespace client
|
||||
RecvFromLocal (); // Restart listener and continue work
|
||||
return;
|
||||
}
|
||||
if (!m_RemoteAddr || !m_RemoteAddr->IsIdentHash ()) // TODO: handle B33
|
||||
if (!isIdentity)
|
||||
{
|
||||
LogPrint (eLogWarning, "UDP Client: Remote endpoint not resolved yet");
|
||||
RecvFromLocal ();
|
||||
@@ -499,7 +499,7 @@ namespace client
|
||||
}
|
||||
// send off to remote i2p destination
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
LogPrint (eLogDebug, "UDP Client: Send ", transferred, " to ", m_RemoteAddr->identHash.ToBase32 (), ":", RemotePort);
|
||||
LogPrint (eLogDebug, "UDP Client: Send ", transferred, " to ", Identity.ToBase32 (), ":", RemotePort);
|
||||
auto session = GetDatagramSession ();
|
||||
uint64_t repliableDatagramInterval = I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL;
|
||||
if (m_RTT && m_RTT >= I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL && m_RTT < I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL*10) repliableDatagramInterval = m_RTT/10; // 10 - 100 ms
|
||||
@@ -543,7 +543,7 @@ namespace client
|
||||
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 ", Identity.ToBase32 ());
|
||||
m_NextSendPacketNum += numPackets + 1;
|
||||
m_LocalDest->GetDatagramDestination ()->FlushSendQueue (session);
|
||||
|
||||
@@ -565,7 +565,8 @@ namespace client
|
||||
i2p::util::SetThreadName ("UDP Resolver");
|
||||
LogPrint (eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest);
|
||||
|
||||
while (!(m_RemoteAddr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve)
|
||||
std::shared_ptr<const Address> remoteAddr;
|
||||
while (!(remoteAddr = context.GetAddressBook().GetAddress(m_RemoteDest)) && !m_cancel_resolve)
|
||||
{
|
||||
LogPrint (eLogWarning, "UDP Tunnel: Failed to lookup ", m_RemoteDest);
|
||||
std::this_thread::sleep_for (std::chrono::seconds (1));
|
||||
@@ -575,29 +576,24 @@ namespace client
|
||||
LogPrint(eLogError, "UDP Tunnel: Lookup of ", m_RemoteDest, " was cancelled");
|
||||
return;
|
||||
}
|
||||
if (!m_RemoteAddr)
|
||||
if (!remoteAddr)
|
||||
{
|
||||
LogPrint (eLogError, "UDP Tunnel: ", m_RemoteDest, " not found");
|
||||
return;
|
||||
}
|
||||
LogPrint(eLogInfo, "UDP Tunnel: Resolved ", m_RemoteDest, " to ", m_RemoteAddr->identHash.ToBase32 ());
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> I2PUDPClientTunnel::GetDatagramSession ()
|
||||
{
|
||||
auto session = m_LastDatagramSession.lock ();
|
||||
if (!session)
|
||||
if (!remoteAddr->IsIdentHash ()) // TODO: handle B33
|
||||
{
|
||||
session = m_LocalDest->GetDatagramDestination ()->GetSession (m_RemoteAddr->identHash);
|
||||
m_LastDatagramSession = session;
|
||||
LogPrint (eLogError, "UDP Tunnel: ", m_RemoteDest, " resolved to invalid address type");
|
||||
return;
|
||||
}
|
||||
return session;
|
||||
LogPrint(eLogInfo, "UDP Tunnel: Resolved ", m_RemoteDest, " to ", remoteAddr->identHash.ToBase32 ());
|
||||
SetIdentity (remoteAddr->identHash);
|
||||
}
|
||||
|
||||
void I2PUDPClientTunnel::HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
|
||||
const uint8_t * buf, size_t len, const i2p::util::Mapping * options)
|
||||
{
|
||||
if (m_RemoteAddr && from.GetIdentHash() == m_RemoteAddr->identHash)
|
||||
if (isIdentity && from.GetIdentHash() == Identity)
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
@@ -632,7 +628,7 @@ namespace client
|
||||
// found convo
|
||||
if (len > 0)
|
||||
{
|
||||
LogPrint (eLogDebug, "UDP Client: Got ", len, "B from ", m_RemoteAddr ? m_RemoteAddr->identHash.ToBase32 () : "");
|
||||
LogPrint (eLogDebug, "UDP Client: Got ", len, "B from ", isIdentity ? Identity.ToBase32 () : "");
|
||||
boost::system::error_code ec;
|
||||
m_LocalSocket->send_to (boost::asio::buffer (buf, len), itr->second->first, 0, ec);
|
||||
if (!ec)
|
||||
|
||||
+24
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2025, The PurpleI2P Project
|
||||
* Copyright (c) 2013-2026, The PurpleI2P Project
|
||||
*
|
||||
* This file is part of Purple i2pd project and licensed under BSD3
|
||||
*
|
||||
@@ -32,40 +32,43 @@ namespace client
|
||||
const uint64_t I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL = 100; // in milliseconds
|
||||
const uint64_t I2P_UDP_MAX_UNACKED_DATAGRAM_TIME = 8000; // in milliseconds
|
||||
const size_t I2P_UDP_MAX_NUM_UNACKED_DATAGRAMS = 500;
|
||||
|
||||
|
||||
/** max size for i2p udp */
|
||||
const size_t I2P_UDP_MAX_MTU = 64*1024;
|
||||
|
||||
struct UDPConnection
|
||||
struct UDPConnection
|
||||
{
|
||||
i2p::datagram::DatagramDestination * m_Destination;
|
||||
std::weak_ptr<i2p::datagram::DatagramSession> m_LastDatagramSession;
|
||||
i2p::data::IdentHash Identity;
|
||||
bool isIdentity = false;
|
||||
uint32_t m_NextSendPacketNum = 1, m_LastReceivedPacketNum = 0;
|
||||
std::list<std::pair<uint32_t, uint64_t> > m_UnackedDatagrams; // list of sent but not acked repliable datagrams(seqn, timestamp) in ascending order
|
||||
uint64_t m_RTT = 0; // milliseconds
|
||||
|
||||
|
||||
boost::asio::deadline_timer m_AckTimer;
|
||||
uint32_t m_AckTimerSeqn = 0;
|
||||
bool m_IsSendingAllowed = true;
|
||||
bool m_IsFirstPacket = true;
|
||||
|
||||
UDPConnection (boost::asio::io_context& service): m_AckTimer (service) {};
|
||||
|
||||
UDPConnection (boost::asio::io_context& service, i2p::datagram::DatagramDestination * destination):
|
||||
m_Destination (destination), m_AckTimer (service) {};
|
||||
void SetIdentity (const i2p::data::IdentHash& ident) { Identity = ident; isIdentity = true; };
|
||||
|
||||
virtual ~UDPConnection () { Stop (); };
|
||||
virtual void Start () {};
|
||||
virtual void Stop ();
|
||||
|
||||
|
||||
void Acked (uint32_t seqn);
|
||||
void ScheduleAckTimer (uint32_t seqn);
|
||||
void DeleteExpiredUnackedDatagrams ();
|
||||
|
||||
virtual std::shared_ptr<i2p::datagram::DatagramSession> GetDatagramSession () = 0;
|
||||
virtual i2p::datagram::DatagramDestination * GetDatagramDestination () const = 0;
|
||||
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> GetDatagramSession ();
|
||||
};
|
||||
|
||||
|
||||
struct UDPSession: public UDPConnection // for server side
|
||||
{
|
||||
i2p::datagram::DatagramDestination * m_Destination;
|
||||
std::weak_ptr<i2p::datagram::DatagramSession> m_LastDatagramSession;
|
||||
boost::asio::ip::udp::socket IPSocket;
|
||||
i2p::data::IdentHash Identity;
|
||||
boost::asio::ip::udp::endpoint FromEndpoint;
|
||||
boost::asio::ip::udp::endpoint SendEndpoint;
|
||||
uint64_t LastActivity, LastRepliableDatagramTime; // milliseconds
|
||||
@@ -74,15 +77,13 @@ namespace client
|
||||
uint16_t RemotePort;
|
||||
|
||||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||
|
||||
|
||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||
const boost::asio::ip::udp::endpoint& remote, const i2p::data::IdentHash& ident,
|
||||
uint16_t ourPort, uint16_t theirPort);
|
||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||
void Receive();
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> GetDatagramSession () override;
|
||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const override { return m_Destination; }
|
||||
};
|
||||
|
||||
|
||||
@@ -132,12 +133,12 @@ namespace client
|
||||
|
||||
private:
|
||||
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
|
||||
const uint8_t * buf, size_t len, const i2p::util::Mapping * options);
|
||||
void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
UDPSessionPtr ObtainUDPSession (const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
|
||||
uint32_t GetSessionIndex (uint16_t fromPort, uint16_t toPort) const { return ((uint32_t)fromPort << 16) + toPort; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
@@ -179,7 +180,7 @@ namespace client
|
||||
m_LocalDest = dest;
|
||||
}
|
||||
const boost::asio::ip::udp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
||||
|
||||
|
||||
void ExpireStale (const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
||||
|
||||
private:
|
||||
@@ -187,14 +188,11 @@ namespace client
|
||||
typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
||||
void RecvFromLocal ();
|
||||
void HandleRecvFromLocal (const boost::system::error_code & e, std::size_t transferred);
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort,
|
||||
const uint8_t * buf, size_t len, const i2p::util::Mapping * options);
|
||||
void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void TryResolving ();
|
||||
std::shared_ptr<i2p::datagram::DatagramSession> GetDatagramSession () override;
|
||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const override
|
||||
{ return m_LocalDest ? m_LocalDest->GetDatagramDestination () : nullptr; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const std::string m_Name;
|
||||
@@ -203,7 +201,6 @@ namespace client
|
||||
const std::string m_RemoteDest;
|
||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
|
||||
const boost::asio::ip::udp::endpoint m_LocalEndpoint;
|
||||
std::shared_ptr<const Address> m_RemoteAddr;
|
||||
std::thread * m_ResolveThread;
|
||||
std::unique_ptr<boost::asio::ip::udp::socket> m_LocalSocket;
|
||||
boost::asio::ip::udp::endpoint m_RecvEndpoint;
|
||||
@@ -213,9 +210,8 @@ namespace client
|
||||
bool m_Gzip;
|
||||
i2p::datagram::DatagramVersion m_DatagramVersion;
|
||||
std::shared_ptr<UDPConvo> m_LastSession;
|
||||
std::weak_ptr<i2p::datagram::DatagramSession> m_LastDatagramSession;
|
||||
uint64_t m_LastRepliableDatagramTime; // millseconds
|
||||
|
||||
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
|
||||
Reference in New Issue
Block a user