From d582c30f6e45f6a47bfcdc1e7608bb03ecd2dc6d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Apr 2016 17:32:24 -0400 Subject: [PATCH 01/49] allow same port at different interfaces --- ClientContext.cpp | 5 +++-- ClientContext.h | 6 +++--- I2PService.h | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 59f11f21..2eb81af2 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -328,7 +328,8 @@ namespace client localDestination = CreateNewLocalDestination (k, false, &options); } auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); - if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr(clientTunnel))).second) + if (m_ClientTunnels.insert (std::make_pair (clientTunnel->GetAcceptor ().local_endpoint (), + std::unique_ptr(clientTunnel))).second) clientTunnel->Start (); else LogPrint (eLogError, "Clients: I2P client tunnel with port ", port, " already exists"); @@ -382,7 +383,7 @@ namespace client serverTunnel->SetAccessList (idents); } if (m_ServerTunnels.insert (std::make_pair ( - std::make_tuple (localDestination->GetIdentHash (), inPort), + std::make_pair (localDestination->GetIdentHash (), inPort), std::unique_ptr(serverTunnel))).second) serverTunnel->Start (); else diff --git a/ClientContext.h b/ClientContext.h index a05c2161..3381228b 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -2,9 +2,9 @@ #define CLIENT_CONTEXT_H__ #include -#include #include #include +#include #include "Destination.h" #include "HTTPProxy.h" #include "SOCKS.h" @@ -78,8 +78,8 @@ namespace client i2p::proxy::HTTPProxy * m_HttpProxy; i2p::proxy::SOCKSProxy * m_SocksProxy; - std::map > m_ClientTunnels; // port->tunnel - std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel + std::map > m_ClientTunnels; // local endpoint->tunnel + std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel SAMBridge * m_SamBridge; BOBCommandChannel * m_BOBCommandChannel; diff --git a/I2PService.h b/I2PService.h index 251a379a..2df11909 100644 --- a/I2PService.h +++ b/I2PService.h @@ -118,6 +118,9 @@ namespace client void Start (); //If you override this make sure you call it from the children void Stop (); + + const boost::asio::ip::tcp::acceptor& GetAcceptor () const { return m_Acceptor; }; + protected: virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } From 85840872ab50fe7e1af312d51912a3ebba3362f9 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Tue, 26 Apr 2016 19:39:10 +0200 Subject: [PATCH 02/49] family: volatile.crt --- contrib/certificates/family/volatile.crt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 contrib/certificates/family/volatile.crt diff --git a/contrib/certificates/family/volatile.crt b/contrib/certificates/family/volatile.crt new file mode 100644 index 00000000..928c7f39 --- /dev/null +++ b/contrib/certificates/family/volatile.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxDCCAWmgAwIBAgIJAJnJIdKHYwWcMAoGCCqGSM49BAMCMGcxCzAJBgNVBAYT +AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn +aXRzIFB0eSBMdGQxIDAeBgNVBAMMF3ZvbGF0aWxlLmZhbWlseS5pMnAubmV0MB4X +DTE2MDQyNjE1MjAyNloXDTI2MDQyNDE1MjAyNlowZzELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDEgMB4GA1UEAwwXdm9sYXRpbGUuZmFtaWx5LmkycC5uZXQwWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAARf6LBfbbfL6HInvC/4wAGaN3rj0eeLE/OdBpA93R3L +s8EUp0YTEJHWPo9APiKMmAwQSsMJfjhNrbp+UWEnnx2LMAoGCCqGSM49BAMCA0kA +MEYCIQDpQu2KPV5G1JOFLoZvdj+rcvEnjxM/FxkaqikwkVx8FAIhANP7DkUal+GT +SuiCtcqM4QyIBsfsCJBWEMzovft164Bo +-----END CERTIFICATE----- From a78caa2976d3d96f8ac2defb7622c48e456e0630 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 00:31:33 +0200 Subject: [PATCH 03/49] added SetFamilyString(); GetFamilyString() and shows family in webiface --- HTTPServer.cpp | 1 + RouterContext.cpp | 12 ++++++++++++ RouterContext.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6c2c6112..08b67e22 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -417,6 +417,7 @@ namespace util default: s << "Unknown"; } s << "
\r\n"; + s << "Family: " << i2p::context.GetFamilyString() << "
\r\n"; s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "Received: "; s << std::fixed << std::setprecision(2); diff --git a/RouterContext.cpp b/RouterContext.cpp index f35d8426..4cdf13fe 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,11 +149,23 @@ namespace i2p UpdateRouterInfo (); } + std::string RouterContext::GetFamilyString () const + { + return m_FamilyString; + } + void RouterContext::SetFamily (const std::string& family) { + + m_FamilyString = family; + if (m_FamilyString.length() == 0) + m_FamilyString = "<undefined>"; + std::string signature; if (family.length () > 0) + { signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); + } if (signature.length () > 0) { m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); diff --git a/RouterContext.h b/RouterContext.h index 9766c66e..1b0f7ed2 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,6 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); + std::string GetFamilyString () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ bool AcceptsTunnels () const { return m_AcceptsTunnels; }; @@ -100,6 +101,7 @@ namespace i2p i2p::data::PrivateKeys m_Keys; uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; + std::string m_FamilyString; uint64_t m_StartupTime; // in seconds since epoch uint32_t m_BandwidthLimit; // allowed bandwidth RouterStatus m_Status; From 61e8becd38e2b1af4948fa56333f8ee82d66040b Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 00:48:23 +0200 Subject: [PATCH 04/49] wrong file version --- Daemon.cpp | 1 + RouterContext.cpp | 14 ++++++++------ RouterContext.h | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index 81bbcdd5..2a32ff04 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -189,6 +189,7 @@ namespace i2p std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); + i2p::context.SetFamilyString (family); if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); diff --git a/RouterContext.cpp b/RouterContext.cpp index 4cdf13fe..bc1f3fc1 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,6 +149,14 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::SetFamilyString (const std::string& family) + { + if (family.length() > 0) + m_FamilyString = family; + else + m_FamilyString = "<undefined>"; + } + std::string RouterContext::GetFamilyString () const { return m_FamilyString; @@ -157,15 +165,9 @@ namespace i2p void RouterContext::SetFamily (const std::string& family) { - m_FamilyString = family; - if (m_FamilyString.length() == 0) - m_FamilyString = "<undefined>"; - std::string signature; if (family.length () > 0) - { signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); - } if (signature.length () > 0) { m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); diff --git a/RouterContext.h b/RouterContext.h index 1b0f7ed2..def89383 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,6 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); + void SetFamilyString (const std::string& family); std::string GetFamilyString () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ From ebee94fb11b436add295ae791cb1fe53c6e99d7d Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 01:19:27 +0200 Subject: [PATCH 05/49] removed 1 blank line.. --- RouterContext.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index bc1f3fc1..29891169 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -164,7 +164,6 @@ namespace i2p void RouterContext::SetFamily (const std::string& family) { - std::string signature; if (family.length () > 0) signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); From 7cf171671db8de9f7dfb34029d2ec7c1db94709c Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 06/49] * HTTPConnection::reply : to_buffers() -> to_string() --- HTTPServer.cpp | 57 +++++++++++++++++++++----------------------------- HTTPServer.h | 4 ++-- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6c2c6112..6897a347 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -212,42 +212,32 @@ namespace util } // namespace misc_strings - std::vector HTTPConnection::reply::to_buffers(int status) + std::string HTTPConnection::reply::to_string(int code) { - std::vector buffers; + std::stringstream ss(""); if (headers.size () > 0) { - status_string = "HTTP/1.1 "; - status_string += std::to_string (status); - status_string += " "; - switch (status) + const char *status; + switch (code) { - case 105: status_string += "Name Not Resolved"; break; - case 200: status_string += "OK"; break; - case 400: status_string += "Bad Request"; break; - case 404: status_string += "Not Found"; break; - case 408: status_string += "Request Timeout"; break; - case 500: status_string += "Internal Server Error"; break; - case 502: status_string += "Bad Gateway"; break; - case 503: status_string += "Not Implemented"; break; - case 504: status_string += "Gateway Timeout"; break; - default: status_string += "WTF"; + case 105: status = "Name Not Resolved"; break; + case 200: status = "OK"; break; + case 400: status = "Bad Request"; break; + case 404: status = "Not Found"; break; + case 408: status = "Request Timeout"; break; + case 500: status = "Internal Server Error"; break; + case 502: status = "Bad Gateway"; break; + case 503: status = "Not Implemented"; break; + case 504: status = "Gateway Timeout"; break; + default: status = "WTF"; } - buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - - for (std::size_t i = 0; i < headers.size(); ++i) - { - header& h = headers[i]; - buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); - buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - } - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - } - buffers.push_back(boost::asio::buffer(content)); - return buffers; + ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; + for (header & h : headers) { + ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; + } + ss << HTTP_CRLF; /* end of headers */ + } + return ss.str(); } void HTTPConnection::Terminate () @@ -914,8 +904,9 @@ namespace util m_Reply.headers[2].name = "Content-Type"; m_Reply.headers[2].value = "text/html"; } - - boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), + std::string res = m_Reply.to_string(status); + + boost::asio::async_write (*m_Socket, res, std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } diff --git a/HTTPServer.h b/HTTPServer.h index 66083d85..889afca9 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -39,8 +39,8 @@ namespace util struct reply { std::vector
headers; - std::string status_string, content; - std::vector to_buffers (int status); + std::string status; + std::string to_string (int code); }; public: From 7a461c168490a98450e716d2972c46672740c6f0 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 07/49] * HTTPServer.{cpp,h}: move #include to one place --- HTTPServer.cpp | 7 +++++++ HTTPServer.h | 12 +----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6897a347..bf895ced 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -1,7 +1,13 @@ #include #include +#include +#include +#include + +#include #include #include + #include "Base.h" #include "FS.h" #include "Log.h" @@ -9,6 +15,7 @@ #include "TransitTunnel.h" #include "Transports.h" #include "NetDb.h" +#include "LeaseSet.h" #include "I2PEndian.h" #include "Streaming.h" #include "Destination.h" diff --git a/HTTPServer.h b/HTTPServer.h index 889afca9..ead03cde 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -1,14 +1,6 @@ #ifndef HTTP_SERVER_H__ #define HTTP_SERVER_H__ -#include -#include -#include -#include -#include -#include "LeaseSet.h" -#include "Streaming.h" - namespace i2p { namespace util @@ -135,6 +127,4 @@ namespace util } } -#endif - - +#endif /* HTTP_SERVER_H__ */ From 6ed709d6e6b2af7516de4ceea69753a73f82428c Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 08/49] * HTTPServer.{cpp,h}: extract itoopie{Image,Favicon} from HTTPConnection (!) class --- HTTPServer.cpp | 10 ++++++---- HTTPServer.h | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index bf895ced..2c0f3ea5 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -30,7 +30,7 @@ namespace i2p { namespace util { - const std::string HTTPConnection::itoopieImage = + const char *itoopieImage = "\"ICToopie"; - const std::string HTTPConnection::itoopieFavicon = + const char *itoopieFavicon = "data:image/png;base64," "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv" "8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My4wOGVynO" @@ -357,7 +357,7 @@ namespace util // Html5 head start s << "\r\n"; // TODO: Add support for locale. s << "\r\n\r\n"; // TODO: Find something to parse html/template system. This is horrible. - s << "\r\n"; + s << "\r\n"; s << "Purple I2P " << VERSION " Webconsole\r\n"; s << "\r\n"; + + const char HTTP_PAGE_TUNNELS[] = "tunnels"; + const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels"; + const char HTTP_PAGE_TRANSPORTS[] = "transports"; + const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations"; + const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination"; + const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions"; + const char HTTP_PAGE_SAM_SESSION[] = "sam_session"; + const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels"; + const char HTTP_PAGE_JUMPSERVICES[] = "jumpservices"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; - const char HTTP_COMMAND_LOCAL_DESTINATIONS[] = "local_destinations"; - const char HTTP_COMMAND_LOCAL_DESTINATION[] = "local_destination"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; - const char HTTP_COMMAND_SAM_SESSIONS[] = "sam_sessions"; - const char HTTP_COMMAND_SAM_SESSION[] = "sam_session"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; - const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels"; - const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices="; const char HTTP_PARAM_ADDRESS[] = "address"; void HTTPConnection::Terminate () @@ -282,52 +299,53 @@ namespace http { { std::stringstream s; // Html5 head start - s << "\r\n"; // TODO: Add support for locale. - s << "\r\n\r\n"; // TODO: Find something to parse html/template system. This is horrible. - s << "\r\n"; - s << "Purple I2P " << VERSION " Webconsole\r\n"; - s << "\r\n\r\n\r\n"; - s << "
i2pd webconsole
"; - s << "
"; - s << "
\r\n"; - s << "Main page
\r\n
\r\n"; - s << "Local destinations
\r\n"; - s << "Tunnels
\r\n"; - s << "Transit tunnels
\r\n"; - s << "Transports
\r\n
\r\n"; - s << "I2P tunnels
\r\n"; + s << + "\r\n" + "\r\n" /* TODO: Add support for locale */ + " \r\n" + " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ + " \r\n" + " Purple I2P " VERSION " Webconsole\r\n" + << cssStyles << + "\r\n"; + s << + "\r\n" + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n
\r\n" + " Local destinations
\r\n" + " Tunnels
\r\n" + " Transit tunnels
\r\n" + " Transports
\r\n" + " I2P tunnels
\r\n" + " Jump services
\r\n" + ; if (i2p::client::context.GetSAMBridge ()) - s << "SAM sessions
\r\n
\r\n"; + s << " SAM sessions
\r\n"; + /* commands */ + s << "
\r\n"; + s << " Run peer test
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << "Stop accepting tunnels
\r\n
\r\n"; + s << " Stop accepting tunnels
\r\n"; else - s << "Start accepting tunnels
\r\n
\r\n"; - s << "Run peer test
\r\n
\r\n"; - s << "Jump services
\r\n
\r\n"; - s << "
"; - if (request.uri.find("cmd=") != std::string::npos) + s << " Start accepting tunnels
\r\n"; + s << "
\r\n"; + s << "
"; + if (request.uri.find("page=") != std::string::npos) + HandlePage (s, request.uri); + else if (request.uri.find("cmd=") != std::string::npos) HandleCommand (s, request.uri); else - FillContent (s); - s << "
\r\n\r\n"; + ShowStatus (s); + s << + "
\r\n" + "\r\n" + "\r\n"; SendReply (s.str ()); } - void HTTPConnection::FillContent (std::stringstream& s) + void HTTPConnection::ShowStatus (std::stringstream& s) { s << "Uptime: " << boost::posix_time::to_simple_string ( boost::posix_time::time_duration (boost::posix_time::seconds ( @@ -396,6 +414,38 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } + void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) + { + std::map params; + std::string page(""); + URL url; + + url.parse(uri); + url.parse_query(params); + page = params["page"]; + + if (page == HTTP_PAGE_TRANSPORTS) + ShowTransports (s); + else if (page == HTTP_PAGE_TUNNELS) + ShowTunnels (s); + else if (page == HTTP_PAGE_JUMPSERVICES) + ShowJumpServices (s, params["address"]); + else if (page == HTTP_PAGE_TRANSIT_TUNNELS) + ShowTransitTunnels (s); + else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) + ShowLocalDestinations (s); + else if (page == HTTP_PAGE_LOCAL_DESTINATION) + ShowLocalDestination (s, params["b32"]); + else if (page == HTTP_PAGE_SAM_SESSIONS) + ShowSAMSessions (s); + else if (page == HTTP_PAGE_SAM_SESSION) + ShowSAMSession (s, params["sam_id"]); + else if (page == HTTP_PAGE_I2P_TUNNELS) + ShowI2PTunnels (s); + else + SendError("Unknown page: " + page); + } + void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) { std::map params; @@ -406,30 +456,14 @@ namespace http { url.parse_query(params); cmd = params["cmd"]; - if (cmd == HTTP_COMMAND_TRANSPORTS) - ShowTransports (s); - else if (cmd == HTTP_COMMAND_TUNNELS) - ShowTunnels (s); - else if (cmd == HTTP_COMMAND_JUMPSERVICES) - ShowJumpServices (s, params["address"]); - else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS) - ShowTransitTunnels (s); - else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) + if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) StartAcceptingTunnels (s); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) StopAcceptingTunnels (s); else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) RunPeerTest (s); - else if (cmd == HTTP_COMMAND_LOCAL_DESTINATIONS) - ShowLocalDestinations (s); - else if (cmd == HTTP_COMMAND_LOCAL_DESTINATION) - ShowLocalDestination (s, params["b32"]); - else if (cmd == HTTP_COMMAND_SAM_SESSIONS) - ShowSAMSessions (s); - else if (cmd == HTTP_COMMAND_SAM_SESSION) - ShowSAMSession (s, params["sam_id"]); - else if (cmd == HTTP_COMMAND_I2P_TUNNELS) - ShowI2PTunnels (s); + else + SendError("Unknown command: " + cmd); } void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) @@ -448,7 +482,7 @@ namespace http { for (auto& it: i2p::client::context.GetDestinations ()) { auto ident = it.second->GetIdentHash ();; - s << ""; + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; } } @@ -548,9 +582,9 @@ namespace http { it->Print (s); auto state = it->GetState (); if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; + s << " " << "Failed"; else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; + s << " " << "Expiring"; s << " " << (int)it->GetNumSentBytes () << "
\r\n"; s << std::endl; } @@ -560,9 +594,9 @@ namespace http { it->Print (s); auto state = it->GetState (); if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; + s << " " << "Failed"; else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; + s << " " << "Expiring"; s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; s << std::endl; } @@ -640,7 +674,7 @@ namespace http { { for (auto& it: sam->GetSessions ()) { - s << ""; + s << ""; s << it.first << "
\r\n" << std::endl; } } @@ -656,7 +690,7 @@ namespace http { if (session) { auto& ident = session->localDestination->GetIdentHash(); - s << ""; + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; s << "Streams:
\r\n"; for (auto it: session->ListSockets()) @@ -688,7 +722,7 @@ namespace http { for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -697,7 +731,7 @@ namespace http { for (auto& it: i2p::client::context.GetServerTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); diff --git a/HTTPServer.h b/HTTPServer.h index 89df8fb5..57d6fa59 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -29,21 +29,24 @@ namespace http { void SendError (const std::string& message); void HandleRequest (const HTTPReq & request); - void HandleCommand (std::stringstream& s, const std::string& request); + void HandlePage (std::stringstream& s, const std::string& request); + void HandleCommand (std::stringstream& s, const std::string& request); + /* pages */ void ShowJumpServices (std::stringstream& s, const std::string& address); void ShowTransports (std::stringstream& s); void ShowTunnels (std::stringstream& s); + void ShowStatus (std::stringstream& s); void ShowTransitTunnels (std::stringstream& s); void ShowLocalDestinations (std::stringstream& s); void ShowLocalDestination (std::stringstream& s, const std::string& b32); void ShowSAMSessions (std::stringstream& s); void ShowSAMSession (std::stringstream& s, const std::string& id); void ShowI2PTunnels (std::stringstream& s); + /* commands */ void StartAcceptingTunnels (std::stringstream& s); void StopAcceptingTunnels (std::stringstream& s); void RunPeerTest (std::stringstream& s); - void FillContent (std::stringstream& s); protected: From 9bbff744e991cfa60cb4fa21684b84a06413d712 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 17/49] * HTTPServer.{cpp,h}: chg HandleRequest() signature --- HTTPServer.cpp | 12 ++++++------ HTTPServer.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 5673e468..80022897 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -271,7 +271,7 @@ namespace http { } if (ret == 0) return; /* need more data */ - HandleRequest (request); + HandleRequest (request.uri); } void HTTPConnection::HandleWriteReply (const boost::system::error_code& ecode) @@ -295,7 +295,7 @@ namespace http { AsyncStreamReceive (); } - void HTTPConnection::HandleRequest (const HTTPReq &request) + void HTTPConnection::HandleRequest (const std::string &uri) { std::stringstream s; // Html5 head start @@ -332,10 +332,10 @@ namespace http { s << " Start accepting tunnels
\r\n"; s << "\r\n"; s << "
"; - if (request.uri.find("page=") != std::string::npos) - HandlePage (s, request.uri); - else if (request.uri.find("cmd=") != std::string::npos) - HandleCommand (s, request.uri); + if (uri.find("page=") != std::string::npos) + HandlePage (s, uri); + else if (uri.find("cmd=") != std::string::npos) + HandleCommand (s, uri); else ShowStatus (s); s << diff --git a/HTTPServer.h b/HTTPServer.h index 57d6fa59..28962dde 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -28,7 +28,7 @@ namespace http { void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); - void HandleRequest (const HTTPReq & request); + void HandleRequest (const std::string& uri); void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); From 48b3959cfb9b71d5765c70439ab7a7b94a93dae6 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 18/49] * HTTPServer.{cpp,h}: cleanup --- HTTPServer.cpp | 18 ++++++++---------- HTTPServer.h | 4 ---- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 80022897..accca463 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -836,11 +836,10 @@ namespace http { { m_Acceptor.close(); m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - m_Thread = nullptr; - } + if (m_Thread) { + m_Thread->join (); + m_Thread = nullptr; + } } void HTTPServer::Run () @@ -858,11 +857,10 @@ namespace http { void HTTPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr newSocket) { - if (!ecode) - { - CreateConnection(newSocket); - Accept (); - } + if (ecode) + return; + CreateConnection(newSocket); + Accept (); } void HTTPServer::CreateConnection(std::shared_ptr newSocket) diff --git a/HTTPServer.h b/HTTPServer.h index 28962dde..a6ef52cc 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -6,7 +6,6 @@ namespace http { extern const char *itoopieImage; extern const char *itoopieFavicon; const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; - const int HTTP_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds class HTTPConnection: public std::enable_shared_from_this { @@ -59,9 +58,6 @@ namespace http { protected: virtual void RunRequest (); - - public: - }; class HTTPServer From 4fa4ba6301d4aadd19b5155218a9efc48832b745 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 19/49] * HTTPServer.cpp: move known jump services to std::map --- HTTPServer.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index accca463..73c9c791 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -226,7 +226,12 @@ namespace http { const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; - + + std::map jumpservices = { + { "inr.i2p", "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/search/?q=" }, + { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, + }; + void HTTPConnection::Terminate () { if (!m_Stream) return; @@ -468,12 +473,16 @@ namespace http { void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) { - s << "
"; - s << ""; - s << "

