diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index c69e419e..3292419a 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -39,7 +39,7 @@ namespace client if (!m_SharedLocalDestination) CreateNewSharedLocalDestination (); - // addressbook + // addressbook m_AddressBook.Start (); // HTTP proxy @@ -207,16 +207,16 @@ namespace client { m_HttpProxy->Stop (); m_HttpProxy = nullptr; - } + } ReadHttpProxy (); - + // recreate SOCKS proxy if (m_SocksProxy) { m_SocksProxy->Stop (); m_SocksProxy = nullptr; - } - ReadSocksProxy (); + } + ReadSocksProxy (); // delete unused destinations std::unique_lock l(m_DestinationsMutex); @@ -391,10 +391,10 @@ namespace client options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND); options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY); options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY); - options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); + options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption(section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); std::string encType = GetI2CPStringOption(section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, ""); - if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; + if (encType.length () > 0) options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = encType; } void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map& options) const @@ -418,21 +418,21 @@ namespace client { int numClientTunnels = 0, numServerTunnels = 0; std::string tunConf; i2p::config::GetOption("tunconf", tunConf); - if (tunConf.empty ()) + if (tunConf.empty ()) { // TODO: cleanup this in 2.8.0 tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); if (i2p::fs::Exists(tunConf)) LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); - else + else tunConf = i2p::fs::DataDirPath ("tunnels.conf"); } LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf); ReadTunnels (tunConf, numClientTunnels, numServerTunnels); - + std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir); if (tunDir.empty ()) - tunDir = i2p::fs::DataDirPath ("tunnels.d"); + tunDir = i2p::fs::DataDirPath ("tunnels.d"); if (i2p::fs::Exists (tunDir)) { std::vector files; @@ -450,7 +450,7 @@ namespace client LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); } - + void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels) { boost::property_tree::ptree pt; @@ -540,7 +540,8 @@ namespace client { // http proxy std::string outproxy = section.second.get("outproxy", ""); - auto tun = std::make_shared(name, address, port, outproxy, localDestination); + bool addresshelper = section.second.get("addresshelper", true); + auto tun = std::make_shared(name, address, port, outproxy, addresshelper, localDestination); clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); } @@ -555,7 +556,7 @@ namespace client { // tcp client auto tun = std::make_shared (name, dest, address, port, localDestination, destinationPort); - clientTunnel = tun; + clientTunnel = tun; clientEndpoint = tun->GetLocalEndpoint (); } uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); @@ -674,7 +675,7 @@ namespace client serverTunnel->SetAccessList (idents); } auto ins = m_ServerTunnels.insert (std::make_pair ( - std::make_pair (localDestination->GetIdentHash (), inPort), + std::make_pair (localDestination->GetIdentHash (), inPort), serverTunnel)); if (ins.second) { @@ -716,6 +717,7 @@ namespace client uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort); i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType); std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL); + bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper); LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort); if (httpProxyKeys.length () > 0) { @@ -732,7 +734,7 @@ namespace client } try { - m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination); + m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, httpAddresshelper, localDestination); m_HttpProxy->Start(); } catch (std::exception& e) @@ -741,7 +743,7 @@ namespace client } } } - + void ClientContext::ReadSocksProxy () { std::shared_ptr localDestination; diff --git a/libi2pd_client/HTTPProxy.cpp b/libi2pd_client/HTTPProxy.cpp index 88c73a8e..df4895a4 100644 --- a/libi2pd_client/HTTPProxy.cpp +++ b/libi2pd_client/HTTPProxy.cpp @@ -64,44 +64,47 @@ namespace proxy { void HostNotFound(std::string & host); void SendProxyError(std::string & content); - void ForwardToUpstreamProxy(); - void HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec); - void HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec); - void HTTPConnect(const std::string & host, uint16_t port); - void HandleHTTPConnectStreamRequestComplete(std::shared_ptr stream); + void ForwardToUpstreamProxy(); + void HandleUpstreamHTTPProxyConnect(const boost::system::error_code & ec); + void HandleUpstreamSocksProxyConnect(const boost::system::error_code & ec); + void HTTPConnect(const std::string & host, uint16_t port); + void HandleHTTPConnectStreamRequestComplete(std::shared_ptr stream); - void HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transfered); - void HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transfered); + void HandleSocksProxySendHandshake(const boost::system::error_code & ec, std::size_t bytes_transfered); + void HandleSocksProxyReply(const boost::system::error_code & ec, std::size_t bytes_transfered); - typedef std::function ProxyResolvedHandler; + typedef std::function ProxyResolvedHandler; - void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr, ProxyResolvedHandler handler); + void HandleUpstreamProxyResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr, ProxyResolvedHandler handler); - void SocksProxySuccess(); - void HandoverToUpstreamProxy(); + void SocksProxySuccess(); + void HandoverToUpstreamProxy(); uint8_t m_recv_chunk[8192]; std::string m_recv_buf; // from client std::string m_send_buf; // to upstream std::shared_ptr m_sock; - std::shared_ptr m_proxysock; - boost::asio::ip::tcp::resolver m_proxy_resolver; - std::string m_OutproxyUrl; - i2p::http::URL m_ProxyURL; - i2p::http::URL m_RequestURL; - uint8_t m_socks_buf[255+8]; // for socks request/response - ssize_t m_req_len; - i2p::http::URL m_ClientRequestURL; - i2p::http::HTTPReq m_ClientRequest; - i2p::http::HTTPRes m_ClientResponse; - std::stringstream m_ClientRequestBuffer; + std::shared_ptr m_proxysock; + boost::asio::ip::tcp::resolver m_proxy_resolver; + std::string m_OutproxyUrl; + bool m_Addresshelper; + i2p::http::URL m_ProxyURL; + i2p::http::URL m_RequestURL; + uint8_t m_socks_buf[255+8]; // for socks request/response + ssize_t m_req_len; + i2p::http::URL m_ClientRequestURL; + i2p::http::HTTPReq m_ClientRequest; + i2p::http::HTTPRes m_ClientResponse; + std::stringstream m_ClientRequestBuffer; + public: HTTPReqHandler(HTTPProxy * parent, std::shared_ptr sock) : I2PServiceHandler(parent), m_sock(sock), m_proxysock(std::make_shared(parent->GetService())), m_proxy_resolver(parent->GetService()), - m_OutproxyUrl(parent->GetOutproxyURL()) {} + m_OutproxyUrl(parent->GetOutproxyURL()), + m_Addresshelper(parent->GetHelperSupport()) {} ~HTTPReqHandler() { Terminate(); } void Handle () { AsyncSockRead(); } /* overload */ }; @@ -114,8 +117,8 @@ namespace proxy { return; } m_sock->async_read_some(boost::asio::buffer(m_recv_chunk, sizeof(m_recv_chunk)), - std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } void HTTPReqHandler::Terminate() { @@ -221,7 +224,7 @@ namespace proxy { /* add headers */ /* close connection, if not Connection: (U|u)pgrade (for websocket) */ auto h = req.GetHeader ("Connection"); - auto x = h.find("pgrade"); + auto x = h.find("pgrade"); if (!(x != std::string::npos && std::tolower(h[x - 1]) == 'u')) req.UpdateHeader("Connection", "close"); } @@ -253,8 +256,7 @@ namespace proxy { std::string jump; if (ExtractAddressHelper(m_RequestURL, jump, m_Confirm)) { - bool addresshelper; i2p::config::GetOption("httpproxy.addresshelper", addresshelper); - if (!addresshelper) + if (!m_Addresshelper) { LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected"); GenericProxyError("Invalid request", "addresshelper is not supported"); @@ -398,9 +400,9 @@ namespace proxy { m_ClientRequest.write(m_ClientRequestBuffer); m_ClientRequestBuffer << m_recv_buf.substr(m_req_len); - + // assume http if empty schema - if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http") + if (m_ProxyURL.schema == "" || m_ProxyURL.schema == "http") { // handle upstream http proxy if (!m_ProxyURL.port) m_ProxyURL.port = 80; @@ -428,8 +430,8 @@ namespace proxy { m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamHTTPProxyConnect, this, std::placeholders::_1)); })); } - } - else if (m_ProxyURL.schema == "socks") + } + else if (m_ProxyURL.schema == "socks") { // handle upstream socks proxy if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified @@ -437,8 +439,8 @@ namespace proxy { m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) { m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1)); })); - } - else + } + else { // unknown type, complain GenericProxyError("unknown outproxy url", m_ProxyURL.to_string().c_str()); @@ -509,7 +511,7 @@ namespace proxy { std::string hostname(host); if(str_rmatch(hostname, ".i2p")) GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleHTTPConnectStreamRequestComplete, - shared_from_this(), std::placeholders::_1), host, port); + shared_from_this(), std::placeholders::_1), host, port); else ForwardToUpstreamProxy(); } @@ -621,9 +623,9 @@ namespace proxy { Done (shared_from_this()); } - HTTPProxy::HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, std::shared_ptr localDestination): - TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), - m_Name (name), m_OutproxyUrl(outproxy) + HTTPProxy::HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination): + TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), + m_Name (name), m_OutproxyUrl (outproxy), m_Addresshelper (addresshelper) { } diff --git a/libi2pd_client/HTTPProxy.h b/libi2pd_client/HTTPProxy.h index 04a43914..590166e3 100644 --- a/libi2pd_client/HTTPProxy.h +++ b/libi2pd_client/HTTPProxy.h @@ -6,12 +6,13 @@ namespace proxy { class HTTPProxy: public i2p::client::TCPIPAcceptor { public: - HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, std::shared_ptr localDestination); + HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr localDestination); HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr localDestination = nullptr) : - HTTPProxy(name, address, port, "", localDestination) {} ; + HTTPProxy(name, address, port, "", true, localDestination) {} ; ~HTTPProxy() {}; std::string GetOutproxyURL() const { return m_OutproxyUrl; } + bool GetHelperSupport() { return m_Addresshelper; } protected: // Implements TCPIPAcceptor @@ -21,6 +22,7 @@ namespace proxy { private: std::string m_Name; std::string m_OutproxyUrl; + bool m_Addresshelper; }; } // http } // i2p