From 49d28789381d541f2360273ac8fe474aa177a0fe Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jun 2016 15:48:36 -0400 Subject: [PATCH 01/62] use local sockets for android --- I2CP.cpp | 25 ++++++++++++++++++++++--- I2CP.h | 23 +++++++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index f506a312..6e53451c 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -114,7 +114,12 @@ namespace client } } - I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): + I2CPSession::I2CPSession (I2CPServer& owner, +#ifdef ANDROID + std::shared_ptr socket): +#else + std::shared_ptr socket): +#endif m_Owner (owner), m_Socket (socket), m_Payload (nullptr), m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) { @@ -583,7 +588,12 @@ namespace client I2CPServer::I2CPServer (const std::string& interface, int port): m_IsRunning (false), m_Thread (nullptr), - m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) + m_Acceptor (m_Service, +#ifdef ANDROID + boost::asio::local::stream_protocol::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address +#else + boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) +#endif { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; @@ -644,12 +654,21 @@ namespace client void I2CPServer::Accept () { +#ifdef ANDROID + auto newSocket = std::make_shared (m_Service); +#else auto newSocket = std::make_shared (m_Service); +#endif m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this, std::placeholders::_1, newSocket)); } - void I2CPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket) + void I2CPServer::HandleAccept(const boost::system::error_code& ecode, +#ifdef ANDROID + std::shared_ptr socket) +#else + std::shared_ptr socket) +#endif { if (!ecode && socket) { diff --git a/I2CP.h b/I2CP.h index 6fc0e846..20f20d63 100644 --- a/I2CP.h +++ b/I2CP.h @@ -99,7 +99,12 @@ namespace client { public: - I2CPSession (I2CPServer& owner, std::shared_ptr socket); + I2CPSession (I2CPServer& owner, +#ifdef ANDROID + std::shared_ptr socket); +#else + std::shared_ptr socket); +#endif ~I2CPSession (); void Start (); @@ -144,7 +149,11 @@ namespace client private: I2CPServer& m_Owner; +#ifdef ANDROID + std::shared_ptr m_Socket; +#else std::shared_ptr m_Socket; +#endif uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload; size_t m_PayloadLen; @@ -173,7 +182,13 @@ namespace client void Run (); void Accept (); - void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); + + void HandleAccept(const boost::system::error_code& ecode, +#ifdef ANDROID + std::shared_ptr socket); +#else + std::shared_ptr socket); +#endif private: @@ -183,7 +198,11 @@ namespace client bool m_IsRunning; std::thread * m_Thread; boost::asio::io_service m_Service; +#ifdef ANDROID + boost::asio::local::stream_protocol::acceptor m_Acceptor; +#else boost::asio::ip::tcp::acceptor m_Acceptor; +#endif public: From 118a7719801e0db2c3ebb62a90013b61953e41c8 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 02/62] * update changelog --- ChangeLog | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9a32e42f..520978df 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,23 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog -## [2.8.0] - UNRELEASED +## [2.9.0] - UNRELEASED ### Changed - Proxy refactoring & speedup + +## [2.8.0] - 2016-06-20 +### Added +- Basic Android support +- I2CP implementation +- 'doxygen' target + +### Changed - I2PControl refactoring & fixes (proper jsonrpc responses on errors) - boost::regex no more needed ### Fixed - initscripts: added openrc one, in sysv-ish make I2PD_PORT optional +- properly close NTCP sessions (memleak) ## [2.7.0] - 2016-05-18 ### Added From 02857cf2b5de99b7ab244951000bae010a5297a6 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 03/62] * Base.cpp : drop logger dependency --- Base.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/Base.cpp b/Base.cpp index e0b6af07..766eaab9 100644 --- a/Base.cpp +++ b/Base.cpp @@ -1,5 +1,4 @@ #include -#include "Log.h" #include "Base.h" namespace i2p @@ -305,13 +304,10 @@ namespace data m_Inflator.next_out = out; m_Inflator.avail_out = outLen; int err; - if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) + if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) { return outLen - m_Inflator.avail_out; - else - { - LogPrint (eLogError, "Decompression error ", err); - return 0; - } + } + return 0; } bool GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& s) @@ -328,13 +324,11 @@ namespace data ret = inflate (&m_Inflator, Z_NO_FLUSH); if (ret < 0) { - LogPrint (eLogError, "Decompression error ", ret); inflateEnd (&m_Inflator); s.setstate(std::ios_base::failbit); break; } - else - s.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); + s.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); } while (!m_Inflator.avail_out); // more data to read delete[] out; @@ -377,13 +371,10 @@ namespace data m_Deflator.next_out = out; m_Deflator.avail_out = outLen; int err; - if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) + if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) { return outLen - m_Deflator.avail_out; - else - { - LogPrint (eLogError, "Compression error ", err); - return 0; - } + } /* else */ + return 0; } } } From 225ed5b6628b7b6f3e353e2c5b3005eeed278c1d Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 04/62] * HTTPProxy.{cpp,h} : move & sort headers --- HTTPProxy.cpp | 8 +++++++- HTTPProxy.h | 7 ------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 48fa0ae6..4d037ebe 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -3,6 +3,13 @@ #include #include #include +#include +#include +#include +#include + +#include "I2PService.h" +#include "Destination.h" #include "HTTPProxy.h" #include "util.h" #include "Identity.h" @@ -344,6 +351,5 @@ namespace proxy { return std::make_shared (this, socket); } - } } diff --git a/HTTPProxy.h b/HTTPProxy.h index b5ed77b9..0356adb5 100644 --- a/HTTPProxy.h +++ b/HTTPProxy.h @@ -1,13 +1,6 @@ #ifndef HTTP_PROXY_H__ #define HTTP_PROXY_H__ -#include -#include -#include -#include -#include "I2PService.h" -#include "Destination.h" - namespace i2p { namespace proxy From dde53ea4ba0bf66d81445bb38f90647ab691ffa0 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 05/62] * HTTPProxy.cpp : HTTPRequestFailed() now responds with error message --- HTTPProxy.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 4d037ebe..8bc617a7 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -43,7 +43,7 @@ namespace proxy void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void Terminate(); void AsyncSockRead(); - void HTTPRequestFailed(/*std::string message*/); + void HTTPRequestFailed(const char *message); void RedirectToJumpService(); void ExtractRequest(); bool IsI2PAddress(); @@ -98,10 +98,17 @@ namespace proxy /* All hope is lost beyond this point */ //TODO: handle this apropriately - void HTTPProxyHandler::HTTPRequestFailed(/*HTTPProxyHandler::errTypes error*/) + void HTTPProxyHandler::HTTPRequestFailed(const char *message) { - static std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n\r\n"; - boost::asio::async_write(*m_sock, boost::asio::buffer(response,response.size()), + std::size_t size = std::strlen(message); + std::stringstream ss; + ss << "HTTP/1.0 500 Internal Server Error\r\n" + << "Content-Type: text/plain\r\n"; + ss << "Content-Length: " << std::to_string(size + 2) << "\r\n" + << "\r\n"; /* end of headers */ + ss << message << "\r\n"; + std::string response = ss.str(); + boost::asio::async_write(*m_sock, boost::asio::buffer(response), std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } @@ -139,7 +146,7 @@ namespace proxy if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" ) { LogPrint(eLogError, "HTTPProxy: unsupported version: ", m_version); - HTTPRequestFailed(); //TODO: send right stuff + HTTPRequestFailed("unsupported HTTP version"); return false; } return true; @@ -276,13 +283,13 @@ namespace proxy case '\n': EnterState(DONE); break; default: LogPrint(eLogError, "HTTPProxy: rejected invalid request ending with: ", ((int)*http_buff)); - HTTPRequestFailed(); //TODO: add correct code + HTTPRequestFailed("rejected invalid request"); return false; } break; default: LogPrint(eLogError, "HTTPProxy: invalid state: ", m_state); - HTTPRequestFailed(); //TODO: add correct code 500 + HTTPRequestFailed("invalid parser state"); return false; } http_buff++; @@ -338,7 +345,7 @@ namespace proxy else { LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info"); - HTTPRequestFailed(); // TODO: Send correct error message host unreachable + HTTPRequestFailed("error when creating the stream, check logs"); } } From d8906f508c22fa6bf66cf3ff60e449bc862e2081 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 06/62] * HTTPProxy.cpp : HTTP error message cleanup --- HTTPProxy.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 8bc617a7..8a430594 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -114,12 +114,16 @@ namespace proxy void HTTPProxyHandler::RedirectToJumpService(/*HTTPProxyHandler::errTypes error*/) { - std::stringstream response; + std::stringstream ss; std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - response << "HTTP/1.1 302 Found\r\nLocation: http://" << httpAddr << ":" << httpPort << "/?page=jumpservices&address=" << m_address << "\r\n\r\n"; - boost::asio::async_write(*m_sock, boost::asio::buffer(response.str (),response.str ().length ()), + ss << "HTTP/1.1 302 Found\r\n" + << "Connection: close\r\n" + << "Location: http://" << httpAddr << ":" << httpPort << "/?page=jumpservices&address=" << m_address << "\r\n" + << "\r\n"; + std::string response = ss.str(); + boost::asio::async_write(*m_sock, boost::asio::buffer(response), std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } From 340686ba067340831b3159814f9747550cd7a8fa Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 23 Jun 2016 00:00:00 +0000 Subject: [PATCH 07/62] * HTTPProxy.{cpp,h} : rename classes, drop typedef --- HTTPProxy.cpp | 58 +++++++++++++++++++++++++-------------------------- HTTPProxy.h | 18 +++++++--------- 2 files changed, 35 insertions(+), 41 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 8a430594..81ed8da6 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -21,12 +21,10 @@ #include "Config.h" #include "HTTP.h" -namespace i2p -{ -namespace proxy -{ +namespace i2p { +namespace proxy { static const size_t http_buffer_size = 8192; - class HTTPProxyHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this + class HTTPReqHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this { private: enum state @@ -66,26 +64,26 @@ namespace proxy public: - HTTPProxyHandler(HTTPProxyServer * parent, std::shared_ptr sock) : + HTTPReqHandler(HTTPProxy * parent, std::shared_ptr sock) : I2PServiceHandler(parent), m_sock(sock) { EnterState(GET_METHOD); } - ~HTTPProxyHandler() { Terminate(); } + ~HTTPReqHandler() { Terminate(); } void Handle () { AsyncSockRead(); } }; - void HTTPProxyHandler::AsyncSockRead() + void HTTPReqHandler::AsyncSockRead() { LogPrint(eLogDebug, "HTTPProxy: async sock read"); if(m_sock) { m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size), - std::bind(&HTTPProxyHandler::HandleSockRecv, shared_from_this(), + std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else { LogPrint(eLogError, "HTTPProxy: no socket for read"); } } - void HTTPProxyHandler::Terminate() { + void HTTPReqHandler::Terminate() { if (Kill()) return; if (m_sock) { @@ -98,7 +96,7 @@ namespace proxy /* All hope is lost beyond this point */ //TODO: handle this apropriately - void HTTPProxyHandler::HTTPRequestFailed(const char *message) + void HTTPReqHandler::HTTPRequestFailed(const char *message) { std::size_t size = std::strlen(message); std::stringstream ss; @@ -109,10 +107,10 @@ namespace proxy ss << message << "\r\n"; std::string response = ss.str(); boost::asio::async_write(*m_sock, boost::asio::buffer(response), - std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); + std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } - void HTTPProxyHandler::RedirectToJumpService(/*HTTPProxyHandler::errTypes error*/) + void HTTPReqHandler::RedirectToJumpService(/*HTTPReqHandler::errTypes error*/) { std::stringstream ss; std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); @@ -124,15 +122,15 @@ namespace proxy << "\r\n"; std::string response = ss.str(); boost::asio::async_write(*m_sock, boost::asio::buffer(response), - std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); + std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } - void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate) + void HTTPReqHandler::EnterState(HTTPReqHandler::state nstate) { m_state = nstate; } - void HTTPProxyHandler::ExtractRequest() + void HTTPReqHandler::ExtractRequest() { LogPrint(eLogDebug, "HTTPProxy: request: ", m_method, " ", m_url); i2p::http::URL url; @@ -145,7 +143,7 @@ namespace proxy LogPrint(eLogDebug, "HTTPProxy: server: ", m_address, ", port: ", m_port, ", path: ", m_path); } - bool HTTPProxyHandler::ValidateHTTPRequest() + bool HTTPReqHandler::ValidateHTTPRequest() { if ( m_version != "HTTP/1.0" && m_version != "HTTP/1.1" ) { @@ -156,7 +154,7 @@ namespace proxy return true; } - void HTTPProxyHandler::HandleJumpServices() + void HTTPReqHandler::HandleJumpServices() { static const char * helpermark1 = "?i2paddresshelper="; static const char * helpermark2 = "&i2paddresshelper="; @@ -188,7 +186,7 @@ namespace proxy m_path.erase(addressHelperPos); } - bool HTTPProxyHandler::IsI2PAddress() + bool HTTPReqHandler::IsI2PAddress() { auto pos = m_address.rfind (".i2p"); if (pos != std::string::npos && (pos+4) == m_address.length ()) @@ -198,7 +196,7 @@ namespace proxy return false; } - bool HTTPProxyHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len) + bool HTTPReqHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len) { ExtractRequest(); //TODO: parse earlier if (!ValidateHTTPRequest()) return false; @@ -253,7 +251,7 @@ namespace proxy return true; } - bool HTTPProxyHandler::HandleData(uint8_t *http_buff, std::size_t len) + bool HTTPReqHandler::HandleData(uint8_t *http_buff, std::size_t len) { while (len > 0) { @@ -304,7 +302,7 @@ namespace proxy return true; } - void HTTPProxyHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len) + void HTTPReqHandler::HandleSockRecv(const boost::system::error_code & ecode, std::size_t len) { LogPrint(eLogDebug, "HTTPProxy: sock recv: ", len, " bytes"); if(ecode) @@ -319,7 +317,7 @@ namespace proxy if (m_state == DONE) { LogPrint(eLogDebug, "HTTPProxy: requested: ", m_url); - GetOwner()->CreateStream (std::bind (&HTTPProxyHandler::HandleStreamRequestComplete, + GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete, shared_from_this(), std::placeholders::_1), m_address, m_port); } else @@ -328,14 +326,14 @@ namespace proxy } - void HTTPProxyHandler::SentHTTPFailed(const boost::system::error_code & ecode) + void HTTPReqHandler::SentHTTPFailed(const boost::system::error_code & ecode) { if (ecode) LogPrint (eLogError, "HTTPProxy: Closing socket after sending failure because: ", ecode.message ()); Terminate(); } - void HTTPProxyHandler::HandleStreamRequestComplete (std::shared_ptr stream) + void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr stream) { if (stream) { @@ -353,14 +351,14 @@ namespace proxy } } - HTTPProxyServer::HTTPProxyServer(const std::string& address, int port, std::shared_ptr localDestination): + HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination): TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()) { } - std::shared_ptr HTTPProxyServer::CreateHandler(std::shared_ptr socket) + std::shared_ptr HTTPProxy::CreateHandler(std::shared_ptr socket) { - return std::make_shared (this, socket); + return std::make_shared (this, socket); } -} -} +} // http +} // i2p diff --git a/HTTPProxy.h b/HTTPProxy.h index 0356adb5..29b997eb 100644 --- a/HTTPProxy.h +++ b/HTTPProxy.h @@ -1,25 +1,21 @@ #ifndef HTTP_PROXY_H__ #define HTTP_PROXY_H__ -namespace i2p -{ -namespace proxy -{ - class HTTPProxyServer: public i2p::client::TCPIPAcceptor +namespace i2p { +namespace proxy { + class HTTPProxy: public i2p::client::TCPIPAcceptor { public: - HTTPProxyServer(const std::string& address, int port, std::shared_ptr localDestination = nullptr); - ~HTTPProxyServer() {}; + HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination = nullptr); + ~HTTPProxy() {}; protected: // Implements TCPIPAcceptor std::shared_ptr CreateHandler(std::shared_ptr socket); const char* GetName() { return "HTTP Proxy"; } }; - - typedef HTTPProxyServer HTTPProxy; -} -} +} // http +} // i2p #endif From 92961bb7bf2d1c4c545bab71bf3c494901cc5d82 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Jun 2016 11:23:06 -0400 Subject: [PATCH 08/62] i2cp for android --- docs/configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9ab85b46..11c8d0ec 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -60,9 +60,9 @@ All options below still possible in cmdline, but better write it in config file: * --bob.port= - Port of BOB command channel. Usually 2827. BOB is off if not specified * --bob.enabled= - If BOB is enabled. false by default -* --i2cp.address= - The address to listen on -* --i2cp.port= - Port of I2CP server. Usually 7654. IPCP is off if not specified -* --i2cp.enabled= - If I2CP is enabled. false by default. Other services don't requeire I2CP +* --i2cp.address= - The address to listen on or an abstract address for Android LocalSocket +* --i2cp.port= - Port of I2CP server. Usually 7654. Ignored for Andorid +* --i2cp.enabled= - If I2CP is enabled. false by default. Other services don't require I2CP * --i2pcontrol.address= - The address to listen on (I2P control service) * --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified From 13e965096b31a4474fee4051a0a3302a5cec415f Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Jun 2016 12:57:36 -0400 Subject: [PATCH 09/62] UPnP for android --- qt/i2pd_qt/i2pd_qt.pro | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index c3b38a8c..fb052641 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -10,14 +10,16 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app -QMAKE_CXXFLAGS *= -std=c++11 +QMAKE_CXXFLAGS *= -std=c++11 -DUSE_UPNP # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt OPENSSL_PATH = /mnt/media/android/OpenSSL-for-Android-Prebuilt +MINIUPNP_PATH = /mnt/media/android/MiniUPnP-for-Android-Prebuilt IFADDRS_PATH = /mnt/media/android/android-ifaddrs # Steps in Android SDK manager: @@ -140,6 +142,7 @@ DEFINES += ANDROID=1 DEFINES += __ANDROID__ INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ $$OPENSSL_PATH/openssl-1.0.2/include \ + $$MINIUPNP_PATH/miniupnp-2.0/include \ $$IFADDRS_PATH DISTFILES += \ android/AndroidManifest.xml @@ -164,7 +167,8 @@ PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so + $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so } equals(ANDROID_TARGET_ARCH, x86){ # http://stackoverflow.com/a/30235934/529442 @@ -181,7 +185,8 @@ PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so + $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so } } From 0f68bbac8ecd9bfb5e8cb8ee64d6927aaf588cf0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 23 Jun 2016 14:01:41 -0400 Subject: [PATCH 10/62] single #ifdef for protocol type --- I2CP.cpp | 23 +++++------------------ I2CP.h | 29 +++++++++-------------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 6e53451c..4884583e 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -114,12 +114,7 @@ namespace client } } - I2CPSession::I2CPSession (I2CPServer& owner, -#ifdef ANDROID - std::shared_ptr socket): -#else - std::shared_ptr socket): -#endif + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_Payload (nullptr), m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) { @@ -590,9 +585,9 @@ namespace client m_IsRunning (false), m_Thread (nullptr), m_Acceptor (m_Service, #ifdef ANDROID - boost::asio::local::stream_protocol::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address + I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address #else - boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) + I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port)) #endif { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); @@ -654,21 +649,13 @@ namespace client void I2CPServer::Accept () { -#ifdef ANDROID - auto newSocket = std::make_shared (m_Service); -#else - auto newSocket = std::make_shared (m_Service); -#endif + auto newSocket = std::make_shared (m_Service); m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this, std::placeholders::_1, newSocket)); } void I2CPServer::HandleAccept(const boost::system::error_code& ecode, -#ifdef ANDROID - std::shared_ptr socket) -#else - std::shared_ptr socket) -#endif + std::shared_ptr socket) { if (!ecode && socket) { diff --git a/I2CP.h b/I2CP.h index 20f20d63..4964c575 100644 --- a/I2CP.h +++ b/I2CP.h @@ -99,12 +99,14 @@ namespace client { public: - I2CPSession (I2CPServer& owner, #ifdef ANDROID - std::shared_ptr socket); + typedef boost::asio::local::stream_protocol proto; #else - std::shared_ptr socket); -#endif + typedef boost::asio::ip::tcp proto; +#endif + + I2CPSession (I2CPServer& owner, std::shared_ptr socket); + ~I2CPSession (); void Start (); @@ -149,11 +151,7 @@ namespace client private: I2CPServer& m_Owner; -#ifdef ANDROID - std::shared_ptr m_Socket; -#else - std::shared_ptr m_Socket; -#endif + std::shared_ptr m_Socket; uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload; size_t m_PayloadLen; @@ -183,12 +181,7 @@ namespace client void Accept (); - void HandleAccept(const boost::system::error_code& ecode, -#ifdef ANDROID - std::shared_ptr socket); -#else - std::shared_ptr socket); -#endif + void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); private: @@ -198,11 +191,7 @@ namespace client bool m_IsRunning; std::thread * m_Thread; boost::asio::io_service m_Service; -#ifdef ANDROID - boost::asio::local::stream_protocol::acceptor m_Acceptor; -#else - boost::asio::ip::tcp::acceptor m_Acceptor; -#endif + I2CPSession::proto::acceptor m_Acceptor; public: From fedbf2cc44f8d868d4976db66bcac8b170c2781c Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 13:15:51 -0400 Subject: [PATCH 11/62] link UPnP with app if USE_UPNP is set --- Makefile.linux | 2 +- UPnP.cpp | 78 +++++------------------------------------- UPnP.h | 6 ---- qt/i2pd_qt/i2pd_qt.pro | 8 +++-- 4 files changed, 15 insertions(+), 79 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index e00fd705..da72a41a 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -44,7 +44,7 @@ endif # UPNP Support (miniupnpc 1.5 or 1.6) ifeq ($(USE_UPNP),1) - LDFLAGS += -ldl + LDFLAGS += -lminiupnpc CXXFLAGS += -DUSE_UPNP endif diff --git a/UPnP.cpp b/UPnP.cpp index ea62998b..477342b3 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -6,13 +6,6 @@ #include #include -#ifdef _WIN32 -#include -#define dlsym GetProcAddress -#else -#include -#endif - #include "Log.h" #include "RouterContext.h" @@ -24,32 +17,11 @@ #include #include -// These are per-process and are safe to reuse for all threads -decltype(upnpDiscover) *upnpDiscoverFunc; -decltype(UPNP_AddPortMapping) *UPNP_AddPortMappingFunc; -decltype(UPNP_GetValidIGD) *UPNP_GetValidIGDFunc; -decltype(UPNP_GetExternalIPAddress) *UPNP_GetExternalIPAddressFunc; -decltype(UPNP_DeletePortMapping) *UPNP_DeletePortMappingFunc; -decltype(freeUPNPDevlist) *freeUPNPDevlistFunc; -decltype(FreeUPNPUrls) *FreeUPNPUrlsFunc; - -// Nice approach http://stackoverflow.com/a/21517513/673826 -template -F GetKnownProcAddressImpl(M hmod, const char *name, F) { - auto proc = reinterpret_cast(dlsym(hmod, name)); - if (!proc) { - LogPrint(eLogError, "UPnP: Error resolving ", name, " from library, version mismatch?"); - } - return proc; -} -#define GetKnownProcAddress(hmod, func) GetKnownProcAddressImpl(hmod, #func, func##Func); - - namespace i2p { namespace transport { - UPnP::UPnP () : m_Thread (nullptr) , m_IsModuleLoaded (false) + UPnP::UPnP () : m_Thread (nullptr) { } @@ -65,33 +37,6 @@ namespace transport void UPnP::Start() { - if (!m_IsModuleLoaded) { -#ifdef MAC_OSX - m_Module = dlopen ("libminiupnpc.dylib", RTLD_LAZY); -#elif _WIN32 - m_Module = LoadLibrary ("libminiupnpc.dll"); // from MSYS2 -#else - m_Module = dlopen ("libminiupnpc.so", RTLD_LAZY); -#endif - if (m_Module == NULL) - { - LogPrint (eLogError, "UPnP: Error loading UPNP library, version mismatch?"); - return; - } - else - { - upnpDiscoverFunc = GetKnownProcAddress (m_Module, upnpDiscover); - UPNP_GetValidIGDFunc = GetKnownProcAddress (m_Module, UPNP_GetValidIGD); - UPNP_GetExternalIPAddressFunc = GetKnownProcAddress (m_Module, UPNP_GetExternalIPAddress); - UPNP_AddPortMappingFunc = GetKnownProcAddress (m_Module, UPNP_AddPortMapping); - UPNP_DeletePortMappingFunc = GetKnownProcAddress (m_Module, UPNP_DeletePortMapping); - freeUPNPDevlistFunc = GetKnownProcAddress (m_Module, freeUPNPDevlist); - FreeUPNPUrlsFunc = GetKnownProcAddress (m_Module, FreeUPNPUrls); - if (upnpDiscoverFunc && UPNP_GetValidIGDFunc && UPNP_GetExternalIPAddressFunc && UPNP_AddPortMappingFunc && - UPNP_DeletePortMappingFunc && freeUPNPDevlistFunc && FreeUPNPUrlsFunc) - m_IsModuleLoaded = true; - } - } m_Thread = new std::thread (std::bind (&UPnP::Run, this)); } @@ -123,16 +68,16 @@ namespace transport { int nerror = 0; #if MINIUPNPC_API_VERSION >= 14 - m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror); + m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror); #else - m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); + m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); #endif int r; - r = UPNP_GetValidIGDFunc (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); + r = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr)); if (r == 1) { - r = UPNP_GetExternalIPAddressFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); + r = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress); if(r != UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: UPNP_GetExternalIPAddress () returned ", r); @@ -171,7 +116,7 @@ namespace transport std::string strDesc = "I2Pd"; try { for (;;) { - r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); + r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); if (r!=UPNPCOMMAND_SUCCESS) { LogPrint (eLogError, "UPnP: AddPortMapping (", strPort.c_str () ,", ", strPort.c_str () ,", ", m_NetworkAddr, ") failed with code ", r); @@ -208,20 +153,15 @@ namespace transport strType = "UDP"; } int r = 0; - r = UPNP_DeletePortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0); + r = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), 0); LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", r, "\n"); } void UPnP::Close () { - freeUPNPDevlistFunc (m_Devlist); + freeUPNPDevlist (m_Devlist); m_Devlist = 0; - FreeUPNPUrlsFunc (&m_upnpUrls); -#ifndef _WIN32 - dlclose (m_Module); -#else - FreeLibrary (m_Module); -#endif + FreeUPNPUrls (&m_upnpUrls); } } diff --git a/UPnP.h b/UPnP.h index 32c42118..0a000177 100644 --- a/UPnP.h +++ b/UPnP.h @@ -48,12 +48,6 @@ namespace transport struct UPNPDev * m_Devlist = 0; char m_NetworkAddr[64]; char m_externalIPAddress[40]; - bool m_IsModuleLoaded; -#ifndef _WIN32 - void *m_Module; -#else - HINSTANCE m_Module; -#endif }; } } diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index fb052641..92ddb839 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -14,7 +14,7 @@ QMAKE_CXXFLAGS *= -std=c++11 -DUSE_UPNP # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt +# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt @@ -159,7 +159,8 @@ LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ -lboost_date_time-gcc-mt-1_53 \ -lboost_filesystem-gcc-mt-1_53 \ -lboost_program_options-gcc-mt-1_53 \ --L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl +-L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ +-L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a @@ -177,7 +178,8 @@ LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ -lboost_date_time-gcc-mt-1_53 \ -lboost_filesystem-gcc-mt-1_53 \ -lboost_program_options-gcc-mt-1_53 \ --L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl +-L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ +-L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a From 0a4888a18ff1111c47b426b244cd91e709cbc768 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 14:18:50 -0400 Subject: [PATCH 12/62] link with miniupnp --- Makefile.mingw | 94 +++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Makefile.mingw b/Makefile.mingw index b859ebb3..682221d1 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -1,47 +1,47 @@ -USE_WIN32_APP=yes -CXX = g++ -WINDRES = windres -CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN -NEEDED_CXXFLAGS = -std=c++11 -BOOST_SUFFIX = -mt -INCFLAGS = -I/usr/include/ -I/usr/local/include/ -LDFLAGS = -Wl,-rpath,/usr/local/lib \ - -L/usr/local/lib \ - -L/c/dev/openssl \ - -L/c/dev/boost/lib -LDLIBS = \ - -Wl,-Bstatic -lboost_system$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_date_time$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_filesystem$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lboost_program_options$(BOOST_SUFFIX) \ - -Wl,-Bstatic -lssl \ - -Wl,-Bstatic -lcrypto \ - -Wl,-Bstatic -lz \ - -Wl,-Bstatic -lwsock32 \ - -Wl,-Bstatic -lws2_32 \ - -Wl,-Bstatic -lgdi32 \ - -Wl,-Bstatic -liphlpapi \ - -static-libgcc -static-libstdc++ \ - -Wl,-Bstatic -lstdc++ \ - -Wl,-Bstatic -lpthread - -ifeq ($(USE_WIN32_APP), yes) - CXXFLAGS += -DWIN32_APP - LDFLAGS += -mwindows -s - DAEMON_RC += Win32/Resource.rc - DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) -endif - -# UPNP Support -ifeq ($(USE_UPNP),1) - CXXFLAGS += -DUSE_UPNP -endif - -ifeq ($(USE_AESNI),1) - CPU_FLAGS = -maes -DAESNI -else - CPU_FLAGS = -msse -endif - -obj/%.o : %.rc - $(WINDRES) -i $< -o $@ +USE_WIN32_APP=yes +CXX = g++ +WINDRES = windres +CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN +NEEDED_CXXFLAGS = -std=c++11 +BOOST_SUFFIX = -mt +INCFLAGS = -I/usr/include/ -I/usr/local/include/ +LDFLAGS = -Wl,-rpath,/usr/local/lib \ + -L/usr/local/lib + +# UPNP Support +ifeq ($(USE_UPNP),1) + CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB + LDLIBS = -Wl,-Bstatic -lminiupnpc +endif + +LDLIBS += \ + -Wl,-Bstatic -lboost_system$(BOOST_SUFFIX) \ + -Wl,-Bstatic -lboost_date_time$(BOOST_SUFFIX) \ + -Wl,-Bstatic -lboost_filesystem$(BOOST_SUFFIX) \ + -Wl,-Bstatic -lboost_program_options$(BOOST_SUFFIX) \ + -Wl,-Bstatic -lssl \ + -Wl,-Bstatic -lcrypto \ + -Wl,-Bstatic -lz \ + -Wl,-Bstatic -lwsock32 \ + -Wl,-Bstatic -lws2_32 \ + -Wl,-Bstatic -lgdi32 \ + -Wl,-Bstatic -liphlpapi \ + -static-libgcc -static-libstdc++ \ + -Wl,-Bstatic -lstdc++ \ + -Wl,-Bstatic -lpthread + +ifeq ($(USE_WIN32_APP), yes) + CXXFLAGS += -DWIN32_APP + LDFLAGS += -mwindows -s + DAEMON_RC += Win32/Resource.rc + DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) +endif + +ifeq ($(USE_AESNI),1) + CPU_FLAGS = -maes -DAESNI +else + CPU_FLAGS = -msse +endif + +obj/%.o : %.rc + $(WINDRES) -i $< -o $@ From ba772ab4811feb25faeaed523b8cb672cc3598b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 14:20:35 -0400 Subject: [PATCH 13/62] static miniupnpc --- docs/build_notes_windows.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/build_notes_windows.md b/docs/build_notes_windows.md index 6290ccc2..8ba36131 100644 --- a/docs/build_notes_windows.md +++ b/docs/build_notes_windows.md @@ -172,8 +172,6 @@ pacman -S mingw-w64-i686-miniupnpc make USE_UPNP=1 ``` -It requires libminiupnpc.dll from /mingw32/bin - ### Creating Visual Studio project Start CMake GUI, navigate to i2pd directory, choose building directory, e.g. ./out, and configure options. From 5fbaf0bc7dbeb90cef2ce6cb14e36155be78cfee Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 15:29:36 -0400 Subject: [PATCH 14/62] disabled UPNP=ON --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d83cdbc0..e52c53a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink boost openssl && brew link boost openssl -f ; fi env: matrix: - - BUILD_TYPE=Release UPNP=ON +# - BUILD_TYPE=Release UPNP=ON - BUILD_TYPE=Release UPNP=OFF script: - cd build && cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_UPNP=${UPNP} && make From 814b174f25ff38c309b4df60998ac785eb2820e7 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 25 Jun 2016 02:47:46 +0800 Subject: [PATCH 15/62] android version code bump --- qt/i2pd_qt/android/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/i2pd_qt/android/AndroidManifest.xml b/qt/i2pd_qt/android/AndroidManifest.xml index 6ab763ff..37a736fd 100644 --- a/qt/i2pd_qt/android/AndroidManifest.xml +++ b/qt/i2pd_qt/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + From 35f6c6cb982db628e250b271b5121baf8af2e979 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sat, 25 Jun 2016 03:37:59 +0800 Subject: [PATCH 16/62] graceful quit button added --- qt/i2pd_qt/i2pd_qt.pro | 15 +++++++++------ qt/i2pd_qt/mainwindow.cpp | 35 +++++++++++++++++++++++++++++++---- qt/i2pd_qt/mainwindow.h | 3 +++ qt/i2pd_qt/mainwindow.ui | 24 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 92ddb839..38df4838 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -10,7 +10,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app -QMAKE_CXXFLAGS *= -std=c++11 -DUSE_UPNP +QMAKE_CXXFLAGS *= -std=c++11 # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git @@ -29,7 +29,7 @@ IFADDRS_PATH = /mnt/media/android/android-ifaddrs SOURCES += DaemonQT.cpp\ mainwindow.cpp \ - ../../HTTPServer.cpp ../../I2PControl.cpp ../../UPnP.cpp ../../Daemon.cpp ../../Config.cpp \ + ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ ../../AddressBook.cpp \ ../../api.cpp \ ../../Base.cpp \ @@ -72,8 +72,7 @@ SOURCES += DaemonQT.cpp\ ../../TunnelGateway.cpp \ ../../TunnelPool.cpp \ ../../util.cpp \ - ../../i2pd.cpp \ - $$IFADDRS_PATH/ifaddrs.c + ../../i2pd.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ @@ -125,8 +124,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../TunnelGateway.h \ ../../TunnelPool.h \ ../../util.h \ - ../../version.h \ - $$IFADDRS_PATH/ifaddrs.h + ../../version.h FORMS += mainwindow.ui @@ -140,6 +138,8 @@ android { message("Using Android settings") DEFINES += ANDROID=1 DEFINES += __ANDROID__ +DEFINES += USE_UPNP + INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ $$OPENSSL_PATH/openssl-1.0.2/include \ $$MINIUPNP_PATH/miniupnp-2.0/include \ @@ -149,6 +149,9 @@ DISTFILES += \ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android +SOURCES += $$IFADDRS_PATH/ifaddrs.c ../../UPnP.cpp +HEADERS += $$IFADDRS_PATH/ifaddrs.h + equals(ANDROID_TARGET_ARCH, armeabi-v7a){ DEFINES += ANDROID_ARM7A diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index c1654295..325c8fc5 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -1,6 +1,7 @@ #include "mainwindow.h" //#include "ui_mainwindow.h" #include +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)/*, @@ -22,20 +23,29 @@ MainWindow::MainWindow(QWidget *parent) : verticalLayout1->setContentsMargins(0, 0, 0, 0); quitButton = new QPushButton(verticalLayoutWidget); quitButton->setObjectName(QStringLiteral("quitButton")); - QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); + QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + sizePolicy.setHorizontalStretch(1); + //sizePolicy.setVerticalStretch(1); sizePolicy.setHeightForWidth(quitButton->sizePolicy().hasHeightForWidth()); quitButton->setSizePolicy(sizePolicy); - verticalLayout1->addWidget(quitButton); + gracefulQuitButton = new QPushButton(verticalLayoutWidget); + gracefulQuitButton->setObjectName(QStringLiteral("gracefulQuitButton")); + QSizePolicy sizePolicy2(QSizePolicy::Maximum, QSizePolicy::Maximum); + sizePolicy2.setHorizontalStretch(1); + //sizePolicy2.setVerticalStretch(1); + sizePolicy2.setHeightForWidth(gracefulQuitButton->sizePolicy().hasHeightForWidth()); + gracefulQuitButton->setSizePolicy(sizePolicy2); + verticalLayout1->addWidget(gracefulQuitButton); setCentralWidget(centralWidget); setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0)); quitButton->setText(QApplication::translate("MainWindow", "Quit", 0)); + gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful Quit", 0)); QObject::connect(quitButton, SIGNAL(released()), this, SLOT(handleQuitButton())); + QObject::connect(gracefulQuitButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); //QMetaObject::connectSlotsByName(this); } @@ -46,6 +56,23 @@ void MainWindow::handleQuitButton() { QApplication::instance()->quit(); } +void MainWindow::handleGracefulQuitButton() { + qDebug("Graceful Quit pressed."); + gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful quit is in progress", 0)); + gracefulQuitButton->setEnabled(false); + gracefulQuitButton->adjustSize(); + verticalLayoutWidget->adjustSize(); + //here, the code to stop tunnels + QTimer::singleShot(10*60*1000/*millis*/, this, SLOT(handleGracefulQuitTimerEvent())); +} + +void MainWindow::handleGracefulQuitTimerEvent() { + qDebug("Hiding the main window"); + close(); + qDebug("Performing quit"); + QApplication::instance()->quit(); +} + MainWindow::~MainWindow() { qDebug("Destroying main window"); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 3a172c25..94e3a7b3 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -27,12 +27,15 @@ public: private slots: void handleQuitButton(); + void handleGracefulQuitButton(); + void handleGracefulQuitTimerEvent(); private: QWidget *centralWidget; QWidget *verticalLayoutWidget; QVBoxLayout *verticalLayout1; QPushButton *quitButton; + QPushButton *gracefulQuitButton; }; #endif // MAINWINDOW_H diff --git a/qt/i2pd_qt/mainwindow.ui b/qt/i2pd_qt/mainwindow.ui index bdb57867..d73e7743 100644 --- a/qt/i2pd_qt/mainwindow.ui +++ b/qt/i2pd_qt/mainwindow.ui @@ -37,6 +37,13 @@ + + + + Graceful Quit + + + @@ -60,8 +67,25 @@ + + gracefulShutdownButton + released() + MainWindow + handleGracefulQuitButton() + + + 395 + 319 + + + 399 + 239 + + + handleQuitButton() + handleGracefulQuitButton() From f22e5c209c338c8f8bef9361ab3c6e1b646790d6 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 16:05:03 -0400 Subject: [PATCH 17/62] fixed QT linux build --- qt/i2pd_qt/i2pd_qt.pro | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 38df4838..8a786e5d 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -11,6 +11,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = i2pd_qt TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 +DEFINES += USE_UPNP # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git @@ -71,6 +72,7 @@ SOURCES += DaemonQT.cpp\ ../../TunnelEndpoint.cpp \ ../../TunnelGateway.cpp \ ../../TunnelPool.cpp \ + ../../UPnP.cpp \ ../../util.cpp \ ../../i2pd.cpp @@ -123,6 +125,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../TunnelEndpoint.h \ ../../TunnelGateway.h \ ../../TunnelPool.h \ + ../../UPnP.h \ ../../util.h \ ../../version.h @@ -138,7 +141,6 @@ android { message("Using Android settings") DEFINES += ANDROID=1 DEFINES += __ANDROID__ -DEFINES += USE_UPNP INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ $$OPENSSL_PATH/openssl-1.0.2/include \ @@ -197,6 +199,6 @@ ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ linux:!android { message("Using Linux settings") -LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread +LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc } From 047c8eda2275bd5b4571c156cfd81ebed330c0a5 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 16:26:13 -0400 Subject: [PATCH 18/62] stop accepting tunnels by graceful shutdown --- qt/i2pd_qt/mainwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 325c8fc5..ab872ff4 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -2,6 +2,7 @@ //#include "ui_mainwindow.h" #include #include +#include "../../RouterContext.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)/*, @@ -62,7 +63,7 @@ void MainWindow::handleGracefulQuitButton() { gracefulQuitButton->setEnabled(false); gracefulQuitButton->adjustSize(); verticalLayoutWidget->adjustSize(); - //here, the code to stop tunnels + i2p::context.SetAcceptsTunnels (false); // stop accpting tunnels QTimer::singleShot(10*60*1000/*millis*/, this, SLOT(handleGracefulQuitTimerEvent())); } From 7e580e6a0bfe3eca72cdc662621f3f6a62e11405 Mon Sep 17 00:00:00 2001 From: xcps Date: Fri, 24 Jun 2016 17:58:46 -0400 Subject: [PATCH 19/62] Update HTTPServer.cpp --- HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index b40cef27..d0895cbc 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -612,7 +612,7 @@ namespace http { HandleCommand (req, res, s); } else { ShowStatus (s); - //res.add_header("Refresh", "5"); + res.add_header("Refresh", 10"); } ShowPageTail (s); From 6b3bd755b08fe3c3af3f1c9b88a06eb3000fcd7a Mon Sep 17 00:00:00 2001 From: xcps Date: Fri, 24 Jun 2016 19:07:47 -0400 Subject: [PATCH 20/62] fixtypo --- HTTPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index d0895cbc..f35e02d3 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -612,7 +612,7 @@ namespace http { HandleCommand (req, res, s); } else { ShowStatus (s); - res.add_header("Refresh", 10"); + res.add_header("Refresh", "10"); } ShowPageTail (s); From 9f411511569916eb7da3e912f9a7448589fe8ca5 Mon Sep 17 00:00:00 2001 From: xcps Date: Fri, 24 Jun 2016 19:25:48 -0400 Subject: [PATCH 21/62] HTTP proxy redirects to 0.0.0.0:7070/?page=jumpservices --- HTTPProxy.cpp | 12 +++--------- HTTPServer.h | 2 ++ qt/i2pd_qt/i2pd_qt.pro | 8 ++++---- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 81ed8da6..e11d430d 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -20,6 +20,7 @@ #include "I2PTunnel.h" #include "Config.h" #include "HTTP.h" +#include "HTTPServer.h" namespace i2p { namespace proxy { @@ -113,15 +114,8 @@ namespace proxy { void HTTPReqHandler::RedirectToJumpService(/*HTTPReqHandler::errTypes error*/) { std::stringstream ss; - std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); - uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); - - ss << "HTTP/1.1 302 Found\r\n" - << "Connection: close\r\n" - << "Location: http://" << httpAddr << ":" << httpPort << "/?page=jumpservices&address=" << m_address << "\r\n" - << "\r\n"; - std::string response = ss.str(); - boost::asio::async_write(*m_sock, boost::asio::buffer(response), + i2p::http::ShowJumpServices (ss, m_address); + boost::asio::async_write(*m_sock, boost::asio::buffer(ss.str ()), std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } diff --git a/HTTPServer.h b/HTTPServer.h index bf7f5c65..6aa0d792 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -61,6 +61,8 @@ namespace http { boost::asio::io_service::work m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; }; + + void ShowJumpServices (std::stringstream& s, const std::string& address); } // http } // i2p diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 8a786e5d..b3829fcc 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -18,10 +18,10 @@ DEFINES += USE_UPNP # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own -BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt -OPENSSL_PATH = /mnt/media/android/OpenSSL-for-Android-Prebuilt -MINIUPNP_PATH = /mnt/media/android/MiniUPnP-for-Android-Prebuilt -IFADDRS_PATH = /mnt/media/android/android-ifaddrs +BOOST_PATH = /home/rebby/andp/Boost-for-Android-Prebuilt +OPENSSL_PATH = /home/rebby/andp/OpenSSL-for-Android-Prebuilt +MINIUPNP_PATH = /home/rebby/andp/MiniUPnP-for-Android-Prebuilt +IFADDRS_PATH = /home/rebby/andp/android-ifaddrs # Steps in Android SDK manager: # 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html From 4bc76995d1d14fc9e8b48def823d200e4157676f Mon Sep 17 00:00:00 2001 From: xcps Date: Fri, 24 Jun 2016 19:29:59 -0400 Subject: [PATCH 22/62] docs: default httpproxy.port changed to actual 4444 --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 11c8d0ec..1b3e899b 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -41,7 +41,7 @@ All options below still possible in cmdline, but better write it in config file: * --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 +* --httpproxy.port= - The port to listen on (HTTP Proxy) 4444 by default * --httpproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS) * --httpproxy.enabled= - If HTTP proxy is enabled. true by default From 096927beeda11b5d39be591a62c23a222cb013d2 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 24 Jun 2016 21:54:58 -0400 Subject: [PATCH 23/62] don't sedn explicit Ack if no NACKs only --- Streaming.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Streaming.cpp b/Streaming.cpp index 1a6fdbca..e5260556 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -395,8 +395,11 @@ namespace stream } if (packets.size () > 0) { - m_IsAckSendScheduled = false; - m_AckSendTimer.cancel (); + if (m_SavedPackets.empty ()) // no NACKS + { + m_IsAckSendScheduled = false; + m_AckSendTimer.cancel (); + } bool isEmpty = m_SentPackets.empty (); auto ts = i2p::util::GetMillisecondsSinceEpoch (); for (auto it: packets) From 134baad56db7531d7f70f1a81b40c3c9c9d654b0 Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 26 Jun 2016 02:32:54 +0800 Subject: [PATCH 24/62] added tray icon to linux and windows versions --- qt/i2pd_qt/i2pd.qrc | 5 +++ qt/i2pd_qt/i2pd_qt.pro | 12 ++++++ qt/i2pd_qt/images/icon.png | Bin 0 -> 8712 bytes qt/i2pd_qt/mainwindow.cpp | 84 ++++++++++++++++++++++++++++++++++++- qt/i2pd_qt/mainwindow.h | 31 ++++++++++++++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 qt/i2pd_qt/i2pd.qrc create mode 100644 qt/i2pd_qt/images/icon.png diff --git a/qt/i2pd_qt/i2pd.qrc b/qt/i2pd_qt/i2pd.qrc new file mode 100644 index 00000000..2abdeb05 --- /dev/null +++ b/qt/i2pd_qt/i2pd.qrc @@ -0,0 +1,5 @@ + + + images/icon.png + + diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index b3829fcc..f9fb78e8 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -202,3 +202,15 @@ message("Using Linux settings") LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc } + +!android:!symbian:!maemo5:!simulator { +message("Build with a system tray icon") +# see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* +#sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images +RESOURCES = i2pd.qrc +QT += xml +#INSTALLS += sources +} + +RESOURCES += \ + i2pd.qrc diff --git a/qt/i2pd_qt/images/icon.png b/qt/i2pd_qt/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a5dc7b680ba9dee30161ffb1c9fcd17bbd6ddd84 GIT binary patch literal 8712 zcmV+jBKO^iP)#iZS6wU+M?20 zYwb(xf+$t%hC*Gcf>03@K~O*el_l&;SQ0|WKAD;OJikBgoyjbBCIJ$XkQ`t0BF=K} zbI9(t4FIPG^#{fQ7XZV7F30fO zZ-GyNCBR~!tW96E3>pT^1j+$rzvKzL0@v69`~}EsV{!AOUjX|XK;ZQO!xmst8_Syq z{Q>YbvfyKZp$hnAn+?!3bPF&GNU()bFG@~8_Q{1#8HkKjl&*uv3r8!^b{@psQ;2qq zd=Ws2J)Za50MPi91$+#gQ6Isd*#~*`c`)WoICmhzoq~oLqAvnm5P$|4r~~_vpMQt= z=qq?<1*-5UT0MEW)HXUjZ2)K-ngqO9m*8_dB7b`w+&&JGoPuV0k3mI*kfwo_0NZzC z&iVlHi9vBo$`0Y|qum2u3ZX~+@Bq(1a5%to1-WQ|r_nDQ5)%Ydfos~9fY>w?SnFi%XQZMIz6rY4Y_(Rc zUEqe{KS!?4k7*Nhz=|HW0U&~kf%ZsYDt99Cz!AqWud~74wgiOG zU+kF?MgO@UmD7a6H{75U=9+xe+siTMF2h{*4btmJ8txd&fr(i6ELx1%#aX~jZ5p7K z(t%PZW=$A{ocAYmzeB)92+)&Y&tBx`8<7Qv(Y=1i>45zHU_`I(X#VOG5PSma`S(yy zy@%Sc!x@0X`XT>%E8?PIXij5%X9ecxrucbt(^QgWZcZT7r*aAROoBPQ{e14=26ilBmmf?XpwL@O} zTeI-5!XcF_BNbCEMTRkOAu`cjEBw5?yv<4}vku{?`|i7Me&{{cJRL2Z!0VZ*VFIez zv}w~?RX;ic6a;?TuPc7FGy(t%QNOv)5daD}v$ZY(KXFq3zqt-&*3_zSO~C#CMtN*2 zyIs3>d$w-f+PgmEpD|;`xQP=dt`b5BfIFW?Ik|3z8)kkG9E+GfefsVJ0|wOBS8u;+ z)v6X!xYS*Db7VQoj(n=&&qHy0Nd_Xn6U2{rA8 zaDWZ6ot?es7=;hunlfdIKLGf- zpGJf3+nu%dy#D&@4H3F8dZ`M5J&WE~`xu9W!Rkab*}>dF7QkfxmYhL^^Tz+L1A} z?uD%l0OvcY|0~alQq64NA6!qxph1IV9oOB7RTUIQg9i`x1^(Vv0FgO7hF*JLm&fBtk)WoRWLIs@D+5m8-Q{*qNcR1Sw;PZzE>YOh2*=L{a$;`~$ zErjSLghIMW*r`*e0wKhg z6DCa9rj#mo8bf(`d3w+uNJn?{{Jk*pbVn_4Mr#8=kH|O9%0uA~XO5JRoe_Lbeg669 zQAL^y7A!b8YSgH%#l^+l?b&1$7Z(p1GGs`Xg$oxR2H3W3TX3T(H3<$6v~NgMZ^@F#9m9iHTyaILY98(K%P-e}s+V4RDJYKKogKty zBF3C)!NTM5bpQJ6uXpF=eTg-H+$%zhpGeL9XkxobXcsEg5EhX z4Z&6e07sXnTb4CLqU?fmYlT}>RMctp>eU-UX1|X(S;Ihw+i$=9>t~;Rwp~CtBTu)o zcfu@mA55tYJ*%NZhkDA&$_6_6u1cw=o_Z?GYG1Ty(N`NcZtNfU%EZyJUF@6=#Ij>@ zS_=Ri_x(Ghp*by^2`u$c-Svc2@LCekv z3a6h^DqcZRZ(t9=iWMuijvYI;ZvbHTOhhRa8vyN7W2TX}8UQ5WENDlD`%QReYN)X& zdSz#4AFQmbEE+g)V0t|RP5}JBb5WTY&d=@l!2B8Y502&M=YKwC%$RRSjvUz+tJ?^j zGLV1yDY}dU9Zkf%M@DM_faAWL&y3Cd>{{8z;T)K4W=>dSHB%;1~4$be2|3g#8TmoFJ1ptmLs*IDp zqZHga4&$%4h6yKa&YU?Tsb}rys((USQv4b2H{n+kFrK-Sy5bE%uK~+Yl?UE{jI_En zNJ!8r3LC8j0F_Q}?kU35iQ2puQCf+a z*$(5h9>`0EBGS^Ve8u{voCyJ23s5oK)k#cHK#NkIDm8zK3HYsv?c(ocY5=^mDUd6 zsY>s!ifM|hY;6Eo?X(2F`3Y!=r>5`?7re1F=2HA|YXg8ID@rQRR)2$eDgwacK`vb% zljrkW8vs6!^}*BswQ2xPHJbT;Ty3aY8vwv+q7+5{{s_(IZyJU)n)**f{drDI_5X5H zjjO2v@UK{|=mW1JwNt2<`Mi&j#bq(w?%7Q>uI9kvSaCm9GasR8Ex)C`k%;R21Jt1s z$7flH)m^kzY5;&oVgOOx{sgAc!b3trz!P(kF@!IG8BIFAX27EatlqkgYyO5=sDa&S zu_j@q2bpnAOkQurI@E&JtO06(M`MBU(tA*bt7Qt`NI;FdFQ)JX@T;aCV{@5V)39RU zQFQPK+Kmt6Z)qUVHF)?{%+EK*)Uum^1x-HAX2i4I#Au=R%}%r)S(s<#p{W+)9Ip5d zdD9~?Cz!yhj5^fR<7{pg_8Q{k$1i&fb^dA19|YU>V-CDEZubwLZTmDiH8px6 zhOV*!zpl*&0Ornx4?aM={4&aR598YYqXr{C{4>IBG+`4-7wU&IFyHv(xF?eU?g9SV zW&{F4Fj6UA$2#7%P9?7i)GO0aKf3JXoE8!~>zA*`f5jir%BsTnsLtnXI+7s|P^hip zoBHrs08e9`eb{ON;1+_pN^v#Eu{AohFKYQez}3jwz;MB?1E|SQpcbtO=ijxAl|SSv z4U~{5bTo8y*7B|Th|kn2*41^+(0jnutq}lM0`JyyJi!9a$PcbQ5Bcr`4S#}2pe5}W z>oFgA1tPnCX46qUz^_Cm8A8Uuu8xi$zj}pt)qIwSIM246813>;RRFvN{6GlemSX0R zEypq1cMfOzI+3Ziu}iy$M^n5ZMMh`zLT;Gt+*dfzug5g&m)30Z!$mOZ59SosqelP`RHxog_(vMX1#~}a5YLwM4w#Lpzes?IjD?OwDe?@Cam)S zk5CP_`e%Y%{0xM7(hE9l$elO(&+S@fct8b}{8m;s_A?X?=bC=?!Q8jK-cd|bn2;t`&W z^%Vs?1>D$@0pPaXo690C_YmQWA9Jvcx@FMHs1@5LmFQGJWB8R&C{O|%z!+?38 z)dC=o9`aZGpJ5^~(2+=0PNnqX6#_v5Zk0}&E|I#4i60YXkE0=l9!cM0a9zvOk6SVT zMgU9fh@NtScLwR|A?~j1M5e64TW?GHJ^tqoTyw$&DEtwTI2Y>um9?|~7OoWmLE73y zxN+(3kYHmK)tqcH&_#RN`AaC(>oAx%G{*h4Mg-OywomJdVd98UYMB289;wKtqg2Nb z`_T}5#OJ~5PQDTm>H9BURXh7TlcfeTpjoDsNhH~HtSgMXp(Sa63BcS~!I}X5R^3*4 z9z)G&|5?@PoP5BNpzza^Q5OwIgqD;WI=rwb)cClxQPuc~kOExs#qeQE@&f)1+#FBv zoyn3j_;pnpDe8EHpG2a1kHtaX|CiUGOizR+(@}G33(wTWj1c~2T5TqPI6))o#;#2uksPKcm*dp@)+ohr|IWO8^cxzeh zS~8k*n#A}^B!Nem74`n7tWxd>r)VQvc1V}amr;@PC=xV|EA61*F?TFF{h*vwbq5yQ~dF;lNbL>hmlAGP4i;4`Vy z=+`91-Ep zNZXbh&<)usD|+nDEvU8jhBG8)yuUF?M`tJd96xhmggyONd?#Z}7!TH_S&IXJwT#2x zBOgowM=29i`BSQii6Zpb6<)mD#ZRikA_AfoK%sQwMbV8JjYN3j-P(Je!p`x(hso87 z@LfWs!mlxYMD(m#w;6NG-rD!iZ-N6jBvQS?J8}nm9Y3$6TC2jN08FG>&YD=(|H~~M z006H5XF;?XUO|<(o%>QZu}#+_Qt204zJJ*IAG(wPy!tV+ssCGK|4FLcBYLq86Dw+1h}DbO{o*5VHZs9kF(Vrha<;RBRXe$t$O7X~X>8&(*y ztuN+NIdqwpNyh(r(z|jX^2T=Ts^^3|ax#~$1_i(f9%pWhhrE}bh9C8YfT03JK={F6 zkL~6K1e~nle=>*7D|?~lc4OZ!JF>rro8rjAOD7%s0ZWuPN%^iidRRDjcoK)Yx#$oW zlV5>^l;^w9^W`pVuLlSYw@3hd0=&X6#SNh5hP*$ETxQcptV78c5IkZPLiP>Vbb%Qk z`Y#|J?!=x+84Nf*5$*C+x;~Um?)E$~H|4SS@-zy9zjqkR8@w+nsX8fIAOdLO(o_<> z4tMq|n9z&}Vv69&Xn&4;b=UeuR1?-m3kRiI#O{}KZHWy;J zvNb`3@IgSLh(24eT0vJA-QMm-*G+j8b#+k~gPG#j{8>pFzm&!x@`+wZ%@uQfXAtp0C!>XBlgNK(6s4ff8`chJD?y`_(Grr zs9zt%n)4Do*)Ra@wzC6mB*j)>|pN@kyTh@!)2vu1Iz z5G;h+`aoMN2%z+i4)|}(fMJPL7{WetSinIadzM$BEvi6&y%bd?;~u=IE@lMhGnCWl zM*?omk4b&Q#X33(xY)@)xrCMckIw?GW>~Rmn#O^$f#g<1=q{Ilqb3FC?jUiO&-vg? ztn{y&TND5Q-U00zkdZFnbo=!^EQREo@i z3mE1OD$7=|=_uB@I;qq)S~}*nK9lyc7u`fJy3vVD)rm|kjT90|Py&GuKNVDp!<5MV z91>gE$p*G44>f_%WjWoD^uVByqvX>i;Mv}n#nu_wWcn2an``K~q>`#vOYyF*CN~bx zg{?g2(Nbs@@NW)kYxT#-(YNitUQNop!a3?kV0>u;*KW4A}dF1y)U-h}iNv9J^3Huo^m%-ZQY%n*0 zSjp0`hq#(fVleH@pOd1EpsRY2BiaHA%}Xyu|NFm?Kfe^c$9hWxXd3xSA(XPJb%Ps0 z@nWj+w3>?|a?ugME)>wQo|h09l+qa;Fwv-?3n_HPOD@UyNk9?a*0LjAN#g+JbUt2< zWY4FQPA9YkEFf2mW50Tt!Q9M-U}Wz)pc6gCQ|wZc$QD1PQ2i0BL?}RaUV#43&n)5J zF$I0*v)myiPiO)qRZ!p}BElU1IZ`O$biABF5-Fqymv;j%8z^QenW(s+7j)w=*OG=m zq>o>Ha!RYI;YB;L9X?i3&+(^VbxCVE8ekmz)hEDcI|D`pP1)0Mvxh&>S$t|0Vu_Eb z&CP!7Cd3!7SZtj(4Wq<^l#*1EN%YQ^F)VaH5AzY9X4#0G?z!%F*=` zSdFrO*Hm`g2|LDffh!`^+Z&*g*rxp_Lii7!jkb3qs;C&X5%}xlu=oXQ4AL(KnDMlv zvIXq}y!Ok-v7fW4lg`)}5yTF78>EClhAbPFI*WD0{Todw{00GlQxB7C=%US|O1@J{_(aihlKN0iLNrQM1F#?nZg)zT}eXaDH)0J=gnV=Ws0b z-?gbdxdzV&x{fo1L6y1=_z5t*0~|bv&~uR9+zZ7q;pbQQc_!IBv2bVu{IWgbop2Qi3jE7p#o9 za60>x13>V}A|9=O0j$}9oIV<^-wvNXia68@p%j^p7dU{?Xzi>e&?RE;z}+ZCgev4O zjr1r>x9=$nfVFEOH@EixKi+IT{Pa)YR)M(hJw$malIY`Ntk7sV?eS33D1%dgPI=gS z`(wrjP9)M&6SOrH8j1KL9N8|XEC2xZ$0&YX<3lX}47qkK07YS*dZ@R*z7eZC!lQzU zWt28}%Zy07#zjIzR50z720$!YzrkJ$ZwFvYn5Q1PiL#nxT=nc8b*v$<(uiJkrF0>` zfphW>2MtSsL5*FmEE+l(*Wv&WVkALmB7_Le4$WQ+l35owh3fc7$3q#ZQ95BEiFg~x z7<6H>!VU%L_;8U(4Mv0pC~e&Ucq#bTQdwhVdf@jbwZrp(7tscFabh0jy#hi|GU?-1z8Z=Or8tZq2f zMSHuJd=5VJ6U>|uR590Hhh0c=L$+=Fc#uFY1_qLCbYwOAk3sWP@is-QAfDwm9r?~3N+H`7`FdTSQzOj+kq97QA+oqX6c3(x1IGPfPH|+7FQk`%D%S% z4&kR99q@7?M;T0eByKdke8XWrAstC7)~>>PnNtN3k2}ApBooodrM}0G#PMYKx6) zsSk?7R8tzqM|tP6HhQIGXyEQk~4QFdqq+ zBqB*f1+~+OUGpbx8o-&#gVyz_O#}twEG`Dkfo`9$=+EbMjC$S-9OV9uYR>HQT z^^l;|Cxq0}#jVT&5?BXmwrK#H+F><+P)*DO)yO<6!RiFI4){?U0KzF3cpUfvjlWT~ z82A#aHXx9vlLlnkuWX=$ZIc*wV5$IEZ~vwoYx63!Qqdpss>W*j?twuRb1 literal 0 HcmV?d00001 diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index ab872ff4..3f220a8c 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -3,10 +3,14 @@ #include #include #include "../../RouterContext.h" +#ifndef ANDROID +#include +#endif MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)/*, - ui(new Ui::MainWindow)*/ + ui(new Ui::MainWindow)*/, + quitting(false) { //ui->setupUi(this); if (objectName().isEmpty()) @@ -41,18 +45,91 @@ MainWindow::MainWindow(QWidget *parent) : setCentralWidget(centralWidget); - setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0)); + setWindowTitle(QApplication::translate("MainWindow", "i2pd", 0)); quitButton->setText(QApplication::translate("MainWindow", "Quit", 0)); gracefulQuitButton->setText(QApplication::translate("MainWindow", "Graceful Quit", 0)); +#ifndef ANDROID + createActions(); + createTrayIcon(); +#endif + QObject::connect(quitButton, SIGNAL(released()), this, SLOT(handleQuitButton())); QObject::connect(gracefulQuitButton, SIGNAL(released()), this, SLOT(handleGracefulQuitButton())); +#ifndef ANDROID + QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); + + setIcon(); + trayIcon->show(); +#endif + //QMetaObject::connectSlotsByName(this); } +#ifndef ANDROID +void MainWindow::createActions() { + toggleWindowVisibleAction = new QAction(tr("&Toggle the window"), this); + connect(toggleWindowVisibleAction, SIGNAL(triggered()), this, SLOT(toggleVisibilitySlot())); + + //quitAction = new QAction(tr("&Quit"), this); + //connect(quitAction, SIGNAL(triggered()), QApplication::instance(), SLOT(quit())); +} + +void MainWindow::toggleVisibilitySlot() { + setVisible(!isVisible()); +} + +void MainWindow::createTrayIcon() { + trayIconMenu = new QMenu(this); + trayIconMenu->addAction(toggleWindowVisibleAction); + //trayIconMenu->addSeparator(); + //trayIconMenu->addAction(quitAction); + + trayIcon = new QSystemTrayIcon(this); + trayIcon->setContextMenu(trayIconMenu); +} + +void MainWindow::setIcon() { + QIcon icon(":/images/icon.png"); + trayIcon->setIcon(icon); + setWindowIcon(icon); + + trayIcon->setToolTip(QApplication::translate("MainWindow", "i2pd", 0)); +} + +void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) { + switch (reason) { + case QSystemTrayIcon::Trigger: + case QSystemTrayIcon::DoubleClick: + case QSystemTrayIcon::MiddleClick: + setVisible(!isVisible()); + break; + default: + qDebug() << "MainWindow::iconActivated(): unknown reason: " << reason << endl; + break; + } +} + +void MainWindow::closeEvent(QCloseEvent *event) { + if(quitting){ QMainWindow::closeEvent(event); return; } + if (trayIcon->isVisible()) { + QMessageBox::information(this, tr("i2pd"), + tr("The program will keep running in the " + "system tray. To gracefully terminate the program, " + "choose Graceful Quit at the main i2pd window.")); + hide(); + event->ignore(); + } +} +#endif + void MainWindow::handleQuitButton() { qDebug("Quit pressed. Hiding the main window"); +#ifndef ANDROID + quitting=true; +#endif close(); QApplication::instance()->quit(); } @@ -69,6 +146,9 @@ void MainWindow::handleGracefulQuitButton() { void MainWindow::handleGracefulQuitTimerEvent() { qDebug("Hiding the main window"); +#ifndef ANDROID + quitting=true; +#endif close(); qDebug("Performing quit"); QApplication::instance()->quit(); diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 94e3a7b3..349eadec 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -12,6 +12,11 @@ #include #include #include +#ifndef ANDROID +#include +#include +#include +#endif namespace Ui { class MainWindow; @@ -25,17 +30,43 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); +//#ifndef ANDROID +// void setVisible(bool visible); +//#endif + private slots: void handleQuitButton(); void handleGracefulQuitButton(); void handleGracefulQuitTimerEvent(); +#ifndef ANDROID + void setIcon(); + void iconActivated(QSystemTrayIcon::ActivationReason reason); + void toggleVisibilitySlot(); +#endif private: +#ifndef ANDROID + void createActions(); + void createTrayIcon(); +#endif + QWidget *centralWidget; QWidget *verticalLayoutWidget; QVBoxLayout *verticalLayout1; QPushButton *quitButton; QPushButton *gracefulQuitButton; + +#ifndef ANDROID + bool quitting; + QAction *toggleWindowVisibleAction; + QSystemTrayIcon *trayIcon; + QMenu *trayIconMenu; +#endif + +protected: +#ifndef ANDROID + void closeEvent(QCloseEvent *event); +#endif }; #endif // MAINWINDOW_H From 10638b6e40bbf519043ea50f6929e7a4547c20cb Mon Sep 17 00:00:00 2001 From: hypnosis-i2p Date: Sun, 26 Jun 2016 02:48:13 +0800 Subject: [PATCH 25/62] fixed unnecessary resources setting --- qt/i2pd_qt/.gitignore | 1 + qt/i2pd_qt/i2pd_qt.pro | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 qt/i2pd_qt/.gitignore diff --git a/qt/i2pd_qt/.gitignore b/qt/i2pd_qt/.gitignore new file mode 100644 index 00000000..35d7caf4 --- /dev/null +++ b/qt/i2pd_qt/.gitignore @@ -0,0 +1 @@ +i2pd_qt.pro.user* diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index f9fb78e8..9f579ffc 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -212,5 +212,3 @@ QT += xml #INSTALLS += sources } -RESOURCES += \ - i2pd.qrc From 9ba7120011f738e2e22ebf5f006d1b471afd4b63 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Jun 2016 08:32:36 -0400 Subject: [PATCH 26/62] fixed build error --- qt/i2pd_qt/mainwindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp index 3f220a8c..0e2ca01c 100644 --- a/qt/i2pd_qt/mainwindow.cpp +++ b/qt/i2pd_qt/mainwindow.cpp @@ -9,8 +9,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)/*, - ui(new Ui::MainWindow)*/, + ui(new Ui::MainWindow)*/ +#ifndef ANDROID + , quitting(false) +#endif { //ui->setupUi(this); if (objectName().isEmpty()) From 2757ef94c93434cfb988aabffc5084d264c6b032 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Jun 2016 08:37:40 -0400 Subject: [PATCH 27/62] don't include UPNP twice for android --- qt/i2pd_qt/i2pd_qt.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 9f579ffc..b2cafdeb 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -151,7 +151,7 @@ DISTFILES += \ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android -SOURCES += $$IFADDRS_PATH/ifaddrs.c ../../UPnP.cpp +SOURCES += $$IFADDRS_PATH/ifaddrs.c HEADERS += $$IFADDRS_PATH/ifaddrs.h equals(ANDROID_TARGET_ARCH, armeabi-v7a){ From 5c6ec70126b3b949031d9bb1e9ae56eb4f2b12e4 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Sun, 26 Jun 2016 11:17:05 -0400 Subject: [PATCH 28/62] fix static build for rpi linux --- Makefile.linux | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.linux b/Makefile.linux index da72a41a..324d9467 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -33,10 +33,10 @@ ifeq ($(USE_STATIC),yes) LDLIBS += $(LIBDIR)/libboost_date_time.a LDLIBS += $(LIBDIR)/libboost_filesystem.a LDLIBS += $(LIBDIR)/libboost_program_options.a - LDLIBS += $(LIBDIR)/libcrypto.a LDLIBS += $(LIBDIR)/libssl.a + LDLIBS += $(LIBDIR)/libcrypto.a LDLIBS += $(LIBDIR)/libz.a - LDLIBS += -lpthread -static-libstdc++ -static-libgcc + LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt USE_AESNI := no else LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread From 4b9e39ac64d7a876bfe562b2eec5d063ec7d9a41 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 26 Jun 2016 17:03:04 -0400 Subject: [PATCH 29/62] limit SSU outgoing windows --- SSUData.cpp | 10 +++++++++- SSUData.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/SSUData.cpp b/SSUData.cpp index 0ccf25a8..4ce7451d 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -425,6 +425,7 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + int numResent = 0; for (auto it = m_SentMessages.begin (); it != m_SentMessages.end ();) { if (ts >= it->second->nextResendTime) @@ -437,6 +438,7 @@ namespace transport try { m_Session.Send (f->buf, f->len); // resend + numResent++; } catch (boost::system::system_error& ec) { @@ -457,7 +459,13 @@ namespace transport else it++; } - ScheduleResend (); + if (numResent < MAX_OUTGOING_WINDOW_SIZE) + ScheduleResend (); + else + { + LogPrint (eLogError, "SSU: resend window exceeds max size. Session terminated"); + m_Session.Close (); + } } } diff --git a/SSUData.h b/SSUData.h index 392bfce6..02135350 100644 --- a/SSUData.h +++ b/SSUData.h @@ -29,6 +29,7 @@ namespace transport const int DECAY_INTERVAL = 20; // in seconds const int INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds const unsigned int MAX_NUM_RECEIVED_MESSAGES = 1000; // how many msgID we store for duplicates check + const int MAX_OUTGOING_WINDOW_SIZE = 200; // how many unacked message we can store // data flags const uint8_t DATA_FLAG_EXTENDED_DATA_INCLUDED = 0x02; const uint8_t DATA_FLAG_WANT_REPLY = 0x04; From c84468dbed5bdc35624b2cc2f35ae1453432e480 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 01:12:20 +0000 Subject: [PATCH 30/62] * fix cmake build with upnp=on --- build/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4a1bfe2b..61e05e83 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -338,6 +338,10 @@ if (WITH_BINARY) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-z relro -z now" ) endif () + if (WITH_UPNP) + target_link_libraries("${PROJECT_NAME}" "miniupnpc") + endif () + # FindBoost pulls pthread for thread which is broken for static linking at least on Ubuntu 15.04 list(GET Boost_LIBRARIES -1 LAST_Boost_LIBRARIES) if(${LAST_Boost_LIBRARIES} MATCHES ".*pthread.*") From e28f910c882156039116ef45157afeb5869b5e66 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 01:30:02 +0000 Subject: [PATCH 31/62] * enable travis for UPNP=ON back --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e52c53a7..d83cdbc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink boost openssl && brew link boost openssl -f ; fi env: matrix: -# - BUILD_TYPE=Release UPNP=ON + - BUILD_TYPE=Release UPNP=ON - BUILD_TYPE=Release UPNP=OFF script: - cd build && cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_UPNP=${UPNP} && make From c5e3e17eae62b2531e13ababd2264f332c7329b6 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 01:30:00 +0000 Subject: [PATCH 32/62] * HTTPProxy.cpp : extract IsI2PAddress() from class --- HTTPProxy.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index e11d430d..b801bfc9 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -24,6 +24,15 @@ namespace i2p { namespace proxy { + bool str_rmatch(std::string & str, const char *suffix) { + auto pos = str.rfind (suffix); + if (pos == std::string::npos) + return false; /* not found */ + if (str.length() == (pos + std::strlen(suffix))) + return true; /* match */ + return false; + } + static const size_t http_buffer_size = 8192; class HTTPReqHandler: public i2p::client::I2PServiceHandler, public std::enable_shared_from_this { @@ -45,7 +54,6 @@ namespace proxy { void HTTPRequestFailed(const char *message); void RedirectToJumpService(); void ExtractRequest(); - bool IsI2PAddress(); bool ValidateHTTPRequest(); void HandleJumpServices(); bool CreateHTTPRequest(uint8_t *http_buff, std::size_t len); @@ -180,16 +188,6 @@ namespace proxy { m_path.erase(addressHelperPos); } - bool HTTPReqHandler::IsI2PAddress() - { - auto pos = m_address.rfind (".i2p"); - if (pos != std::string::npos && (pos+4) == m_address.length ()) - { - return true; - } - return false; - } - bool HTTPReqHandler::CreateHTTPRequest(uint8_t *http_buff, std::size_t len) { ExtractRequest(); //TODO: parse earlier @@ -197,14 +195,13 @@ namespace proxy { HandleJumpServices(); i2p::data::IdentHash identHash; - if (IsI2PAddress ()) + if (str_rmatch(m_address, ".i2p")) { if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){ RedirectToJumpService(); return false; } } - m_request = m_method; m_request.push_back(' '); @@ -317,7 +314,6 @@ namespace proxy { else AsyncSockRead(); } - } void HTTPReqHandler::SentHTTPFailed(const boost::system::error_code & ecode) From 6f77c6f3f49c3acb842c4f320e9a096a40253cdf Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 01:30:00 +0000 Subject: [PATCH 33/62] * HTTPProxy.cpp : don't reuse part of httppserver, addresshelpers handling will be moved to proxy in future --- HTTPProxy.cpp | 25 ++++++++++++++++++------- HTTPServer.h | 2 -- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index b801bfc9..ed41049a 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -20,7 +20,6 @@ #include "I2PTunnel.h" #include "Config.h" #include "HTTP.h" -#include "HTTPServer.h" namespace i2p { namespace proxy { @@ -52,7 +51,7 @@ namespace proxy { void Terminate(); void AsyncSockRead(); void HTTPRequestFailed(const char *message); - void RedirectToJumpService(); + void RedirectToJumpService(std::string & host); void ExtractRequest(); bool ValidateHTTPRequest(); void HandleJumpServices(); @@ -119,11 +118,23 @@ namespace proxy { std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } - void HTTPReqHandler::RedirectToJumpService(/*HTTPReqHandler::errTypes error*/) + void HTTPReqHandler::RedirectToJumpService(std::string & host) { - std::stringstream ss; - i2p::http::ShowJumpServices (ss, m_address); - boost::asio::async_write(*m_sock, boost::asio::buffer(ss.str ()), + i2p::http::HTTPRes res; + i2p::http::URL url; + + /* TODO: don't redirect to webconsole, it's not always work, handle jumpservices here */ + i2p::config::GetOption("http.address", url.host); + i2p::config::GetOption("http.port", url.port); + url.path = "/"; + url.query = "page=jumpservices&address="; + url.query += host; + + res.code = 302; /* redirect */ + res.add_header("Location", url.to_string().c_str()); + + std::string response = res.to_string(); + boost::asio::async_write(*m_sock, boost::asio::buffer(response), std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } @@ -198,7 +209,7 @@ namespace proxy { if (str_rmatch(m_address, ".i2p")) { if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){ - RedirectToJumpService(); + RedirectToJumpService(m_address); return false; } } diff --git a/HTTPServer.h b/HTTPServer.h index 6aa0d792..bf7f5c65 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -61,8 +61,6 @@ namespace http { boost::asio::io_service::work m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; }; - - void ShowJumpServices (std::stringstream& s, const std::string& address); } // http } // i2p From 727068cc4bf9336945e5f611f750031c0d79af0e Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 01:30:00 +0000 Subject: [PATCH 34/62] * HTTPProxy.cpp : migrate HTTPRequestFailed() to new http classes --- HTTPProxy.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index ed41049a..af914b47 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -106,14 +106,13 @@ namespace proxy { //TODO: handle this apropriately void HTTPReqHandler::HTTPRequestFailed(const char *message) { - std::size_t size = std::strlen(message); - std::stringstream ss; - ss << "HTTP/1.0 500 Internal Server Error\r\n" - << "Content-Type: text/plain\r\n"; - ss << "Content-Length: " << std::to_string(size + 2) << "\r\n" - << "\r\n"; /* end of headers */ - ss << message << "\r\n"; - std::string response = ss.str(); + i2p::http::HTTPRes res; + res.code = 500; + res.add_header("Content-Type", "text/plain"); + res.add_header("Connection", "close"); + res.body = message; + res.body += "\r\n"; + std::string response = res.to_string(); boost::asio::async_write(*m_sock, boost::asio::buffer(response), std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } From 09b15f4940f10030019e3f02da06e611c5ded42c Mon Sep 17 00:00:00 2001 From: MXPLRS|Kirill Date: Mon, 27 Jun 2016 05:55:07 +0300 Subject: [PATCH 35/62] edited i2pd_qt.pro --- qt/i2pd_qt/i2pd_qt.pro | 252 ++++++++++++++--------------------------- 1 file changed, 83 insertions(+), 169 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index b2cafdeb..07e71839 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -1,10 +1,4 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-06-14T04:53:04 -# -#------------------------------------------------- - -QT += core gui +QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -13,202 +7,122 @@ TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 DEFINES += USE_UPNP +# change to your own path, where you will store all needed libraries with 'git clone' commands below. +MAIN_PATH = /path/to/libraries + # git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git -# change to your own -BOOST_PATH = /home/rebby/andp/Boost-for-Android-Prebuilt -OPENSSL_PATH = /home/rebby/andp/OpenSSL-for-Android-Prebuilt -MINIUPNP_PATH = /home/rebby/andp/MiniUPnP-for-Android-Prebuilt -IFADDRS_PATH = /home/rebby/andp/android-ifaddrs + +BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt +OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt +MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt +IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs # Steps in Android SDK manager: # 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html # 2) Check API 11 # Finally, click Install. -SOURCES += DaemonQT.cpp\ - mainwindow.cpp \ - ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ - ../../AddressBook.cpp \ - ../../api.cpp \ - ../../Base.cpp \ - ../../BOB.cpp \ - ../../ClientContext.cpp \ - ../../Crypto.cpp \ - ../../Datagram.cpp \ - ../../Destination.cpp \ - ../../Family.cpp \ - ../../FS.cpp \ - ../../Garlic.cpp \ - ../../HTTP.cpp \ - ../../HTTPProxy.cpp \ - ../../I2CP.cpp \ - ../../I2NPProtocol.cpp \ - ../../I2PEndian.cpp \ - ../../I2PService.cpp \ - ../../I2PTunnel.cpp \ - ../../Identity.cpp \ - ../../LeaseSet.cpp \ - ../../Log.cpp \ - ../../NetDb.cpp \ - ../../NetDbRequests.cpp \ - ../../NTCPSession.cpp \ - ../../Profiling.cpp \ - ../../Reseed.cpp \ - ../../RouterContext.cpp \ - ../../RouterInfo.cpp \ - ../../SAM.cpp \ - ../../Signature.cpp \ - ../../SOCKS.cpp \ - ../../SSU.cpp \ - ../../SSUData.cpp \ - ../../SSUSession.cpp \ - ../../Streaming.cpp \ - ../../TransitTunnel.cpp \ - ../../Transports.cpp \ - ../../Tunnel.cpp \ - ../../TunnelEndpoint.cpp \ - ../../TunnelGateway.cpp \ - ../../TunnelPool.cpp \ - ../../UPnP.cpp \ - ../../util.cpp \ - ../../i2pd.cpp +SOURCES += DaemonQT.cpp mainwindow.cpp \ + ../../HTTPServer.cpp ../../I2PControl.cpp ../../Daemon.cpp ../../Config.cpp \ + ../../AddressBook.cpp ../../api.cpp ../../Base.cpp ../../BOB.cpp ../../ClientContext.cpp \ + ../../Crypto.cpp ../../Datagram.cpp ../../Destination.cpp ../../Family.cpp ../../FS.cpp \ + ../../Garlic.cpp ../../HTTP.cpp ../../HTTPProxy.cpp ../../I2CP.cpp ../../I2NPProtocol.cpp \ + ../../I2PEndian.cpp ../../I2PService.cpp ../../I2PTunnel.cpp ../../Identity.cpp \ + ../../LeaseSet.cpp ../../Log.cpp ../../NetDb.cpp ../../NetDbRequests.cpp \ + ../../NTCPSession.cpp ../../Profiling.cpp ../../Reseed.cpp ../../RouterContext.cpp \ + ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ + ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ + ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ + ../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../i2pd.cpp HEADERS += DaemonQT.h mainwindow.h \ - ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ - ../../AddressBook.h \ - ../../api.h \ - ../../Base.h \ - ../../BOB.h \ - ../../ClientContext.h \ - ../../Crypto.h \ - ../../Datagram.h \ - ../../Destination.h \ - ../../Family.h \ - ../../FS.h \ - ../../Garlic.h \ - ../../HTTP.h \ - ../../HTTPProxy.h \ - ../../I2CP.h \ - ../../I2NPProtocol.h \ - ../../I2PEndian.h \ - ../../I2PService.h \ - ../../I2PTunnel.h \ - ../../Identity.h \ - ../../LeaseSet.h \ - ../../LittleBigEndian.h \ - ../../Log.h \ - ../../NetDb.h \ - ../../NetDbRequests.h \ - ../../NTCPSession.h \ - ../../Profiling.h \ - ../../Queue.h \ - ../../Reseed.h \ - ../../RouterContext.h \ - ../../RouterInfo.h \ - ../../SAM.h \ - ../../Signature.h \ - ../../SOCKS.h \ - ../../SSU.h \ - ../../SSUData.h \ - ../../SSUSession.h \ - ../../Streaming.h \ - ../../Timestamp.h \ - ../../TransitTunnel.h \ - ../../Transports.h \ - ../../TransportSession.h \ - ../../Tunnel.h \ - ../../TunnelBase.h \ - ../../TunnelConfig.h \ - ../../TunnelEndpoint.h \ - ../../TunnelGateway.h \ - ../../TunnelPool.h \ - ../../UPnP.h \ - ../../util.h \ - ../../version.h + ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ + ../../AddressBook.h ../../api.h ../../Base.h ../../BOB.h ../../ClientContext.h \ + ../../Crypto.h ../../Datagram.h ../../Destination.h ../../Family.h ../../FS.h \ + ../../Garlic.h ../../HTTP.h ../../HTTPProxy.h ../../I2CP.h ../../I2NPProtocol.h \ + ../../I2PEndian.h ../../I2PService.h ../../I2PTunnel.h ../../Identity.h ../../LeaseSet.h \ + ../../LittleBigEndian.h ../../Log.h ../../NetDb.h ../../NetDbRequests.h ../../NTCPSession.h \ + ../../Profiling.h ../../Queue.h ../../Reseed.h ../../RouterContext.h ../../RouterInfo.h \ + ../../SAM.h ../../Signature.h ../../SOCKS.h ../../SSU.h ../../SSUData.h ../../SSUSession.h \ + ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ + ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ + ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ + ../../util.h ../../version.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui CONFIG += mobility -MOBILITY = +MOBILITY = LIBS += -lz android { -message("Using Android settings") -DEFINES += ANDROID=1 -DEFINES += __ANDROID__ + message("Using Android settings") + DEFINES += ANDROID=1 + DEFINES += __ANDROID__ -INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ - $$OPENSSL_PATH/openssl-1.0.2/include \ - $$MINIUPNP_PATH/miniupnp-2.0/include \ - $$IFADDRS_PATH -DISTFILES += \ - android/AndroidManifest.xml + INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ + $$OPENSSL_PATH/openssl-1.0.2/include \ + $$MINIUPNP_PATH/miniupnp-2.0/include \ + $$IFADDRS_PATH + DISTFILES += android/AndroidManifest.xml -ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android -SOURCES += $$IFADDRS_PATH/ifaddrs.c -HEADERS += $$IFADDRS_PATH/ifaddrs.h + SOURCES += $$IFADDRS_PATH/ifaddrs.c + HEADERS += $$IFADDRS_PATH/ifaddrs.h -equals(ANDROID_TARGET_ARCH, armeabi-v7a){ + equals(ANDROID_TARGET_ARCH, armeabi-v7a){ + DEFINES += ANDROID_ARM7A + # http://stackoverflow.com/a/30235934/529442 + LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ + -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ + -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ + -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ + -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc -DEFINES += ANDROID_ARM7A + PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ + $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a + DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include -# http://stackoverflow.com/a/30235934/529442 -LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ --lboost_system-gcc-mt-1_53 \ --lboost_date_time-gcc-mt-1_53 \ --lboost_filesystem-gcc-mt-1_53 \ --lboost_program_options-gcc-mt-1_53 \ --L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ --L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc + ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ + $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so + } -PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a + equals(ANDROID_TARGET_ARCH, x86){ + # http://stackoverflow.com/a/30235934/529442 + LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ + -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ + -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ + -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ + -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc -DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include + PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ + $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a -ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so -} -equals(ANDROID_TARGET_ARCH, x86){ -# http://stackoverflow.com/a/30235934/529442 -LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ --lboost_system-gcc-mt-1_53 \ --lboost_date_time-gcc-mt-1_53 \ --lboost_filesystem-gcc-mt-1_53 \ --lboost_program_options-gcc-mt-1_53 \ --L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ --L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc + DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include -PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a - -DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include - -ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so -} + ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ + $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so + } } linux:!android { -message("Using Linux settings") -LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc + message("Using Linux settings") + LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc } - !android:!symbian:!maemo5:!simulator { -message("Build with a system tray icon") -# see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* -#sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images -RESOURCES = i2pd.qrc -QT += xml -#INSTALLS += sources + message("Build with a system tray icon") + # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* + #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images + RESOURCES = i2pd.qrc + QT += xml + #INSTALLS += sources } - From 881d0652e71441dc3e0555ce95c5412d54b8f2dd Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 36/62] * update debian package defaults --- debian/control | 1 + ...ble-aesni-by-default.patch => 01-tune-build-opts.patch} | 7 +++++-- debian/patches/series | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) rename debian/patches/{0001-disable-aesni-by-default.patch => 01-tune-build-opts.patch} (55%) diff --git a/debian/control b/debian/control index 78906ba4..ac6f5e28 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 9.0.0), dpkg-dev (>= 1.16.1~), libboost-date-time-dev, libboost-filesystem-dev, libboost-program-options-dev, + libminiupnpc-dev, libssl-dev Standards-Version: 3.9.3 Homepage: https://github.com/PurpleI2P/i2pd diff --git a/debian/patches/0001-disable-aesni-by-default.patch b/debian/patches/01-tune-build-opts.patch similarity index 55% rename from debian/patches/0001-disable-aesni-by-default.patch rename to debian/patches/01-tune-build-opts.patch index eae44c8b..e0e24408 100644 --- a/debian/patches/0001-disable-aesni-by-default.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -1,13 +1,16 @@ diff --git a/Makefile b/Makefile -index 2e86fd8..c1037af 100644 +index fe8ae7e..fc8abda 100644 --- a/Makefile +++ b/Makefile -@@ -9,7 +9,7 @@ DEPS := obj/make.dep +@@ -9,9 +9,9 @@ DEPS := obj/make.dep include filelist.mk -USE_AESNI := yes +USE_AESNI := no USE_STATIC := no +-USE_UPNP := no ++USE_UPNP := yes ifeq ($(UNAME),Darwin) + DAEMON_SRC += DaemonLinux.cpp diff --git a/debian/patches/series b/debian/patches/series index 1c9d0fbf..972d2a10 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1 @@ -0001-disable-aesni-by-default.patch +01-tune-build-opts.patch From 4e7375c09c8fd2c644e54b78da6c82c1ad48564d Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 37/62] * Addressbook.cpp : move storage creation to Start() --- AddressBook.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index 5e7510a5..3cf2bc56 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -203,7 +203,7 @@ namespace client } //--------------------------------------------------------------------- - AddressBook::AddressBook (): m_Storage(new AddressBookFilesystemStorage), m_IsLoaded (false), m_IsDownloading (false), + AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false), m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr) { } @@ -215,6 +215,8 @@ namespace client void AddressBook::Start () { + if (!m_Storage) + m_Storage = new AddressBookFilesystemStorage; m_Storage->Init(); LoadHosts (); /* try storage, then hosts.txt, then download */ StartSubscriptions (); From a973630cb4b8e9fc3e52d92ce0c4e628ace48a69 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 38/62] * fix tests --- tests/test-http-req.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test-http-req.cpp b/tests/test-http-req.cpp index d5362622..c857ca24 100644 --- a/tests/test-http-req.cpp +++ b/tests/test-http-req.cpp @@ -22,7 +22,6 @@ int main() { assert(req->version == "HTTP/1.0"); assert(req->method == "GET"); assert(req->uri == "/"); - assert(req->host == "inr.i2p"); assert(req->headers.size() == 3); assert(req->headers.count("Host") == 1); assert(req->headers.count("Accept") == 1); @@ -42,7 +41,6 @@ int main() { assert(req->version == "HTTP/1.0"); assert(req->method == "GET"); assert(req->uri == "/"); - assert(req->host == ""); assert(req->headers.size() == 0); delete req; @@ -52,7 +50,7 @@ int main() { "\r\n"; len = strlen(buf); req = new HTTPReq; - assert((ret = req->parse(buf, len)) == -1); /* no host header */ + assert((ret = req->parse(buf, len)) > 0); delete req; /* test: parsing incomplete request */ @@ -76,7 +74,6 @@ int main() { assert((ret = req->parse(buf, len)) == len); /* no host header */ assert(req->method == "GET"); assert(req->uri == "http://inr.i2p"); - assert(req->host == "stats.i2p"); assert(req->headers.size() == 3); assert(req->headers.count("Host") == 1); assert(req->headers.count("Accept") == 1); From 646778227aff0beb9046359b4089e1660ea1cfa9 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 39/62] * tune log messages --- NTCPSession.cpp | 4 ++-- NetDb.cpp | 2 +- SSU.cpp | 8 ++++---- SSUData.cpp | 2 +- SSUSession.cpp | 4 ++-- TransitTunnel.cpp | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/NTCPSession.cpp b/NTCPSession.cpp index ae020f5f..8dc200b1 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -430,7 +430,7 @@ namespace transport } else { - LogPrint (eLogInfo, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); + LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected"); m_Server.AddNTCPSession (shared_from_this ()); Connected (); @@ -942,7 +942,7 @@ namespace transport { if (ecode) { - LogPrint (eLogError, "NTCP: Connect error: ", ecode.message ()); + LogPrint (eLogError, "NTCP: Can't connect to ", conn->GetSocket ().remote_endpoint (), ": ", ecode.message ()); if (ecode != boost::asio::error::operation_aborted) i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true); conn->Terminate (); diff --git a/NetDb.cpp b/NetDb.cpp index d2afc50a..e94cc97d 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -671,7 +671,7 @@ namespace data if (!replyMsg) { - LogPrint (eLogWarning, "NetDb: Requested ", key, " not found. ", numExcluded, " excluded"); + LogPrint (eLogWarning, "NetDb: Requested ", key, " not found, ", numExcluded, " peers excluded"); // find or cleate response std::vector closestFloodfills; bool found = false; diff --git a/SSU.cpp b/SSU.cpp index ddfd1501..d635a7f9 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -231,7 +231,7 @@ namespace transport session = std::make_shared (*this, packet->from); session->WaitForConnect (); (*sessions)[packet->from] = session; - LogPrint (eLogInfo, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created"); + LogPrint (eLogDebug, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created"); } } session->ProcessNextMessage (packet->buf, packet->len, packet->from); @@ -312,7 +312,7 @@ namespace transport auto session = std::make_shared (*this, remoteEndpoint, router, peerTest); sessions[remoteEndpoint] = session; // connect - LogPrint (eLogInfo, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ", + LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ", remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ()); session->Connect (); } @@ -364,10 +364,10 @@ namespace transport } if (introducerSession) // session found - LogPrint (eLogInfo, "SSU: Session to introducer already exists"); + LogPrint (eLogWarning, "SSU: Session to introducer already exists"); else // create new { - LogPrint (eLogInfo, "SSU: Creating new session to introducer"); + LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost); boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort); introducerSession = std::make_shared (*this, introducerEndpoint, router); m_Sessions[introducerEndpoint] = introducerSession; diff --git a/SSUData.cpp b/SSUData.cpp index 4ce7451d..2bd65682 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -241,7 +241,7 @@ namespace transport if (!msg->IsExpired ()) m_Handler.PutNextMessage (msg); else - LogPrint (eLogInfo, "SSU: message expired"); + LogPrint (eLogDebug, "SSU: message expired"); } else LogPrint (eLogWarning, "SSU: Message ", msgID, " already received"); diff --git a/SSUSession.cpp b/SSUSession.cpp index cf56ca15..9b480888 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -814,7 +814,7 @@ namespace transport if (!ecode) { // timeout expired - LogPrint (eLogWarning, "SSU: session was not established after ", SSU_CONNECT_TIMEOUT, " seconds"); + LogPrint (eLogWarning, "SSU: session with ", m_RemoteEndpoint, " was not established after ", SSU_CONNECT_TIMEOUT, " seconds"); Failed (); } } @@ -891,7 +891,7 @@ namespace transport { if (ecode != boost::asio::error::operation_aborted) { - LogPrint (eLogWarning, "SSU: no activity for ", SSU_TERMINATION_TIMEOUT, " seconds"); + LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", SSU_TERMINATION_TIMEOUT, " seconds"); Failed (); } } diff --git a/TransitTunnel.cpp b/TransitTunnel.cpp index 0d54fc11..dfe01a05 100644 --- a/TransitTunnel.cpp +++ b/TransitTunnel.cpp @@ -92,7 +92,7 @@ namespace tunnel { if (isEndpoint) { - LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created"); + LogPrint (eLogDebug, "TransitTunnel: endpoint ", receiveTunnelID, " created"); return std::make_shared (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); } else if (isGateway) @@ -102,7 +102,7 @@ namespace tunnel } else { - LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created"); + LogPrint (eLogDebug, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created"); return std::make_shared (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey); } } From b668c4c302a8ba69234e067c061f9607353c5fc5 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 40/62] * add global switch USE_UPNP to makefile --- Makefile | 1 + Makefile.homebrew | 2 +- Makefile.linux | 2 +- Makefile.mingw | 4 ++-- Makefile.osx | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 4cc313a9..fe8ae7e3 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ include filelist.mk USE_AESNI := yes USE_STATIC := no +USE_UPNP := no ifeq ($(UNAME),Darwin) DAEMON_SRC += DaemonLinux.cpp diff --git a/Makefile.homebrew b/Makefile.homebrew index 6ce513fe..f57f6495 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -8,7 +8,7 @@ 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_program_options -lpthread -ifeq ($(USE_UPNP),1) +ifeq ($(USE_UPNP),yes) LDFLAGS += -ldl CXXFLAGS += -DUSE_UPNP endif diff --git a/Makefile.linux b/Makefile.linux index 324d9467..1376260a 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -43,7 +43,7 @@ else endif # UPNP Support (miniupnpc 1.5 or 1.6) -ifeq ($(USE_UPNP),1) +ifeq ($(USE_UPNP),yes) LDFLAGS += -lminiupnpc CXXFLAGS += -DUSE_UPNP endif diff --git a/Makefile.mingw b/Makefile.mingw index 682221d1..5cf16bf5 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -9,7 +9,7 @@ LDFLAGS = -Wl,-rpath,/usr/local/lib \ -L/usr/local/lib # UPNP Support -ifeq ($(USE_UPNP),1) +ifeq ($(USE_UPNP),yes) CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB LDLIBS = -Wl,-Bstatic -lminiupnpc endif @@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes) DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) endif -ifeq ($(USE_AESNI),1) +ifeq ($(USE_AESNI),yes) CPU_FLAGS = -maes -DAESNI else CPU_FLAGS = -msse diff --git a/Makefile.osx b/Makefile.osx index ef236c9a..f40ce1af 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -5,7 +5,7 @@ INCFLAGS = -I/usr/local/include -I/usr/local/ssl/include LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -ifeq ($(USE_UPNP),1) +ifeq ($(USE_UPNP),yes) LDFLAGS += -ldl CXXFLAGS += -DUSE_UPNP endif From 6b29d6b8dcb4834085e31d47654849321526d873 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 41/62] * HTTPProxy.cpp : unwrap AsyncSockRead() --- HTTPProxy.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index af914b47..5b8aedde 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -82,13 +82,13 @@ namespace proxy { void HTTPReqHandler::AsyncSockRead() { LogPrint(eLogDebug, "HTTPProxy: async sock read"); - if(m_sock) { - m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size), - std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); - } else { + if (!m_sock) { LogPrint(eLogError, "HTTPProxy: no socket for read"); + return; } + m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size), + std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } void HTTPReqHandler::Terminate() { From e2acc5581939eb61a44fb8bc78e7a3b7af3af5a2 Mon Sep 17 00:00:00 2001 From: hagen Date: Mon, 27 Jun 2016 13:00:00 +0000 Subject: [PATCH 42/62] * HTTPProxy.cpp : unwrap HandleStreamRequestComplete() --- HTTPProxy.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 5b8aedde..db58d1dc 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -335,20 +335,18 @@ namespace proxy { void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr stream) { - if (stream) - { - if (Kill()) return; - LogPrint (eLogInfo, "HTTPProxy: New I2PTunnel connection"); - auto connection = std::make_shared(GetOwner(), m_sock, stream); - GetOwner()->AddHandler (connection); - connection->I2PConnect (reinterpret_cast(m_request.data()), m_request.size()); - Done(shared_from_this()); - } - else - { + if (!stream) { LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info"); HTTPRequestFailed("error when creating the stream, check logs"); + return; } + if (Kill()) + return; + LogPrint (eLogDebug, "HTTPProxy: New I2PTunnel connection"); + auto connection = std::make_shared(GetOwner(), m_sock, stream); + GetOwner()->AddHandler (connection); + connection->I2PConnect (reinterpret_cast(m_request.data()), m_request.size()); + Done (shared_from_this()); } HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr localDestination): From 9cfc61cd45e4b738f80086add09d851cebace3c6 Mon Sep 17 00:00:00 2001 From: MXPLRS|Kirill Date: Tue, 28 Jun 2016 00:00:54 +0300 Subject: [PATCH 43/62] fixed #546 --- DaemonWin32.cpp | 226 ++++++++++++++++++++++++------------------------ HTTPServer.cpp | 8 +- 2 files changed, 120 insertions(+), 114 deletions(-) diff --git a/DaemonWin32.cpp b/DaemonWin32.cpp index 3afb70ce..6eb43dc0 100644 --- a/DaemonWin32.cpp +++ b/DaemonWin32.cpp @@ -1,113 +1,115 @@ -#include -#include "Config.h" -#include "Daemon.h" -#include "util.h" -#include "Log.h" - -#ifdef _WIN32 - -#include "Win32/Win32Service.h" -#ifdef WIN32_APP -#include "Win32/Win32App.h" -#endif - -namespace i2p -{ - namespace util - { - bool DaemonWin32::init(int argc, char* argv[]) - { - setlocale(LC_CTYPE, ""); - SetConsoleCP(1251); - SetConsoleOutputCP(1251); - - if (!Daemon_Singleton::init(argc, argv)) - return false; - - std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); - if (serviceControl == "install") - { - LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); - InstallService( - SERVICE_NAME, // Name of service - SERVICE_DISPLAY_NAME, // Name to display - SERVICE_START_TYPE, // Service start type - SERVICE_DEPENDENCIES, // Dependencies - SERVICE_ACCOUNT, // Service running account - SERVICE_PASSWORD // Password of the account - ); - return false; - } - else if (serviceControl == "remove") - { - LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); - UninstallService(SERVICE_NAME); - return false; - } - +#include +#include +#include "Config.h" +#include "Daemon.h" +#include "util.h" +#include "Log.h" + +#ifdef _WIN32 + +#include "Win32/Win32Service.h" +#ifdef WIN32_APP +#include "Win32/Win32App.h" +#endif + +namespace i2p +{ + namespace util + { + bool DaemonWin32::init(int argc, char* argv[]) + { + setlocale(LC_CTYPE, ""); + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + setlocale(LC_ALL, "Russian"); + + if (!Daemon_Singleton::init(argc, argv)) + return false; + + std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl); + if (serviceControl == "install") + { + LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service"); + InstallService( + SERVICE_NAME, // Name of service + SERVICE_DISPLAY_NAME, // Name to display + SERVICE_START_TYPE, // Service start type + SERVICE_DEPENDENCIES, // Dependencies + SERVICE_ACCOUNT, // Service running account + SERVICE_PASSWORD // Password of the account + ); + return false; + } + else if (serviceControl == "remove") + { + LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service"); + UninstallService(SERVICE_NAME); + return false; + } + if (isDaemon) - { - LogPrint(eLogDebug, "Daemon: running as service"); - I2PService service(SERVICE_NAME); - if (!I2PService::Run(service)) - { - LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); - return false; - } - return false; - } - else - LogPrint(eLogDebug, "Daemon: running as user"); - - return true; - } - - bool DaemonWin32::start() - { - setlocale(LC_CTYPE, ""); - SetConsoleCP(1251); - SetConsoleOutputCP(1251); - setlocale(LC_ALL, "Russian"); -#ifdef WIN32_APP - if (!i2p::win32::StartWin32App ()) return false; - - // override log - i2p::config::SetOption("log", std::string ("file")); -#endif - bool ret = Daemon_Singleton::start(); - if (ret && i2p::log::Logger().GetLogType() == eLogFile) - { - // TODO: find out where this garbage to console comes from - SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); - SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); - } - bool insomnia; i2p::config::GetOption("insomnia", insomnia); - if (insomnia) - SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); - return ret; - } - - bool DaemonWin32::stop() - { -#ifdef WIN32_APP - i2p::win32::StopWin32App (); -#endif - return Daemon_Singleton::stop(); - } - - void DaemonWin32::run () - { -#ifdef WIN32_APP - i2p::win32::RunWin32App (); -#else - while (running) - { - std::this_thread::sleep_for (std::chrono::seconds(1)); - } - -#endif - } - } -} - -#endif + { + LogPrint(eLogDebug, "Daemon: running as service"); + I2PService service(SERVICE_NAME); + if (!I2PService::Run(service)) + { + LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError()); + return false; + } + return false; + } + else + LogPrint(eLogDebug, "Daemon: running as user"); + + return true; + } + + bool DaemonWin32::start() + { + setlocale(LC_CTYPE, ""); + SetConsoleCP(1251); + SetConsoleOutputCP(1251); + setlocale(LC_ALL, "Russian"); +#ifdef WIN32_APP + if (!i2p::win32::StartWin32App ()) return false; + + // override log + i2p::config::SetOption("log", std::string ("file")); +#endif + bool ret = Daemon_Singleton::start(); + if (ret && i2p::log::Logger().GetLogType() == eLogFile) + { + // TODO: find out where this garbage to console comes from + SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); + SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); + } + bool insomnia; i2p::config::GetOption("insomnia", insomnia); + if (insomnia) + SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); + return ret; + } + + bool DaemonWin32::stop() + { +#ifdef WIN32_APP + i2p::win32::StopWin32App (); +#endif + return Daemon_Singleton::stop(); + } + + void DaemonWin32::run () + { +#ifdef WIN32_APP + i2p::win32::RunWin32App (); +#else + while (running) + { + std::this_thread::sleep_for (std::chrono::seconds(1)); + } + +#endif + } + } +} + +#endif diff --git a/HTTPServer.cpp b/HTTPServer.cpp index f35e02d3..be3b9b58 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -126,8 +126,12 @@ namespace http { 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" /* TODO: Find something to parse html/template system. This is horrible. */ +#if (!defined(WIN32)) + " \r\n" +#else + " \r\n" +#endif " \r\n" " Purple I2P " VERSION " Webconsole\r\n" << cssStyles << From 6350f5e6e80dbaa9ba8b0855b9580f1bc47190c4 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 00:00:00 +0000 Subject: [PATCH 44/62] * Base.cpp : extract gzip classes to separate file --- Base.cpp | 93 ------------------------------------- Base.h | 36 --------------- Gzip.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++ Gzip.h | 44 ++++++++++++++++++ NTCPSession.cpp | 2 +- NetDb.cpp | 2 +- NetDb.h | 2 + build/CMakeLists.txt | 1 + filelist.mk | 2 +- 9 files changed, 158 insertions(+), 132 deletions(-) create mode 100644 Gzip.cpp create mode 100644 Gzip.h diff --git a/Base.cpp b/Base.cpp index 766eaab9..600afebc 100644 --- a/Base.cpp +++ b/Base.cpp @@ -283,99 +283,6 @@ namespace data } return ret; } - - GzipInflator::GzipInflator (): m_IsDirty (false) - { - memset (&m_Inflator, 0, sizeof (m_Inflator)); - inflateInit2 (&m_Inflator, MAX_WBITS + 16); // gzip - } - - GzipInflator::~GzipInflator () - { - inflateEnd (&m_Inflator); - } - - size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) - { - if (m_IsDirty) inflateReset (&m_Inflator); - m_IsDirty = true; - m_Inflator.next_in = const_cast(in); - m_Inflator.avail_in = inLen; - m_Inflator.next_out = out; - m_Inflator.avail_out = outLen; - int err; - if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) { - return outLen - m_Inflator.avail_out; - } - return 0; - } - - bool GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& s) - { - m_IsDirty = true; - uint8_t * out = new uint8_t[GZIP_CHUNK_SIZE]; - m_Inflator.next_in = const_cast(in); - m_Inflator.avail_in = inLen; - int ret; - do - { - m_Inflator.next_out = out; - m_Inflator.avail_out = GZIP_CHUNK_SIZE; - ret = inflate (&m_Inflator, Z_NO_FLUSH); - if (ret < 0) - { - inflateEnd (&m_Inflator); - s.setstate(std::ios_base::failbit); - break; - } - s.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); - } - while (!m_Inflator.avail_out); // more data to read - delete[] out; - return ret == Z_STREAM_END || ret < 0; - } - - void GzipInflator::Inflate (std::istream& in, std::ostream& out) - { - uint8_t * buf = new uint8_t[GZIP_CHUNK_SIZE]; - while (!in.eof ()) - { - in.read ((char *)buf, GZIP_CHUNK_SIZE); - Inflate (buf, in.gcount (), out); - } - delete[] buf; - } - - GzipDeflator::GzipDeflator (): m_IsDirty (false) - { - memset (&m_Deflator, 0, sizeof (m_Deflator)); - deflateInit2 (&m_Deflator, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15 + 16 sets gzip - } - - GzipDeflator::~GzipDeflator () - { - deflateEnd (&m_Deflator); - } - - void GzipDeflator::SetCompressionLevel (int level) - { - deflateParams (&m_Deflator, level, Z_DEFAULT_STRATEGY); - } - - size_t GzipDeflator::Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) - { - if (m_IsDirty) deflateReset (&m_Deflator); - m_IsDirty = true; - m_Deflator.next_in = const_cast(in); - m_Deflator.avail_in = inLen; - m_Deflator.next_out = out; - m_Deflator.avail_out = outLen; - int err; - if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) { - return outLen - m_Deflator.avail_out; - } /* else */ - return 0; - } } } diff --git a/Base.h b/Base.h index 0c38725e..5bcb8f16 100644 --- a/Base.h +++ b/Base.h @@ -4,7 +4,6 @@ #include #include #include -#include #include namespace i2p @@ -93,41 +92,6 @@ namespace data uint64_t ll[sz/8]; }; }; - - const size_t GZIP_CHUNK_SIZE = 16384; - class GzipInflator - { - public: - - GzipInflator (); - ~GzipInflator (); - - size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); - bool Inflate (const uint8_t * in, size_t inLen, std::ostream& s); - // return true when finshed or error, s failbit will be set in case of error - void Inflate (std::istream& in, std::ostream& out); - - private: - - z_stream m_Inflator; - bool m_IsDirty; - }; - - class GzipDeflator - { - public: - - GzipDeflator (); - ~GzipDeflator (); - - void SetCompressionLevel (int level); - size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); - - private: - - z_stream m_Deflator; - bool m_IsDirty; - }; } } diff --git a/Gzip.cpp b/Gzip.cpp new file mode 100644 index 00000000..da9f06b1 --- /dev/null +++ b/Gzip.cpp @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + +#include +#include /* memset */ +#include + +#include "Gzip.h" + +namespace i2p { +namespace data { + const size_t GZIP_CHUNK_SIZE = 16384; + + GzipInflator::GzipInflator (): m_IsDirty (false) + { + memset (&m_Inflator, 0, sizeof (m_Inflator)); + inflateInit2 (&m_Inflator, MAX_WBITS + 16); // gzip + } + + GzipInflator::~GzipInflator () + { + inflateEnd (&m_Inflator); + } + + size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) + { + if (m_IsDirty) inflateReset (&m_Inflator); + m_IsDirty = true; + m_Inflator.next_in = const_cast(in); + m_Inflator.avail_in = inLen; + m_Inflator.next_out = out; + m_Inflator.avail_out = outLen; + int err; + if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) { + return outLen - m_Inflator.avail_out; + } + return 0; + } + + void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os) + { + m_IsDirty = true; + uint8_t * out = new uint8_t[GZIP_CHUNK_SIZE]; + m_Inflator.next_in = const_cast(in); + m_Inflator.avail_in = inLen; + int ret; + do { + m_Inflator.next_out = out; + m_Inflator.avail_out = GZIP_CHUNK_SIZE; + ret = inflate (&m_Inflator, Z_NO_FLUSH); + if (ret < 0) { + inflateEnd (&m_Inflator); + os.setstate(std::ios_base::failbit); + break; + } + os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); + } while (!m_Inflator.avail_out); // more data to read + delete[] out; + } + + void GzipInflator::Inflate (std::istream& in, std::ostream& out) + { + uint8_t * buf = new uint8_t[GZIP_CHUNK_SIZE]; + while (!in.eof ()) + { + in.read ((char *) buf, GZIP_CHUNK_SIZE); + Inflate (buf, in.gcount (), out); + } + delete[] buf; + } + + GzipDeflator::GzipDeflator (): m_IsDirty (false) + { + memset (&m_Deflator, 0, sizeof (m_Deflator)); + deflateInit2 (&m_Deflator, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15 + 16 sets gzip + } + + GzipDeflator::~GzipDeflator () + { + deflateEnd (&m_Deflator); + } + + void GzipDeflator::SetCompressionLevel (int level) + { + deflateParams (&m_Deflator, level, Z_DEFAULT_STRATEGY); + } + + size_t GzipDeflator::Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen) + { + if (m_IsDirty) deflateReset (&m_Deflator); + m_IsDirty = true; + m_Deflator.next_in = const_cast(in); + m_Deflator.avail_in = inLen; + m_Deflator.next_out = out; + m_Deflator.avail_out = outLen; + int err; + if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) { + return outLen - m_Deflator.avail_out; + } /* else */ + return 0; + } +} // data +} // i2p diff --git a/Gzip.h b/Gzip.h new file mode 100644 index 00000000..35661abe --- /dev/null +++ b/Gzip.h @@ -0,0 +1,44 @@ +#ifndef GZIP_H__ +#define GZIP_H__ + +#include + +namespace i2p { +namespace data { + class GzipInflator + { + public: + + GzipInflator (); + ~GzipInflator (); + + size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); + /** @note @a os failbit will be set in case of error */ + void Inflate (const uint8_t * in, size_t inLen, std::ostream& os); + void Inflate (std::istream& in, std::ostream& out); + + private: + + z_stream m_Inflator; + bool m_IsDirty; + }; + + class GzipDeflator + { + public: + + GzipDeflator (); + ~GzipDeflator (); + + void SetCompressionLevel (int level); + size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen); + + private: + + z_stream m_Deflator; + bool m_IsDirty; + }; +} // data +} // i2p + +#endif /* GZIP_H__ */ diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 8dc200b1..953c0707 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -1,6 +1,6 @@ #include #include -#include + #include "I2PEndian.h" #include "Base.h" #include "Crypto.h" diff --git a/NetDb.cpp b/NetDb.cpp index e94cc97d..937ea830 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -2,7 +2,7 @@ #include #include #include -#include + #include "I2PEndian.h" #include "Base.h" #include "Crypto.h" diff --git a/NetDb.h b/NetDb.h index 1c062358..823dbb54 100644 --- a/NetDb.h +++ b/NetDb.h @@ -8,7 +8,9 @@ #include #include #include + #include "Base.h" +#include "Gzip.h" #include "FS.h" #include "Queue.h" #include "I2NPProtocol.h" diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 61e05e83..3f5f599f 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -21,6 +21,7 @@ set (LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/Config.cpp" "${CMAKE_SOURCE_DIR}/Crypto.cpp" "${CMAKE_SOURCE_DIR}/Garlic.cpp" + "${CMAKE_SOURCE_DIR}/Gzip.cpp" "${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp" "${CMAKE_SOURCE_DIR}/Identity.cpp" "${CMAKE_SOURCE_DIR}/LeaseSet.cpp" diff --git a/filelist.mk b/filelist.mk index 8abf0b4b..d8d74252 100644 --- a/filelist.mk +++ b/filelist.mk @@ -1,5 +1,5 @@ LIB_SRC = \ - Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \ + Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \ Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \ Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \ SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \ From d838ce85c3caa05bcc2fd57256de58bba0c50a8b Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 00:00:00 +0000 Subject: [PATCH 45/62] * Base.h : extract Tag template class to separate header --- Base.cpp | 2 ++ Base.h | 81 +++---------------------------------------------------- Crypto.h | 2 ++ Tag.h | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 77 deletions(-) create mode 100644 Tag.h diff --git a/Base.cpp b/Base.cpp index 600afebc..35aae437 100644 --- a/Base.cpp +++ b/Base.cpp @@ -1,4 +1,6 @@ #include +#include + #include "Base.h" namespace i2p diff --git a/Base.h b/Base.h index 5bcb8f16..66192d1b 100644 --- a/Base.h +++ b/Base.h @@ -2,14 +2,11 @@ #define BASE_H__ #include -#include #include #include -namespace i2p -{ -namespace data -{ +namespace i2p { +namespace data { size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); const char * GetBase32SubstitutionTable (); @@ -22,77 +19,7 @@ namespace data Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes */ size_t Base64EncodingBufferSize(const size_t input_size); - - template - class Tag - { - public: - - Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }; - Tag (const Tag& ) = default; -#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it - Tag (Tag&& ) = default; -#endif - Tag () = default; - - Tag& operator= (const Tag& ) = default; -#ifndef _WIN32 - Tag& operator= (Tag&& ) = default; -#endif - - uint8_t * operator()() { return m_Buf; }; - const uint8_t * operator()() const { return m_Buf; }; - - operator uint8_t * () { return m_Buf; }; - operator const uint8_t * () const { return m_Buf; }; - - const uint64_t * GetLL () const { return ll; }; - - bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }; - bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }; - - bool IsZero () const - { - for (int i = 0; i < sz/8; i++) - if (ll[i]) return false; - return true; - } - - std::string ToBase64 () const - { - char str[sz*2]; - int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); - str[l] = 0; - return std::string (str); - } - - std::string ToBase32 () const - { - char str[sz*2]; - int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); - str[l] = 0; - return std::string (str); - } - - void FromBase32 (const std::string& s) - { - i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } - - void FromBase64 (const std::string& s) - { - i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); - } - - private: - - union // 8 bytes alignment - { - uint8_t m_Buf[sz]; - uint64_t ll[sz/8]; - }; - }; -} -} +} // data +} // i2p #endif diff --git a/Crypto.h b/Crypto.h index 7ce202ce..a66f51b7 100644 --- a/Crypto.h +++ b/Crypto.h @@ -9,7 +9,9 @@ #include #include #include + #include "Base.h" +#include "Tag.h" namespace i2p { diff --git a/Tag.h b/Tag.h new file mode 100644 index 00000000..e3432501 --- /dev/null +++ b/Tag.h @@ -0,0 +1,82 @@ +#ifndef TAG_H__ +#define TAG_H__ + +#include /* memcpy */ + +#include "Base.h" + +namespace i2p { +namespace data { + template + class Tag + { + public: + + Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }; + Tag (const Tag& ) = default; +#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it + Tag (Tag&& ) = default; +#endif + Tag () = default; + + Tag& operator= (const Tag& ) = default; +#ifndef _WIN32 + Tag& operator= (Tag&& ) = default; +#endif + + uint8_t * operator()() { return m_Buf; }; + const uint8_t * operator()() const { return m_Buf; }; + + operator uint8_t * () { return m_Buf; }; + operator const uint8_t * () const { return m_Buf; }; + + const uint64_t * GetLL () const { return ll; }; + + bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }; + bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }; + + bool IsZero () const + { + for (int i = 0; i < sz/8; i++) + if (ll[i]) return false; + return true; + } + + std::string ToBase64 () const + { + char str[sz*2]; + int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2); + str[l] = 0; + return std::string (str); + } + + std::string ToBase32 () const + { + char str[sz*2]; + int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2); + str[l] = 0; + return std::string (str); + } + + void FromBase32 (const std::string& s) + { + i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + void FromBase64 (const std::string& s) + { + i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz); + } + + private: + + union // 8 bytes alignment + { + uint8_t m_Buf[sz]; + uint64_t ll[sz/8]; + }; + }; +} // data +} // i2p + +#endif /* TAG_H__ */ From 7f266701734940122e1e65398f56f386b3465caf Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 00:00:00 +0000 Subject: [PATCH 46/62] + tests/test-base-64.cpp --- tests/Makefile | 7 +++++-- tests/test-base-64.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/test-base-64.cpp diff --git a/tests/Makefile b/tests/Makefile index 957d4632..ef30c631 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,11 +1,14 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 TESTS = test-http-url test-http-req test-http-res test-http-url_decode \ - test-http-merge_chunked + test-http-merge_chunked test-base-64 all: $(TESTS) run -test-http-%: test-http-%.cpp ../HTTP.cpp +test-http-%: ../HTTP.cpp test-http-%.cpp + $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ + +test-base-%: ../Base.cpp test-base-%.cpp $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ run: $(TESTS) diff --git a/tests/test-base-64.cpp b/tests/test-base-64.cpp new file mode 100644 index 00000000..d8d0ce2f --- /dev/null +++ b/tests/test-base-64.cpp @@ -0,0 +1,45 @@ +#include +#include + +#include "../Base.h" + +using namespace i2p::data; + +int main() { + const char *in = "test"; + size_t in_len = strlen(in); + char out[16]; + + /* bytes -> b64 */ + assert(ByteStreamToBase64(NULL, 0, NULL, 0) == 0); + assert(ByteStreamToBase64(NULL, 0, out, sizeof(out)) == 0); + + assert(Base64EncodingBufferSize(2) == 4); + assert(Base64EncodingBufferSize(4) == 8); + assert(Base64EncodingBufferSize(6) == 8); + assert(Base64EncodingBufferSize(7) == 12); + assert(Base64EncodingBufferSize(9) == 12); + assert(Base64EncodingBufferSize(10) == 16); + assert(Base64EncodingBufferSize(12) == 16); + assert(Base64EncodingBufferSize(13) == 20); + + assert(ByteStreamToBase64((uint8_t *) in, in_len, out, sizeof(out)) == 8); + assert(memcmp(out, "dGVzdA==", 8) == 0); + + /* b64 -> bytes */ + assert(Base64ToByteStream(NULL, 0, NULL, 0) == 0); + assert(Base64ToByteStream(NULL, 0, (uint8_t *) out, sizeof(out)) == 0); + + in = "dGVzdA=="; /* valid b64 */ + assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 4); + assert(memcmp(out, "test", 4) == 0); + + in = "dGVzdA="; /* invalid b64 : not padded */ + assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0); + + in = "dG/z.A=="; /* invalid b64 : char not from alphabet */ +// assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0); +// ^^^ fails, current implementation not checks acceptable symbols + + return 0; +} From 2be1c10522fb33c183bb157872c2cfcc8870259f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Jun 2016 07:11:55 -0400 Subject: [PATCH 47/62] Tag.h and Gzip.h/.cpp added --- qt/i2pd_qt/i2pd_qt.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 07e71839..db3f21c8 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \ ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ - ../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../i2pd.cpp + ../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../Gzip.cpp ../../i2pd.cpp HEADERS += DaemonQT.h mainwindow.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ @@ -50,7 +50,7 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \ ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ - ../../util.h ../../version.h + ../../util.h ../../version.h ..//../Gzip.h ../../Tag.h FORMS += mainwindow.ui From 8cb3e3418ad0bbab54284b802376a7e6d8832f28 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 28 Jun 2016 09:31:41 -0400 Subject: [PATCH 48/62] send garlic cloves directly if garlic was received derectly --- Garlic.cpp | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index c1100f64..17740fae 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -7,6 +7,7 @@ #include "I2NPProtocol.h" #include "Tunnel.h" #include "TunnelPool.h" +#include "Transports.h" #include "Timestamp.h" #include "Log.h" #include "Garlic.h" @@ -514,22 +515,34 @@ namespace garlic buf += 32; uint32_t gwTunnel = bufbe32toh (buf); buf += 4; - std::shared_ptr tunnel; - if (from && from->GetTunnelPool ()) - tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel (); - if (tunnel) // we have send it through an outbound tunnel - { - auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from); - tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); - } - else - LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from); + if (from) // received through an inbound tunnel + { + std::shared_ptr tunnel; + if (from->GetTunnelPool ()) + tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel (); + else + LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel"); + if (tunnel) // we have send it through an outbound tunnel + tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg); + else + LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove"); + } + else // received directly + i2p::transport::transports.SendMessage (gwHash, i2p::CreateTunnelGatewayMsg (gwTunnel, msg)); // send directly break; } case eGarlicDeliveryTypeRouter: - LogPrint (eLogWarning, "Garlic: type router not supported"); + { + uint8_t * ident = buf; buf += 32; - break; + if (!from) // received directly + i2p::transport::transports.SendMessage (ident, + CreateI2NPMessage (buf, GetI2NPMessageLength (buf))); + else + LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported"); + break; + } default: LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType); } From 2d252e6459fff5396b8925136ce6c40b4cd90a91 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 13:00:00 +0000 Subject: [PATCH 49/62] * HTTP.cpp : rename method --- HTTP.cpp | 2 +- HTTP.h | 2 +- I2PControl.cpp | 2 +- tests/test-http-res.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/HTTP.cpp b/HTTP.cpp index eca21fde..31567bbd 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -276,7 +276,7 @@ namespace http { return false; } - long int HTTPMsg::length() { + long int HTTPMsg::content_length() { unsigned long int length = 0; auto it = headers.find("Content-Length"); if (it == headers.end()) diff --git a/HTTP.h b/HTTP.h index 19d0612e..bce55026 100644 --- a/HTTP.h +++ b/HTTP.h @@ -62,7 +62,7 @@ namespace http { void del_header(const char *name); /** @brief Returns declared message length or -1 if unknown */ - long int length(); + long int content_length(); }; struct HTTPReq : HTTPMsg { diff --git a/I2PControl.cpp b/I2PControl.cpp index c0c87fd4..aa3c55e8 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -205,7 +205,7 @@ namespace client } /* append to json chunk of data from 1st request */ json.write(buf->begin() + len, bytes_transferred - len); - remains = req.length() - len; + remains = req.content_length() - len; /* if request has Content-Length header, fetch rest of data and store to json buffer */ while (remains > 0) { len = ((long int) buf->size() < remains) ? buf->size() : remains; diff --git a/tests/test-http-res.cpp b/tests/test-http-res.cpp index 7dd74e1e..896a4403 100644 --- a/tests/test-http-res.cpp +++ b/tests/test-http-res.cpp @@ -29,7 +29,7 @@ int main() { assert(res->headers.find("Server")->second == "nginx/1.2.1"); assert(res->headers.find("Content-Length")->second == "536"); assert(res->is_chunked() == false); - assert(res->length() == 536); + assert(res->content_length() == 536); delete res; /* test: building request */ From 21b76d3d2b8b25af1438213bd7efa4696bb3f6ea Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 13:00:00 +0000 Subject: [PATCH 50/62] * Config.cpp : drop compat parser --- Config.cpp | 79 +----------------------------------------------------- 1 file changed, 1 insertion(+), 78 deletions(-) diff --git a/Config.cpp b/Config.cpp index e6d44d59..2a7668c5 100644 --- a/Config.cpp +++ b/Config.cpp @@ -26,83 +26,6 @@ namespace config { options_description m_OptionsDesc; variables_map m_Options; - /* list of renamed options */ - std::map remapped_options = { - { "tunnelscfg", "tunconf" }, - { "v6", "ipv6" }, - { "httpaddress", "http.address" }, - { "httpport", "http.port" }, - { "httpproxyaddress", "httpproxy.address" }, - { "httpproxyport", "httpproxy.port" }, - { "socksproxyaddress", "socksproxy.address" }, - { "socksproxyport", "socksproxy.port" }, - { "samaddress", "sam.address" }, - { "samport", "sam.port" }, - { "bobaddress", "bob.address" }, - { "bobport", "bob.port" }, - { "i2pcontroladdress", "i2pcontrol.address" }, - { "i2pcontroladdress", "i2pcontrol.port" }, - { "proxykeys", "httpproxy.keys" }, - }; - /* list of options, that loose their argument and become simple switch */ - std::set boolean_options = { - "daemon", "floodfill", "notransit", "service", "ipv6" - }; - - /* this function is a solid piece of shit, remove it after 2.6.0 */ - std::pair old_syntax_parser(const std::string& s) { - std::string name = ""; - std::string value = ""; - std::size_t pos = 0; - /* shortcuts -- -h */ - if (s.length() == 2 && s.at(0) == '-' && s.at(1) != '-') - return make_pair(s.substr(1), ""); - /* old-style -- -log, /log, etc */ - if (s.at(0) == '/' || (s.at(0) == '-' && s.at(1) != '-')) { - if ((pos = s.find_first_of("= ")) != std::string::npos) { - name = s.substr(1, pos - 1); - value = s.substr(pos + 1); - } else { - name = s.substr(1, pos); - value = ""; - } - if (boolean_options.count(name) > 0 && value != "") - std::cerr << "args: don't give an argument to switch option: " << s << std::endl; - if (m_OptionsDesc.find_nothrow(name, false)) { - std::cerr << "args: option " << s << " style is DEPRECATED, use --" << name << " instead" << std::endl; - return std::make_pair(name, value); - } - if (remapped_options.count(name) > 0) { - name = remapped_options[name]; - std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl; - return std::make_pair(name, value); - } /* else */ - } - /* long options -- --help */ - if (s.substr(0, 2) == "--") { - if ((pos = s.find_first_of("= ")) != std::string::npos) { - name = s.substr(2, pos - 2); - value = s.substr(pos + 1); - } else { - name = s.substr(2, pos); - value = ""; - } - if (boolean_options.count(name) > 0 && value != "") { - std::cerr << "args: don't give an argument to switch option: " << s << std::endl; - value = ""; - } - if (m_OptionsDesc.find_nothrow(name, false)) - return std::make_pair(name, value); - if (remapped_options.count(name) > 0) { - name = remapped_options[name]; - std::cerr << "args: option " << s << " is DEPRECATED, use --" << name << " instead" << std::endl; - return std::make_pair(name, value); - } /* else */ - } - std::cerr << "args: unknown option -- " << s << std::endl; - return std::make_pair("", ""); - } - void Init() { options_description general("General options"); general.add_options() @@ -225,7 +148,7 @@ namespace config { auto style = boost::program_options::command_line_style::unix_style | boost::program_options::command_line_style::allow_long_disguise; style &= ~ boost::program_options::command_line_style::allow_guessing; - store(parse_command_line(argc, argv, m_OptionsDesc, style, old_syntax_parser), m_Options); + store(parse_command_line(argc, argv, m_OptionsDesc, style), m_Options); } catch (boost::program_options::error& e) { std::cerr << "args: " << e.what() << std::endl; exit(EXIT_FAILURE); From 2e5226356b492423b763d5d5e687a296a7c9fac8 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 28 Jun 2016 13:00:00 +0000 Subject: [PATCH 51/62] * Tag.h : add (c) header --- Tag.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tag.h b/Tag.h index e3432501..b6f94de7 100644 --- a/Tag.h +++ b/Tag.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef TAG_H__ #define TAG_H__ From 14cdb531c8c6a00629769133898fafd23d22be93 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 29 Jun 2016 01:00:00 +0000 Subject: [PATCH 52/62] * Streaming.cpp : tune logs --- Streaming.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Streaming.cpp b/Streaming.cpp index e5260556..2d3c92ce 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -87,7 +87,7 @@ namespace stream return; } - LogPrint (eLogDebug, "Streaming: Received seqn=", receivedSeqn); + LogPrint (eLogDebug, "Streaming: Received seqn=", receivedSeqn, " on sSID=", m_SendStreamID); if (receivedSeqn == m_LastReceivedSequenceNumber + 1) { // we have received next in sequence message @@ -129,13 +129,13 @@ namespace stream if (receivedSeqn <= m_LastReceivedSequenceNumber) { // we have received duplicate - LogPrint (eLogWarning, "Streaming: Duplicate message ", receivedSeqn, " received"); + LogPrint (eLogWarning, "Streaming: Duplicate message ", receivedSeqn, " on sSID=", m_SendStreamID); SendQuickAck (); // resend ack for previous message again delete packet; // packet dropped } else { - LogPrint (eLogWarning, "Streaming: Missing messages from ", m_LastReceivedSequenceNumber + 1, " to ", receivedSeqn - 1); + LogPrint (eLogWarning, "Streaming: Missing messages on sSID=", m_SendStreamID, ": from ", m_LastReceivedSequenceNumber + 1, " to ", receivedSeqn - 1); // save message and wait for missing message again SavePacket (packet); if (m_LastReceivedSequenceNumber >= 0) @@ -183,7 +183,7 @@ namespace stream m_RemoteIdentity = std::make_shared(optionData, packet->GetOptionSize ()); optionData += m_RemoteIdentity->GetFullLen (); if (!m_RemoteLeaseSet) - LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 ()); + LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID); } if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED) @@ -263,7 +263,7 @@ namespace stream uint64_t rtt = ts - sentPacket->sendTime; m_RTT = (m_RTT*seqn + rtt)/(seqn + 1); m_RTO = m_RTT*1.5; // TODO: implement it better - LogPrint (eLogDebug, "Packet ", seqn, " acknowledged rtt=", rtt); + LogPrint (eLogDebug, "Streaming: Packet ", seqn, " acknowledged rtt=", rtt); m_SentPackets.erase (it++); delete sentPacket; acknowledged = true; @@ -451,7 +451,7 @@ namespace stream auto seqn = it->GetSeqn (); if (numNacks + (seqn - nextSeqn) >= 256) { - LogPrint (eLogError, "Number of NACKs exceeds 256. seqn=", seqn, " nextSeqn=", nextSeqn); + LogPrint (eLogError, "Streaming: Number of NACKs exceeds 256. seqn=", seqn, " nextSeqn=", nextSeqn); htobe32buf (packet + 12, nextSeqn); // change ack Through break; } @@ -492,7 +492,7 @@ namespace stream m_Status = eStreamStatusClosing; Close (); // recursion if (m_Status == eStreamStatusClosing) //still closing - LogPrint (eLogInfo, "Streaming: Trying to send stream data before closing"); + LogPrint (eLogDebug, "Streaming: Trying to send stream data before closing, sSID=", m_SendStreamID); break; case eStreamStatusReset: SendClose (); @@ -514,7 +514,7 @@ namespace stream m_LocalDestination.DeleteStream (shared_from_this ()); break; default: - LogPrint (eLogWarning, "Streaming: Unexpected stream status ", (int)m_Status); + LogPrint (eLogWarning, "Streaming: Unexpected stream status ", (int)m_Status, "sSID=", m_SendStreamID); }; } @@ -546,7 +546,7 @@ namespace stream p->len = size; m_Service.post (std::bind (&Stream::SendPacket, shared_from_this (), p)); - LogPrint (eLogDebug, "Streaming: FIN sent"); + LogPrint (eLogDebug, "Streaming: FIN sent, sSID=", m_SendStreamID); } size_t Stream::ConcatenatePackets (uint8_t * buf, size_t len) @@ -600,7 +600,7 @@ namespace stream UpdateCurrentRemoteLease (); if (!m_RemoteLeaseSet) { - LogPrint (eLogError, "Streaming: Can't send packets, missing remote LeaseSet"); + LogPrint (eLogError, "Streaming: Can't send packets, missing remote LeaseSet, sSID=", m_SendStreamID); return; } } @@ -625,7 +625,7 @@ namespace stream m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNewOutboundTunnel (m_CurrentOutboundTunnel); if (!m_CurrentOutboundTunnel) { - LogPrint (eLogError, "Streaming: No outbound tunnels in the pool"); + LogPrint (eLogError, "Streaming: No outbound tunnels in the pool, sSID=", m_SendStreamID); return; } @@ -649,7 +649,7 @@ namespace stream m_CurrentOutboundTunnel->SendTunnelDataMsg (msgs); } else - LogPrint (eLogWarning, "Streaming: All leases are expired"); + LogPrint (eLogWarning, "Streaming: All leases are expired, sSID=", m_SendStreamID); } @@ -668,7 +668,7 @@ namespace stream // check for resend attempts if (m_NumResendAttempts >= MAX_NUM_RESEND_ATTEMPTS) { - LogPrint (eLogWarning, "Streaming: packet was not ACKed after ", MAX_NUM_RESEND_ATTEMPTS, " attempts, terminate"); + LogPrint (eLogWarning, "Streaming: packet was not ACKed after ", MAX_NUM_RESEND_ATTEMPTS, " attempts, terminate, sSID=", m_SendStreamID); m_Status = eStreamStatusReset; Close (); return; @@ -703,13 +703,13 @@ namespace stream case 4: if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); UpdateCurrentRemoteLease (); // pick another lease - LogPrint (eLogWarning, "Streaming: Another remote lease has been selected for stream"); + LogPrint (eLogWarning, "Streaming: Another remote lease has been selected for stream with sSID=", m_SendStreamID); break; case 3: // pick another outbound tunnel if (m_RoutingSession) m_RoutingSession->SetSharedRoutingPath (nullptr); m_CurrentOutboundTunnel = m_LocalDestination.GetOwner ()->GetTunnelPool ()->GetNextOutboundTunnel (m_CurrentOutboundTunnel); - LogPrint (eLogWarning, "Streaming: Another outbound tunnel has been selected for stream"); + LogPrint (eLogWarning, "Streaming: Another outbound tunnel has been selected for stream with sSID=", m_SendStreamID); break; default: ; } @@ -725,7 +725,7 @@ namespace stream { if (m_LastReceivedSequenceNumber < 0) { - LogPrint (eLogWarning, "Streaming: SYN has not been recived after ", ACK_SEND_TIMEOUT, " milliseconds after follow on, terminate"); + LogPrint (eLogWarning, "Streaming: SYN has not been recived after ", ACK_SEND_TIMEOUT, " milliseconds after follow on, terminate sSID=", m_SendStreamID); m_Status = eStreamStatusReset; Close (); return; @@ -828,7 +828,7 @@ namespace stream it->second->HandleNextPacket (packet); else { - LogPrint (eLogError, "Streaming: Unknown stream sendStreamID=", sendStreamID); + LogPrint (eLogError, "Streaming: Unknown stream sSID=", sendStreamID); delete packet; } } @@ -844,7 +844,7 @@ namespace stream auto it = m_SavedPackets.find (receiveStreamID); if (it != m_SavedPackets.end ()) { - LogPrint (eLogDebug, "Streaming: Processing ", it->second.size (), " saved packets for receiveStreamID=", receiveStreamID); + LogPrint (eLogDebug, "Streaming: Processing ", it->second.size (), " saved packets for rSID=", receiveStreamID); for (auto it1: it->second) incomingStream->HandleNextPacket (it1); m_SavedPackets.erase (it); @@ -863,7 +863,7 @@ namespace stream m_PendingIncomingTimer.expires_from_now (boost::posix_time::seconds(PENDING_INCOMING_TIMEOUT)); m_PendingIncomingTimer.async_wait (std::bind (&StreamingDestination::HandlePendingIncomingTimer, shared_from_this (), std::placeholders::_1)); - LogPrint (eLogDebug, "Streaming: Pending incoming stream added"); + LogPrint (eLogDebug, "Streaming: Pending incoming stream added, rSID=", receiveStreamID); } else { From f6e988d6fdca673104b43461d92f723ea9072911 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jun 2016 11:26:46 -0400 Subject: [PATCH 53/62] support zero-hops tunnels for destinations --- Tunnel.cpp | 28 ++++++++++++++++++++-------- Tunnel.h | 11 +++++++---- TunnelConfig.h | 5 +++++ TunnelPool.cpp | 21 +++++++++++++++------ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 961cc97e..478b57bc 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -768,6 +768,22 @@ namespace tunnel return newTunnel; } + std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + { + if (config->IsEmpty ()) + return CreateZeroHopsInboundTunnel (); + else + return CreateTunnel(config, outboundTunnel); + } + + std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config) + { + if (config->IsEmpty ()) + return CreateZeroHopsOutboundTunnel (); + else + return CreateTunnel(config); + } + void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { m_PendingInboundTunnels[replyMsgID] = tunnel; @@ -815,20 +831,22 @@ namespace tunnel } - void Tunnels::CreateZeroHopsInboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel () { auto inboundTunnel = std::make_shared (); inboundTunnel->SetState (eTunnelStateEstablished); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; + return inboundTunnel; } - void Tunnels::CreateZeroHopsOutboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel () { auto outboundTunnel = std::make_shared (); outboundTunnel->SetState (eTunnelStateEstablished); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels + return outboundTunnel; } int Tunnels::GetTransitTunnelsExpirationTimeout () @@ -861,12 +879,6 @@ namespace tunnel // TODO: locking return m_OutboundTunnels.size(); } - -#ifdef ANDROID_ARM7A - template std::shared_ptr Tunnels::CreateTunnel(std::shared_ptr, std::shared_ptr); - template std::shared_ptr Tunnels::CreateTunnel(std::shared_ptr, std::shared_ptr); -#endif - } } diff --git a/Tunnel.h b/Tunnel.h index 43417e5d..5bc8b195 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -176,10 +176,10 @@ namespace tunnel void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); + std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel); + std::shared_ptr CreateOutboundTunnel (std::shared_ptr config); void PostTunnelData (std::shared_ptr msg); void PostTunnelData (const std::vector >& msgs); - template - std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); std::shared_ptr CreateTunnelPool (int numInboundHops, @@ -189,6 +189,9 @@ namespace tunnel private: + template + std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); + template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); @@ -204,8 +207,8 @@ namespace tunnel void ManagePendingTunnels (PendingTunnels& pendingTunnels); void ManageTunnelPools (); - void CreateZeroHopsInboundTunnel (); - void CreateZeroHopsOutboundTunnel (); + std::shared_ptr CreateZeroHopsInboundTunnel (); + std::shared_ptr CreateZeroHopsOutboundTunnel (); private: diff --git a/TunnelConfig.h b/TunnelConfig.h index 0340254e..7546c9b2 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -159,6 +159,11 @@ namespace tunnel return num; } + bool IsEmpty () const + { + return !m_FirstHop; + } + virtual bool IsInbound () const { return m_FirstHop->isGateway; } virtual uint32_t GetTunnelID () const diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 5e7e8ec4..92e5f6ff 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -329,8 +329,9 @@ namespace tunnel bool TunnelPool::SelectPeers (std::vector >& peers, bool isInbound) { if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); - auto prevHop = i2p::context.GetSharedRouterInfo (); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; + if (numHops <= 0) return true; // peers is empty + auto prevHop = i2p::context.GetSharedRouterInfo (); if (i2p::transport::transports.GetNumPeers () > 25) { auto r = i2p::transport::transports.GetRandomPeer (); @@ -390,8 +391,10 @@ namespace tunnel if (SelectPeers (peers, true)) { std::reverse (peers.begin (), peers.end ()); - auto tunnel = tunnels.CreateTunnel (std::make_shared (peers), outboundTunnel); + auto tunnel = tunnels.CreateInboundTunnel (std::make_shared (peers), outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); + if (tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else LogPrint (eLogError, "Tunnels: Can't create inbound tunnel, no peers available"); @@ -403,8 +406,10 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); - auto newTunnel = tunnels.CreateTunnel (std::make_shared(tunnel->GetPeers ()), outboundTunnel); + auto newTunnel = tunnels.CreateInboundTunnel (std::make_shared(tunnel->GetPeers ()), outboundTunnel); newTunnel->SetTunnelPool (shared_from_this()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); } void TunnelPool::CreateOutboundTunnel () @@ -418,9 +423,11 @@ namespace tunnel std::vector > peers; if (SelectPeers (peers, false)) { - auto tunnel = tunnels.CreateTunnel ( + auto tunnel = tunnels.CreateOutboundTunnel ( std::make_shared (peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); tunnel->SetTunnelPool (shared_from_this ()); + if (tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); @@ -437,10 +444,12 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); - auto newTunnel = tunnels.CreateTunnel ( + auto newTunnel = tunnels.CreateOutboundTunnel ( std::make_shared (tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); newTunnel->SetTunnelPool (shared_from_this ()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); } else LogPrint (eLogDebug, "Tunnels: Can't re-create outbound tunnel, no inbound tunnels found"); @@ -449,7 +458,7 @@ namespace tunnel void TunnelPool::CreatePairedInboundTunnel (std::shared_ptr outboundTunnel) { LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); - auto tunnel = tunnels.CreateTunnel (std::make_shared(outboundTunnel->GetInvertedPeers ()), outboundTunnel); + auto tunnel = tunnels.CreateInboundTunnel (std::make_shared(outboundTunnel->GetInvertedPeers ()), outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); } } From c50105493a7df6cff760e0b12ed7cd6c2be4b8b0 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jun 2016 21:37:17 -0400 Subject: [PATCH 54/62] fixed zero-hops tunnels --- Destination.cpp | 4 ++-- Tunnel.cpp | 1 + TunnelPool.cpp | 29 +++++++++++++++++++++-------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index bb67b601..6cc24537 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -31,7 +31,7 @@ namespace client { int len = i2p::util::lexical_cast(it->second, inboundTunnelLen); - if (len > 0) + if (len >= 0) { inboundTunnelLen = len; } @@ -42,7 +42,7 @@ namespace client { int len = i2p::util::lexical_cast(it->second, outboundTunnelLen); - if (len > 0) + if (len >= 0) { outboundTunnelLen = len; } diff --git a/Tunnel.cpp b/Tunnel.cpp index 478b57bc..7983635a 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -217,6 +217,7 @@ namespace tunnel if (msg) { m_NumReceivedBytes += msg->GetLength (); + msg->from = shared_from_this (); HandleI2NPMessage (msg); } } diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 92e5f6ff..f922853f 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -390,8 +390,15 @@ namespace tunnel std::vector > peers; if (SelectPeers (peers, true)) { - std::reverse (peers.begin (), peers.end ()); - auto tunnel = tunnels.CreateInboundTunnel (std::make_shared (peers), outboundTunnel); + std::shared_ptr config; + if (m_NumInboundHops > 0) + { + std::reverse (peers.begin (), peers.end ()); + config = std::make_shared (peers); + } + else + config = std::make_shared (); + auto tunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); @@ -406,7 +413,9 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); - auto newTunnel = tunnels.CreateInboundTunnel (std::make_shared(tunnel->GetPeers ()), outboundTunnel); + std::shared_ptr config = m_NumInboundHops > 0 ? + std::make_shared(tunnel->GetPeers ()) : std::make_shared (); + auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); newTunnel->SetTunnelPool (shared_from_this()); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); @@ -423,8 +432,11 @@ namespace tunnel std::vector > peers; if (SelectPeers (peers, false)) { - auto tunnel = tunnels.CreateOutboundTunnel ( - std::make_shared (peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); + std::shared_ptr config = m_NumOutboundHops > 0 ? + std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) : + std::make_shared (); + + auto tunnel = tunnels.CreateOutboundTunnel (config); tunnel->SetTunnelPool (shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops TunnelCreated (tunnel); @@ -444,9 +456,10 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); - auto newTunnel = tunnels.CreateOutboundTunnel ( - std::make_shared (tunnel->GetPeers (), - inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); + std::shared_ptr config = m_NumOutboundHops > 0 ? + std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) : + std::make_shared (); + auto newTunnel = tunnels.CreateOutboundTunnel (config); newTunnel->SetTunnelPool (shared_from_this ()); if (newTunnel->IsEstablished ()) // zero hops TunnelCreated (newTunnel); From 79fbf9d47fe35afc03384ab85327e814416f5f02 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 30 Jun 2016 07:35:30 -0400 Subject: [PATCH 55/62] add RouterInfo hash to web ui --- HTTPServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index be3b9b58..9eed80d9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -58,6 +58,7 @@ namespace http { " .tunnel.another { color: #434343; }\r\n" " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" + " .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -205,6 +206,7 @@ namespace http { 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 << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64()<< "
\r\n"; s << "Our external address:" << "
\r\n" ; for (auto address : i2p::context.GetRouterInfo().GetAddresses()) { From 28ab1230e2a97f9693eac1d9d7f32681b7a9f9fd Mon Sep 17 00:00:00 2001 From: xcps Date: Thu, 30 Jun 2016 07:59:58 -0400 Subject: [PATCH 56/62] '@' can exist in url path --- HTTP.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HTTP.cpp b/HTTP.cpp index 31567bbd..7fd87c55 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -81,7 +81,8 @@ namespace http { } /* user[:pass] */ pos_c = url.find('@', pos_p); - if (pos_c != std::string::npos) { + std::size_t pos_slash = url.find('/', pos_p); + if (pos_c != std::string::npos && (pos_slash == std::string::npos || pos_slash > pos_c)) { std::size_t delim = url.find(':', pos_p); if (delim != std::string::npos && delim < pos_c) { user = url.substr(pos_p, delim - pos_p); @@ -90,7 +91,7 @@ namespace http { } else { user = url.substr(pos_p, pos_c - pos_p); } - pos_p = pos_c + 1; + pos_p = pos_c + 1; } /* hostname[:port][/path] */ pos_c = url.find_first_of(":/", pos_p); From ea1ba0f09b57eb1bf7ecae243b306ed6fe4e105a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jun 2016 10:21:53 -0400 Subject: [PATCH 57/62] don't flood to itself --- NetDb.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NetDb.cpp b/NetDb.cpp index 937ea830..d146c7d7 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -488,11 +488,15 @@ namespace data memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + payloadOffset, msgLen); floodMsg->FillI2NPMessageHeader (eI2NPDatabaseStore); std::set excluded; - for (int i = 0; i < 3; i++) + excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself + for (int i = 0; i < 3; i++) { auto floodfill = GetClosestFloodfill (ident, excluded); if (floodfill) + { transports.SendMessage (floodfill->GetIdentHash (), floodMsg); + excluded.insert (floodfill->GetIdentHash ()); + } else break; } From 6ab7e799872698614363685b7699552b3cd6bae3 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jun 2016 11:01:21 -0400 Subject: [PATCH 58/62] send own copy of a message during flood --- NetDb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetDb.cpp b/NetDb.cpp index d146c7d7..888e2e7f 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -494,7 +494,7 @@ namespace data auto floodfill = GetClosestFloodfill (ident, excluded); if (floodfill) { - transports.SendMessage (floodfill->GetIdentHash (), floodMsg); + transports.SendMessage (floodfill->GetIdentHash (), CopyI2NPMessage(floodMsg)); excluded.insert (floodfill->GetIdentHash ()); } else From 0493f00a7abd595729058548c192dd26ef2d247d Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jun 2016 12:24:26 -0400 Subject: [PATCH 59/62] pass null tunnel config for zero hops tunnel --- Tunnel.cpp | 12 ++++++------ TunnelPool.cpp | 19 ++++++++----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 7983635a..5da18542 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -771,18 +771,18 @@ namespace tunnel std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) { - if (config->IsEmpty ()) - return CreateZeroHopsInboundTunnel (); - else + if (config) return CreateTunnel(config, outboundTunnel); + else + return CreateZeroHopsInboundTunnel (); } std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config) { - if (config->IsEmpty ()) - return CreateZeroHopsOutboundTunnel (); - else + if (config) return CreateTunnel(config); + else + return CreateZeroHopsOutboundTunnel (); } void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) diff --git a/TunnelPool.cpp b/TunnelPool.cpp index f922853f..7024e1a1 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -396,8 +396,6 @@ namespace tunnel std::reverse (peers.begin (), peers.end ()); config = std::make_shared (peers); } - else - config = std::make_shared (); auto tunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops @@ -413,8 +411,8 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); - std::shared_ptr config = m_NumInboundHops > 0 ? - std::make_shared(tunnel->GetPeers ()) : std::make_shared (); + std::shared_ptr config; + if (m_NumInboundHops > 0) config = std::make_shared(tunnel->GetPeers ()); auto newTunnel = tunnels.CreateInboundTunnel (config, outboundTunnel); newTunnel->SetTunnelPool (shared_from_this()); if (newTunnel->IsEstablished ()) // zero hops @@ -432,10 +430,9 @@ namespace tunnel std::vector > peers; if (SelectPeers (peers, false)) { - std::shared_ptr config = m_NumOutboundHops > 0 ? - std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) : - std::make_shared (); - + std::shared_ptr config; + if (m_NumOutboundHops > 0) + config = std::make_shared(peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); auto tunnel = tunnels.CreateOutboundTunnel (config); tunnel->SetTunnelPool (shared_from_this ()); if (tunnel->IsEstablished ()) // zero hops @@ -456,9 +453,9 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); - std::shared_ptr config = m_NumOutboundHops > 0 ? - std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()) : - std::make_shared (); + std::shared_ptr config; + if (m_NumOutboundHops > 0) + config = std::make_shared(tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ()); auto newTunnel = tunnels.CreateOutboundTunnel (config); newTunnel->SetTunnelPool (shared_from_this ()); if (newTunnel->IsEstablished ()) // zero hops From eab08ea78caffe01831d9322c53fb420036c6689 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 30 Jun 2016 13:15:36 -0400 Subject: [PATCH 60/62] don't accept our own RouterInfo --- NetDb.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NetDb.cpp b/NetDb.cpp index 888e2e7f..1ecf646e 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -450,6 +450,12 @@ namespace data } offset += 32; } + // we must send reply back before this check + if (ident == i2p::context.GetIdentHash ()) + { + LogPrint (eLogError, "NetDb: database store with own RouterInfo received, dropped"); + return; + } size_t payloadOffset = offset; bool updated = false; @@ -489,6 +495,7 @@ namespace data floodMsg->FillI2NPMessageHeader (eI2NPDatabaseStore); std::set excluded; excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself + excluded.insert (ident); // don't flood back for (int i = 0; i < 3; i++) { auto floodfill = GetClosestFloodfill (ident, excluded); From ff7cf503ae37b62fb0811385ad69917cdebb5e64 Mon Sep 17 00:00:00 2001 From: MXPLRS|Kirill Date: Thu, 30 Jun 2016 21:21:37 +0300 Subject: [PATCH 61/62] added hiding information in webconsole --- HTTPServer.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 9eed80d9..cfcf4261 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -59,6 +59,8 @@ namespace http { " caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n" " table { width: 100%; border-collapse: collapse; text-align: center; }\r\n" " .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n" + " .slide p, .slide [type='checkbox']{ display:none; } \r\n" + " .slide [type='checkbox']:checked ~ p { display:block; } \r\n" "\r\n"; const char HTTP_PAGE_TUNNELS[] = "tunnels"; @@ -206,7 +208,10 @@ namespace http { 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 << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64()<< "
\r\n"; + s << "
\r\n\r\n

\r\n"; + s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n"; + s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n"; + s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n"; s << "Our external address:" << "
\r\n" ; for (auto address : i2p::context.GetRouterInfo().GetAddresses()) { @@ -229,6 +234,7 @@ namespace http { } s << address->host.to_string() << ":" << address->port << "
\r\n"; } + s << "

\r\n
\r\n"; s << "
\r\nRouters: " << i2p::data::netdb.GetNumRouters () << " "; s << "Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " "; s << "LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n"; From f62ccc2d480e967d640c830ca7ea69658ee0abc6 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 30 Jun 2016 13:35:36 -0400 Subject: [PATCH 62/62] off by one? --- NetDb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NetDb.cpp b/NetDb.cpp index 937ea830..9aa015f7 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -610,7 +610,7 @@ namespace data uint32_t replyTunnelID = 0; if (flag & DATABASE_LOOKUP_DELIVERY_FLAG) //reply to tunnel { - replyTunnelID = bufbe32toh (buf + 64); + replyTunnelID = bufbe32toh (buf + 65); excluded += 4; } uint16_t numExcluded = bufbe16toh (excluded);