From 7ea5af448efc18f5aef984bfda3bfe753e6686ff Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jun 2016 09:41:01 -0400 Subject: [PATCH 01/29] UPNP support from windows --- Makefile.mingw | 5 +++++ UPnP.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.mingw b/Makefile.mingw index 0390d66a..b859ebb3 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -32,6 +32,11 @@ ifeq ($(USE_WIN32_APP), yes) 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 diff --git a/UPnP.cpp b/UPnP.cpp index fea2ff9e..ea62998b 100644 --- a/UPnP.cpp +++ b/UPnP.cpp @@ -69,7 +69,7 @@ namespace transport #ifdef MAC_OSX m_Module = dlopen ("libminiupnpc.dylib", RTLD_LAZY); #elif _WIN32 - m_Module = LoadLibrary ("miniupnpc.dll"); // official prebuilt binary, e.g., in upnpc-exe-win32-20140422.zip + m_Module = LoadLibrary ("libminiupnpc.dll"); // from MSYS2 #else m_Module = dlopen ("libminiupnpc.so", RTLD_LAZY); #endif From ca55a9a8a68d9d69623b85a8f41c440d58dbe8ca Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jun 2016 10:53:29 -0400 Subject: [PATCH 02/29] build with UPnP --- docs/build_notes_windows.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/build_notes_windows.md b/docs/build_notes_windows.md index 921a6110..47ace84b 100644 --- a/docs/build_notes_windows.md +++ b/docs/build_notes_windows.md @@ -164,6 +164,11 @@ folder name included in downloaded archive. Note that you might need to build DLL yourself for 64-bit systems using msys2 as 64-bit DLLs are not provided by the project. +You can also install it through the MSYS2 +pacman -S mingw-w64-i686-miniupnpc +and build with USE_UPNP key +make USE_UPNP=1 +It requires libminiupnpc.dll from /mingw32/bin ### Creating Visual Studio project From c3dbbc9144af66ed09e451412cb2d5c4579626a9 Mon Sep 17 00:00:00 2001 From: MXPLRS | Kirill Date: Wed, 22 Jun 2016 18:04:11 +0300 Subject: [PATCH 03/29] Update build_notes_windows.md --- docs/build_notes_windows.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/build_notes_windows.md b/docs/build_notes_windows.md index 47ace84b..72da830f 100644 --- a/docs/build_notes_windows.md +++ b/docs/build_notes_windows.md @@ -164,10 +164,14 @@ folder name included in downloaded archive. Note that you might need to build DLL yourself for 64-bit systems using msys2 as 64-bit DLLs are not provided by the project. -You can also install it through the MSYS2 +You can also install it through the MSYS2 + +```bash pacman -S mingw-w64-i686-miniupnpc and build with USE_UPNP key make USE_UPNP=1 +``` + It requires libminiupnpc.dll from /mingw32/bin ### Creating Visual Studio project From 2b1e40c6c6f3cb137efc1d63c5db91448efa35aa Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jun 2016 11:15:40 -0400 Subject: [PATCH 04/29] Update build_notes_windows.md --- docs/build_notes_windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build_notes_windows.md b/docs/build_notes_windows.md index 72da830f..6290ccc2 100644 --- a/docs/build_notes_windows.md +++ b/docs/build_notes_windows.md @@ -165,10 +165,10 @@ Note that you might need to build DLL yourself for 64-bit systems using msys2 as 64-bit DLLs are not provided by the project. You can also install it through the MSYS2 +and build with USE_UPNP key. ```bash pacman -S mingw-w64-i686-miniupnpc -and build with USE_UPNP key make USE_UPNP=1 ``` From 49d28789381d541f2360273ac8fe474aa177a0fe Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 22 Jun 2016 15:48:36 -0400 Subject: [PATCH 05/29] 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 06/29] * 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 07/29] * 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 08/29] * 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 09/29] * 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 10/29] * 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 11/29] * 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 12/29] 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 13/29] 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 14/29] 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 15/29] 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 16/29] 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 17/29] 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 18/29] 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 19/29] 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 20/29] 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 21/29] 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 22/29] 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 23/29] 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 24/29] 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 25/29] 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 26/29] 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 27/29] 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 28/29] 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 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 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 29/29] 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