\r\n"; - s << "Jump services for " << address << ""; - s << ""; + s << "
"; + s << ""; + s << ""; + s << ""; + s << "

\r\n"; + s << "Jump services for " << address << "\r\n\r\n"; } void HTTPConnection::ShowLocalDestinations (std::stringstream& s) From 2a1fe99a2981dbfe6966d60379155346b1c723c2 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 20/49] * HTTPServer.{cpp,h}: drop rest of streaming support --- HTTPServer.cpp | 52 +++----------------------------------------------- HTTPServer.h | 9 +++------ 2 files changed, 6 insertions(+), 55 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 73c9c791..5f195792 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -17,8 +17,6 @@ #include "NetDb.h" #include "HTTP.h" #include "LeaseSet.h" -#include "I2PEndian.h" -#include "Streaming.h" #include "Destination.h" #include "RouterContext.h" #include "ClientContext.h" @@ -234,9 +232,6 @@ namespace http { void HTTPConnection::Terminate () { - if (!m_Stream) return; - m_Stream->Close (); - m_Stream = nullptr; m_Socket->close (); } @@ -251,14 +246,9 @@ namespace http { { if (!ecode) { - if (!m_Stream) // new request - { - m_Buffer[bytes_transferred] = '\0'; - m_BufferLen = bytes_transferred; - RunRequest(); - } - else // follow-on - m_Stream->Send ((uint8_t *)m_Buffer, bytes_transferred); + m_Buffer[bytes_transferred] = '\0'; + m_BufferLen = bytes_transferred; + RunRequest(); Receive (); } else if (ecode != boost::asio::error::operation_aborted) @@ -289,17 +279,6 @@ namespace http { } } - void HTTPConnection::HandleWrite (const boost::system::error_code& ecode) - { - if (ecode || (m_Stream && !m_Stream->IsOpen ())) - { - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else // data keeps coming - AsyncStreamReceive (); - } - void HTTPConnection::HandleRequest (const std::string &uri) { std::stringstream s; @@ -769,31 +748,6 @@ namespace http { s << "Peer test is running" << std::endl; } - void HTTPConnection::AsyncStreamReceive () - { - if (m_Stream) - m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, 8192), - std::bind (&HTTPConnection::HandleStreamReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2), - 45); // 45 seconds timeout - } - - void HTTPConnection::HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - if (!ecode) - { - boost::asio::async_write (*m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), - std::bind (&HTTPConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); - } - else - { - if (ecode == boost::asio::error::timed_out) - SendError ("Host not responding"); - else if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - } - void HTTPConnection::SendReply (const std::string& content, int code) { std::time_t time_now = std::time(nullptr); diff --git a/HTTPServer.h b/HTTPServer.h index a6ef52cc..cafa9b46 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -13,17 +13,15 @@ namespace http { HTTPConnection (std::shared_ptr socket): m_Socket (socket), m_Timer (socket->get_io_service ()), - m_Stream (nullptr), m_BufferLen (0) {}; + m_BufferLen (0) {}; void Receive (); private: void Terminate (); void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void AsyncStreamReceive (); - void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleWriteReply(const boost::system::error_code& ecode); - void HandleWrite (const boost::system::error_code& ecode); + void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); @@ -51,8 +49,7 @@ namespace http { std::shared_ptr m_Socket; boost::asio::deadline_timer m_Timer; - std::shared_ptr m_Stream; - char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1], m_StreamBuffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; + char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; protected: From fd928e8d12167c87ff63f540d7a2d0c9ff9cd78f Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 21/49] * HTTPServer.h: not virtual: not inherited anywhere --- HTTPServer.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/HTTPServer.h b/HTTPServer.h index cafa9b46..18c6bed8 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -25,6 +25,7 @@ namespace http { void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); + void RunRequest (); void HandleRequest (const std::string& uri); void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); @@ -45,16 +46,12 @@ namespace http { void StopAcceptingTunnels (std::stringstream& s); void RunPeerTest (std::stringstream& s); - protected: + private: std::shared_ptr m_Socket; boost::asio::deadline_timer m_Timer; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; - - protected: - - virtual void RunRequest (); }; class HTTPServer @@ -62,7 +59,7 @@ namespace http { public: HTTPServer (const std::string& address, int port); - virtual ~HTTPServer (); + ~HTTPServer (); void Start (); void Stop (); @@ -73,6 +70,7 @@ namespace http { void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr newSocket); + void CreateConnection(std::shared_ptr newSocket); private: @@ -80,9 +78,6 @@ namespace http { boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; - - protected: - virtual void CreateConnection(std::shared_ptr newSocket); }; } // http } // i2p From 0c8fdfca7d9670a692891cebb25ef8848411a794 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 22/49] * HTTPServer.{cpp,h}: merge HandleWriteReply & Terminate : the same purpose --- HTTPServer.cpp | 36 +++++++++++++++--------------------- HTTPServer.h | 3 +-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 5f195792..c7b91fd0 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -230,11 +230,6 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; - void HTTPConnection::Terminate () - { - m_Socket->close (); - } - void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -244,15 +239,15 @@ namespace http { void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (!ecode) - { - m_Buffer[bytes_transferred] = '\0'; - m_BufferLen = bytes_transferred; - RunRequest(); - Receive (); + if (ecode) { + if (ecode != boost::asio::error::operation_aborted) + Terminate (ecode); + return; } - else if (ecode != boost::asio::error::operation_aborted) - Terminate (); + m_Buffer[bytes_transferred] = '\0'; + m_BufferLen = bytes_transferred; + RunRequest(); + Receive (); } void HTTPConnection::RunRequest () @@ -269,14 +264,13 @@ namespace http { HandleRequest (request.uri); } - void HTTPConnection::HandleWriteReply (const boost::system::error_code& ecode) + void HTTPConnection::Terminate (const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - boost::system::error_code ignored_ec; - m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); - Terminate (); - } + if (ecode == boost::asio::error::operation_aborted) + return; + boost::system::error_code ignored_ec; + m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + m_Socket->close (); } void HTTPConnection::HandleRequest (const std::string &uri) @@ -767,7 +761,7 @@ namespace http { buffers.push_back(boost::asio::buffer(content)); boost::asio::async_write (*m_Socket, buffers, - std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); + std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1)); } void HTTPConnection::SendError(const std::string& content) diff --git a/HTTPServer.h b/HTTPServer.h index 18c6bed8..f3070502 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -18,9 +18,8 @@ namespace http { private: - void Terminate (); void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandleWriteReply(const boost::system::error_code& ecode); + void Terminate (const boost::system::error_code& ecode); void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); From 4d98a64000bf3ccce04f5165a59c3deb3f29beac Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 23/49] * HTTPServer.{cpp,h}: extract html-rendering methods from class --- HTTPServer.cpp | 734 ++++++++++++++++++++++++------------------------- HTTPServer.h | 16 -- 2 files changed, 367 insertions(+), 383 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index c7b91fd0..98080808 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -230,6 +230,373 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; + void ShowStatus (std::stringstream& s) + { + s << "Uptime: " << boost::posix_time::to_simple_string ( + boost::posix_time::time_duration (boost::posix_time::seconds ( + i2p::context.GetUptime ()))) << "
\r\n"; + s << "Status: "; + switch (i2p::context.GetStatus ()) + { + case eRouterStatusOK: s << "OK"; break; + case eRouterStatusTesting: s << "Testing"; break; + case eRouterStatusFirewalled: s << "Firewalled"; break; + default: s << "Unknown"; + } + s << "
\r\n"; + s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; + s << "Received: "; + s << std::fixed << std::setprecision(2); + auto numKBytesReceived = (double) i2p::transport::transports.GetTotalReceivedBytes () / 1024; + if (numKBytesReceived < 1024) + s << numKBytesReceived << " KiB"; + else if (numKBytesReceived < 1024 * 1024) + s << numKBytesReceived / 1024 << " MiB"; + else + s << numKBytesReceived / 1024 / 1024 << " GiB"; + s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " KiB/s)
\r\n"; + s << "Sent: "; + auto numKBytesSent = (double) i2p::transport::transports.GetTotalSentBytes () / 1024; + if (numKBytesSent < 1024) + s << numKBytesSent << " KiB"; + else if (numKBytesSent < 1024 * 1024) + s << numKBytesSent / 1024 << " MiB"; + else + s << numKBytesSent / 1024 / 1024 << " GiB"; + s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
\r\n"; + s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n
\r\n"; + s << "Our external address:" << "
\r\n" ; + for (auto address : i2p::context.GetRouterInfo().GetAddresses()) + { + switch (address->transportStyle) + { + case i2p::data::RouterInfo::eTransportNTCP: + if (address->host.is_v6 ()) + s << "NTCP6  "; + else + s << "NTCP  "; + break; + case i2p::data::RouterInfo::eTransportSSU: + if (address->host.is_v6 ()) + s << "SSU6     "; + else + s << "SSU     "; + break; + default: + s << "Unknown  "; + } + s << address->host.to_string() << ":" << address->port << "
\r\n"; + } + s << "
\r\nRouters: " << i2p::data::netdb.GetNumRouters () << " "; + s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; + s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; + + size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); + clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); + size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); + + s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; + s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; + } + + void ShowJumpServices (std::stringstream& s, const std::string& address) + { + s << "
"; + s << ""; + s << ""; + s << ""; + s << "

