Browse Source

Make address for proxies, BOB, SAM, ... configurable (#235).

pull/237/head
EinMByte 9 years ago
parent
commit
524a02cb0d
  1. 8
      BOB.cpp
  2. 2
      BOB.h
  3. 99
      ClientContext.cpp
  4. 1
      ClientContext.h
  5. 4
      HTTPProxy.cpp
  6. 2
      HTTPProxy.h
  7. 10
      I2PControl.cpp
  8. 2
      I2PControl.h
  9. 14
      I2PService.h
  10. 8
      I2PTunnel.cpp
  11. 5
      I2PTunnel.h
  12. 6
      README.md
  13. 11
      SAM.cpp
  14. 2
      SAM.h
  15. 7
      SOCKS.cpp
  16. 3
      SOCKS.h

8
BOB.cpp

@ -524,9 +524,11 @@ namespace client
SendReplyError ("malformed"); SendReplyError ("malformed");
} }
BOBCommandChannel::BOBCommandChannel (int port): BOBCommandChannel::BOBCommandChannel(const std::string& address, int port)
m_IsRunning (false), m_Thread (nullptr), : m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint(
boost::asio::ip::address::from_string(address), port)
)
{ {
// command -> handler // command -> handler
m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler; m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler;

2
BOB.h

@ -199,7 +199,7 @@ namespace client
{ {
public: public:
BOBCommandChannel (int port); BOBCommandChannel(const std::string& address, int port);
~BOBCommandChannel (); ~BOBCommandChannel ();
void Start (); void Start ();

99
ClientContext.cpp

@ -42,10 +42,18 @@ namespace client
std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", ""); std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", "");
if (proxyKeys.length () > 0) if (proxyKeys.length () > 0)
localDestination = LoadLocalDestination (proxyKeys, false); localDestination = LoadLocalDestination (proxyKeys, false);
m_HttpProxy = new i2p::proxy::HTTPProxy(i2p::util::config::GetArg("-httpproxyport", 4446), localDestination); m_HttpProxy = new i2p::proxy::HTTPProxy(
i2p::util::config::GetArg("-httpproxyaddress", "127.0.0.1"),
i2p::util::config::GetArg("-httpproxyport", 4446),
localDestination
);
m_HttpProxy->Start(); m_HttpProxy->Start();
LogPrint("HTTP Proxy started"); LogPrint("HTTP Proxy started");
m_SocksProxy = new i2p::proxy::SOCKSProxy(i2p::util::config::GetArg("-socksproxyport", 4447), localDestination); m_SocksProxy = new i2p::proxy::SOCKSProxy(
i2p::util::config::GetArg("-socksproxyaddress", "127.0.0.1"),
i2p::util::config::GetArg("-socksproxyport", 4447),
localDestination
);
m_SocksProxy->Start(); m_SocksProxy->Start();
LogPrint("SOCKS Proxy Started"); LogPrint("SOCKS Proxy Started");
@ -58,9 +66,15 @@ namespace client
if (ircKeys.length () > 0) if (ircKeys.length () > 0)
localDestination = LoadLocalDestination (ircKeys, false); localDestination = LoadLocalDestination (ircKeys, false);
auto ircPort = i2p::util::config::GetArg("-ircport", 6668); auto ircPort = i2p::util::config::GetArg("-ircport", 6668);
auto ircTunnel = new I2PClientTunnel (ircDestination, ircPort, localDestination); auto ircTunnel = new I2PClientTunnel(
ircDestination, i2p::util::config::GetArg("-ircaddress", "127.0.0.1"),
ircPort, localDestination
);
ircTunnel->Start (); ircTunnel->Start ();
m_ClientTunnels.insert (std::make_pair(ircPort, std::unique_ptr<I2PClientTunnel>(ircTunnel))); // TODO: allow muliple tunnels on the same port (but on a different address)
m_ClientTunnels.insert(std::make_pair(
ircPort, std::unique_ptr<I2PClientTunnel>(ircTunnel)
));
LogPrint("IRC tunnel started"); LogPrint("IRC tunnel started");
} }
std::string eepKeys = i2p::util::config::GetArg("-eepkeys", ""); std::string eepKeys = i2p::util::config::GetArg("-eepkeys", "");
@ -79,7 +93,9 @@ namespace client
int samPort = i2p::util::config::GetArg("-samport", 0); int samPort = i2p::util::config::GetArg("-samport", 0);
if (samPort) if (samPort)
{ {
m_SamBridge = new SAMBridge (samPort); m_SamBridge = new SAMBridge(
i2p::util::config::GetArg("-samaddress", "127.0.0.1"), samPort
);
m_SamBridge->Start (); m_SamBridge->Start ();
LogPrint("SAM bridge started"); LogPrint("SAM bridge started");
} }
@ -88,17 +104,21 @@ namespace client
int bobPort = i2p::util::config::GetArg("-bobport", 0); int bobPort = i2p::util::config::GetArg("-bobport", 0);
if (bobPort) if (bobPort)
{ {
m_BOBCommandChannel = new BOBCommandChannel (bobPort); m_BOBCommandChannel = new BOBCommandChannel(
i2p::util::config::GetArg("-bobaddress", "127.0.0.1"), bobPort
);
m_BOBCommandChannel->Start (); m_BOBCommandChannel->Start ();
LogPrint("BOB command channel started"); LogPrint("BOB command channel started");
} }
// I2P Control // I2P Control
int i2pcontrolPort = i2p::util::config::GetArg("-i2pcontrolport", 0); int i2pcontrolPort = i2p::util::config::GetArg("-i2pcontrolport", 0);
if (i2pcontrolPort) if(i2pcontrolPort) {
{ m_I2PControlService = new I2PControlService(
m_I2PControlService = new I2PControlService (i2pcontrolPort); i2p::util::config::GetArg("-i2pcontroladdress", "127.0.0.1"),
m_I2PControlService->Start (); i2pcontrolPort
);
m_I2PControlService->Start();
LogPrint("I2PControl started"); LogPrint("I2PControl started");
} }
m_AddressBook.Start (); m_AddressBook.Start ();
@ -259,43 +279,46 @@ namespace client
void ClientContext::ReadTunnels () void ClientContext::ReadTunnels ()
{ {
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
try try {
{ boost::property_tree::read_ini(
boost::property_tree::read_ini (i2p::util::filesystem::GetFullPath (TUNNELS_CONFIG_FILENAME), pt); i2p::util::filesystem::GetFullPath(TUNNELS_CONFIG_FILENAME),
} pt
catch (std::exception& ex) );
{ } catch(const std::exception& ex) {
LogPrint (eLogWarning, "Can't read ", TUNNELS_CONFIG_FILENAME, ": ", ex.what ()); LogPrint(eLogWarning, "Can't read ", TUNNELS_CONFIG_FILENAME, ": ", ex.what ());
return; return;
} }
int numClientTunnels = 0, numServerTunnels = 0; int numClientTunnels = 0, numServerTunnels = 0;
for (auto& section: pt) for(auto& section: pt) {
{
std::string name = section.first; std::string name = section.first;
try try {
{
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE); std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT) if(type == I2P_TUNNELS_SECTION_TYPE_CLIENT) {
{
// mandatory params // mandatory params
std::string dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION); std::string dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT); int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT);
// optional params // optional params
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); std::string address = section.second.get(
int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"
);
std::string keys = section.second.get(I2P_CLIENT_TUNNEL_KEYS, "");
int destinationPort = section.second.get(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0);
std::shared_ptr<ClientDestination> localDestination = nullptr; std::shared_ptr<ClientDestination> localDestination = nullptr;
if (keys.length () > 0) if(keys.length () > 0)
localDestination = LoadLocalDestination (keys, false); localDestination = LoadLocalDestination (keys, false);
auto clientTunnel = new I2PClientTunnel (dest, port, localDestination, destinationPort);
if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr<I2PClientTunnel>(clientTunnel))).second) auto clientTunnel = new I2PClientTunnel(
dest, address, port, localDestination, destinationPort
);
// TODO: allow muliple tunnels on the same port (but on a different address)
if(m_ClientTunnels.insert(std::make_pair(port, std::unique_ptr<I2PClientTunnel>(clientTunnel))).second)
clientTunnel->Start (); clientTunnel->Start ();
else else
LogPrint (eLogError, "I2P client tunnel with port ", port, " already exists"); LogPrint (eLogError, "I2P client tunnel with port ", port, " already exists");
numClientTunnels++; numClientTunnels++;
} } else if(type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP)
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP)
{ {
// mandatory params // mandatory params
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST); std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
@ -307,19 +330,16 @@ namespace client
auto localDestination = LoadLocalDestination (keys, true); auto localDestination = LoadLocalDestination (keys, true);
I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ? new I2PServerTunnelHTTP (host, port, localDestination, inPort) : new I2PServerTunnel (host, port, localDestination, inPort); I2PServerTunnel * serverTunnel = (type == I2P_TUNNELS_SECTION_TYPE_HTTP) ? new I2PServerTunnelHTTP (host, port, localDestination, inPort) : new I2PServerTunnel (host, port, localDestination, inPort);
if (accessList.length () > 0) if (accessList.length () > 0) {
{
std::set<i2p::data::IdentHash> idents; std::set<i2p::data::IdentHash> idents;
size_t pos = 0, comma; size_t pos = 0, comma;
do do {
{
comma = accessList.find (',', pos); comma = accessList.find (',', pos);
i2p::data::IdentHash ident; i2p::data::IdentHash ident;
ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
idents.insert (ident); idents.insert (ident);
pos = comma + 1; pos = comma + 1;
} } while (comma != std::string::npos);
while (comma != std::string::npos);
serverTunnel->SetAccessList (idents); serverTunnel->SetAccessList (idents);
} }
if (m_ServerTunnels.insert (std::make_pair (localDestination->GetIdentHash (), std::unique_ptr<I2PServerTunnel>(serverTunnel))).second) if (m_ServerTunnels.insert (std::make_pair (localDestination->GetIdentHash (), std::unique_ptr<I2PServerTunnel>(serverTunnel))).second)
@ -327,13 +347,10 @@ namespace client
else else
LogPrint (eLogError, "I2P server tunnel for destination ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), " already exists"); LogPrint (eLogError, "I2P server tunnel for destination ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), " already exists");
numServerTunnels++; numServerTunnels++;
} } else
else
LogPrint (eLogWarning, "Unknown section type=", type, " of ", name, " in ", TUNNELS_CONFIG_FILENAME); LogPrint (eLogWarning, "Unknown section type=", type, " of ", name, " in ", TUNNELS_CONFIG_FILENAME);
} } catch (const std::exception& ex) {
catch (std::exception& ex)
{
LogPrint (eLogError, "Can't read tunnel ", name, " params: ", ex.what ()); LogPrint (eLogError, "Can't read tunnel ", name, " params: ", ex.what ());
} }
} }

