assign next available UDP port to UDP associate

This commit is contained in:
orignal 2025-10-26 21:09:12 -04:00
parent aafaebc560
commit e73f738bfa
2 changed files with 28 additions and 6 deletions

View file

@ -127,6 +127,7 @@ namespace proxy
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
void Terminate(); void Terminate();
void AsyncSockRead(); void AsyncSockRead();
SOCKSServer * GetServer () { return (SOCKSServer *)GetOwner (); };
boost::asio::const_buffer GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); boost::asio::const_buffer GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port);
boost::asio::const_buffer GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); boost::asio::const_buffer GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port);
bool Socks5ChooseAuth(); bool Socks5ChooseAuth();
@ -234,6 +235,7 @@ namespace proxy
if (m_UDPTunnel) if (m_UDPTunnel)
{ {
m_UDPTunnel->Stop (); m_UDPTunnel->Stop ();
GetServer ()->ReleaseLocalUDPPort (m_UDPTunnel->GetLocalEndpoint ().port ());
m_UDPTunnel = nullptr; m_UDPTunnel = nullptr;
} }
Done(shared_from_this()); Done(shared_from_this());
@ -647,19 +649,16 @@ namespace proxy
shared_from_this(), std::placeholders::_1), m_address.dns.ToString(), m_port); shared_from_this(), std::placeholders::_1), m_address.dns.ToString(), m_port);
break; break;
case CMD_UDP: case CMD_UDP:
{
// create UDP client tunnel // create UDP client tunnel
LogPrint (eLogInfo, "SOCKS: New UDP associate connection"); LogPrint (eLogInfo, "SOCKS: New UDP associate connection");
const auto& localEndpoint = ((SOCKSServer *)GetOwner ())->GetLocalEndpoint ();
m_UDPTunnel = std::make_unique<i2p::client::I2PUDPClientTunnel>("", addr, m_UDPTunnel = std::make_unique<i2p::client::I2PUDPClientTunnel>("", addr,
boost::asio::ip::udp::endpoint (localEndpoint.address (), localEndpoint.port ()), // use proxy endpoint TODO: select UDP port GetServer ()->GetNextLocalUDPEndpoint (),
GetOwner ()->GetLocalDestination (), m_port, false, i2p::datagram::eDatagramV3); GetOwner ()->GetLocalDestination (), m_port, false, i2p::datagram::eDatagramV3);
boost::asio::post (GetOwner ()->GetService (), [this](void) boost::asio::post (GetOwner ()->GetService (), [this](void)
{ {
SocksRequestSuccess(); SocksRequestSuccess();
}); });
break; break;
}
default: ; default: ;
} }
} }
@ -872,5 +871,25 @@ namespace proxy
m_UpstreamProxyPort = port; m_UpstreamProxyPort = port;
m_UseUpstreamProxy = true; m_UseUpstreamProxy = true;
} }
boost::asio::ip::udp::endpoint SOCKSServer::GetNextLocalUDPEndpoint ()
{
const auto& localEndpoint = GetLocalEndpoint ();
uint16_t port = localEndpoint.port ();
#if __cplusplus >= 202002L // C++20
while (m_UDPPorts.contains (port))
#else
while (m_UDPPorts.count (port) > 0)
#endif
port++;
m_UDPPorts.insert (port);
return boost::asio::ip::udp::endpoint (localEndpoint.address (), port); // use proxy address
}
void SOCKSServer::ReleaseLocalUDPPort (uint16_t port)
{
m_UDPPorts.erase (port);
}
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2023, The PurpleI2P Project * Copyright (c) 2013-2025, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -28,6 +28,8 @@ namespace proxy
~SOCKSServer() {}; ~SOCKSServer() {};
void SetUpstreamProxy(const std::string & addr, const uint16_t port); void SetUpstreamProxy(const std::string & addr, const uint16_t port);
boost::asio::ip::udp::endpoint GetNextLocalUDPEndpoint ();
void ReleaseLocalUDPPort (uint16_t port);
protected: protected:
@ -41,6 +43,7 @@ namespace proxy
std::string m_UpstreamProxyAddress; std::string m_UpstreamProxyAddress;
uint16_t m_UpstreamProxyPort; uint16_t m_UpstreamProxyPort;
bool m_UseUpstreamProxy; bool m_UseUpstreamProxy;
std::set<uint16_t> m_UDPPorts;
}; };
typedef SOCKSServer SOCKSProxy; typedef SOCKSServer SOCKSProxy;