mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
Add support for multiple udp server tunnels on one destionation
This commit is contained in:
parent
c5a1806528
commit
5b93558bd0
@ -19,7 +19,7 @@ namespace i2p
|
|||||||
namespace datagram
|
namespace datagram
|
||||||
{
|
{
|
||||||
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip):
|
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip):
|
||||||
m_Owner (owner), m_Receiver (nullptr), m_RawReceiver (nullptr), m_Gzip (gzip)
|
m_Owner (owner), m_DefaultReceiver (nullptr), m_DefaultRawReceiver (nullptr), m_Gzip (gzip)
|
||||||
{
|
{
|
||||||
if (m_Gzip)
|
if (m_Gzip)
|
||||||
m_Deflator.reset (new i2p::data::GzipDeflator);
|
m_Deflator.reset (new i2p::data::GzipDeflator);
|
||||||
@ -119,19 +119,79 @@ namespace datagram
|
|||||||
|
|
||||||
void DatagramDestination::HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
void DatagramDestination::HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
if (m_RawReceiver)
|
auto r = FindRawReceiver(toPort);
|
||||||
m_RawReceiver (fromPort, toPort, buf, len);
|
|
||||||
|
if (r)
|
||||||
|
r (fromPort, toPort, buf, len);
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram");
|
LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatagramDestination::SetReceiver (const Receiver& receiver, uint16_t port)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
|
||||||
|
m_ReceiversByPorts[port] = receiver;
|
||||||
|
if (!m_DefaultReceiver) {
|
||||||
|
m_DefaultReceiver = receiver;
|
||||||
|
m_DefaultReceiverPort = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatagramDestination::ResetReceiver (uint16_t port)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
|
||||||
|
m_ReceiversByPorts.erase (port);
|
||||||
|
if (m_DefaultReceiverPort == port) {
|
||||||
|
m_DefaultReceiver = nullptr;
|
||||||
|
m_DefaultReceiverPort = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DatagramDestination::SetRawReceiver (const RawReceiver& receiver, uint16_t port)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
|
||||||
|
m_RawReceiversByPorts[port] = receiver;
|
||||||
|
if (!m_DefaultRawReceiver) {
|
||||||
|
m_DefaultRawReceiver = receiver;
|
||||||
|
m_DefaultRawReceiverPort = port;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void DatagramDestination::ResetRawReceiver (uint16_t port)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
|
||||||
|
m_RawReceiversByPorts.erase (port);
|
||||||
|
if (m_DefaultRawReceiverPort == port) {
|
||||||
|
m_DefaultRawReceiver = nullptr;
|
||||||
|
m_DefaultRawReceiverPort = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
|
DatagramDestination::Receiver DatagramDestination::FindReceiver(uint16_t port)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
|
std::lock_guard<std::mutex> lock(m_ReceiversMutex);
|
||||||
Receiver r = m_Receiver;
|
Receiver r = nullptr;
|
||||||
auto itr = m_ReceiversByPorts.find(port);
|
auto itr = m_ReceiversByPorts.find(port);
|
||||||
if (itr != m_ReceiversByPorts.end())
|
if (itr != m_ReceiversByPorts.end())
|
||||||
r = itr->second;
|
r = itr->second;
|
||||||
|
else {
|
||||||
|
r = m_DefaultReceiver;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
DatagramDestination::RawReceiver DatagramDestination::FindRawReceiver(uint16_t port)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_RawReceiversMutex);
|
||||||
|
RawReceiver r = nullptr;
|
||||||
|
auto itr = m_RawReceiversByPorts.find(port);
|
||||||
|
if (itr != m_RawReceiversByPorts.end())
|
||||||
|
r = itr->second;
|
||||||
|
else {
|
||||||
|
r = m_DefaultRawReceiver;
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +126,12 @@ namespace datagram
|
|||||||
|
|
||||||
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false);
|
void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false);
|
||||||
|
|
||||||
void SetReceiver (const Receiver& receiver) { m_Receiver = receiver; };
|
|
||||||
void ResetReceiver () { m_Receiver = nullptr; };
|
|
||||||
|
|
||||||
void SetReceiver (const Receiver& receiver, uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts[port] = receiver; };
|
void SetReceiver (const Receiver& receiver, uint16_t port);
|
||||||
void ResetReceiver (uint16_t port) { std::lock_guard<std::mutex> lock(m_ReceiversMutex); m_ReceiversByPorts.erase (port); };
|
void ResetReceiver (uint16_t port);
|
||||||
|
|
||||||
void SetRawReceiver (const RawReceiver& receiver) { m_RawReceiver = receiver; };
|
void SetRawReceiver (const RawReceiver& receiver, uint16_t port);
|
||||||
void ResetRawReceiver () { m_RawReceiver = nullptr; };
|
void ResetRawReceiver (uint16_t port);
|
||||||
|
|
||||||
std::shared_ptr<DatagramSession::Info> GetInfoForRemote(const i2p::data::IdentHash & remote);
|
std::shared_ptr<DatagramSession::Info> GetInfoForRemote(const i2p::data::IdentHash & remote);
|
||||||
|
|
||||||
@ -150,20 +148,26 @@ namespace datagram
|
|||||||
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
|
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
|
||||||
void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
/** find a receiver by port, if none by port is found try default receiver, otherwise returns nullptr */
|
|
||||||
Receiver FindReceiver(uint16_t port);
|
Receiver FindReceiver(uint16_t port);
|
||||||
|
RawReceiver FindRawReceiver(uint16_t port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<i2p::client::ClientDestination> m_Owner;
|
std::shared_ptr<i2p::client::ClientDestination> m_Owner;
|
||||||
Receiver m_Receiver; // default
|
|
||||||
RawReceiver m_RawReceiver; // default
|
|
||||||
bool m_Gzip; // gzip compression of data messages
|
|
||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::map<i2p::data::IdentHash, DatagramSession_ptr > m_Sessions;
|
std::map<i2p::data::IdentHash, DatagramSession_ptr > m_Sessions;
|
||||||
std::mutex m_ReceiversMutex;
|
|
||||||
std::map<uint16_t, Receiver> m_ReceiversByPorts;
|
|
||||||
|
|
||||||
|
Receiver m_DefaultReceiver;
|
||||||
|
RawReceiver m_DefaultRawReceiver;
|
||||||
|
uint16_t m_DefaultReceiverPort;
|
||||||
|
uint16_t m_DefaultRawReceiverPort;
|
||||||
|
std::mutex m_ReceiversMutex;
|
||||||
|
std::mutex m_RawReceiversMutex;
|
||||||
|
std::unordered_map<uint16_t, Receiver> m_ReceiversByPorts;
|
||||||
|
std::unordered_map<uint16_t, RawReceiver> m_RawReceiversByPorts;
|
||||||
|
|
||||||
|
bool m_Gzip; // gzip compression of data messages
|
||||||
i2p::data::GzipInflator m_Inflator;
|
i2p::data::GzipInflator m_Inflator;
|
||||||
std::unique_ptr<i2p::data::GzipDeflator> m_Deflator;
|
std::unique_ptr<i2p::data::GzipDeflator> m_Deflator;
|
||||||
std::vector<uint8_t> m_From, m_Signature;
|
std::vector<uint8_t> m_From, m_Signature;
|
||||||
|
@ -775,7 +775,7 @@ namespace client
|
|||||||
address = "127.0.0.1";
|
address = "127.0.0.1";
|
||||||
}
|
}
|
||||||
auto localAddress = boost::asio::ip::address::from_string(address);
|
auto localAddress = boost::asio::ip::address::from_string(address);
|
||||||
auto serverTunnel = std::make_shared<I2PUDPServerTunnel>(name, localDestination, localAddress, endpoint, port, gzip);
|
auto serverTunnel = std::make_shared<I2PUDPServerTunnel>(name, localDestination, localAddress, endpoint, inPort, gzip);
|
||||||
if(!isUniqueLocal)
|
if(!isUniqueLocal)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "Clients: Disabling loopback address mapping");
|
LogPrint(eLogInfo, "Clients: Disabling loopback address mapping");
|
||||||
|
@ -415,12 +415,17 @@ namespace client
|
|||||||
{
|
{
|
||||||
session->UDPEndpoint = forward;
|
session->UDPEndpoint = forward;
|
||||||
auto dest = session->GetLocalDestination ()->CreateDatagramDestination ();
|
auto dest = session->GetLocalDestination ()->CreateDatagramDestination ();
|
||||||
|
auto port = std::stoi(params[SAM_PARAM_PORT]);
|
||||||
if (type == eSAMSessionTypeDatagram)
|
if (type == eSAMSessionTypeDatagram)
|
||||||
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
|
||||||
|
port
|
||||||
|
);
|
||||||
else // raw
|
else // raw
|
||||||
dest->SetRawReceiver (std::bind (&SAMSocket::HandleI2PRawDatagramReceive, shared_from_this (),
|
dest->SetRawReceiver (std::bind (&SAMSocket::HandleI2PRawDatagramReceive, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
|
||||||
|
port
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->GetLocalDestination ()->IsReady ())
|
if (session->GetLocalDestination ()->IsReady ())
|
||||||
|
@ -163,9 +163,9 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
I2PUDPServerTunnel::I2PUDPServerTunnel (const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
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 port, bool gzip) :
|
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),
|
m_IsUniqueLocal (true), m_Name (name), m_LocalAddress (localAddress),
|
||||||
m_RemoteEndpoint (forwardTo), m_LocalDest (localDestination), m_Gzip (gzip)
|
m_RemoteEndpoint (forwardTo), m_LocalDest (localDestination), m_inPort(inPort), m_Gzip (gzip)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,14 +179,23 @@ namespace client
|
|||||||
m_LocalDest->Start ();
|
m_LocalDest->Start ();
|
||||||
|
|
||||||
auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip);
|
auto dgram = m_LocalDest->CreateDatagramDestination (m_Gzip);
|
||||||
dgram->SetReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
dgram->SetReceiver (
|
||||||
dgram->SetRawReceiver (std::bind (&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
std::bind (&I2PUDPServerTunnel::HandleRecvFromI2P, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
|
||||||
|
m_inPort
|
||||||
|
);
|
||||||
|
dgram->SetRawReceiver (
|
||||||
|
std::bind (&I2PUDPServerTunnel::HandleRecvFromI2PRaw, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
|
||||||
|
m_inPort
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PUDPServerTunnel::Stop ()
|
void I2PUDPServerTunnel::Stop ()
|
||||||
{
|
{
|
||||||
auto dgram = m_LocalDest->GetDatagramDestination ();
|
auto dgram = m_LocalDest->GetDatagramDestination ();
|
||||||
if (dgram) dgram->ResetReceiver ();
|
if (dgram) {
|
||||||
|
dgram->ResetReceiver (m_inPort);
|
||||||
|
dgram->ResetRawReceiver (m_inPort);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPServerTunnel::GetSessions ()
|
std::vector<std::shared_ptr<DatagramSessionInfo> > I2PUDPServerTunnel::GetSessions ()
|
||||||
@ -240,9 +249,13 @@ namespace client
|
|||||||
dgram->SetReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2P, this,
|
dgram->SetReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2P, this,
|
||||||
std::placeholders::_1, std::placeholders::_2,
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
std::placeholders::_3, std::placeholders::_4,
|
std::placeholders::_3, std::placeholders::_4,
|
||||||
std::placeholders::_5));
|
std::placeholders::_5),
|
||||||
|
RemotePort
|
||||||
|
);
|
||||||
dgram->SetRawReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this,
|
dgram->SetRawReceiver (std::bind (&I2PUDPClientTunnel::HandleRecvFromI2PRaw, this,
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
|
||||||
|
RemotePort
|
||||||
|
);
|
||||||
|
|
||||||
m_LocalDest->Start ();
|
m_LocalDest->Start ();
|
||||||
if (m_ResolveThread == nullptr)
|
if (m_ResolveThread == nullptr)
|
||||||
@ -253,7 +266,10 @@ namespace client
|
|||||||
void I2PUDPClientTunnel::Stop ()
|
void I2PUDPClientTunnel::Stop ()
|
||||||
{
|
{
|
||||||
auto dgram = m_LocalDest->GetDatagramDestination ();
|
auto dgram = m_LocalDest->GetDatagramDestination ();
|
||||||
if (dgram) dgram->ResetReceiver ();
|
if (dgram) {
|
||||||
|
dgram->ResetReceiver (RemotePort);
|
||||||
|
dgram->ResetRawReceiver (RemotePort);
|
||||||
|
}
|
||||||
m_cancel_resolve = true;
|
m_cancel_resolve = true;
|
||||||
|
|
||||||
m_Sessions.clear();
|
m_Sessions.clear();
|
||||||
|
@ -116,6 +116,7 @@ namespace client
|
|||||||
std::unordered_map<uint32_t, UDPSessionPtr> m_Sessions; // (from port, to port)->session
|
std::unordered_map<uint32_t, UDPSessionPtr> m_Sessions; // (from port, to port)->session
|
||||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
|
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
|
||||||
UDPSessionPtr m_LastSession;
|
UDPSessionPtr m_LastSession;
|
||||||
|
uint16_t m_inPort;
|
||||||
bool m_Gzip;
|
bool m_Gzip;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user