\r\n"; + s << "Jump services for " << address << "\r\n\r\n"; + } + + void ShowLocalDestinations (std::stringstream& s) + { + s << "Local Destinations:
\r\n
\r\n"; + for (auto& it: i2p::client::context.GetDestinations ()) + { + auto ident = it.second->GetIdentHash ();; + s << ""; + s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; + } + } + + void ShowLocalDestination (std::stringstream& s, const std::string& b32) + { + s << "Local Destination:
\r\n
\r\n"; + i2p::data::IdentHash ident; + ident.FromBase32 (b32); + auto dest = i2p::client::context.FindLocalDestination (ident); + if (dest) + { + s << "Base64:
\r\n
\r\n
\r\n"; + s << "LeaseSets: " << dest->GetNumRemoteLeaseSets () << "
\r\n"; + auto pool = dest->GetTunnelPool (); + if (pool) + { + s << "Tunnels:
\r\n"; + for (auto it: pool->GetOutboundTunnels ()) + { + it->Print (s); + auto state = it->GetState (); + if (state == i2p::tunnel::eTunnelStateFailed) + s << " " << "Failed"; + else if (state == i2p::tunnel::eTunnelStateExpiring) + s << " " << "Exp"; + s << "
\r\n" << std::endl; + } + for (auto it: pool->GetInboundTunnels ()) + { + it->Print (s); + auto state = it->GetState (); + if (state == i2p::tunnel::eTunnelStateFailed) + s << " " << "Failed"; + else if (state == i2p::tunnel::eTunnelStateExpiring) + s << " " << "Exp"; + s << "
\r\n" << std::endl; + } + } + s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
Outgoing:
" << std::endl; + for (auto it: dest->GetSessions ()) + { + s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " "; + s << it.second->GetNumOutgoingTags () << "
" << std::endl; + } + s << "
" << std::endl; + // s << "
\r\nStreams:
\r\n"; + // for (auto it: dest->GetStreamingDestination ()->GetStreams ()) + // { + // s << it.first << "->" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetRemoteIdentity ()) << " "; + // s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; + // s << " [out:" << it.second->GetSendQueueSize () << "][in:" << it.second->GetReceiveQueueSize () << "]"; + // s << "[buf:" << it.second->GetSendBufferSize () << "]"; + // s << "[RTT:" << it.second->GetRTT () << "]"; + // s << "[Window:" << it.second->GetWindowSize () << "]"; + // s << "[Status:" << (int)it.second->GetStatus () << "]"; + // s << "
\r\n"<< std::endl; + // } + s << "
\r\n"; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + + for (auto it: dest->GetAllStreams ()) + { + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << ""; + s << "
\r\n" << std::endl; + } + } + } + + void ShowTunnels (std::stringstream& s) + { + s << "Tunnels:
\r\n
\r\n"; + s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; + for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) + { + it->Print (s); + auto state = it->GetState (); + if (state == i2p::tunnel::eTunnelStateFailed) + s << " " << "Failed"; + else if (state == i2p::tunnel::eTunnelStateExpiring) + s << " " << "Expiring"; + s << " " << (int)it->GetNumSentBytes () << "
\r\n"; + s << std::endl; + } + + for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) + { + it->Print (s); + auto state = it->GetState (); + if (state == i2p::tunnel::eTunnelStateFailed) + s << " " << "Failed"; + else if (state == i2p::tunnel::eTunnelStateExpiring) + s << " " << "Expiring"; + s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; + s << std::endl; + } + } + + void ShowTransitTunnels (std::stringstream& s) + { + s << "Transit tunnels:
\r\n
\r\n"; + for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) + { + if (std::dynamic_pointer_cast(it)) + s << it->GetTunnelID () << " ⇒ "; + else if (std::dynamic_pointer_cast(it)) + s << " ⇒ " << it->GetTunnelID (); + else + s << " ⇒ " << it->GetTunnelID () << " ⇒ "; + s << " " << it->GetNumTransmittedBytes () << "
\r\n"; + } + } + + void ShowTransports (std::stringstream& s) + { + s << "Transports:
\r\n
\r\n"; + auto ntcpServer = i2p::transport::transports.GetNTCPServer (); + if (ntcpServer) + { + s << "NTCP
\r\n"; + for (auto it: ntcpServer->GetNTCPSessions ()) + { + if (it.second && it.second->IsEstablished ()) + { + // incoming connection doesn't have remote RI + if (it.second->IsOutgoing ()) s << " ⇒ "; + s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " + << it.second->GetSocket ().remote_endpoint().address ().to_string (); + if (!it.second->IsOutgoing ()) s << " ⇒ "; + s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; + s << "
\r\n" << std::endl; + } + } + } + auto ssuServer = i2p::transport::transports.GetSSUServer (); + if (ssuServer) + { + s << "
\r\nSSU
\r\n"; + for (auto it: ssuServer->GetSessions ()) + { + auto endpoint = it.second->GetRemoteEndpoint (); + if (it.second->IsOutgoing ()) s << " ⇒ "; + s << endpoint.address ().to_string () << ":" << endpoint.port (); + if (!it.second->IsOutgoing ()) s << " ⇒ "; + s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; + if (it.second->GetRelayTag ()) + s << " [itag:" << it.second->GetRelayTag () << "]"; + s << "
\r\n" << std::endl; + } + s << "
\r\nSSU6
\r\n"; + for (auto it: ssuServer->GetSessionsV6 ()) + { + auto endpoint = it.second->GetRemoteEndpoint (); + if (it.second->IsOutgoing ()) s << " ⇒ "; + s << endpoint.address ().to_string () << ":" << endpoint.port (); + if (!it.second->IsOutgoing ()) s << " ⇒ "; + s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; + s << "
\r\n" << std::endl; + } + } + } + + void ShowSAMSessions (std::stringstream& s) + { + s << "SAM Sessions:
\r\n
\r\n"; + auto sam = i2p::client::context.GetSAMBridge (); + if (sam) + { + for (auto& it: sam->GetSessions ()) + { + s << ""; + s << it.first << "
\r\n" << std::endl; + } + } + } + + void ShowSAMSession (std::stringstream& s, const std::string& id) + { + s << "SAM Session:
\r\n
\r\n"; + auto sam = i2p::client::context.GetSAMBridge (); + if (sam) + { + auto session = sam->FindSession (id); + if (session) + { + auto& ident = session->localDestination->GetIdentHash(); + s << ""; + s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; + s << "Streams:
\r\n"; + for (auto it: session->ListSockets()) + { + switch (it->GetSocketType ()) + { + case i2p::client::eSAMSocketTypeSession: + s << "session"; + break; + case i2p::client::eSAMSocketTypeStream: + s << "stream"; + break; + case i2p::client::eSAMSocketTypeAcceptor: + s << "acceptor"; + break; + default: + s << "unknown"; + } + s << " [" << it->GetSocket ().remote_endpoint() << "]"; + s << "
\r\n" << std::endl; + } + } + } + } + + void ShowI2PTunnels (std::stringstream& s) + { + s << "Client Tunnels:
\r\n
\r\n"; + for (auto& it: i2p::client::context.GetClientTunnels ()) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + s << ""; + s << it.second->GetName () << " ⇐ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << "
\r\n"<< std::endl; + } + s << "
\r\nServer Tunnels:
\r\n
\r\n"; + for (auto& it: i2p::client::context.GetServerTunnels ()) + { + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); + s << ""; + s << it.second->GetName () << " ⇒ "; + s << i2p::client::context.GetAddressBook ().ToAddress(ident); + s << ":" << it.second->GetLocalPort (); + s << "
\r\n"<< std::endl; + } + } + + void StopAcceptingTunnels (std::stringstream& s) + { + s << "Stop Accepting Tunnels:
\r\n
\r\n"; + i2p::context.SetAcceptsTunnels (false); + s << "Accepting tunnels stopped" << std::endl; + } + + void StartAcceptingTunnels (std::stringstream& s) + { + s << "Start Accepting Tunnels:
\r\n
\r\n"; + i2p::context.SetAcceptsTunnels (true); + s << "Accepting tunnels started" << std::endl; + } + + void RunPeerTest (std::stringstream& s) + { + s << "Run Peer Test:
\r\n
\r\n"; + i2p::transport::transports.PeerTest (); + s << "Peer test is running" << std::endl; + } + void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -323,75 +690,6 @@ namespace http { SendReply (s.str ()); } - void HTTPConnection::ShowStatus (std::stringstream& s) - { - s << "Uptime: " << boost::posix_time::to_simple_string ( - boost::posix_time::time_duration (boost::posix_time::seconds ( - i2p::context.GetUptime ()))) << "
\r\n"; - s << "Status: "; - switch (i2p::context.GetStatus ()) - { - case eRouterStatusOK: s << "OK"; break; - case eRouterStatusTesting: s << "Testing"; break; - case eRouterStatusFirewalled: s << "Firewalled"; break; - default: s << "Unknown"; - } - s << "
\r\n"; - s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; - s << "Received: "; - s << std::fixed << std::setprecision(2); - auto numKBytesReceived = (double) i2p::transport::transports.GetTotalReceivedBytes () / 1024; - if (numKBytesReceived < 1024) - s << numKBytesReceived << " KiB"; - else if (numKBytesReceived < 1024 * 1024) - s << numKBytesReceived / 1024 << " MiB"; - else - s << numKBytesReceived / 1024 / 1024 << " GiB"; - s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " KiB/s)
\r\n"; - s << "Sent: "; - auto numKBytesSent = (double) i2p::transport::transports.GetTotalSentBytes () / 1024; - if (numKBytesSent < 1024) - s << numKBytesSent << " KiB"; - else if (numKBytesSent < 1024 * 1024) - s << numKBytesSent / 1024 << " MiB"; - else - s << numKBytesSent / 1024 / 1024 << " GiB"; - s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)
\r\n"; - s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n
\r\n"; - s << "Our external address:" << "
\r\n" ; - for (auto address : i2p::context.GetRouterInfo().GetAddresses()) - { - switch (address->transportStyle) - { - case i2p::data::RouterInfo::eTransportNTCP: - if (address->host.is_v6 ()) - s << "NTCP6  "; - else - s << "NTCP  "; - break; - case i2p::data::RouterInfo::eTransportSSU: - if (address->host.is_v6 ()) - s << "SSU6     "; - else - s << "SSU     "; - break; - default: - s << "Unknown  "; - } - s << address->host.to_string() << ":" << address->port << "
\r\n"; - } - s << "
\r\nRouters: " << i2p::data::netdb.GetNumRouters () << " "; - s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; - s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; - - size_t clientTunnelCount = i2p::tunnel::tunnels.CountOutboundTunnels(); - clientTunnelCount += i2p::tunnel::tunnels.CountInboundTunnels(); - size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels(); - - s << "Client Tunnels: " << std::to_string(clientTunnelCount) << " "; - s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; - } - void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) { std::map params; @@ -444,304 +742,6 @@ namespace http { SendError("Unknown command: " + cmd); } - void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) - { - s << "
"; - s << ""; - s << ""; - s << ""; - s << "
\r\n"; - s << "Jump services for " << address << "\r\n\r\n"; - } - - void HTTPConnection::ShowLocalDestinations (std::stringstream& s) - { - s << "Local Destinations:
\r\n
\r\n"; - for (auto& it: i2p::client::context.GetDestinations ()) - { - auto ident = it.second->GetIdentHash ();; - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; - } - } - - void HTTPConnection::ShowLocalDestination (std::stringstream& s, const std::string& b32) - { - s << "Local Destination:
\r\n
\r\n"; - i2p::data::IdentHash ident; - ident.FromBase32 (b32); - auto dest = i2p::client::context.FindLocalDestination (ident); - if (dest) - { - s << "Base64:
\r\n
\r\n
\r\n"; - s << "LeaseSets: " << dest->GetNumRemoteLeaseSets () << "
\r\n"; - auto pool = dest->GetTunnelPool (); - if (pool) - { - s << "Tunnels:
\r\n"; - for (auto it: pool->GetOutboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; - s << "
\r\n" << std::endl; - } - for (auto it: pool->GetInboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; - s << "
\r\n" << std::endl; - } - } - s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
Outgoing:
" << std::endl; - for (auto it: dest->GetSessions ()) - { - s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " "; - s << it.second->GetNumOutgoingTags () << "
" << std::endl; - } - s << "
" << std::endl; - // s << "
\r\nStreams:
\r\n"; - // for (auto it: dest->GetStreamingDestination ()->GetStreams ()) - // { - // s << it.first << "->" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetRemoteIdentity ()) << " "; - // s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - // s << " [out:" << it.second->GetSendQueueSize () << "][in:" << it.second->GetReceiveQueueSize () << "]"; - // s << "[buf:" << it.second->GetSendBufferSize () << "]"; - // s << "[RTT:" << it.second->GetRTT () << "]"; - // s << "[Window:" << it.second->GetWindowSize () << "]"; - // s << "[Status:" << (int)it.second->GetStatus () << "]"; - // s << "
\r\n"<< std::endl; - // } - s << "
\r\n
Streams
StreamIDDestinationSentReceivedOutInBufRTTWindowStatus
" << it->GetSendStreamID () << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << "" << it->GetNumSentBytes () << "" << it->GetNumReceivedBytes () << "" << it->GetSendQueueSize () << "" << it->GetReceiveQueueSize () << "" << it->GetSendBufferSize () << "" << it->GetRTT () << "" << it->GetWindowSize () << "" << (int)it->GetStatus () << "
"; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - - for (auto it: dest->GetAllStreams ()) - { - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << ""; - s << "
\r\n" << std::endl; - } - } - } - - void HTTPConnection::ShowTunnels (std::stringstream& s) - { - s << "Tunnels:
\r\n
\r\n"; - s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; - for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Expiring"; - s << " " << (int)it->GetNumSentBytes () << "
\r\n"; - s << std::endl; - } - - for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Expiring"; - s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; - s << std::endl; - } - } - - void HTTPConnection::ShowTransitTunnels (std::stringstream& s) - { - s << "Transit tunnels:
\r\n
\r\n"; - for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) - { - if (std::dynamic_pointer_cast(it)) - s << it->GetTunnelID () << " ⇒ "; - else if (std::dynamic_pointer_cast(it)) - s << " ⇒ " << it->GetTunnelID (); - else - s << " ⇒ " << it->GetTunnelID () << " ⇒ "; - s << " " << it->GetNumTransmittedBytes () << "
\r\n"; - } - } - - void HTTPConnection::ShowTransports (std::stringstream& s) - { - s << "Transports:
\r\n
\r\n"; - auto ntcpServer = i2p::transport::transports.GetNTCPServer (); - if (ntcpServer) - { - s << "NTCP
\r\n"; - for (auto it: ntcpServer->GetNTCPSessions ()) - { - if (it.second && it.second->IsEstablished ()) - { - // incoming connection doesn't have remote RI - if (it.second->IsOutgoing ()) s << " ⇒ "; - s << i2p::data::GetIdentHashAbbreviation (it.second->GetRemoteIdentity ()->GetIdentHash ()) << ": " - << it.second->GetSocket ().remote_endpoint().address ().to_string (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; - s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - s << "
\r\n" << std::endl; - } - } - } - auto ssuServer = i2p::transport::transports.GetSSUServer (); - if (ssuServer) - { - s << "
\r\nSSU
\r\n"; - for (auto it: ssuServer->GetSessions ()) - { - auto endpoint = it.second->GetRemoteEndpoint (); - if (it.second->IsOutgoing ()) s << " ⇒ "; - s << endpoint.address ().to_string () << ":" << endpoint.port (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; - s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - if (it.second->GetRelayTag ()) - s << " [itag:" << it.second->GetRelayTag () << "]"; - s << "
\r\n" << std::endl; - } - s << "
\r\nSSU6
\r\n"; - for (auto it: ssuServer->GetSessionsV6 ()) - { - auto endpoint = it.second->GetRemoteEndpoint (); - if (it.second->IsOutgoing ()) s << " ⇒ "; - s << endpoint.address ().to_string () << ":" << endpoint.port (); - if (!it.second->IsOutgoing ()) s << " ⇒ "; - s << " [" << it.second->GetNumSentBytes () << ":" << it.second->GetNumReceivedBytes () << "]"; - s << "
\r\n" << std::endl; - } - } - } - - void HTTPConnection::ShowSAMSessions (std::stringstream& s) - { - s << "SAM Sessions:
\r\n
\r\n"; - auto sam = i2p::client::context.GetSAMBridge (); - if (sam) - { - for (auto& it: sam->GetSessions ()) - { - s << ""; - s << it.first << "
\r\n" << std::endl; - } - } - } - - void HTTPConnection::ShowSAMSession (std::stringstream& s, const std::string& id) - { - s << "SAM Session:
\r\n
\r\n"; - auto sam = i2p::client::context.GetSAMBridge (); - if (sam) - { - auto session = sam->FindSession (id); - if (session) - { - auto& ident = session->localDestination->GetIdentHash(); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; - s << "Streams:
\r\n"; - for (auto it: session->ListSockets()) - { - switch (it->GetSocketType ()) - { - case i2p::client::eSAMSocketTypeSession: - s << "session"; - break; - case i2p::client::eSAMSocketTypeStream: - s << "stream"; - break; - case i2p::client::eSAMSocketTypeAcceptor: - s << "acceptor"; - break; - default: - s << "unknown"; - } - s << " [" << it->GetSocket ().remote_endpoint() << "]"; - s << "
\r\n" << std::endl; - } - } - } - } - - void HTTPConnection::ShowI2PTunnels (std::stringstream& s) - { - s << "Client Tunnels:
\r\n
\r\n"; - for (auto& it: i2p::client::context.GetClientTunnels ()) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; - s << it.second->GetName () << " ⇐ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; - } - s << "
\r\nServer Tunnels:
\r\n
\r\n"; - for (auto& it: i2p::client::context.GetServerTunnels ()) - { - auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; - s << it.second->GetName () << " ⇒ "; - s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << ":" << it.second->GetLocalPort (); - s << "
\r\n"<< std::endl; - } - } - - void HTTPConnection::StopAcceptingTunnels (std::stringstream& s) - { - s << "Stop Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (false); - s << "Accepting tunnels stopped" << std::endl; - } - - void HTTPConnection::StartAcceptingTunnels (std::stringstream& s) - { - s << "Start Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (true); - s << "Accepting tunnels started" << std::endl; - } - - void HTTPConnection::RunPeerTest (std::stringstream& s) - { - s << "Run Peer Test:
\r\n
\r\n"; - i2p::transport::transports.PeerTest (); - s << "Peer test is running" << std::endl; - } - void HTTPConnection::SendReply (const std::string& content, int code) { std::time_t time_now = std::time(nullptr); diff --git a/HTTPServer.h b/HTTPServer.h index f3070502..06fa4457 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -29,22 +29,6 @@ namespace http { void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); - /* pages */ - void ShowJumpServices (std::stringstream& s, const std::string& address); - void ShowTransports (std::stringstream& s); - void ShowTunnels (std::stringstream& s); - void ShowStatus (std::stringstream& s); - void ShowTransitTunnels (std::stringstream& s); - void ShowLocalDestinations (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32); - void ShowSAMSessions (std::stringstream& s); - void ShowSAMSession (std::stringstream& s, const std::string& id); - void ShowI2PTunnels (std::stringstream& s); - /* commands */ - void StartAcceptingTunnels (std::stringstream& s); - void StopAcceptingTunnels (std::stringstream& s); - void RunPeerTest (std::stringstream& s); - private: std::shared_ptr m_Socket; From 849308e28d3f0852bf86873399bea809d16719fe Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 24/49] * HTTPServer.cpp: drop boost::date_time dep --- HTTPServer.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 98080808..d5a4622e 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -6,7 +6,6 @@ #include #include -#include #include "Base.h" #include "FS.h" @@ -230,11 +229,29 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; + void ShowUptime (std::stringstream& s, int seconds) { + int num; + + if ((num = seconds / 86400) > 0) { + s << num << " days, "; + seconds -= num; + } + if ((num = seconds / 3600) > 0) { + s << num << " hours, "; + seconds -= num; + } + if ((num = seconds / 60) > 0) { + s << num << " min, "; + seconds -= num; + } + s << seconds << " seconds"; + } + void ShowStatus (std::stringstream& s) { - s << "Uptime: " << boost::posix_time::to_simple_string ( - boost::posix_time::time_duration (boost::posix_time::seconds ( - i2p::context.GetUptime ()))) << "
\r\n"; + s << "Uptime: "; + ShowUptime(s, i2p::context.GetUptime ()); + s << "
\r\n"; s << "Status: "; switch (i2p::context.GetStatus ()) { From 65395516b0b087d09fc28ae3df9dd012f38160e0 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 25/49] * HTTPServer.cpp: drop separate function handlers for commands --- HTTPServer.cpp | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index d5a4622e..d3a57b50 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -593,27 +593,6 @@ namespace http { } } - void StopAcceptingTunnels (std::stringstream& s) - { - s << "Stop Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (false); - s << "Accepting tunnels stopped" << std::endl; - } - - void StartAcceptingTunnels (std::stringstream& s) - { - s << "Start Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (true); - s << "Accepting tunnels started" << std::endl; - } - - void RunPeerTest (std::stringstream& s) - { - s << "Run Peer Test:
\r\n
\r\n"; - i2p::transport::transports.PeerTest (); - s << "Peer test is running" << std::endl; - } - void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -749,14 +728,17 @@ namespace http { url.parse_query(params); cmd = params["cmd"]; - if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) - StartAcceptingTunnels (s); + if (cmd == HTTP_COMMAND_RUN_PEER_TEST) + i2p::transport::transports.PeerTest (); + else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) + i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) - StopAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) - RunPeerTest (s); - else + i2p::context.SetAcceptsTunnels (false); + else { SendError("Unknown command: " + cmd); + return; + } + s << "Command accepted"; } void HTTPConnection::SendReply (const std::string& content, int code) From 23b8df1c36a420f367b12bfa5e897bb163813e2a Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 26/49] * HTTPServer.cpp: move commands to separate page --- HTTPServer.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index d3a57b50..44841a91 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -217,6 +217,7 @@ namespace http { const char HTTP_PAGE_SAM_SESSION[] = "sam_session"; const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels"; const char HTTP_PAGE_JUMPSERVICES[] = "jumpservices"; + const char HTTP_PAGE_COMMANDS[] = "commands"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; @@ -452,10 +453,20 @@ namespace http { else if (state == i2p::tunnel::eTunnelStateExpiring) s << " " << "Expiring"; s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; - s << std::endl; } } + void ShowCommands (std::stringstream& s) + { + /* commands */ + s << "Router Commands
\r\n"; + s << " Run peer test
\r\n"; + if (i2p::context.AcceptsTunnels ()) + s << " Stop accepting tunnels
\r\n"; + else + s << " Start accepting tunnels
\r\n"; + } + void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; @@ -655,22 +666,16 @@ namespace http { "
\r\n" "
\r\n" " Main page
\r\n
\r\n" + " Router commands
\r\n" " Local destinations
\r\n" " Tunnels
\r\n" " Transit tunnels
\r\n" " Transports
\r\n" " I2P tunnels
\r\n" - " Jump services
\r\n" + " Jump services
\r\n" ; if (i2p::client::context.GetSAMBridge ()) s << " SAM sessions
\r\n"; - /* commands */ - s << "
\r\n"; - s << " Run peer test
\r\n"; - if (i2p::context.AcceptsTunnels ()) - s << " Stop accepting tunnels
\r\n"; - else - s << " Start accepting tunnels
\r\n"; s << "
\r\n"; s << "
"; if (uri.find("page=") != std::string::npos) @@ -700,6 +705,8 @@ namespace http { ShowTransports (s); else if (page == HTTP_PAGE_TUNNELS) ShowTunnels (s); + else if (page == HTTP_PAGE_COMMANDS) + ShowCommands (s); else if (page == HTTP_PAGE_JUMPSERVICES) ShowJumpServices (s, params["address"]); else if (page == HTTP_PAGE_TRANSIT_TUNNELS) @@ -738,7 +745,8 @@ namespace http { SendError("Unknown command: " + cmd); return; } - s << "Command accepted"; + s << "Command accepted

\r\n"; + s << "Back to commands list"; } void HTTPConnection::SendReply (const std::string& content, int code) From 54078087e5713da4b692563b55a1b3420462a0cd Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 27/49] * HTTPServer.cpp: move common code to function --- HTTPServer.cpp | 78 ++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 44841a91..142c392b 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -248,6 +248,23 @@ namespace http { s << seconds << " seconds"; } + void ShowTunnelDetails (std::stringstream& s, enum i2p::tunnel::TunnelState eState, int bytes) + { + std::string state; + switch (eState) { + case i2p::tunnel::eTunnelStateBuildReplyReceived : + case i2p::tunnel::eTunnelStatePending : state = "building"; break; + case i2p::tunnel::eTunnelStateBuildFailed : + case i2p::tunnel::eTunnelStateTestFailed : + case i2p::tunnel::eTunnelStateFailed : state = "failed"; break; + case i2p::tunnel::eTunnelStateExpiring : state = "expiring"; break; + case i2p::tunnel::eTunnelStateEstablished : state = "established"; break; + default: state = "unknown"; break; + } + s << " " << state << ", "; + s << " " << (int) (bytes / 1024) << " KiB
\r\n"; + } + void ShowStatus (std::stringstream& s) { s << "Uptime: "; @@ -356,28 +373,19 @@ namespace http { auto pool = dest->GetTunnelPool (); if (pool) { - s << "Tunnels:
\r\n"; - for (auto it: pool->GetOutboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; - s << "
\r\n" << std::endl; + s << "Inbound tunnels:
\r\n"; + for (auto & it : pool->GetInboundTunnels ()) { + it->Print(s); + ShowTunnelDetails(s, it->GetState (), it->GetNumReceivedBytes ()); } - for (auto it: pool->GetInboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; - s << "
\r\n" << std::endl; + s << "
\r\n"; + s << "Outbound tunnels:
\r\n"; + for (auto & it : pool->GetOutboundTunnels ()) { + it->Print(s); + ShowTunnelDetails(s, it->GetState (), it->GetNumSentBytes ()); } } + s << "
\r\n"; s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
Outgoing:
" << std::endl; for (auto it: dest->GetSessions ()) { @@ -430,30 +438,20 @@ namespace http { void ShowTunnels (std::stringstream& s) { - s << "Tunnels:
\r\n
\r\n"; s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; - for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Expiring"; - s << " " << (int)it->GetNumSentBytes () << "
\r\n"; - s << std::endl; - } - for (auto it: i2p::tunnel::tunnels.GetInboundTunnels ()) - { - it->Print (s); - auto state = it->GetState (); - if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; - else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Expiring"; - s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; + s << "Inbound tunnels:
\r\n"; + for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) { + it->Print(s); + ShowTunnelDetails(s, it->GetState (), it->GetNumReceivedBytes ()); } + s << "
\r\n"; + s << "Outbound tunnels:
\r\n"; + for (auto & it : i2p::tunnel::tunnels.GetOutboundTunnels ()) { + it->Print(s); + ShowTunnelDetails(s, it->GetState (), it->GetNumSentBytes ()); + } + s << "
\r\n"; } void ShowCommands (std::stringstream& s) From 1f404bb62291542b7923bb3656b7e23c8e4d0bb0 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 28/49] * HTTPServer.cpp: move html parts outside HTTPConnection class --- HTTPServer.cpp | 70 ++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 142c392b..864c9fd3 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -265,6 +265,43 @@ namespace http { s << " " << (int) (bytes / 1024) << " KiB
\r\n"; } + void ShowPageHead (std::stringstream& s) + { + s << + "\r\n" + "\r\n" /* TODO: Add support for locale */ + " \r\n" + " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ + " \r\n" + " Purple I2P " VERSION " Webconsole\r\n" + << cssStyles << + "\r\n"; + s << + "\r\n" + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n
\r\n" + " Router commands
\r\n" + " Local destinations
\r\n" + " Tunnels
\r\n" + " Transit tunnels
\r\n" + " Transports
\r\n" + " I2P tunnels
\r\n" + " Jump services
\r\n" + " SAM sessions
\r\n" + "
\r\n" + "
"; + } + + void ShowPageTail (std::stringstream& s) + { + s << + "
\r\n" + "\r\n" + "\r\n"; + } + void ShowStatus (std::stringstream& s) { s << "Uptime: "; @@ -649,43 +686,14 @@ namespace http { { std::stringstream s; // Html5 head start - s << - "\r\n" - "\r\n" /* TODO: Add support for locale */ - " \r\n" - " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ - " \r\n" - " Purple I2P " VERSION " Webconsole\r\n" - << cssStyles << - "\r\n"; - s << - "\r\n" - "
i2pd webconsole
\r\n" - "
\r\n" - "
\r\n" - " Main page
\r\n
\r\n" - " Router commands
\r\n" - " Local destinations
\r\n" - " Tunnels
\r\n" - " Transit tunnels
\r\n" - " Transports
\r\n" - " I2P tunnels
\r\n" - " Jump services
\r\n" - ; - if (i2p::client::context.GetSAMBridge ()) - s << " SAM sessions
\r\n"; - s << "
\r\n"; - s << "
"; + ShowPageHead (s); if (uri.find("page=") != std::string::npos) HandlePage (s, uri); else if (uri.find("cmd=") != std::string::npos) HandleCommand (s, uri); else ShowStatus (s); - s << - "
\r\n" - "\r\n" - "\r\n"; + ShowPageTail (s); SendReply (s.str ()); } From 80e37df0123067aedc784321ff2c7eb2f0074030 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 29/49] * HTTPServer.{cpp,h}: change page/cmd processing flow --- Daemon.cpp | 1 + HTTPServer.cpp | 55 ++++++++++++++++++++++++++------------------------ HTTPServer.h | 10 ++++----- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index fdb9bf3f..c98bce05 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -13,6 +13,7 @@ #include "RouterInfo.h" #include "RouterContext.h" #include "Tunnel.h" +#include "HTTP.h" #include "NetDb.h" #include "Garlic.h" #include "Streaming.h" diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 864c9fd3..e5093bba 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -302,6 +302,11 @@ namespace http { "\r\n"; } + void ShowError(std::stringstream& s, const std::string& string) + { + s << "ERROR: " << string << "
\r\n"; + } + void ShowStatus (std::stringstream& s) { s << "Uptime: "; @@ -670,7 +675,7 @@ namespace http { } if (ret == 0) return; /* need more data */ - HandleRequest (request.uri); + HandleRequest (request); } void HTTPConnection::Terminate (const boost::system::error_code& ecode) @@ -682,28 +687,31 @@ namespace http { m_Socket->close (); } - void HTTPConnection::HandleRequest (const std::string &uri) + void HTTPConnection::HandleRequest (const HTTPReq & req) { std::stringstream s; + std::string content; + HTTPRes res; // Html5 head start ShowPageHead (s); - if (uri.find("page=") != std::string::npos) - HandlePage (s, uri); - else if (uri.find("cmd=") != std::string::npos) - HandleCommand (s, uri); + if (req.uri.find("page=") != std::string::npos) + HandlePage (req, res, s); + else if (req.uri.find("cmd=") != std::string::npos) + HandleCommand (req, res, s); else ShowStatus (s); ShowPageTail (s); - SendReply (s.str ()); + content = s.str (); + SendReply (res, content); } - void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) + void HTTPConnection::HandlePage (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; std::string page(""); URL url; - url.parse(uri); + url.parse(req.uri); url.parse_query(params); page = params["page"]; @@ -727,17 +735,20 @@ namespace http { ShowSAMSession (s, params["sam_id"]); else if (page == HTTP_PAGE_I2P_TUNNELS) ShowI2PTunnels (s); - else - SendError("Unknown page: " + page); + else { + res.code = 400; + ShowError(s, "Unknown page: " + page); + return; + } } - void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) + void HTTPConnection::HandleCommand (const HTTPReq& req, HTTPRes& res, std::stringstream& s) { std::map params; std::string cmd(""); URL url; - url.parse(uri); + url.parse(req.uri); url.parse_query(params); cmd = params["cmd"]; @@ -748,21 +759,20 @@ namespace http { else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) i2p::context.SetAcceptsTunnels (false); else { - SendError("Unknown command: " + cmd); + res.code = 400; + ShowError(s, "Unknown command: " + cmd); return; } - s << "Command accepted

\r\n"; + s << "SUCCESS: Command accepted

\r\n"; s << "Back to commands list"; } - void HTTPConnection::SendReply (const std::string& content, int code) + void HTTPConnection::SendReply (HTTPRes& reply, std::string& content) { std::time_t time_now = std::time(nullptr); char time_buff[128]; std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); - HTTPRes reply; - reply.code = code; - reply.status = HTTPCodeToStatus(code); + reply.status = HTTPCodeToStatus(reply.code); reply.headers.insert(std::pair("Date", time_buff)); reply.headers.insert(std::pair("Content-Type", "text/html")); reply.headers.insert(std::pair("Content-Length", std::to_string(content.size()))); @@ -777,13 +787,6 @@ namespace http { std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1)); } - void HTTPConnection::SendError(const std::string& content) - { - std::stringstream ss; - ss << "" << itoopieImage << "
\r\n" << content << ""; - SendReply (ss.str(), 504); - } - HTTPServer::HTTPServer (const std::string& address, int port): m_Thread (nullptr), m_Work (m_Service), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)) diff --git a/HTTPServer.h b/HTTPServer.h index 06fa4457..72a0c383 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -21,13 +21,11 @@ namespace http { void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void Terminate (const boost::system::error_code& ecode); - void SendReply (const std::string& content, int code = 200); - void SendError (const std::string& message); - void RunRequest (); - void HandleRequest (const std::string& uri); - void HandlePage (std::stringstream& s, const std::string& request); - void HandleCommand (std::stringstream& s, const std::string& request); + void HandleRequest (const HTTPReq & req); + void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); + void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); + void SendReply (HTTPRes & res, std::string & content); private: From 75db2867dcdd77452414e4cbfec6c19ef3c44619 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 30/49] * HTTPServer.cpp: protect SAM pages if disabled --- HTTPServer.cpp | 65 ++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index e5093bba..7dc8d910 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -573,15 +573,16 @@ namespace http { void ShowSAMSessions (std::stringstream& s) { - s << "SAM Sessions:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); - if (sam) - { - for (auto& it: sam->GetSessions ()) - { - s << ""; - s << it.first << "
\r\n" << std::endl; - } + if (!sam) { + ShowError(s, "SAM disabled"); + return; + } + s << "SAM Sessions:
\r\n
\r\n"; + for (auto& it: sam->GetSessions ()) + { + s << ""; + s << it.first << "
\r\n" << std::endl; } } @@ -589,35 +590,31 @@ namespace http { { s << "SAM Session:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); - if (sam) + if (!sam) { + ShowError(s, "SAM disabled"); + return; + } + auto session = sam->FindSession (id); + if (!session) { + ShowError(s, "SAM session not found"); + return; + } + auto& ident = session->localDestination->GetIdentHash(); + s << ""; + s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n"; + s << "
\r\n"; + s << "Streams:
\r\n"; + for (auto it: session->ListSockets()) { - auto session = sam->FindSession (id); - if (session) + switch (it->GetSocketType ()) { - auto& ident = session->localDestination->GetIdentHash(); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; - s << "Streams:
\r\n"; - for (auto it: session->ListSockets()) - { - switch (it->GetSocketType ()) - { - case i2p::client::eSAMSocketTypeSession: - s << "session"; - break; - case i2p::client::eSAMSocketTypeStream: - s << "stream"; - break; - case i2p::client::eSAMSocketTypeAcceptor: - s << "acceptor"; - break; - default: - s << "unknown"; - } - s << " [" << it->GetSocket ().remote_endpoint() << "]"; - s << "
\r\n" << std::endl; - } + case i2p::client::eSAMSocketTypeSession : s << "session"; break; + case i2p::client::eSAMSocketTypeStream : s << "stream"; break; + case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break; + default: s << "unknown"; break; } + s << " [" << it->GetSocket ().remote_endpoint() << "]"; + s << "
\r\n"; } } From e09386be445fde1a9e7fe63bbbabb6cff39ebff4 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 31/49] * add http.auth, http.user & http.pass options --- Config.cpp | 3 +++ docs/configuration.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Config.cpp b/Config.cpp index d7cef879..44dec286 100644 --- a/Config.cpp +++ b/Config.cpp @@ -141,6 +141,9 @@ namespace config { ("http.enabled", value()->default_value(true), "Enable or disable webconsole") ("http.address", value()->default_value("127.0.0.1"), "Webconsole listen address") ("http.port", value()->default_value(7070), "Webconsole listen port") + ("http.auth", value()->default_value(false), "Enable Basic HTTP auth for webconsole") + ("http.user", value()->default_value("i2pd"), "Username for basic auth") + ("http.pass", value()->default_value(""), "Password for basic auth (default: random, see logs)") ; options_description httpproxy("HTTP Proxy options"); diff --git a/docs/configuration.md b/docs/configuration.md index 2a639be3..11e8b4a8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -36,6 +36,9 @@ All options below still possible in cmdline, but better write it in config file: * --http.address= - The address to listen on (HTTP server) * --http.port= - The port to listen on (HTTP server) +* --http.auth - Enable basic HTTP auth for webconsole +* --http.user= - Username for basic auth (default: i2pd) +* --http.pass= - Password for basic auth (default: random, see logs) * --httpproxy.address= - The address to listen on (HTTP Proxy) * --httpproxy.port= - The port to listen on (HTTP Proxy) 4446 by default From 678650beaff02b59491233b43aee2ffc5e660e6d Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 32/49] * HTTPServer.{cpp,h}: basic auth --- HTTPServer.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++- HTTPServer.h | 8 ++++--- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7dc8d910..8d9be41f 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -10,6 +10,7 @@ #include "Base.h" #include "FS.h" #include "Log.h" +#include "Config.h" #include "Tunnel.h" #include "TransitTunnel.h" #include "Transports.h" @@ -640,7 +641,16 @@ namespace http { s << "
\r\n"<< std::endl; } } - + + HTTPConnection::HTTPConnection (std::shared_ptr socket): + m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0) + { + /* cache options */ + i2p::config::GetOption("http.auth", needAuth); + i2p::config::GetOption("http.user", user); + i2p::config::GetOption("http.pass", pass); + }; + void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -672,6 +682,7 @@ namespace http { } if (ret == 0) return; /* need more data */ + HandleRequest (request); } @@ -684,11 +695,44 @@ namespace http { m_Socket->close (); } + bool HTTPConnection::CheckAuth (const HTTPReq & req) { + /* method #1: http://user:pass@127.0.0.1:7070/ */ + if (req.uri.find('@') != std::string::npos) { + URL url; + if (url.parse(req.uri) && url.user == user && url.pass == pass) + return true; + } + /* method #2: 'Authorization' header sent */ + if (req.headers.count("Authorization") > 0) { + std::string provided = req.headers.find("Authorization")->second; + std::string expected = user + ":" + pass; + char b64_creds[64]; + std::size_t len = 0; + len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, sizeof(b64_creds)); + b64_creds[len] = '\0'; + expected = "Basic "; + expected += b64_creds; + if (provided == expected) + return true; + } + + LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ()); + return false; + } + void HTTPConnection::HandleRequest (const HTTPReq & req) { std::stringstream s; std::string content; HTTPRes res; + + if (needAuth && !CheckAuth(req)) { + res.code = 401; + res.headers.insert(std::pair("WWW-Authenticate", "Basic realm=\"WebAdmin\"")); + SendReply(res, content); + return; + } + // Html5 head start ShowPageHead (s); if (req.uri.find("page=") != std::string::npos) @@ -797,6 +841,21 @@ namespace http { void HTTPServer::Start () { + bool needAuth; i2p::config::GetOption("http.auth", needAuth); + std::string user; i2p::config::GetOption("http.user", user); + std::string pass; i2p::config::GetOption("http.pass", pass); + /* generate pass if needed */ + if (needAuth && pass == "") { + char alnum[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + pass.resize(16); + for (size_t i = 0; i < pass.size(); i++) { + pass[i] = alnum[rand() % (sizeof(alnum) - 1)]; + } + i2p::config::SetOption("http.pass", pass); + LogPrint(eLogInfo, "HTTPServer: password set to ", pass); + } m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); diff --git a/HTTPServer.h b/HTTPServer.h index 72a0c383..2635c3be 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -11,9 +11,7 @@ namespace http { { public: - HTTPConnection (std::shared_ptr socket): - m_Socket (socket), m_Timer (socket->get_io_service ()), - m_BufferLen (0) {}; + HTTPConnection (std::shared_ptr socket); void Receive (); private: @@ -22,6 +20,7 @@ namespace http { void Terminate (const boost::system::error_code& ecode); void RunRequest (); + bool CheckAuth (const HTTPReq & req); void HandleRequest (const HTTPReq & req); void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); @@ -33,6 +32,9 @@ namespace http { boost::asio::deadline_timer m_Timer; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; + bool needAuth; + std::string user; + std::string pass; }; class HTTPServer From 8fd55a210a7613acc01f4467c1a91186028b0ab5 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 33/49] * HTTPServer.cpp: add 'Shutdown' commands --- HTTPServer.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8d9be41f..36ff2a37 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -21,6 +21,7 @@ #include "RouterContext.h" #include "ClientContext.h" #include "HTTPServer.h" +#include "Daemon.h" // For image and info #include "version.h" @@ -221,6 +222,9 @@ namespace http { const char HTTP_PAGE_COMMANDS[] = "commands"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; + const char HTTP_COMMAND_SHUTDOWN_START[] = "shutdown_start"; + const char HTTP_COMMAND_SHUTDOWN_CANCEL[] = "shutdown_cancel"; + const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; @@ -506,6 +510,14 @@ namespace http { s << " Stop accepting tunnels
\r\n"; else s << " Start accepting tunnels
\r\n"; + if (Daemon.gracefullShutdownInterval) { + s << " Cancel gracefull shutdown ("; + s << Daemon.gracefullShutdownInterval; + s << " seconds remains)
\r\n"; + } else { + s << " Start gracefull shutdown
\r\n"; + } + s << " Force shutdown
\r\n"; } void ShowTransitTunnels (std::stringstream& s) @@ -799,7 +811,15 @@ namespace http { i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) i2p::context.SetAcceptsTunnels (false); - else { + else if (cmd == HTTP_COMMAND_SHUTDOWN_START) { + i2p::context.SetAcceptsTunnels (false); + Daemon.gracefullShutdownInterval = 10*60; + } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { + i2p::context.SetAcceptsTunnels (true); + Daemon.gracefullShutdownInterval = 0; + } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { + Daemon.running = false; + } else { res.code = 400; ShowError(s, "Unknown command: " + cmd); return; From f131e319496739cd3983964cf7e048bec8663423 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 34/49] * HTTPServer.cpp: add request logging --- HTTPServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 36ff2a37..b3efc57d 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -738,6 +738,8 @@ namespace http { std::string content; HTTPRes res; + LogPrint(eLogDebug, "HTTPServer: request: ", req.uri); + if (needAuth && !CheckAuth(req)) { res.code = 401; res.headers.insert(std::pair("WWW-Authenticate", "Basic realm=\"WebAdmin\"")); From 2373b94d3e7794dc19a95322a0c407fddf6ae8d9 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Apr 2016 12:08:08 -0400 Subject: [PATCH 35/49] try fixing issue #482 --- Destination.cpp | 25 ++++++++++++++----------- util.h | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 5893caff..1534cbf9 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -9,6 +9,7 @@ #include "Timestamp.h" #include "NetDb.h" #include "Destination.h" +#include "util.h" namespace i2p { @@ -35,28 +36,30 @@ namespace client { auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH); if (it != params->end ()) - { - int len = boost::lexical_cast(it->second); + { + + int len = i2p::util::lexical_cast(it->second, inboundTunnelLen); if (len > 0) { - inboundTunnelLen = len; - LogPrint (eLogInfo, "Destination: Inbound tunnel length set to ", len); + inboundTunnelLen = len; } + LogPrint (eLogInfo, "Destination: Inbound tunnel length set to ", inboundTunnelLen); } it = params->find (I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH); if (it != params->end ()) { - int len = boost::lexical_cast(it->second); + + int len = i2p::util::lexical_cast(it->second, outboundTunnelLen); if (len > 0) { - outboundTunnelLen = len; - LogPrint (eLogInfo, "Destination: Outbound tunnel length set to ", len); + outboundTunnelLen = len; } + LogPrint (eLogInfo, "Destination: Outbound tunnel length set to ", outboundTunnelLen); } it = params->find (I2CP_PARAM_INBOUND_TUNNELS_QUANTITY); if (it != params->end ()) { - int quantity = boost::lexical_cast(it->second); + int quantity = i2p::util::lexical_cast(it->second, inboundTunnelsQuantity); if (quantity > 0) { inboundTunnelsQuantity = quantity; @@ -66,7 +69,7 @@ namespace client it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY); if (it != params->end ()) { - int quantity = boost::lexical_cast(it->second); + int quantity = i2p::util::lexical_cast(it->second, outboundTunnelsQuantity); if (quantity > 0) { outboundTunnelsQuantity = quantity; @@ -76,11 +79,11 @@ namespace client it = params->find (I2CP_PARAM_TAGS_TO_SEND); if (it != params->end ()) { - int tagsToSend = boost::lexical_cast(it->second); + int tagsToSend = i2p::util::lexical_cast(it->second, numTags); if (tagsToSend > 0) { numTags = tagsToSend; - LogPrint (eLogInfo, "Destination: Tags to send set to ", tagsToSend); + LogPrint (eLogInfo, "Destination: Tags to send set to ", tagsToSend); } } it = params->find (I2CP_PARAM_EXPLICIT_PEERS); diff --git a/util.h b/util.h index 13200591..f5dbc9aa 100644 --- a/util.h +++ b/util.h @@ -5,11 +5,25 @@ #include #include #include +#include namespace i2p { namespace util { + + /** + wrapper arround boost::lexical_cast that "never" fails + */ + template + T lexical_cast(const std::string & str, const T fallback) { + try { + return boost::lexical_cast(str); + } catch ( ... ) { + return fallback; + } + } + namespace http { // in (lower case) From 5e2dc14dd5564fda8f6458db0de38485edd9d6de Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Apr 2016 18:16:11 -0400 Subject: [PATCH 36/49] get family string from local RouterInfo --- Daemon.cpp | 1 - HTTPServer.cpp | 4 +++- RouterContext.cpp | 12 ++---------- RouterContext.h | 4 +--- RouterInfo.cpp | 8 ++++++++ RouterInfo.h | 1 + 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index 2a32ff04..81bbcdd5 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -189,7 +189,6 @@ namespace i2p std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); - i2p::context.SetFamilyString (family); if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 08b67e22..458a717f 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -417,7 +417,9 @@ namespace util default: s << "Unknown"; } s << "
\r\n"; - s << "Family: " << i2p::context.GetFamilyString() << "
\r\n"; + auto family = i2p::context.GetFamily (); + if (family.length () > 0) + s << "Family: " << family << "
\r\n"; s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "Received: "; s << std::fixed << std::setprecision(2); diff --git a/RouterContext.cpp b/RouterContext.cpp index 29891169..5fa32a13 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,17 +149,9 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::SetFamilyString (const std::string& family) + std::string RouterContext::GetFamily () const { - if (family.length() > 0) - m_FamilyString = family; - else - m_FamilyString = "<undefined>"; - } - - std::string RouterContext::GetFamilyString () const - { - return m_FamilyString; + return m_RouterInfo.GetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY); } void RouterContext::SetFamily (const std::string& family) diff --git a/RouterContext.h b/RouterContext.h index def89383..5a72ad58 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,8 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); - void SetFamilyString (const std::string& family); - std::string GetFamilyString () const; + std::string GetFamily () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ bool AcceptsTunnels () const { return m_AcceptsTunnels; }; @@ -102,7 +101,6 @@ namespace i2p i2p::data::PrivateKeys m_Keys; uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; - std::string m_FamilyString; uint64_t m_StartupTime; // in seconds since epoch uint32_t m_BandwidthLimit; // allowed bandwidth RouterStatus m_Status; diff --git a/RouterInfo.cpp b/RouterInfo.cpp index c27f8754..2e76127c 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -636,6 +636,14 @@ namespace data m_Properties.erase (key); } + std::string RouterInfo::GetProperty (const std::string& key) const + { + auto it = m_Properties.find (key); + if (it != m_Properties.end ()) + return it->second; + return ""; + } + bool RouterInfo::IsNTCP (bool v4only) const { if (v4only) diff --git a/RouterInfo.h b/RouterInfo.h index c9881dd2..a55924a8 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -128,6 +128,7 @@ namespace data bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only void DeleteProperty (const std::string& key); // called from RouterContext only + std::string GetProperty (const std::string& key) const; // called from RouterContext only void ClearProperties () { m_Properties.clear (); }; bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; From 00cfdc7d9257cfdb0ada151b77bf14b52c4da729 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 4 May 2016 12:12:24 -0400 Subject: [PATCH 37/49] fix mac brew, use libressl and homebrew --- Makefile | 2 +- Makefile.homebrew | 29 +++++++++++++++++++++++++++++ docs/build_notes_unix.md | 15 +++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 Makefile.homebrew diff --git a/Makefile b/Makefile index ae49ae4f..db6da2df 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ USE_STATIC := no ifeq ($(UNAME),Darwin) DAEMON_SRC += DaemonLinux.cpp - include Makefile.osx + include Makefile.homebrew else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1) DAEMON_SRC += DaemonLinux.cpp include Makefile.bsd diff --git a/Makefile.homebrew b/Makefile.homebrew new file mode 100644 index 00000000..163b7950 --- /dev/null +++ b/Makefile.homebrew @@ -0,0 +1,29 @@ +# root directory holding homebrew +BREWROOT = /usr/local/ +BOOSTROOT = ${BREWROOT}/opt/boost +SSLROOT = ${BREWROOT}/opt/libressl +CXX = clang++ +CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX +INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include +LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib +LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread + +ifeq ($(USE_UPNP),1) + LDFLAGS += -ldl + CXXFLAGS += -DUSE_UPNP +endif + +# OSX Notes +# http://www.hutsby.net/2011/08/macs-with-aes-ni.html +# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2 +# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic +# note from psi: 2009 macbook does not have aesni +#ifeq ($(USE_AESNI),yes) +# CXXFLAGS += -maes -DAESNI +#endif + +# Disabled, since it will be the default make rule. I think its better +# to define the default rule in Makefile and not Makefile. - torkel +#install: all +# test -d ${PREFIX} || mkdir -p ${PREFIX}/ +# cp -r i2p ${PREFIX}/ diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index d02eb5df..d173d4ae 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -93,6 +93,21 @@ If you need UPnP support (don't forget to run CMake with `WITH_UPNP=ON`) miniupn miniupnpc-devel ``` +MAC OS X +-------- + +Requires homebrew + +```bash +brew install libressl boost +``` + +Then build: +```bash +make +``` + + FreeBSD ------- From ca36a6fe41afffc1f9f8f2fd69ded564a71e69a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 May 2016 15:55:48 -0400 Subject: [PATCH 38/49] update our IP after signture verification --- SSUSession.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/SSUSession.cpp b/SSUSession.cpp index aa534c56..a1bbf4d9 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -265,8 +265,6 @@ namespace transport uint16_t ourPort = bufbe16toh (payload); s.Insert (payload, 2); // our port payload += 2; // port - LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); - i2p::context.UpdateAddress (ourIP); if (m_RemoteEndpoint.address ().is_v4 ()) s.Insert (m_RemoteEndpoint.address ().to_v4 ().to_bytes ().data (), 4); // remote IP v4 else @@ -283,11 +281,18 @@ namespace transport //TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved m_SessionKeyDecryption.SetIV (((SSUHeader *)buf)->iv); m_SessionKeyDecryption.Decrypt (payload, signatureLen, payload); // TODO: non-const payload - // verify - if (!s.Verify (m_RemoteIdentity, payload)) + // verify signature + if (s.Verify (m_RemoteIdentity, payload)) + { + LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); + i2p::context.UpdateAddress (ourIP); + SendSessionConfirmed (y, ourAddress, addressSize + 2); + } + else + { LogPrint (eLogError, "SSU: message 'created' signature verification failed"); - - SendSessionConfirmed (y, ourAddress, addressSize + 2); + Failed (); + } } void SSUSession::ProcessSessionConfirmed (const uint8_t * buf, size_t len) @@ -313,11 +318,17 @@ namespace transport paddingSize &= 0x0F; // %16 if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; - // verify - if (m_SignedData && !m_SignedData->Verify (m_RemoteIdentity, payload)) + // verify signature + if (m_SignedData && m_SignedData->Verify (m_RemoteIdentity, payload)) + { + m_Data.Send (CreateDeliveryStatusMsg (0)); + Established (); + } + else + { LogPrint (eLogError, "SSU message 'confirmed' signature verification failed"); - m_Data.Send (CreateDeliveryStatusMsg (0)); - Established (); + Failed (); + } } void SSUSession::SendSessionRequest () From aa215f2a5a975742ad78410caf59be49c6759ce3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 07:08:02 -0400 Subject: [PATCH 39/49] regular/homebrew build selection for Mac OS X --- Makefile | 6 +++++- docs/build_notes_unix.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index db6da2df..e3807d93 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,11 @@ USE_STATIC := no ifeq ($(UNAME),Darwin) DAEMON_SRC += DaemonLinux.cpp - include Makefile.homebrew + ifeq ($(HOMEBREW),1) + include Makefile.homebrew + else + include Makefile.osx + endif else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1) DAEMON_SRC += DaemonLinux.cpp include Makefile.bsd diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index d173d4ae..05605343 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -104,7 +104,7 @@ brew install libressl boost Then build: ```bash -make +make HOMEBREW=1 ``` From 28b5f39b840a4b10542d9f1a29a1d693e1376c94 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 11 May 2016 08:41:32 -0400 Subject: [PATCH 40/49] fix http unit test SIGBUS in os x --- HTTP.cpp | 27 +++++++++++++-------------- HTTP.h | 4 ++-- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/HTTP.cpp b/HTTP.cpp index 74acfb7a..02b58f99 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -10,23 +10,22 @@ namespace i2p { namespace http { - const char *HTTP_METHODS[] = { + const std::vector HTTP_METHODS = { "GET", "HEAD", "POST", "PUT", "PATCH", - "DELETE", "OPTIONS", "CONNECT", - NULL + "DELETE", "OPTIONS", "CONNECT" }; - const char *HTTP_VERSIONS[] = { - "HTTP/1.0", "HTTP/1.1", NULL + const std::vector HTTP_VERSIONS = { + "HTTP/1.0", "HTTP/1.1" }; - bool in_cstr_array(const char **haystack, const char *needle) { - for (const char *p = haystack[0]; p != NULL; p++) { - if (strcmp(p, needle) == 0) - return true; - } - return false; + inline bool is_http_version(const std::string & str) { + return std::find(HTTP_VERSIONS.begin(), HTTP_VERSIONS.end(), str) != std::end(HTTP_VERSIONS); } + inline bool is_http_method(const std::string & str) { + return std::find(HTTP_METHODS.begin(), HTTP_METHODS.end(), str) != std::end(HTTP_METHODS); + } + void strsplit(const std::string & line, std::vector &tokens, char delim, std::size_t limit = 0) { std::size_t count = 0; std::stringstream ss(line); @@ -205,9 +204,9 @@ namespace http { strsplit(line, tokens, ' '); if (tokens.size() != 3) return -1; - if (!in_cstr_array(HTTP_METHODS, tokens[0].c_str())) + if (!is_http_method(tokens[0])) return -1; - if (!in_cstr_array(HTTP_VERSIONS, tokens[2].c_str())) + if (!is_http_version(tokens[2])) return -1; if (!url.parse(tokens[1])) return -1; @@ -288,7 +287,7 @@ namespace http { strsplit(line, tokens, ' ', 3); if (tokens.size() != 3) return -1; - if (!in_cstr_array(HTTP_VERSIONS, tokens[0].c_str())) + if (!is_http_version(tokens[0])) return -1; code = atoi(tokens[1].c_str()); if (code < 100 || code >= 600) diff --git a/HTTP.h b/HTTP.h index 864ad88b..9bd31c75 100644 --- a/HTTP.h +++ b/HTTP.h @@ -19,8 +19,8 @@ namespace i2p { namespace http { const char CRLF[] = "\r\n"; /**< HTTP line terminator */ const char HTTP_EOH[] = "\r\n\r\n"; /**< HTTP end-of-headers mark */ - extern const char *HTTP_METHODS[]; /**< list of valid HTTP methods */ - extern const char *HTTP_VERSIONS[]; /**< list of valid HTTP versions */ + extern const std::vector HTTP_METHODS; /**< list of valid HTTP methods */ + extern const std::vector HTTP_VERSIONS; /**< list of valid HTTP versions */ struct URL { std::string schema; From 8363b4fda78ced508e0f505239389195b7bfde79 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 11 May 2016 09:33:25 -0400 Subject: [PATCH 41/49] add missing header --- HTTP.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/HTTP.cpp b/HTTP.cpp index 02b58f99..ef43d55f 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -7,6 +7,7 @@ */ #include "HTTP.h" +#include namespace i2p { namespace http { From aa5ea0e3a17737d6b6046724734aa0893a1b5bae Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 11:57:02 -0400 Subject: [PATCH 42/49] support gcc 6 --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 24816770..791382c6 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -19,7 +19,7 @@ else ifeq ($(shell expr match ${CXXVER} "4\.[7-9]"),3) # >= 4.7 NEEDED_CXXFLAGS += -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6 NEEDED_CXXFLAGS += -std=c++0x -else ifeq ($(shell expr match ${CXXVER} "5\.[0-9]"),3) # gcc >= 5.0 +else ifeq ($(shell expr match ${CXXVER} "[5-6]\.[0-9]"),3) # gcc >= 5.0 NEEDED_CXXFLAGS += -std=c++11 else # not supported $(error Compiler too old) From 3907b4101a1794fa1d3cf2f3d659deb1c5f10921 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 15:12:38 -0400 Subject: [PATCH 43/49] include openssl through OPENSSL macro --- Crypto.cpp | 16 +++++----- Crypto.h | 12 +++++--- CryptoConst.cpp | 73 ---------------------------------------------- CryptoConst.h | 38 ------------------------ Datagram.cpp | 3 +- Destination.cpp | 4 +-- Family.cpp | 6 ++-- Garlic.cpp | 5 ++-- I2NPProtocol.cpp | 2 -- I2NPProtocol.h | 2 +- I2PControl.cpp | 5 ++-- I2PControl.h | 2 +- Identity.cpp | 3 -- NTCPSession.cpp | 4 +-- NetDb.cpp | 2 +- Reseed.cpp | 10 +++---- SSUSession.cpp | 4 +-- Signature.h | 14 ++++----- Streaming.cpp | 2 +- Transports.cpp | 1 - Tunnel.cpp | 2 +- TunnelConfig.h | 1 - TunnelEndpoint.cpp | 2 +- TunnelGateway.cpp | 3 +- TunnelPool.cpp | 1 - 25 files changed, 48 insertions(+), 169 deletions(-) delete mode 100644 CryptoConst.cpp delete mode 100644 CryptoConst.h diff --git a/Crypto.cpp b/Crypto.cpp index 742296f5..ff68ff6a 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -3,15 +3,15 @@ #include #include #include -#include -#include -#include -#include -#include -#include "TunnelBase.h" -#include -#include "Log.h" #include "Crypto.h" +#include OPENSSL(sha.h) +#include OPENSSL(dh.h) +#include OPENSSL(md5.h) +#include OPENSSL(rand.h) +#include OPENSSL(crypto.h) +#include "TunnelBase.h" +#include OPENSSL(ssl.h) +#include "Log.h" namespace i2p { diff --git a/Crypto.h b/Crypto.h index e333940e..7b580c94 100644 --- a/Crypto.h +++ b/Crypto.h @@ -1,12 +1,16 @@ #ifndef CRYPTO_H__ #define CRYPTO_H__ +#define OPENSSL(file) + #include #include -#include -#include -#include -#include +#include OPENSSL(bn.h) +#include OPENSSL(dh.h) +#include OPENSSL(aes.h) +#include OPENSSL(dsa.h) +#include OPENSSL(sha.h) +#include OPENSSL(rand.h) #include "Base.h" namespace i2p diff --git a/CryptoConst.cpp b/CryptoConst.cpp deleted file mode 100644 index a8868988..00000000 --- a/CryptoConst.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include "CryptoConst.h" - -namespace i2p -{ -namespace crypto -{ - const uint8_t elgp_[256]= - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - }; - - const uint8_t dsap_[128]= - { - 0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c, - 0x30, 0x26, 0xe9, 0xb8, 0xed, 0x92, 0xfa, 0xd0, 0xa6, 0x9c, 0xc8, 0x86, 0xd5, 0xbf, 0x80, 0x15, - 0xfc, 0xad, 0xae, 0x31, 0xa0, 0xad, 0x18, 0xfa, 0xb3, 0xf0, 0x1b, 0x00, 0xa3, 0x58, 0xde, 0x23, - 0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c, - 0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8, - 0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c, - 0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11, - 0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93 - }; - - const uint8_t dsaq_[20]= - { - 0xa5, 0xdf, 0xc2, 0x8f, 0xef, 0x4c, 0xa1, 0xe2, 0x86, 0x74, 0x4c, 0xd8, 0xee, 0xd9, 0xd2, 0x9d, - 0x68, 0x40, 0x46, 0xb7 - }; - - const uint8_t dsag_[128]= - { - 0x0c, 0x1f, 0x4d, 0x27, 0xd4, 0x00, 0x93, 0xb4, 0x29, 0xe9, 0x62, 0xd7, 0x22, 0x38, 0x24, 0xe0, - 0xbb, 0xc4, 0x7e, 0x7c, 0x83, 0x2a, 0x39, 0x23, 0x6f, 0xc6, 0x83, 0xaf, 0x84, 0x88, 0x95, 0x81, - 0x07, 0x5f, 0xf9, 0x08, 0x2e, 0xd3, 0x23, 0x53, 0xd4, 0x37, 0x4d, 0x73, 0x01, 0xcd, 0xa1, 0xd2, - 0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52, - 0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc, - 0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a, - 0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c, - 0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82 - }; - - const CryptoConstants& GetCryptoConstants () - { - static CryptoConstants cryptoConstants = - { - {elgp_, 256}, // elgp - {2}, // elgg - {dsap_, 128}, // dsap - {dsaq_, 20}, // dsaq - {dsag_, 128} // dsag - }; - return cryptoConstants; - } - -} -} - diff --git a/CryptoConst.h b/CryptoConst.h deleted file mode 100644 index ba48a35d..00000000 --- a/CryptoConst.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CRYPTO_CONST_H__ -#define CRYPTO_CONST_H__ - -#include - -namespace i2p -{ -namespace crypto -{ - struct CryptoConstants - { - // DH/ElGamal - const CryptoPP::Integer elgp; - const CryptoPP::Integer elgg; - - // DSA - const CryptoPP::Integer dsap; - const CryptoPP::Integer dsaq; - const CryptoPP::Integer dsag; - }; - - const CryptoConstants& GetCryptoConstants (); - - // DH/ElGamal - #define elgp GetCryptoConstants ().elgp - #define elgg GetCryptoConstants ().elgg - - // DSA - #define dsap GetCryptoConstants ().dsap - #define dsaq GetCryptoConstants ().dsaq - #define dsag GetCryptoConstants ().dsag - - // RSA - const int rsae = 65537; -} -} - -#endif diff --git a/Datagram.cpp b/Datagram.cpp index 9221824d..2015622c 100644 --- a/Datagram.cpp +++ b/Datagram.cpp @@ -1,7 +1,6 @@ #include #include -#include -#include +#include "Crypto.h" #include "Log.h" #include "TunnelBase.h" #include "RouterContext.h" diff --git a/Destination.cpp b/Destination.cpp index 1534cbf9..f487b9ad 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -1,11 +1,9 @@ #include #include #include -#include - +#include "Crypto.h" #include "Log.h" #include "FS.h" -#include "Crypto.h" #include "Timestamp.h" #include "NetDb.h" #include "Destination.h" diff --git a/Family.cpp b/Family.cpp index 34406faa..a3dc5bd0 100644 --- a/Family.cpp +++ b/Family.cpp @@ -1,9 +1,9 @@ #include -#include -#include +#include "Crypto.h" +#include OPENSSL(evp.h) +#include OPENSSL(ssl.h) #include "FS.h" #include "Log.h" -#include "Crypto.h" #include "Family.h" namespace i2p diff --git a/Garlic.cpp b/Garlic.cpp index e11f8ec8..2188ade7 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -2,8 +2,9 @@ #include "I2PEndian.h" #include #include -#include -#include +#include "Crypto.h" +#include OPENSSL(rand.h) +#include OPENSSL(sha.h) #include "RouterContext.h" #include "I2NPProtocol.h" #include "Tunnel.h" diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 9674fdca..e2451f68 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include "Base.h" #include "Log.h" #include "Crypto.h" diff --git a/I2NPProtocol.h b/I2NPProtocol.h index cf8f4266..113e8eb8 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include "Crypto.h" #include "I2PEndian.h" #include "Identity.h" #include "RouterInfo.h" diff --git a/I2PControl.cpp b/I2PControl.cpp index 1ef56c2d..ef9b5081 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -1,7 +1,8 @@ #include #include -#include -#include +#include "Crypto.h" +#include OPENSSL(x509.h) +#include OPENSSL(pem.h) #include #include #include diff --git a/I2PControl.h b/I2PControl.h index 728c9925..0bd70956 100644 --- a/I2PControl.h +++ b/I2PControl.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include // might include openssl #include namespace i2p diff --git a/Identity.cpp b/Identity.cpp index f221dd04..71ca007f 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -1,8 +1,5 @@ #include #include -#include -#include -#include #include "Crypto.h" #include "I2PEndian.h" #include "Log.h" diff --git a/NTCPSession.cpp b/NTCPSession.cpp index a7832335..ae020f5f 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -1,13 +1,11 @@ #include #include -#include -#include #include #include "I2PEndian.h" #include "Base.h" +#include "Crypto.h" #include "Log.h" #include "Timestamp.h" -#include "Crypto.h" #include "I2NPProtocol.h" #include "RouterContext.h" #include "Transports.h" diff --git a/NetDb.cpp b/NetDb.cpp index 857381d8..3aeff92f 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -2,10 +2,10 @@ #include #include #include -#include #include #include "I2PEndian.h" #include "Base.h" +#include "Crypto.h" #include "Log.h" #include "Timestamp.h" #include "I2NPProtocol.h" diff --git a/Reseed.cpp b/Reseed.cpp index caac8071..81811a5e 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -3,10 +3,11 @@ #include #include #include -#include -#include -#include -#include +#include // might include openssl +#include "Crypto.h" +#include OPENSSL(bn.h) +#include OPENSSL(ssl.h) +#include OPENSSL(err.h) #include #include "I2PEndian.h" @@ -14,7 +15,6 @@ #include "FS.h" #include "Log.h" #include "Identity.h" -#include "Crypto.h" #include "NetDb.h" #include "util.h" diff --git a/SSUSession.cpp b/SSUSession.cpp index a1bbf4d9..cf56ca15 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -1,7 +1,5 @@ #include -#include -#include -#include +#include "Crypto.h" #include "Log.h" #include "Timestamp.h" #include "RouterContext.h" diff --git a/Signature.h b/Signature.h index a0b54468..e3a39339 100644 --- a/Signature.h +++ b/Signature.h @@ -3,14 +3,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include #include "Crypto.h" +#include OPENSSL(sha.h) +#include OPENSSL(dsa.h) +#include OPENSSL(ec.h) +#include OPENSSL(ecdsa.h) +#include OPENSSL(rsa.h) +#include OPENSSL(rand.h) +#include OPENSSL(evp.h) namespace i2p { diff --git a/Streaming.cpp b/Streaming.cpp index e425ce27..ab0a6df0 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -1,4 +1,4 @@ -#include +#include "Crypto.h" #include "Log.h" #include "RouterInfo.h" #include "RouterContext.h" diff --git a/Transports.cpp b/Transports.cpp index 0fdfce3d..057e2472 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -1,4 +1,3 @@ -#include #include "Log.h" #include "Crypto.h" #include "RouterContext.h" diff --git a/Tunnel.cpp b/Tunnel.cpp index 5e237d87..bf81dc5e 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include "Crypto.h" #include "RouterContext.h" #include "Log.h" #include "Timestamp.h" diff --git a/TunnelConfig.h b/TunnelConfig.h index c089b13c..0340254e 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -5,7 +5,6 @@ #include #include #include -#include #include "Crypto.h" #include "Identity.h" #include "RouterContext.h" diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index 842b624f..1bc8a937 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -1,6 +1,6 @@ #include "I2PEndian.h" #include -#include +#include "Crypto.h" #include "Log.h" #include "NetDb.h" #include "I2NPProtocol.h" diff --git a/TunnelGateway.cpp b/TunnelGateway.cpp index 4f517eb8..3383010b 100644 --- a/TunnelGateway.cpp +++ b/TunnelGateway.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include "Crypto.h" #include "I2PEndian.h" #include "Log.h" #include "RouterContext.h" diff --git a/TunnelPool.cpp b/TunnelPool.cpp index c74ff475..5e7e8ec4 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -1,5 +1,4 @@ #include -#include #include "I2PEndian.h" #include "Crypto.h" #include "Tunnel.h" From ae81cc2644a83dfdfebf4ef6009cfdba68f25308 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 15:33:53 -0400 Subject: [PATCH 44/49] windows doesn't support graceful shutdown yet --- HTTPServer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7ad8279d..63975722 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -513,6 +513,7 @@ namespace http { s << " Stop accepting tunnels
\r\n"; else s << " Start accepting tunnels
\r\n"; +#ifndef WIN32 if (Daemon.gracefullShutdownInterval) { s << " Cancel gracefull shutdown ("; s << Daemon.gracefullShutdownInterval; @@ -521,6 +522,7 @@ namespace http { s << " Start gracefull shutdown
\r\n"; } s << " Force shutdown
\r\n"; +#endif } void ShowTransitTunnels (std::stringstream& s) @@ -818,10 +820,14 @@ namespace http { i2p::context.SetAcceptsTunnels (false); else if (cmd == HTTP_COMMAND_SHUTDOWN_START) { i2p::context.SetAcceptsTunnels (false); +#ifndef WIN32 Daemon.gracefullShutdownInterval = 10*60; +#endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { i2p::context.SetAcceptsTunnels (true); +#ifndef WIN32 Daemon.gracefullShutdownInterval = 0; +#endif } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { Daemon.running = false; } else { From 7c835bae20cd5d877b7a16351b851881577d6aac Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 16:02:26 -0400 Subject: [PATCH 45/49] changed back to #include #include -#include "Crypto.h" -#include OPENSSL(sha.h) -#include OPENSSL(dh.h) -#include OPENSSL(md5.h) -#include OPENSSL(rand.h) -#include OPENSSL(crypto.h) +#include +#include +#include #include "TunnelBase.h" -#include OPENSSL(ssl.h) +#include #include "Log.h" +#include "Crypto.h" namespace i2p { diff --git a/Crypto.h b/Crypto.h index 7b580c94..7ce202ce 100644 --- a/Crypto.h +++ b/Crypto.h @@ -1,16 +1,14 @@ #ifndef CRYPTO_H__ #define CRYPTO_H__ -#define OPENSSL(file) - #include #include -#include OPENSSL(bn.h) -#include OPENSSL(dh.h) -#include OPENSSL(aes.h) -#include OPENSSL(dsa.h) -#include OPENSSL(sha.h) -#include OPENSSL(rand.h) +#include +#include +#include +#include +#include +#include #include "Base.h" namespace i2p diff --git a/Family.cpp b/Family.cpp index a3dc5bd0..90c5ccd0 100644 --- a/Family.cpp +++ b/Family.cpp @@ -1,7 +1,7 @@ #include +#include +#include #include "Crypto.h" -#include OPENSSL(evp.h) -#include OPENSSL(ssl.h) #include "FS.h" #include "Log.h" #include "Family.h" diff --git a/Garlic.cpp b/Garlic.cpp index 2188ade7..c1100f64 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -3,8 +3,6 @@ #include #include #include "Crypto.h" -#include OPENSSL(rand.h) -#include OPENSSL(sha.h) #include "RouterContext.h" #include "I2NPProtocol.h" #include "Tunnel.h" diff --git a/I2PControl.cpp b/I2PControl.cpp index ef9b5081..ab9feeed 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -1,8 +1,7 @@ #include #include -#include "Crypto.h" -#include OPENSSL(x509.h) -#include OPENSSL(pem.h) +#include +#include #include #include #include @@ -14,6 +13,7 @@ #include #endif +#include "Crypto.h" #include "FS.h" #include "Log.h" #include "Config.h" diff --git a/I2PControl.h b/I2PControl.h index 0bd70956..f2e82254 100644 --- a/I2PControl.h +++ b/I2PControl.h @@ -10,7 +10,7 @@ #include #include #include -#include // might include openssl +#include #include namespace i2p diff --git a/Reseed.cpp b/Reseed.cpp index 81811a5e..ddefc460 100644 --- a/Reseed.cpp +++ b/Reseed.cpp @@ -3,13 +3,12 @@ #include #include #include -#include // might include openssl -#include "Crypto.h" -#include OPENSSL(bn.h) -#include OPENSSL(ssl.h) -#include OPENSSL(err.h) +#include +#include +#include #include +#include "Crypto.h" #include "I2PEndian.h" #include "Reseed.h" #include "FS.h" diff --git a/Signature.h b/Signature.h index e3a39339..5934f8d2 100644 --- a/Signature.h +++ b/Signature.h @@ -3,14 +3,12 @@ #include #include +#include +#include +#include +#include +#include #include "Crypto.h" -#include OPENSSL(sha.h) -#include OPENSSL(dsa.h) -#include OPENSSL(ec.h) -#include OPENSSL(ecdsa.h) -#include OPENSSL(rsa.h) -#include OPENSSL(rand.h) -#include OPENSSL(evp.h) namespace i2p { From c49fdf12334c5fae3cb5545ecb14eba9bc0f0fb5 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 12 May 2016 11:38:18 -0400 Subject: [PATCH 46/49] initial commit for reload config command --- ClientContext.cpp | 18 ++++++++++++++---- ClientContext.h | 2 ++ HTTPServer.cpp | 6 +++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 2eb81af2..aad41ab2 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -171,6 +171,11 @@ namespace client m_Destinations.clear (); m_SharedLocalDestination = nullptr; } + + void ClientContext::ReloadConfig () + { + ReadTunnels (); // TODO: it reads new tunnels only, should be implemented better + } void ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename, i2p::data::SigningKeyType sigType) { @@ -330,10 +335,12 @@ namespace client auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); if (m_ClientTunnels.insert (std::make_pair (clientTunnel->GetAcceptor ().local_endpoint (), std::unique_ptr(clientTunnel))).second) + { clientTunnel->Start (); + numClientTunnels++; + } else - LogPrint (eLogError, "Clients: I2P client tunnel with port ", port, " already exists"); - numClientTunnels++; + LogPrint (eLogError, "Clients: I2P client tunnel for endpoint ", clientTunnel->GetAcceptor ().local_endpoint (), " already exists"); } else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP || type == I2P_TUNNELS_SECTION_TYPE_IRC) { @@ -385,10 +392,13 @@ namespace client if (m_ServerTunnels.insert (std::make_pair ( std::make_pair (localDestination->GetIdentHash (), inPort), std::unique_ptr(serverTunnel))).second) + { serverTunnel->Start (); + numServerTunnels++; + } else - LogPrint (eLogError, "Clients: I2P server tunnel for destination ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), " already exists"); - numServerTunnels++; + LogPrint (eLogError, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); + } else LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf); diff --git a/ClientContext.h b/ClientContext.h index 3381228b..15ae73c2 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -48,6 +48,8 @@ namespace client void Start (); void Stop (); + void ReloadConfig (); + std::shared_ptr GetSharedLocalDestination () const { return m_SharedLocalDestination; }; std::shared_ptr CreateNewLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1, const std::map * params = nullptr); // transient diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 63975722..19ccecb5 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -225,7 +225,8 @@ namespace http { const char HTTP_COMMAND_SHUTDOWN_START[] = "shutdown_start"; const char HTTP_COMMAND_SHUTDOWN_CANCEL[] = "shutdown_cancel"; const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; - const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; + const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; + const char HTTP_COMMAND_RELOAD_CONFIG[] = "reload_config"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; @@ -509,6 +510,7 @@ namespace http { /* commands */ s << "Router Commands
\r\n"; s << " Run peer test
\r\n"; + s << " Reload config
\r\n"; if (i2p::context.AcceptsTunnels ()) s << " Stop accepting tunnels
\r\n"; else @@ -814,6 +816,8 @@ namespace http { if (cmd == HTTP_COMMAND_RUN_PEER_TEST) i2p::transport::transports.PeerTest (); + else if (cmd == HTTP_COMMAND_RELOAD_CONFIG) + i2p::client::context.ReloadConfig (); else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) From 67f1e07508a2a4348d95d2d8024430f5d67a78c0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 12 May 2016 15:37:46 -0400 Subject: [PATCH 47/49] I2CP added --- ClientContext.cpp | 3 ++- ClientContext.h | 2 ++ I2CP.cpp | 13 +++++++++++++ I2CP.h | 21 +++++++++++++++++++++ build/CMakeLists.txt | 1 + filelist.mk | 2 +- 6 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 I2CP.cpp create mode 100644 I2CP.h diff --git a/ClientContext.cpp b/ClientContext.cpp index aad41ab2..df0de4e5 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -16,7 +16,7 @@ namespace client ClientContext::ClientContext (): m_SharedLocalDestination (nullptr), m_HttpProxy (nullptr), m_SocksProxy (nullptr), m_SamBridge (nullptr), - m_BOBCommandChannel (nullptr) + m_BOBCommandChannel (nullptr), m_I2CPServer (nullptr) { } @@ -26,6 +26,7 @@ namespace client delete m_SocksProxy; delete m_SamBridge; delete m_BOBCommandChannel; + delete m_I2CPServer; } void ClientContext::Start () diff --git a/ClientContext.h b/ClientContext.h index 15ae73c2..cfbc039f 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -11,6 +11,7 @@ #include "I2PTunnel.h" #include "SAM.h" #include "BOB.h" +#include "I2CP.h" #include "AddressBook.h" namespace i2p @@ -84,6 +85,7 @@ namespace client std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel SAMBridge * m_SamBridge; BOBCommandChannel * m_BOBCommandChannel; + I2CPServer * m_I2CPServer; public: // for HTTP diff --git a/I2CP.cpp b/I2CP.cpp new file mode 100644 index 00000000..77ff06e2 --- /dev/null +++ b/I2CP.cpp @@ -0,0 +1,13 @@ +#include "I2CP.h" + + +namespace i2p +{ +namespace client +{ + I2CPServer::I2CPServer (const std::string& interface, int port) + { + } +} +} + diff --git a/I2CP.h b/I2CP.h new file mode 100644 index 00000000..c5460c93 --- /dev/null +++ b/I2CP.h @@ -0,0 +1,21 @@ +#ifndef I2CP_H__ +#define I2CP_H__ + +#include +#include + +namespace i2p +{ +namespace client +{ + class I2CPServer + { + public: + + I2CPServer (const std::string& interface, int port); + }; +} +} + +#endif + diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 22029e85..7944e2ec 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -76,6 +76,7 @@ set (CLIENT_SRC "${CMAKE_SOURCE_DIR}/SOCKS.cpp" "${CMAKE_SOURCE_DIR}/HTTP.cpp" "${CMAKE_SOURCE_DIR}/HTTPProxy.cpp" + "${CMAKE_SOURCE_DIR}/I2CP.cpp" ) add_library(i2pdclient ${CLIENT_SRC}) diff --git a/filelist.mk b/filelist.mk index e2a3da36..8abf0b4b 100644 --- a/filelist.mk +++ b/filelist.mk @@ -9,7 +9,7 @@ LIB_SRC = \ LIB_CLIENT_SRC = \ AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \ - SAM.cpp SOCKS.cpp HTTP.cpp HTTPProxy.cpp + SAM.cpp SOCKS.cpp HTTP.cpp HTTPProxy.cpp I2CP.cpp # also: Daemon{Linux,Win32}.cpp will be added later DAEMON_SRC = \ From 4c2d4009dab26fc4daffb2349e426adeb3636cd6 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 12 May 2016 16:17:10 -0400 Subject: [PATCH 48/49] handle protocol byte --- I2CP.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ I2CP.h | 24 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/I2CP.cpp b/I2CP.cpp index 77ff06e2..d3e25e99 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -5,6 +5,46 @@ namespace i2p { namespace client { + I2CPSession::I2CPSession (std::shared_ptr socket): + m_Socket (socket) + { + ReadProtocolByte (); + } + + void I2CPSession::ReadProtocolByte () + { + if (m_Socket) + { + auto s = shared_from_this (); + m_Socket->async_read_some (boost::asio::buffer (m_Buffer, 1), + [s](const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (!ecode && bytes_transferred > 0 && s->m_Buffer[0] == I2CP_PRTOCOL_BYTE) + s->Receive (); + else + s->Terminate (); + }); + } + } + + void I2CPSession::Receive () + { + m_Socket->async_read_some (boost::asio::buffer (m_Buffer, I2CP_SESSION_BUFFER_SIZE), + std::bind (&I2CPSession::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + + void I2CPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (ecode) + Terminate (); + else + Receive (); + } + + void I2CPSession::Terminate () + { + } + I2CPServer::I2CPServer (const std::string& interface, int port) { } diff --git a/I2CP.h b/I2CP.h index c5460c93..e4b94870 100644 --- a/I2CP.h +++ b/I2CP.h @@ -1,13 +1,37 @@ #ifndef I2CP_H__ #define I2CP_H__ +#include #include +#include #include namespace i2p { namespace client { + const uint8_t I2CP_PRTOCOL_BYTE = 0x2A; + const size_t I2CP_SESSION_BUFFER_SIZE = 8192; + + class I2CPSession: public std::enable_shared_from_this + { + public: + + I2CPSession (std::shared_ptr socket); + + private: + + void ReadProtocolByte (); + void Receive (); + void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void Terminate (); + + private: + + std::shared_ptr m_Socket; + uint8_t m_Buffer[I2CP_SESSION_BUFFER_SIZE]; + }; + class I2CPServer { public: From 448b25a8b2adf3fb1a03589111781ae94141ec78 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 13 May 2016 15:13:36 -0400 Subject: [PATCH 49/49] receive I2CP messages --- I2CP.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- I2CP.h | 31 ++++++++++++++++++++++++---- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index d3e25e99..d6ba4e42 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -1,3 +1,6 @@ +#include +#include "I2PEndian.h" +#include "Log.h" #include "I2CP.h" @@ -5,12 +8,18 @@ namespace i2p { namespace client { - I2CPSession::I2CPSession (std::shared_ptr socket): - m_Socket (socket) + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): + m_Owner (owner), m_Socket (socket), + m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0) { ReadProtocolByte (); } + I2CPSession::~I2CPSession () + { + delete[] m_NextMessage; + } + void I2CPSession::ReadProtocolByte () { if (m_Socket) @@ -38,15 +47,65 @@ namespace client if (ecode) Terminate (); else + { + size_t offset = 0; + if (m_NextMessage) + { + if (m_NextMessageOffset + bytes_transferred <= m_NextMessageLen) + { + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, bytes_transferred); + m_NextMessageOffset += bytes_transferred; + } + else + { + offset = m_NextMessageLen - m_NextMessageOffset; + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, offset); + HandleNextMessage (m_NextMessage); + delete[] m_NextMessage; + } + } + while (offset < bytes_transferred) + { + auto msgLen = bufbe32toh (m_Buffer + offset + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE; + if (msgLen <= bytes_transferred - offset) + { + HandleNextMessage (m_Buffer + offset); + offset += msgLen; + } + else + { + m_NextMessageLen = msgLen; + m_NextMessageOffset = bytes_transferred - offset; + m_NextMessage = new uint8_t[m_NextMessageLen]; + memcpy (m_NextMessage, m_Buffer + offset, m_NextMessageOffset); + offset = bytes_transferred; + } + } Receive (); + } + } + + void I2CPSession::HandleNextMessage (const uint8_t * buf) + { + auto handler = m_Owner.GetMessagesHandlers ()[buf[I2CP_HEADER_TYPE_OFFSET]]; + if (handler) + (this->*handler)(buf + I2CP_HEADER_SIZE, bufbe32toh (buf + I2CP_HEADER_LENGTH_OFFSET)); + else + LogPrint (eLogError, "I2CP: Unknown I2CP messsage ", (int)buf[I2CP_HEADER_TYPE_OFFSET]); } void I2CPSession::Terminate () { } + void I2CPSession::GetDateMessageHandler (const uint8_t * buf, size_t len) + { + } + I2CPServer::I2CPServer (const std::string& interface, int port) { + memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); + m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; } } } diff --git a/I2CP.h b/I2CP.h index e4b94870..cb17626d 100644 --- a/I2CP.h +++ b/I2CP.h @@ -11,32 +11,55 @@ namespace i2p namespace client { const uint8_t I2CP_PRTOCOL_BYTE = 0x2A; - const size_t I2CP_SESSION_BUFFER_SIZE = 8192; + const size_t I2CP_SESSION_BUFFER_SIZE = 4096; + const size_t I2CP_HEADER_LENGTH_OFFSET = 0; + const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4; + const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1; + + const uint8_t I2CP_GET_DATE_MESSAGE = 32; + + class I2CPServer; class I2CPSession: public std::enable_shared_from_this { public: - I2CPSession (std::shared_ptr socket); + I2CPSession (I2CPServer& owner, std::shared_ptr socket); + ~I2CPSession (); + + // message handlers + void GetDateMessageHandler (const uint8_t * buf, size_t len); private: void ReadProtocolByte (); void Receive (); void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleNextMessage (const uint8_t * buf); void Terminate (); private: + I2CPServer& m_Owner; std::shared_ptr m_Socket; - uint8_t m_Buffer[I2CP_SESSION_BUFFER_SIZE]; + uint8_t m_Buffer[I2CP_SESSION_BUFFER_SIZE], * m_NextMessage; + size_t m_NextMessageLen, m_NextMessageOffset; }; - + typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); + class I2CPServer { public: I2CPServer (const std::string& interface, int port); + + private: + + I2CPMessageHandler m_MessagesHandlers[256]; + + public: + + const decltype(m_MessagesHandlers)& GetMessagesHandlers () const { return m_MessagesHandlers; }; }; } }
Streams
StreamIDDestinationSentReceivedOutInBufRTTWindowStatus
" << it->GetSendStreamID () << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << "" << it->GetNumSentBytes () << "" << it->GetNumReceivedBytes () << "" << it->GetSendQueueSize () << "" << it->GetReceiveQueueSize () << "" << it->GetSendBufferSize () << "" << it->GetRTT () << "" << it->GetWindowSize () << "" << (int)it->GetStatus () << "