1
ClientContext.h

@ -22,6 +22,7 @@ namespace client
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
const char I2P_CLIENT_TUNNEL_PORT[] = "port"; const char I2P_CLIENT_TUNNEL_PORT[] = "port";
const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address";
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination"; const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
const char I2P_CLIENT_TUNNEL_KEYS[] = "keys"; const char I2P_CLIENT_TUNNEL_KEYS[] = "keys";
const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport";

4
HTTPProxy.cpp

@ -285,8 +285,8 @@ namespace proxy
} }
} }
HTTPProxyServer::HTTPProxyServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination): HTTPProxyServer::HTTPProxyServer(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
TCPIPAcceptor(port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
{ {
} }

2
HTTPProxy.h

@ -16,7 +16,7 @@ namespace proxy
{ {
public: public:
HTTPProxyServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr); HTTPProxyServer(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
~HTTPProxyServer() {}; ~HTTPProxyServer() {};
protected: protected:

10
I2PControl.cpp

@ -22,10 +22,12 @@ namespace i2p
{ {
namespace client namespace client
{ {
I2PControlService::I2PControlService (int port): I2PControlService::I2PControlService(const std::string& address, int port)
m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr), : m_Password(I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning(false),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), m_Thread(nullptr), m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint(
m_ShutdownTimer (m_Service) boost::asio::ip::address::from_string(address), port)
),
m_ShutdownTimer (m_Service)
{ {
m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler; m_MethodHandlers[I2P_CONTROL_METHOD_AUTHENTICATE] = &I2PControlService::AuthenticateHandler;
m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler; m_MethodHandlers[I2P_CONTROL_METHOD_ECHO] = &I2PControlService::EchoHandler;

2
I2PControl.h

@ -66,7 +66,7 @@ namespace client
{ {
public: public:
I2PControlService (int port); I2PControlService(const std::string& address, int port);
~I2PControlService (); ~I2PControlService ();
void Start (); void Start ();

14
I2PService.h

@ -81,14 +81,12 @@ namespace client
class TCPIPAcceptor: public I2PService class TCPIPAcceptor: public I2PService
{ {
public: public:
TCPIPAcceptor (int port, std::shared_ptr<ClientDestination> localDestination = nullptr) : TCPIPAcceptor(const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr)
I2PService(localDestination), : I2PService(localDestination), m_Acceptor(GetService(), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
m_Acceptor (GetService (), boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)), m_Timer (GetService()) {}
m_Timer (GetService ()) {} TCPIPAcceptor(const std::string& address, int port, i2p::data::SigningKeyType kt)
TCPIPAcceptor (int port, i2p::data::SigningKeyType kt) : : I2PService(kt), m_Acceptor(GetService(), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
I2PService(kt), m_Timer(GetService()) {}
m_Acceptor (GetService (), boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)),
m_Timer (GetService ()) {}
virtual ~TCPIPAcceptor () { TCPIPAcceptor::Stop(); } virtual ~TCPIPAcceptor () { TCPIPAcceptor::Stop(); }
//If you override this make sure you call it from the children //If you override this make sure you call it from the children
void Start (); void Start ();

8
I2PTunnel.cpp

@ -256,8 +256,12 @@ namespace client
Done(shared_from_this()); Done(shared_from_this());
} }
I2PClientTunnel::I2PClientTunnel (const std::string& destination, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort): I2PClientTunnel::I2PClientTunnel(
TCPIPAcceptor (port,localDestination), m_Destination (destination), m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) const std::string& destination, const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, int destinationPort
)
: TCPIPAcceptor(address, port, localDestination), m_Destination(destination),
m_DestinationIdentHash(nullptr), m_DestinationPort(destinationPort)
{} {}
void I2PClientTunnel::Start () void I2PClientTunnel::Start ()

5
I2PTunnel.h

@ -86,7 +86,10 @@ namespace client
public: public:
I2PClientTunnel (const std::string& destination, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0); I2PClientTunnel(
const std::string& destination, const std::string& address, int port,
std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0
);
~I2PClientTunnel () {} ~I2PClientTunnel () {}
void Start (); void Start ();

6
README.md

@ -81,9 +81,12 @@ Cmdline options
* --floodfill= - 1 if router is floodfill, off by default * --floodfill= - 1 if router is floodfill, off by default
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O if not. Always O if floodfill, otherwise L by default. * --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O if not. Always O if floodfill, otherwise L by default.
* --httpproxyport= - The port to listen on (HTTP Proxy) * --httpproxyport= - The port to listen on (HTTP Proxy)
* --httpproxyaddress= - The address to listen on (HTTP Proxy)
* --socksproxyport= - The port to listen on (SOCKS Proxy) * --socksproxyport= - The port to listen on (SOCKS Proxy)
* --socksproxyaddress= - The address to listen on (SOCKS Proxy)
* --proxykeys= - optional keys file for proxy's local destination * --proxykeys= - optional keys file for proxy's local destination
* --ircport= - The local port of IRC tunnel to listen on. 6668 by default * --ircport= - The local port of IRC tunnel to listen on. 6668 by default
* --irchost= - The adddress of IRC tunnel to listen on, 127.0.0.1 by default
* --ircdest= - I2P destination address of IRC server. For example irc.postman.i2p * --ircdest= - I2P destination address of IRC server. For example irc.postman.i2p
* --irckeys= - optional keys file for tunnel's local destination * --irckeys= - optional keys file for tunnel's local destination
* --eepkeys= - File name containing destination keys, for example privKeys.dat. * --eepkeys= - File name containing destination keys, for example privKeys.dat.
@ -91,8 +94,11 @@ Cmdline options
* --eephost= - Address incoming trafic forward to. 127.0.0.1 by default * --eephost= - Address incoming trafic forward to. 127.0.0.1 by default
* --eepport= - Port incoming trafic forward to. 80 by default * --eepport= - Port incoming trafic forward to. 80 by default
* --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified * --samport= - Port of SAM bridge. Usually 7656. SAM is off if not specified
* --samhost= - Address of SAM bridge, 127.0.0.1 by default (only used if SAM is on)
* --bobport= - Port of BOB command channel. Usually 2827. BOB is off if not specified * --bobport= - Port of BOB command channel. Usually 2827. BOB is off if not specified
* --bobaddress= - Address of BOB service, 127.0.0.1 by default (only used if BOB is on)
* --i2pcontrolport= - Port of I2P control service. Usually 7650. I2PControl is off if not specified * --i2pcontrolport= - Port of I2P control service. Usually 7650. I2PControl is off if not specified
* --i2pcontroladdress= - Address of I2P control service, 127.0.0.1 by default (only used if I2PControl is on)
* --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf) * --conf= - Config file (default: ~/.i2pd/i2p.conf or /var/lib/i2pd/i2p.conf)
This parameter will be silently ignored if the specified config file does not exist. This parameter will be silently ignored if the specified config file does not exist.
Options specified on the command line take precedence over those in the config file. Options specified on the command line take precedence over those in the config file.

11
SAM.cpp

@ -684,10 +684,13 @@ namespace client
sockets.clear (); sockets.clear ();
} }
SAMBridge::SAMBridge (int port): SAMBridge::SAMBridge(const std::string& address, int port)
m_IsRunning (false), m_Thread (nullptr), : m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint(
m_DatagramEndpoint (boost::asio::ip::udp::v4 (), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint) boost::asio::ip::address::from_string(address), port)
),
m_DatagramEndpoint(boost::asio::ip::address::from_string(address), port - 1),
m_DatagramSocket(m_Service, m_DatagramEndpoint)
{ {
} }

2
SAM.h

@ -146,7 +146,7 @@ namespace client
{ {
public: public:
SAMBridge (int port); SAMBridge(const std::string& address, int port);
~SAMBridge (); ~SAMBridge ();
void Start (); void Start ();

7
SOCKS.cpp

@ -560,8 +560,11 @@ namespace proxy
} }
} }
SOCKSServer::SOCKSServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination) : SOCKSServer::SOCKSServer(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination)
TCPIPAcceptor (port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) : TCPIPAcceptor(
address, port,
localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination()
)
{ {
} }

3
SOCKS.h

@ -15,7 +15,8 @@ namespace proxy
{ {
public: public:
SOCKSServer(int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr); SOCKSServer(const std::string& address, int port,
std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
~SOCKSServer() {}; ~SOCKSServer() {};
protected: protected:

Loading…
Cancel
Save