diff --git a/BOB.cpp b/BOB.cpp index 724933d9..cbe8f142 100644 --- a/BOB.cpp +++ b/BOB.cpp @@ -524,9 +524,11 @@ namespace client SendReplyError ("malformed"); } - BOBCommandChannel::BOBCommandChannel (int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) + BOBCommandChannel::BOBCommandChannel(const std::string& address, int port) + : m_IsRunning (false), m_Thread (nullptr), + m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint( + boost::asio::ip::address::from_string(address), port) + ) { // command -> handler m_CommandHandlers[BOB_COMMAND_ZAP] = &BOBCommandSession::ZapCommandHandler; diff --git a/BOB.h b/BOB.h index 801571cb..ca7e4c45 100644 --- a/BOB.h +++ b/BOB.h @@ -199,7 +199,7 @@ namespace client { public: - BOBCommandChannel (int port); + BOBCommandChannel(const std::string& address, int port); ~BOBCommandChannel (); void Start (); diff --git a/ClientContext.cpp b/ClientContext.cpp index c7514a3b..34e195e0 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -42,10 +42,18 @@ namespace client std::string proxyKeys = i2p::util::config::GetArg("-proxykeys", ""); if (proxyKeys.length () > 0) 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(); 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(); LogPrint("SOCKS Proxy Started"); @@ -58,9 +66,15 @@ namespace client if (ircKeys.length () > 0) localDestination = LoadLocalDestination (ircKeys, false); 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 (); - m_ClientTunnels.insert (std::make_pair(ircPort, std::unique_ptr(ircTunnel))); + // TODO: allow muliple tunnels on the same port (but on a different address) + m_ClientTunnels.insert(std::make_pair( + ircPort, std::unique_ptr(ircTunnel) + )); LogPrint("IRC tunnel started"); } std::string eepKeys = i2p::util::config::GetArg("-eepkeys", ""); @@ -79,7 +93,9 @@ namespace client int samPort = i2p::util::config::GetArg("-samport", 0); if (samPort) { - m_SamBridge = new SAMBridge (samPort); + m_SamBridge = new SAMBridge( + i2p::util::config::GetArg("-samaddress", "127.0.0.1"), samPort + ); m_SamBridge->Start (); LogPrint("SAM bridge started"); } @@ -88,17 +104,21 @@ namespace client int bobPort = i2p::util::config::GetArg("-bobport", 0); if (bobPort) { - m_BOBCommandChannel = new BOBCommandChannel (bobPort); + m_BOBCommandChannel = new BOBCommandChannel( + i2p::util::config::GetArg("-bobaddress", "127.0.0.1"), bobPort + ); m_BOBCommandChannel->Start (); LogPrint("BOB command channel started"); } // I2P Control int i2pcontrolPort = i2p::util::config::GetArg("-i2pcontrolport", 0); - if (i2pcontrolPort) - { - m_I2PControlService = new I2PControlService (i2pcontrolPort); - m_I2PControlService->Start (); + if(i2pcontrolPort) { + m_I2PControlService = new I2PControlService( + i2p::util::config::GetArg("-i2pcontroladdress", "127.0.0.1"), + i2pcontrolPort + ); + m_I2PControlService->Start(); LogPrint("I2PControl started"); } m_AddressBook.Start (); @@ -259,43 +279,46 @@ namespace client void ClientContext::ReadTunnels () { boost::property_tree::ptree pt; - try - { - boost::property_tree::read_ini (i2p::util::filesystem::GetFullPath (TUNNELS_CONFIG_FILENAME), pt); - } - catch (std::exception& ex) - { - LogPrint (eLogWarning, "Can't read ", TUNNELS_CONFIG_FILENAME, ": ", ex.what ()); + try { + boost::property_tree::read_ini( + i2p::util::filesystem::GetFullPath(TUNNELS_CONFIG_FILENAME), + pt + ); + } catch(const std::exception& ex) { + LogPrint(eLogWarning, "Can't read ", TUNNELS_CONFIG_FILENAME, ": ", ex.what ()); return; } int numClientTunnels = 0, numServerTunnels = 0; - for (auto& section: pt) - { + for(auto& section: pt) { std::string name = section.first; - try - { + try { std::string type = section.second.get (I2P_TUNNELS_SECTION_TYPE); - if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT) - { + if(type == I2P_TUNNELS_SECTION_TYPE_CLIENT) { // mandatory params std::string dest = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION); int port = section.second.get (I2P_CLIENT_TUNNEL_PORT); // optional params - std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); - int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); + std::string address = section.second.get( + 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 localDestination = nullptr; - if (keys.length () > 0) + if(keys.length () > 0) localDestination = LoadLocalDestination (keys, false); - auto clientTunnel = new I2PClientTunnel (dest, port, localDestination, destinationPort); - if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr(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(clientTunnel))).second) clientTunnel->Start (); else LogPrint (eLogError, "I2P client tunnel with port ", port, " already exists"); 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 std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); @@ -307,19 +330,16 @@ namespace client 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); - if (accessList.length () > 0) - { + if (accessList.length () > 0) { std::set idents; size_t pos = 0, comma; - do - { + do { comma = accessList.find (',', pos); i2p::data::IdentHash ident; ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); idents.insert (ident); pos = comma + 1; - } - while (comma != std::string::npos); + } while (comma != std::string::npos); serverTunnel->SetAccessList (idents); } if (m_ServerTunnels.insert (std::make_pair (localDestination->GetIdentHash (), std::unique_ptr(serverTunnel))).second) @@ -327,13 +347,10 @@ namespace client else LogPrint (eLogError, "I2P server tunnel for destination ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), " already exists"); numServerTunnels++; - } - else + } else LogPrint (eLogWarning, "Unknown section type=", type, " of ", name, " in ", TUNNELS_CONFIG_FILENAME); - } - catch (std::exception& ex) - { + } catch (const std::exception& ex) { LogPrint (eLogError, "Can't read tunnel ", name, " params: ", ex.what ()); } } diff --git a/ClientContext.h b/ClientContext.h index 0506b945..52a7a0e7 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -22,6 +22,7 @@ namespace client const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; 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_KEYS[] = "keys"; const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport"; diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 25f9b3f1..3902348e 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -285,8 +285,8 @@ namespace proxy } } - HTTPProxyServer::HTTPProxyServer(int port, std::shared_ptr localDestination): - TCPIPAcceptor(port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) + HTTPProxyServer::HTTPProxyServer(const std::string& address, int port, std::shared_ptr localDestination): + TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) { } diff --git a/HTTPProxy.h b/HTTPProxy.h index 33dc898e..9fe8fdc7 100644 --- a/HTTPProxy.h +++ b/HTTPProxy.h @@ -16,7 +16,7 @@ namespace proxy { public: - HTTPProxyServer(int port, std::shared_ptr localDestination = nullptr); + HTTPProxyServer(const std::string& address, int port, std::shared_ptr localDestination = nullptr); ~HTTPProxyServer() {}; protected: diff --git a/I2PControl.cpp b/I2PControl.cpp index 3e62f947..9c36b2ac 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -22,10 +22,12 @@ namespace i2p { namespace client { - I2PControlService::I2PControlService (int port): - m_Password (I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), - m_ShutdownTimer (m_Service) + I2PControlService::I2PControlService(const std::string& address, int port) + : m_Password(I2P_CONTROL_DEFAULT_PASSWORD), m_IsRunning(false), + m_Thread(nullptr), m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint( + 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_ECHO] = &I2PControlService::EchoHandler; diff --git a/I2PControl.h b/I2PControl.h index 47ed0d3f..9dae9344 100644 --- a/I2PControl.h +++ b/I2PControl.h @@ -66,7 +66,7 @@ namespace client { public: - I2PControlService (int port); + I2PControlService(const std::string& address, int port); ~I2PControlService (); void Start (); diff --git a/I2PService.h b/I2PService.h index 78fad26b..cde91132 100644 --- a/I2PService.h +++ b/I2PService.h @@ -81,14 +81,12 @@ namespace client class TCPIPAcceptor: public I2PService { public: - TCPIPAcceptor (int port, std::shared_ptr localDestination = nullptr) : - I2PService(localDestination), - m_Acceptor (GetService (), boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)), - m_Timer (GetService ()) {} - TCPIPAcceptor (int port, i2p::data::SigningKeyType kt) : - I2PService(kt), - m_Acceptor (GetService (), boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)), - m_Timer (GetService ()) {} + TCPIPAcceptor(const std::string& address, int port, std::shared_ptr localDestination = nullptr) + : I2PService(localDestination), m_Acceptor(GetService(), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_Timer (GetService()) {} + TCPIPAcceptor(const std::string& address, int port, i2p::data::SigningKeyType kt) + : I2PService(kt), m_Acceptor(GetService(), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), + m_Timer(GetService()) {} virtual ~TCPIPAcceptor () { TCPIPAcceptor::Stop(); } //If you override this make sure you call it from the children void Start (); diff --git a/I2PTunnel.cpp b/I2PTunnel.cpp index e0e84d6a..50ecd27c 100644 --- a/I2PTunnel.cpp +++ b/I2PTunnel.cpp @@ -256,8 +256,12 @@ namespace client Done(shared_from_this()); } - I2PClientTunnel::I2PClientTunnel (const std::string& destination, int port, std::shared_ptr localDestination, int destinationPort): - TCPIPAcceptor (port,localDestination), m_Destination (destination), m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) + I2PClientTunnel::I2PClientTunnel( + const std::string& destination, const std::string& address, int port, + std::shared_ptr localDestination, int destinationPort + ) + : TCPIPAcceptor(address, port, localDestination), m_Destination(destination), + m_DestinationIdentHash(nullptr), m_DestinationPort(destinationPort) {} void I2PClientTunnel::Start () diff --git a/I2PTunnel.h b/I2PTunnel.h index c8fe92d8..4eff2ba7 100644 --- a/I2PTunnel.h +++ b/I2PTunnel.h @@ -86,7 +86,10 @@ namespace client public: - I2PClientTunnel (const std::string& destination, int port, std::shared_ptr localDestination, int destinationPort = 0); + I2PClientTunnel( + const std::string& destination, const std::string& address, int port, + std::shared_ptr localDestination, int destinationPort = 0 + ); ~I2PClientTunnel () {} void Start (); diff --git a/README.md b/README.md index c021a46a..f11bce6e 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,12 @@ Cmdline options * --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. * --httpproxyport= - The port to listen on (HTTP Proxy) +* --httpproxyaddress= - The address to listen on (HTTP 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 * --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 * --irckeys= - optional keys file for tunnel's local destination * --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 * --eepport= - Port incoming trafic forward to. 80 by default * --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 +* --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 +* --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) 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. diff --git a/SAM.cpp b/SAM.cpp index d8ed184f..9014f373 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -684,10 +684,13 @@ namespace client sockets.clear (); } - SAMBridge::SAMBridge (int port): - m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), - m_DatagramEndpoint (boost::asio::ip::udp::v4 (), port-1), m_DatagramSocket (m_Service, m_DatagramEndpoint) + SAMBridge::SAMBridge(const std::string& address, int port) + : m_IsRunning (false), m_Thread (nullptr), + m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint( + 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) { } diff --git a/SAM.h b/SAM.h index 06063fb6..10b97191 100644 --- a/SAM.h +++ b/SAM.h @@ -146,7 +146,7 @@ namespace client { public: - SAMBridge (int port); + SAMBridge(const std::string& address, int port); ~SAMBridge (); void Start (); diff --git a/SOCKS.cpp b/SOCKS.cpp index 7d0d020e..be68d35d 100644 --- a/SOCKS.cpp +++ b/SOCKS.cpp @@ -560,8 +560,11 @@ namespace proxy } } - SOCKSServer::SOCKSServer(int port, std::shared_ptr localDestination) : - TCPIPAcceptor (port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) + SOCKSServer::SOCKSServer(const std::string& address, int port, std::shared_ptr localDestination) + : TCPIPAcceptor( + address, port, + localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination() + ) { } diff --git a/SOCKS.h b/SOCKS.h index 87469c79..1f779f89 100644 --- a/SOCKS.h +++ b/SOCKS.h @@ -15,7 +15,8 @@ namespace proxy { public: - SOCKSServer(int port, std::shared_ptr localDestination = nullptr); + SOCKSServer(const std::string& address, int port, + std::shared_ptr localDestination = nullptr); ~SOCKSServer() {}; protected: