From 97afa502c52fde5c5b265884ae916050c2dd249d Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 2 Apr 2016 22:16:49 -0400 Subject: [PATCH 01/76] shard_ptr for SAMSession --- SAM.cpp | 36 ++++++++++++++++++++---------------- SAM.h | 8 ++++---- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index ecdd513d..dea3614e 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -47,19 +47,16 @@ namespace client break; case eSAMSocketTypeStream: { - if (m_Session) { + if (m_Session) m_Session->DelSocket (shared_from_this ()); - m_Session = nullptr; - } break; } case eSAMSocketTypeAcceptor: { if (m_Session) - { + { m_Session->DelSocket (shared_from_this ()); - m_Session->localDestination->StopAcceptingStreams (); - m_Session = nullptr; + m_Session->localDestination->StopAcceptingStreams (); } break; } @@ -68,6 +65,7 @@ namespace client } m_SocketType = eSAMSocketTypeTerminated; if (m_Socket.is_open()) m_Socket.close (); + m_Session = nullptr; } void SAMSocket::ReceiveHandshake () @@ -721,7 +719,7 @@ namespace client m_IsRunning = false; m_Acceptor.cancel (); for (auto it: m_Sessions) - delete it.second; + it.second->CloseStreams (); m_Sessions.clear (); m_Service.stop (); if (m_Thread) @@ -775,7 +773,7 @@ namespace client Accept (); } - SAMSession * SAMBridge::CreateSession (const std::string& id, const std::string& destination, + std::shared_ptr SAMBridge::CreateSession (const std::string& id, const std::string& destination, const std::map * params) { std::shared_ptr localDestination = nullptr; @@ -800,8 +798,9 @@ namespace client } if (localDestination) { + auto session = std::make_shared(localDestination); std::unique_lock l(m_SessionsMutex); - auto ret = m_Sessions.insert (std::pair(id, new SAMSession (localDestination))); + auto ret = m_Sessions.insert (std::make_pair(id, session)); if (!ret.second) LogPrint (eLogWarning, "SAM: Session ", id, " already exists"); return ret.first->second; @@ -811,19 +810,24 @@ namespace client void SAMBridge::CloseSession (const std::string& id) { - std::unique_lock l(m_SessionsMutex); - auto it = m_Sessions.find (id); - if (it != m_Sessions.end ()) + std::shared_ptr session; { - auto session = it->second; + std::unique_lock l(m_SessionsMutex); + auto it = m_Sessions.find (id); + if (it != m_Sessions.end ()) + { + session = it->second; + m_Sessions.erase (it); + } + } + if (session) + { session->localDestination->StopAcceptingStreams (); session->CloseStreams (); - m_Sessions.erase (it); - delete session; } } - SAMSession * SAMBridge::FindSession (const std::string& id) const + std::shared_ptr SAMBridge::FindSession (const std::string& id) const { std::unique_lock l(m_SessionsMutex); auto it = m_Sessions.find (id); diff --git a/SAM.h b/SAM.h index 4cdea686..ef36f285 100644 --- a/SAM.h +++ b/SAM.h @@ -128,7 +128,7 @@ namespace client std::string m_ID; // nickname bool m_IsSilent; std::shared_ptr m_Stream; - SAMSession * m_Session; + std::shared_ptr m_Session; }; struct SAMSession @@ -176,10 +176,10 @@ namespace client void Stop (); boost::asio::io_service& GetService () { return m_Service; }; - SAMSession * CreateSession (const std::string& id, const std::string& destination, // empty string means transient + std::shared_ptr CreateSession (const std::string& id, const std::string& destination, // empty string means transient const std::map * params); void CloseSession (const std::string& id); - SAMSession * FindSession (const std::string& id) const; + std::shared_ptr FindSession (const std::string& id) const; private: @@ -200,7 +200,7 @@ namespace client boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::socket m_DatagramSocket; mutable std::mutex m_SessionsMutex; - std::map m_Sessions; + std::map > m_Sessions; uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1]; public: From 941f30d1ea17c8bf63b856ee8d91e949804d11d7 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 4 Apr 2016 22:17:04 -0400 Subject: [PATCH 02/76] show streams from all streaming destinations --- Destination.cpp | 14 ++++++++++++++ Destination.h | 1 + HTTPServer.cpp | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index c53c4ee6..5893caff 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -780,5 +780,19 @@ namespace client } LogPrint(eLogError, "Destinations: Can't save keys to ", path); } + + std::vector > ClientDestination::GetAllStreams () const + { + std::vector > ret; + if (m_StreamingDestination) + { + for (auto& it: m_StreamingDestination->GetStreams ()) + ret.push_back (it.second); + } + for (auto& it: m_StreamingDestinationsByPorts) + for (auto& it1: it.second->GetStreams ()) + ret.push_back (it1.second); + return ret; + } } } diff --git a/Destination.h b/Destination.h index 44cb7424..3011b4cb 100644 --- a/Destination.h +++ b/Destination.h @@ -159,6 +159,7 @@ namespace client // for HTTP only int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; + std::vector > GetAllStreams () const; }; } } diff --git a/HTTPServer.cpp b/HTTPServer.cpp index f7efcba9..8db9d330 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -609,19 +609,19 @@ namespace util s << "Status"; s << ""; - for (auto it: dest->GetStreamingDestination ()->GetStreams ()) + for (auto it: dest->GetAllStreams ()) { s << ""; - s << "" << it.first << ""; - s << "" << i2p::client::context.GetAddressBook ().ToAddress(it.second->GetRemoteIdentity ()) << ""; - s << "" << it.second->GetNumSentBytes () << ""; - s << "" << it.second->GetNumReceivedBytes () << ""; - s << "" << it.second->GetSendQueueSize () << ""; - s << "" << it.second->GetReceiveQueueSize () << ""; - s << "" << it.second->GetSendBufferSize () << ""; - s << "" << it.second->GetRTT () << ""; - s << "" << it.second->GetWindowSize () << ""; - s << "" << (int)it.second->GetStatus () << ""; + s << "" << it->GetSendStreamID () << ""; + s << "" << i2p::client::context.GetAddressBook ().ToAddress(it->GetRemoteIdentity ()) << ""; + s << "" << it->GetNumSentBytes () << ""; + s << "" << it->GetNumReceivedBytes () << ""; + s << "" << it->GetSendQueueSize () << ""; + s << "" << it->GetReceiveQueueSize () << ""; + s << "" << it->GetSendBufferSize () << ""; + s << "" << it->GetRTT () << ""; + s << "" << it->GetWindowSize () << ""; + s << "" << (int)it->GetStatus () << ""; s << "
\r\n" << std::endl; } } From f412f4ca883dd69839e3df8299b937774c4d6644 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 03/76] * use commented i2pd.conf as default --- debian/i2pd.conf | 19 ------------------- debian/i2pd.install | 2 +- docs/i2pd.conf | 4 ++-- 3 files changed, 3 insertions(+), 22 deletions(-) delete mode 100644 debian/i2pd.conf diff --git a/debian/i2pd.conf b/debian/i2pd.conf deleted file mode 100644 index 4a518916..00000000 --- a/debian/i2pd.conf +++ /dev/null @@ -1,19 +0,0 @@ -ipv6 - -[httpproxy] -address = 127.0.0.1 -port = 4444 - -# other services (disabled by default) -# -#[sam] -#address = 127.0.0.1 -#port = 7656 -# -#[bob] -#address = 127.0.0.1 -#port = 2827 -# -#[i2pcontrol] -#address = 127.0.0.1 -#port = 7650 diff --git a/debian/i2pd.install b/debian/i2pd.install index f4e7e4f1..2e3c93cd 100644 --- a/debian/i2pd.install +++ b/debian/i2pd.install @@ -1,5 +1,5 @@ i2pd usr/sbin/ -debian/i2pd.conf etc/i2pd/ +docs/i2pd.conf etc/i2pd/ debian/tunnels.conf etc/i2pd/ debian/subscriptions.txt etc/i2pd/ contrib/certificates/ usr/share/i2pd/ diff --git a/docs/i2pd.conf b/docs/i2pd.conf index e85eaa17..d4ea226a 100644 --- a/docs/i2pd.conf +++ b/docs/i2pd.conf @@ -69,8 +69,8 @@ port = 7070 ## Uncomment and set to 'false' to disable HTTP Proxy # enabled = true ## Address and port service will listen on -# address = 127.0.0.1 -# port = 4444 +address = 127.0.0.1 +port = 4444 ## Optional keys file for proxy local destination # keys = http-proxy-keys.dat From cb8333a48f0441bf553ce70b8b8436d0a51659ff Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 04/76] * update manpage --- debian/i2pd.1 | 87 ++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/debian/i2pd.1 b/debian/i2pd.1 index 2a1e7f88..f61e243e 100644 --- a/debian/i2pd.1 +++ b/debian/i2pd.1 @@ -5,7 +5,7 @@ i2pd \- Load-balanced unspoofable packet switching network .SH SYNOPSIS .B i2pd -[\fIOPTION1\fR) [\fIOPTION2\fR]... +[\fIOPTION1\fR] [\fIOPTION2\fR]... .SH DESCRIPTION i2pd @@ -18,59 +18,58 @@ network is both distributed and dynamic, with no trusted parties. Any of the configuration options below can be used in the \fBDAEMON_ARGS\fR variable in \fI/etc/default/i2pd\fR. .BR .TP -\fB\-\-host=\fR -The external IP (deprecated) -.TP -\fB\-\-port=\fR -The external port to listen on +\fB\-\-help\fR +Show available options. .TP -\fB\-\-httpport=\fR -The HTTP port to listen on +\fB\-\-conf=\fR +Config file (default: \fI~/.i2pd/i2pd.conf\fR or \fI/var/lib/i2pd/i2pd.conf\fR) +.BR +This parameter will be silently ignored if the specified config file does not exist. +Options specified on the command line take precedence over those in the config file. .TP -\fB\-\-log=\fR[\fI1\fR|\fI0\fR] -.br -Enable of disable logging to a file. \fI1\fR for yes, \fI0\fR for no. (default: \fI0\fR, off) +\fB\-\-tunconf=\fR +Tunnels config file (default: \fI~/.i2pd/tunnels.conf\fR or \fI/var/lib/i2pd/tunnels.conf\fR) .TP -\fB\-\-daemon=\fR[\fI1\fR|\fI0\fR] -Enable or disable daemon mode. Daemon mode is enabled with \fI1\fR and disabled with \fI0\fR. (default: \fI0\fR, off) +\fB\-\-pidfile=\fR +Where to write pidfile (don\'t write by default) .TP -\fB\-\-service=\fR[\fI1\fR|\fI0\fR] -If enabled, system folders (\fB/var/run/i2pd.pid\fR, \fB/var/log/i2pd.log\fR, \fB/var/lib/i2pd\fR) will be used. If off, \fB$HOME/.i2pd\fR will be used instead. (default: \fI0\fR, off). +\fB\-\-log=\fR +Logs destination: \fIstdout\fR, \fIfile\fR, \fIsyslog\fR (\fIstdout\fR if not set, \fIfile\fR - otherwise, for compatibility) .TP -\fB\-\-unreachable=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if router is declared as unreachable and works through introducers. (default: \fI0\fR, off) +\fB\-\-loglevel=\fR +Log messages above this level (\fIdebug\fR, \fBinfo\fR, \fIwarn\fR, \fIerror\fR) .TP -\fB\-\-v6=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if \fBi2pd\fR should communicate via IPv6. (default: \fI0\fR, off) +\fB\-\-datadir=\fR +Path to storage of i2pd data (RI, keys, peer profiles, ...) .TP -\fB\-\-floodfill=\fR[\fI1\fR|\fI0\fR] -\fI1\fR if \fBi2pd\fR should become a floodfill. (default: \fI0\fR, off) +\fB\-\-host=\fR +The external IP address .TP -\fB\-\-bandwidth=\fR[\fI1\fR|\fI0\fR] -\fIL\fR if \fBi2pd\fR should be limited to 32KiB/s. Enabling floodfill will automatically set this to \fI0\fR (default: \fI0\fR, no limit) +\fB\-\-port=\fR +The port to listen on for incoming connections .TP -\fB\-\-httpproxyport=\fR -The local port for the HTTP Proxy to listen on (default: \fI4446\fR) +\fB\-\-daemon\fR +Router will go to background after start .TP -\fB\-\-socksproxyport=\fR -The local port for the SOCKS proxy to listen on (default: \fI4447\fR) +\fB\-\-service\fR +Router will use system folders like \fI/var/lib/i2pd\fR .TP -\fB\-\-proxykeys=\fR -An optional keys file for tunnel local destination (both HTTP and SOCKS) +\fB\-\-ipv6\fR +Enable communication through ipv6. false by default .TP -\fB\-\-samport=\fR -Port of SAM bridge. Usually \fI7656\fR. SAM will not be enabled if this is not set. (default: unset) +\fB\-\-notransit\fR +Router will not accept transit tunnels at startup .TP -\fB\-\-bobport=\fR -Port of BOB command channel. Usually \fI2827\fR. BOB will not be enabled if this is not set. (default: unset) +\fB\-\-floodfill\fR +Router will be floodfill .TP -\fB\-\-i2pcontrolport=\fR -Port of I2P control service. Usually \fI7650\fR. I2PControl will not be enabled if this is not set. (default: unset) +\fB\-\-bandwidth=\fR +Bandwidth limit: integer in KBps or letter aliases: \fIL (32KBps)\fR, O (256), P (2048), X (>9000) .TP -\fB\-\-conf=\fR -Config file (default: \fI~/.i2pd/i2pd.conf\fR or \fI/var/lib/i2pd/i2pd.conf\fR) -This parameter will be silently ignored if the specified config file does not exist. -Options specified on the command line take precedence over those in the config file. +\fB\-\-family=\fR +Name of a family, router belongs to. +.PP +See service-specific parameters in page \fIdocs/configuration.md\fR or in example config file \fIdocs/i2pd.conf\fR .SH FILES .PP @@ -82,10 +81,10 @@ i2pd configuration files (when running as a system service) .PP /var/lib/i2pd/ .RS 4 -i2pd profile directory (when running as a system service, see \fB\-\-service=\fR above) +i2pd profile directory (when running as a system service, see \fB\-\-service\fR above) .RE .PP -$HOME/.i2pd +$HOME/.i2pd/ .RS 4 i2pd profile directory (when running as a normal user) .RE @@ -95,7 +94,9 @@ i2pd profile directory (when running as a normal user) default I2P hosts file .SH AUTHOR This manual page was written by kytv for the Debian system (but may be used by others). -.BR +.PP +Updated by hagen in 2016. +.PP Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation .BR -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL +On Debian systems, the complete text of the GNU General Public License can be found in \fI/usr/share/common-licenses/GPL\fR From b5875f3a0a9ab0efe64e46e5f1e3b4ade2c89e2c Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 05/76] * update year in copyrights --- debian/copyright | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/copyright b/debian/copyright index 117fcffd..606d059b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,9 +3,9 @@ Upstream-Name: i2pd Source: https://github.com/PurpleI2P Files: * -Copyright: 2013-2015 PurpleI2P +Copyright: 2013-2016 PurpleI2P License: BSD-3-clause - Copyright (c) 2013-2015, The PurpleI2P Project + Copyright (c) 2013-2016, The PurpleI2P Project . All rights reserved. . @@ -34,7 +34,7 @@ License: BSD-3-clause SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Files: debian/* -Copyright: 2014-2015 hagen +Copyright: 2014-2016 hagen 2013-2015 Kill Your TV License: GPL-2.0+ This package is free software; you can redistribute it and/or modify From cc55335a8dc982dad2f951bcf5e025f9b76a5de2 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 06/76] * docs/configuration.md --- docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index f3e9f98c..ac5c4684 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -16,8 +16,8 @@ If you are upgrading your very old router (< 2.3.0) see also [this](config_opts_ * --logfile= - Path to logfile (default - autodetect) * --loglevel= - Log messages above this level (debug, *info, warn, error) * --datadir= - Path to storage of i2pd data (RI, keys, peer profiles, ...) -* --host= - The external IP -* --port= - The port to listen on +* --host= - Router external IP for incoming connections +* --port= - Port to listen for incoming connections (default: auto) * --daemon - Router will go to background after start * --service - Router will use system folders like '/var/lib/i2pd' * --ipv6 - Enable communication through ipv6. false by default From f63dd75f0876eb32c021041465108c31acda4748 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 07/76] * set bw limits thru i2pcontrol (#461) (experimental) --- I2PControl.cpp | 20 ++++++++++++++++++++ I2PControl.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/I2PControl.cpp b/I2PControl.cpp index 907fa2fd..1ef56c2d 100644 --- a/I2PControl.cpp +++ b/I2PControl.cpp @@ -83,6 +83,10 @@ namespace client m_RouterManagerHandlers["Reseed"] = &I2PControlService::ReseedHandler; m_RouterManagerHandlers["Shutdown"] = &I2PControlService::ShutdownHandler; m_RouterManagerHandlers["ShutdownGraceful"] = &I2PControlService::ShutdownGracefulHandler; + + // NetworkSetting + m_NetworkSettingHandlers["i2p.router.net.bw.in"] = &I2PControlService::InboundBandwidthLimit; + m_NetworkSettingHandlers["i2p.router.net.bw.out"] = &I2PControlService::OutboundBandwidthLimit; } I2PControlService::~I2PControlService () @@ -496,6 +500,22 @@ namespace client } } + void I2PControlService::InboundBandwidthLimit (const std::string& value, std::ostringstream& results) + { + if (value != "null") + i2p::context.SetBandwidth (std::atoi(value.c_str())); + int bw = i2p::context.GetBandwidthLimit(); + InsertParam (results, "i2p.router.net.bw.in", bw); + } + + void I2PControlService::OutboundBandwidthLimit (const std::string& value, std::ostringstream& results) + { + if (value != "null") + i2p::context.SetBandwidth (std::atoi(value.c_str())); + int bw = i2p::context.GetBandwidthLimit(); + InsertParam (results, "i2p.router.net.bw.out", bw); + } + // certificate void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path) { diff --git a/I2PControl.h b/I2PControl.h index 714d3aa5..728c9925 100644 --- a/I2PControl.h +++ b/I2PControl.h @@ -94,6 +94,8 @@ namespace client // NetworkSetting typedef void (I2PControlService::*NetworkSettingRequestHandler)(const std::string& value, std::ostringstream& results); + void InboundBandwidthLimit (const std::string& value, std::ostringstream& results); + void OutboundBandwidthLimit (const std::string& value, std::ostringstream& results); private: From 5f73f09836e04d83fd126cbf4c6b74925b7e0a71 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 5 Apr 2016 00:00:00 +0000 Subject: [PATCH 08/76] * RouterInfo::SaveToFile() now returns bool --- RouterInfo.cpp | 21 +++++++++++---------- RouterInfo.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/RouterInfo.cpp b/RouterInfo.cpp index dfd54059..8b12f591 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -514,19 +514,20 @@ namespace data m_BufferLen += privateKeys.GetPublic ()->GetSignatureLen (); } - void RouterInfo::SaveToFile (const std::string& fullPath) + bool RouterInfo::SaveToFile (const std::string& fullPath) { m_FullPath = fullPath; - if (m_Buffer) - { - std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); - if (f.is_open ()) - f.write ((char *)m_Buffer, m_BufferLen); - else - LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); - } - else + if (!m_Buffer) { LogPrint (eLogError, "RouterInfo: Can't save, m_Buffer == NULL"); + return false; + } + std::ofstream f (fullPath, std::ofstream::binary | std::ofstream::out); + if (!f.is_open ()) { + LogPrint(eLogError, "RouterInfo: Can't save to ", fullPath); + return false; + } + f.write ((char *)m_Buffer, m_BufferLen); + return true; } size_t RouterInfo::ReadString (char * str, std::istream& s) diff --git a/RouterInfo.h b/RouterInfo.h index 7648c6ba..c9881dd2 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -161,7 +161,7 @@ namespace data bool IsUpdated () const { return m_IsUpdated; }; void SetUpdated (bool updated) { m_IsUpdated = updated; }; - void SaveToFile (const std::string& fullPath); + bool SaveToFile (const std::string& fullPath); std::shared_ptr GetProfile () const; void SaveProfile () { if (m_Profile) m_Profile->Save (); }; From f48a7df80fc413e543822ddf20164488cd3d96e3 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Apr 2016 10:22:32 -0400 Subject: [PATCH 09/76] recreate router.info if missing or malformed --- RouterContext.cpp | 24 ++++++++++++++++-------- RouterInfo.cpp | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index e50681d9..f35d8426 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -356,16 +356,24 @@ namespace i2p delete[] buf; } - i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); // TODO m_RouterInfo.SetRouterIdentity (GetIdentity ()); - m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); - m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION); - m_RouterInfo.SetProperty ("router.version", I2P_VERSION); + i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); + if (!routerInfo.IsUnreachable ()) // router.info looks good + { + m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); + m_RouterInfo.SetProperty ("coreVersion", I2P_VERSION); + m_RouterInfo.SetProperty ("router.version", I2P_VERSION); + + // Migration to 0.9.24. TODO: remove later + m_RouterInfo.DeleteProperty ("coreVersion"); + m_RouterInfo.DeleteProperty ("stat_uptime"); + } + else + { + LogPrint (eLogError, ROUTER_INFO, " is malformed. Creating new"); + NewRouterInfo (); + } - // Migration to 0.9.24. TODO: remove later - m_RouterInfo.DeleteProperty ("coreVersion"); - m_RouterInfo.DeleteProperty ("stat_uptime"); - if (IsUnreachable ()) SetReachable (); // we assume reachable until we discover firewall through peer tests diff --git a/RouterInfo.cpp b/RouterInfo.cpp index dfd54059..9f590d74 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -104,6 +104,8 @@ namespace data { if (LoadFile ()) ReadFromBuffer (false); + else + m_IsUnreachable = true; } void RouterInfo::ReadFromBuffer (bool verifySignature) From 405aa906c5cffb3d7aba8da58ae7a28473806d6c Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Apr 2016 13:18:25 -0400 Subject: [PATCH 10/76] short exponent for non-x64 --- Crypto.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 8416a337..b42dafa6 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -200,8 +200,11 @@ namespace crypto ctx = BN_CTX_new (); // select random k BIGNUM * k = BN_new (); - BN_rand_range (k, elgp); - if (BN_is_zero (k)) BN_one (k); +#if defined(__x86_64__) + BN_rand (k, 2048, -1, 1); // full exponent for x64 +#else + BN_rand (k, 226, -1, 1); // short exponent of 226 bits +#endif // caulculate a a = BN_new (); BN_mod_exp (a, elgg, k, elgp, ctx); From 86572265945b6ef2ea2d5bb8e60765d47cf663b6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 15:49:46 -0400 Subject: [PATCH 11/76] use 226 bits private keys for non-x64 --- Crypto.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index b42dafa6..1dc8a2e5 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -146,6 +146,10 @@ namespace crypto } // DH/ElGamal + + const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; + const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg @@ -169,6 +173,10 @@ namespace crypto { if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; }; if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; }; +#if !defined(__x86_64__) // use short exponent for non x64 + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); +#endif DH_generate_key (m_DH); if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); @@ -201,9 +209,9 @@ namespace crypto // select random k BIGNUM * k = BN_new (); #if defined(__x86_64__) - BN_rand (k, 2048, -1, 1); // full exponent for x64 + BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 #else - BN_rand (k, 226, -1, 1); // short exponent of 226 bits + BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits #endif // caulculate a a = BN_new (); @@ -282,6 +290,14 @@ namespace crypto { #if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) RAND_bytes (priv, 256); +#else + // lower 226 bits (28 bytes and 2 bits) only. short exponent + auto numBytes = (ELGAMAL_SHORT_EXPONENT_NUM_BITS)/8 + 1; // 29 + auto numZeroBytes = 256 - numBytes; + RAND_bytes (priv + numZeroBytes, numBytes); + memset (priv, 0, numZeroBytes); + priv[numZeroBytes] &= 0x04; +#endif BN_CTX * ctx = BN_CTX_new (); BIGNUM * p = BN_new (); BN_bin2bn (priv, 256, p); @@ -289,11 +305,6 @@ namespace crypto bn2buf (p, pub, 256); BN_free (p); BN_CTX_free (ctx); -#else - DHKeys dh; - dh.GenerateKeys (priv, pub); - -#endif } // HMAC From 380c7b7720bb00aaa6670541462660fb0323b568 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 16:11:18 -0400 Subject: [PATCH 12/76] use 226 bits private keys for non-x64 --- Crypto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Crypto.cpp b/Crypto.cpp index 1dc8a2e5..0ec0f020 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -296,7 +296,7 @@ namespace crypto auto numZeroBytes = 256 - numBytes; RAND_bytes (priv + numZeroBytes, numBytes); memset (priv, 0, numZeroBytes); - priv[numZeroBytes] &= 0x04; + priv[numZeroBytes] &= 0x03; #endif BN_CTX * ctx = BN_CTX_new (); BIGNUM * p = BN_new (); From afe2935c9db67d62b1dd6e2694db9ac8e1f7fa52 Mon Sep 17 00:00:00 2001 From: xcps Date: Wed, 6 Apr 2016 16:33:23 -0400 Subject: [PATCH 13/76] webconsole update --- HTTPServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8db9d330..06fabc31 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -777,20 +777,20 @@ namespace util s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) { - s << it.second->GetName () << " ⇐ "; auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; + s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); - s << "
\r\n"<< std::endl; + s << "
\r\n"<< std::endl; } s << "
\r\nServer Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetServerTunnels ()) { - s << it.second->GetName () << " ⇒ "; auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); s << ""; + s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); s << "
\r\n"<< std::endl; From 2ebb2d8f0e7ec783e188645a96c4d252c60b671e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 6 Apr 2016 21:02:58 -0400 Subject: [PATCH 14/76] fixed race condition --- Identity.cpp | 26 +++++++++++++++++--------- Identity.h | 1 + 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index 0ca9567a..f221dd04 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -311,18 +311,18 @@ namespace data switch (keyType) { case SIGNING_KEY_TYPE_DSA_SHA1: - m_Verifier.reset (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); + UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey)); break; case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: { size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64 - m_Verifier.reset (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA384_P384: { size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96 - m_Verifier.reset (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_ECDSA_SHA512_P521: @@ -331,7 +331,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto::ECDSAP521Verifier (signingKey)); + UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA256_2048: @@ -340,7 +340,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA384_3072: @@ -349,7 +349,7 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_RSA_SHA512_4096: @@ -358,20 +358,28 @@ namespace data memcpy (signingKey, m_StandardIdentity.signingKey, 128); size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128 memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - m_Verifier.reset (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); + UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); break; } case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 - m_Verifier.reset (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding)); break; } default: LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported"); } } - + + void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const + { + if (!m_Verifier || !verifier) + m_Verifier.reset (verifier); + else + delete verifier; + } + void IdentityEx::DropVerifier () const { // TODO: potential race condition with Verify diff --git a/Identity.h b/Identity.h index 27da190d..d8abd6f4 100644 --- a/Identity.h +++ b/Identity.h @@ -95,6 +95,7 @@ namespace data private: void CreateVerifier () const; + void UpdateVerifier (i2p::crypto::Verifier * verifier) const; private: From c45aab7cefb75ee5b7f3802bd0b3a0b9a317a791 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 8 Apr 2016 15:45:23 -0400 Subject: [PATCH 15/76] precalculate g^x mod p table --- Crypto.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Crypto.cpp b/Crypto.cpp index 0ec0f020..9858d6fd 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -153,6 +153,32 @@ namespace crypto #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg + void PrecalculateElggTable (BIGNUM * table[][256], int len) // table is len's array of array of 256 bignums + { + if (len <= 0) return; + BN_CTX * ctx = BN_CTX_new (); + BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (montCtx, elgp, ctx); + BIGNUM * elggMont = BN_new (); + BN_from_montgomery(elggMont, elgg, montCtx, ctx); + for (int i = 0; i < len; i++) + { + table[i][0] = BN_new (); + if (!i) + BN_from_montgomery (table[0][0], BN_value_one (), montCtx, ctx); // 2^0 = 1 + else + BN_mod_mul_montgomery (table[i][0], table[i-1][255], elggMont, montCtx, ctx); + for (int j = 1; j < 256; j++) + { + table[i][j] = BN_new (); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], elggMont, montCtx, ctx); + } + } + BN_free (elggMont); + BN_MONT_CTX_free (montCtx); + BN_CTX_free (ctx); + } + // DH DHKeys::DHKeys (): m_IsUpdated (true) From ffc666eaaa5390019809f957412427b4d740f8e6 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 9 Apr 2016 22:44:13 -0400 Subject: [PATCH 16/76] g^x mod p using precalculated table --- Crypto.cpp | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 9858d6fd..6891e776 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -153,32 +153,62 @@ namespace crypto #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg - void PrecalculateElggTable (BIGNUM * table[][256], int len) // table is len's array of array of 256 bignums + void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); - BIGNUM * elggMont = BN_new (); - BN_from_montgomery(elggMont, elgg, montCtx, ctx); + BN_MONT_CTX_set (montCtx, elgp, ctx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_from_montgomery (table[0][0], BN_value_one (), montCtx, ctx); // 2^0 = 1 + BN_to_montgomery (table[0][0], elgg, montCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][255], elggMont, montCtx, ctx); - for (int j = 1; j < 256; j++) + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); + for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], elggMont, montCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); } } - BN_free (elggMont); BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } + BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) + // exp is in Big Endian + { + if (len <= 0) return nullptr; + BIGNUM * res = nullptr; + BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (montCtx, elgp, ctx); + for (int i = 0; i < len; i++) + { + if (res) + { + if (exp[i]) + BN_mod_mul_montgomery (res, res, table[len-1-i][exp[i]-1], montCtx, ctx); + } + else if (exp[i]) + res = BN_dup (table[len-i-1][exp[i]-1]); + } + if (res) + BN_from_montgomery (res, res, montCtx, ctx); + BN_MONT_CTX_free (montCtx); + return res; + } + + BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) + { + auto len = BN_num_bytes (exp); + uint8_t * buf = new uint8_t[len]; + BN_bn2bin (exp, buf); + auto ret = ElggPow (buf, len, table, ctx); + delete[] buf; + return ret; + } + // DH DHKeys::DHKeys (): m_IsUpdated (true) From 34a8d4a57d8d6cccf0fc6f40999f74b57eb30f2f Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Apr 2016 17:06:02 -0400 Subject: [PATCH 17/76] use precalculated table for ElGamal encryption --- Crypto.cpp | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 6891e776..0523f55f 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -148,12 +148,15 @@ namespace crypto // DH/ElGamal const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; + const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg - void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums +#if !defined(__x86_64__) // use precalculated table + + static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); @@ -176,7 +179,17 @@ namespace crypto BN_CTX_free (ctx); } - BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) + static void DestroyElggTable (BIGNUM * table[][255], int len) + { + for (int i = 0; i < len; i++) + for (int j = 0; j < 255; j++) + { + BN_free (table[i][j]); + table[i][j] = nullptr; + } + } + + static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) // exp is in Big Endian { if (len <= 0) return nullptr; @@ -199,7 +212,7 @@ namespace crypto return res; } - BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) + static BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx) { auto len = BN_num_bytes (exp); uint8_t * buf = new uint8_t[len]; @@ -208,6 +221,10 @@ namespace crypto delete[] buf; return ret; } + + BIGNUM * g_ElggTable[ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; + +#endif // DH @@ -229,9 +246,9 @@ namespace crypto { if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; }; if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; }; -#if !defined(__x86_64__) // use short exponent for non x64 +#if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); - BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); + BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); #endif DH_generate_key (m_DH); if (priv) bn2buf (m_DH->priv_key, priv, 256); @@ -266,12 +283,14 @@ namespace crypto BIGNUM * k = BN_new (); #if defined(__x86_64__) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 + // calculate a + a = BN_new (); + BN_mod_exp (a, elgg, k, elgp, ctx); #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits + // calculate a + a = ElggPow (k, g_ElggTable, ctx); #endif - // caulculate a - a = BN_new (); - BN_mod_exp (a, elgg, k, elgp, ctx); BIGNUM * y = BN_new (); BN_bin2bn (key, 256, y); // calculate b1 @@ -772,10 +791,16 @@ namespace crypto for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); CRYPTO_set_locking_callback (OpensslLockingCallback);*/ +#if !defined(__x86_64__) + PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); +#endif } void TerminateCrypto () { +#if !defined(__x86_64__) + DestroyElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); +#endif /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } From 6a9d2ba653e1f99e4591908bed5f01c2baaeb4a0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 10 Apr 2016 21:16:18 -0400 Subject: [PATCH 18/76] use precalculated table for DH --- Crypto.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index 0523f55f..fbd3e139 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -155,27 +155,27 @@ namespace crypto #define elgg GetCryptoConstants ().elgg #if !defined(__x86_64__) // use precalculated table - + + static BN_MONT_CTX * g_MontCtx = nullptr; static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { if (len <= 0) return; BN_CTX * ctx = BN_CTX_new (); - BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); + g_MontCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_set (g_MontCtx, elgp, ctx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_to_montgomery (table[0][0], elgg, montCtx, ctx); + BN_to_montgomery (table[0][0], elgg, g_MontCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], g_MontCtx, ctx); for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], g_MontCtx, ctx); } } - BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } @@ -187,15 +187,16 @@ namespace crypto BN_free (table[i][j]); table[i][j] = nullptr; } + BN_MONT_CTX_free (g_MontCtx); } static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx) // exp is in Big Endian { if (len <= 0) return nullptr; + auto montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_copy (montCtx, g_MontCtx); BIGNUM * res = nullptr; - BN_MONT_CTX * montCtx = BN_MONT_CTX_new (); - BN_MONT_CTX_set (montCtx, elgp, ctx); for (int i = 0; i < len; i++) { if (res) @@ -249,8 +250,12 @@ namespace crypto #if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); -#endif + auto ctx = BN_CTX_new (); + m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); + BN_CTX_free (ctx); +#else DH_generate_key (m_DH); +#endif if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); m_IsUpdated = true; From 6336d38a3ea14bafdb5d34f36b9dd2cd80838aa5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 11 Apr 2016 12:04:15 -0400 Subject: [PATCH 19/76] Removed downloads. Added Docimentation --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4f167754..b985abf4 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,11 @@ Donations BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59 ANC: AQJYweYYUqM1nVfLqfoSMpUMfzxvS4Xd7z +DOGE: DNXLQKziRPAsD9H3DFNjk4fLQrdaSX893Y -Downloads ------------- - -Official binary releases could be found at: -http://i2pd.website/releases/ -older releases -http://download.i2p.io/purplei2p/i2pd/releases/ +Documentation: +-------------- +http://i2pd.readthedocs.org Supported OS ------------ From d15cc7cc4766e766fe56b3f41b4ea9817a0cfeaa Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 11 Apr 2016 12:39:32 -0400 Subject: [PATCH 20/76] changed tray icon back to ictoopie --- Win32/Resource.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Win32/Resource.rc b/Win32/Resource.rc index bdc532e9..c885c044 100644 --- a/Win32/Resource.rc +++ b/Win32/Resource.rc @@ -52,8 +52,8 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -//MAINICON ICON "ictoopie.ico" -MAINICON ICON "anke.ico" +MAINICON ICON "ictoopie.ico" +//MAINICON ICON "anke.ico" MASCOT BITMAP "Anke_700px.bmp" From c0b0df34d2817034b4775b6626198a966f543432 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 12 Apr 2016 19:07:11 -0400 Subject: [PATCH 21/76] clean montgomery context --- Crypto.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Crypto.cpp b/Crypto.cpp index fbd3e139..fe6dfa8f 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -163,19 +163,22 @@ namespace crypto BN_CTX * ctx = BN_CTX_new (); g_MontCtx = BN_MONT_CTX_new (); BN_MONT_CTX_set (g_MontCtx, elgp, ctx); + auto montCtx = BN_MONT_CTX_new (); + BN_MONT_CTX_copy (montCtx, g_MontCtx); for (int i = 0; i < len; i++) { table[i][0] = BN_new (); if (!i) - BN_to_montgomery (table[0][0], elgg, g_MontCtx, ctx); + BN_to_montgomery (table[0][0], elgg, montCtx, ctx); else - BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], g_MontCtx, ctx); + BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx); for (int j = 1; j < 255; j++) { table[i][j] = BN_new (); - BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], g_MontCtx, ctx); + BN_mod_mul_montgomery (table[i][j], table[i][j-1], table[i][0], montCtx, ctx); } } + BN_MONT_CTX_free (montCtx); BN_CTX_free (ctx); } From ef106f3232ed1bb99994c61e7b10edb1a3e0870a Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 13 Apr 2016 11:22:08 -0400 Subject: [PATCH 22/76] fixed typo --- TunnelEndpoint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TunnelEndpoint.cpp b/TunnelEndpoint.cpp index a3907ce5..842b624f 100644 --- a/TunnelEndpoint.cpp +++ b/TunnelEndpoint.cpp @@ -119,7 +119,7 @@ namespace tunnel if (ret.second) HandleOutOfSequenceFragment (msgID, ret.first->second); else - LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, "already exists"); + LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists"); } else { From a4773d259da5d61c39ea1539d61634e0a2a02b6f Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 23/76] * use std::to_string() instead boost's function --- HTTPServer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 06fabc31..7a15eaa4 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "Base.h" #include "FS.h" @@ -911,7 +910,7 @@ namespace util m_Reply.headers[0].name = "Date"; m_Reply.headers[0].value = std::string(time_buff); m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = boost::lexical_cast(m_Reply.content.size()); + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); m_Reply.headers[2].name = "Content-Type"; m_Reply.headers[2].value = "text/html"; } From 5d38693b4dd7456b0e88c63f4f907db75e3ec526 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 24/76] * HTTPServer : fold namespace to two constants --- HTTPServer.cpp | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7a15eaa4..86808e25 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -23,7 +23,6 @@ namespace i2p { namespace util { - const std::string HTTPConnection::itoopieImage = "\"ICToopie HTTPConnection::reply::to_buffers(int status) { std::vector buffers; @@ -236,17 +228,17 @@ namespace util default: status_string += "WTF"; } buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); for (std::size_t i = 0; i < headers.size(); ++i) { header& h = headers[i]; buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); + buffers.push_back(boost::asio::buffer(HTTP_HEADER_KV_SEP)); buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); } - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + buffers.push_back(boost::asio::buffer(HTTP_CRLF)); } buffers.push_back(boost::asio::buffer(content)); return buffers; @@ -977,6 +969,3 @@ namespace util } } } - - - From a5c0b48b575f99a648885bd85b960092cf7d5877 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 25/76] * HandleDestinationRequestTimeout() : readable code --- HTTPServer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 86808e25..2d69ae7a 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -846,11 +846,13 @@ namespace util if (ecode != boost::asio::error::operation_aborted) { auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination); - if (leaseSet && !leaseSet->IsExpired ()) + if (leaseSet && !leaseSet->IsExpired ()) { SendToDestination (leaseSet, port, buf, len); - else - // still no LeaseSet - SendReply (leaseSet ? "" + itoopieImage + "
\r\nLeases expired" : "" + itoopieImage + "LeaseSet not found", 504); + } else if (leaseSet) { + SendReply ("" + itoopieImage + "
\r\nLeaseSet expired", 504); + } else { + SendReply ("" + itoopieImage + "
\r\nLeaseSet not found", 504); + } } } From 87dd890eb054aabee7e6082d9dc50c91180b95d0 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 26/76] * HTTPConnection::reply : to_buffers() -> to_string() --- HTTPServer.cpp | 49 ++++++++++++++++++++----------------------------- HTTPServer.h | 2 +- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 2d69ae7a..4b426aa9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -206,42 +206,33 @@ namespace util const char HTTP_HEADER_KV_SEP[] = ": "; const char HTTP_CRLF[] = "\r\n"; - std::vector HTTPConnection::reply::to_buffers(int status) + std::string HTTPConnection::reply::to_string(int code) { - std::vector buffers; + std::stringstream ss(""); if (headers.size () > 0) { - status_string = "HTTP/1.1 "; - status_string += std::to_string (status); - status_string += " "; - switch (status) + const char *status; + switch (code) { - case 105: status_string += "Name Not Resolved"; break; - case 200: status_string += "OK"; break; - case 400: status_string += "Bad Request"; break; - case 404: status_string += "Not Found"; break; - case 408: status_string += "Request Timeout"; break; - case 500: status_string += "Internal Server Error"; break; - case 502: status_string += "Bad Gateway"; break; - case 503: status_string += "Not Implemented"; break; - case 504: status_string += "Gateway Timeout"; break; - default: status_string += "WTF"; + case 105: status = "Name Not Resolved"; break; + case 200: status = "OK"; break; + case 400: status = "Bad Request"; break; + case 404: status = "Not Found"; break; + case 408: status = "Request Timeout"; break; + case 500: status = "Internal Server Error"; break; + case 502: status = "Bad Gateway"; break; + case 503: status = "Not Implemented"; break; + case 504: status = "Gateway Timeout"; break; + default: status = "WTF"; } - buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); - - for (std::size_t i = 0; i < headers.size(); ++i) - { - header& h = headers[i]; - buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(HTTP_HEADER_KV_SEP)); - buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); + ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; + for (header & h : headers) { + ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; } - buffers.push_back(boost::asio::buffer(HTTP_CRLF)); + ss << HTTP_CRLF; /* end of headers */ } - buffers.push_back(boost::asio::buffer(content)); - return buffers; + ss << content; + return ss.str(); } void HTTPConnection::Terminate () diff --git a/HTTPServer.h b/HTTPServer.h index f70e27dc..8dd40dea 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -40,7 +40,7 @@ namespace util { std::vector
headers; std::string status_string, content; - std::vector to_buffers (int status); + std::string to_string (int status); }; public: From 04bfd52fba8107bec4c5438c2bfc649f96ced768 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 27/76] * HTTPConnection::SendReply() : cleaner code --- HTTPServer.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 4b426aa9..b54f55e8 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -885,22 +885,23 @@ namespace util void HTTPConnection::SendReply (const std::string& content, int status) { - m_Reply.content = content; + // we need the date header to be complaint with http 1.1 + std::time_t time_now = std::time(nullptr); + char time_buff[128]; + std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); + /* fill reply with headers */ m_Reply.headers.resize(3); - // we need the date header to be complaint with http 1.1 - std::time_t time_now = std::time(nullptr); - char time_buff[128]; - if (std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now))) - { - m_Reply.headers[0].name = "Date"; - m_Reply.headers[0].value = std::string(time_buff); - m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); - m_Reply.headers[2].name = "Content-Type"; - m_Reply.headers[2].value = "text/html"; - } - - boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), + m_Reply.headers[0].name = "Date"; + m_Reply.headers[0].value = std::string(time_buff); + m_Reply.headers[1].name = "Content-Length"; + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); + m_Reply.headers[2].name = "Content-Type"; + m_Reply.headers[2].value = "text/html"; + + std::vector buffers; + buffers.push_back(boost::asio::buffer(m_Reply.to_string(status))); + buffers.push_back(boost::asio::buffer(content)); + boost::asio::async_write (*m_Socket, buffers, std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } From 3f9d2601b41a95e4630e2e538602503a8e76a726 Mon Sep 17 00:00:00 2001 From: hagen Date: Thu, 14 Apr 2016 00:00:00 +0000 Subject: [PATCH 28/76] + HTTPConnection::SendError() --- HTTPServer.cpp | 13 +++++++++---- HTTPServer.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index b54f55e8..66506908 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -813,7 +813,7 @@ namespace util if (!i2p::client::context.GetAddressBook ().GetIdentHash (address, destination)) { LogPrint (eLogWarning, "HTTPServer: Unknown address ", address); - SendReply ("" + itoopieImage + "
\r\nUnknown address " + address + "", 404); + SendError ("Unknown address " + address); return; } @@ -840,9 +840,9 @@ namespace util if (leaseSet && !leaseSet->IsExpired ()) { SendToDestination (leaseSet, port, buf, len); } else if (leaseSet) { - SendReply ("" + itoopieImage + "
\r\nLeaseSet expired", 504); + SendError ("LeaseSet expired"); } else { - SendReply ("" + itoopieImage + "
\r\nLeaseSet not found", 504); + SendError ("LeaseSet not found"); } } } @@ -877,7 +877,7 @@ namespace util else { if (ecode == boost::asio::error::timed_out) - SendReply ("" + itoopieImage + "
\r\nNot responding", 504); + SendError ("Host not responding"); else if (ecode != boost::asio::error::operation_aborted) Terminate (); } @@ -905,6 +905,11 @@ namespace util std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } + void HTTPConnection::SendError(const std::string& content) + { + SendReply ("" + itoopieImage + "
\r\n" + content + "", 504); + } + HTTPServer::HTTPServer (const std::string& address, int port): m_Thread (nullptr), m_Work (m_Service), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)) diff --git a/HTTPServer.h b/HTTPServer.h index 8dd40dea..d5cef8ad 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -59,6 +59,7 @@ namespace util void HandleWriteReply(const boost::system::error_code& ecode); void HandleWrite (const boost::system::error_code& ecode); void SendReply (const std::string& content, int status = 200); + void SendError (const std::string& message); void HandleRequest (const std::string& address); void HandleCommand (const std::string& command, std::stringstream& s); From bce2a63772532d15de617c059f24bbe86c333cbf Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 14 Apr 2016 14:05:25 -0400 Subject: [PATCH 29/76] rollback some changes --- HTTPServer.cpp | 90 +++++++++++++++++++++++++++++--------------------- HTTPServer.h | 2 +- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 66506908..6c2c6112 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -203,36 +203,51 @@ namespace util const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels"; const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices="; const char HTTP_PARAM_ADDRESS[] = "address"; - const char HTTP_HEADER_KV_SEP[] = ": "; - const char HTTP_CRLF[] = "\r\n"; - std::string HTTPConnection::reply::to_string(int code) + namespace misc_strings { - std::stringstream ss(""); + + const char name_value_separator[] = { ':', ' ' }; + const char crlf[] = { '\r', '\n' }; + + } // namespace misc_strings + + std::vector HTTPConnection::reply::to_buffers(int status) + { + std::vector buffers; if (headers.size () > 0) { - const char *status; - switch (code) + status_string = "HTTP/1.1 "; + status_string += std::to_string (status); + status_string += " "; + switch (status) { - case 105: status = "Name Not Resolved"; break; - case 200: status = "OK"; break; - case 400: status = "Bad Request"; break; - case 404: status = "Not Found"; break; - case 408: status = "Request Timeout"; break; - case 500: status = "Internal Server Error"; break; - case 502: status = "Bad Gateway"; break; - case 503: status = "Not Implemented"; break; - case 504: status = "Gateway Timeout"; break; - default: status = "WTF"; + case 105: status_string += "Name Not Resolved"; break; + case 200: status_string += "OK"; break; + case 400: status_string += "Bad Request"; break; + case 404: status_string += "Not Found"; break; + case 408: status_string += "Request Timeout"; break; + case 500: status_string += "Internal Server Error"; break; + case 502: status_string += "Bad Gateway"; break; + case 503: status_string += "Not Implemented"; break; + case 504: status_string += "Gateway Timeout"; break; + default: status_string += "WTF"; } - ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; - for (header & h : headers) { - ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; + buffers.push_back(boost::asio::buffer(status_string, status_string.size())); + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); + + for (std::size_t i = 0; i < headers.size(); ++i) + { + header& h = headers[i]; + buffers.push_back(boost::asio::buffer(h.name)); + buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); + buffers.push_back(boost::asio::buffer(h.value)); + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } - ss << HTTP_CRLF; /* end of headers */ + buffers.push_back(boost::asio::buffer(misc_strings::crlf)); } - ss << content; - return ss.str(); + buffers.push_back(boost::asio::buffer(content)); + return buffers; } void HTTPConnection::Terminate () @@ -885,23 +900,22 @@ namespace util void HTTPConnection::SendReply (const std::string& content, int status) { - // we need the date header to be complaint with http 1.1 - std::time_t time_now = std::time(nullptr); - char time_buff[128]; - std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); - /* fill reply with headers */ + m_Reply.content = content; m_Reply.headers.resize(3); - m_Reply.headers[0].name = "Date"; - m_Reply.headers[0].value = std::string(time_buff); - m_Reply.headers[1].name = "Content-Length"; - m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); - m_Reply.headers[2].name = "Content-Type"; - m_Reply.headers[2].value = "text/html"; - - std::vector buffers; - buffers.push_back(boost::asio::buffer(m_Reply.to_string(status))); - buffers.push_back(boost::asio::buffer(content)); - boost::asio::async_write (*m_Socket, buffers, + // we need the date header to be complaint with http 1.1 + std::time_t time_now = std::time(nullptr); + char time_buff[128]; + if (std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now))) + { + m_Reply.headers[0].name = "Date"; + m_Reply.headers[0].value = std::string(time_buff); + m_Reply.headers[1].name = "Content-Length"; + m_Reply.headers[1].value = std::to_string(m_Reply.content.size()); + m_Reply.headers[2].name = "Content-Type"; + m_Reply.headers[2].value = "text/html"; + } + + boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } diff --git a/HTTPServer.h b/HTTPServer.h index d5cef8ad..66083d85 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -40,7 +40,7 @@ namespace util { std::vector
headers; std::string status_string, content; - std::string to_string (int status); + std::vector to_buffers (int status); }; public: From aff8cd478c6318dadf594acf9cfe408c869e108c Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Apr 2016 16:57:58 -0400 Subject: [PATCH 30/76] optional elgamal precomputation for x64 --- Config.cpp | 12 ++++++++++ Crypto.cpp | 65 ++++++++++++++++++++++++++++++++++++------------------ Crypto.h | 2 +- Daemon.cpp | 3 ++- api.cpp | 6 ++++- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/Config.cpp b/Config.cpp index 8d42895a..d5ff2a46 100644 --- a/Config.cpp +++ b/Config.cpp @@ -180,6 +180,17 @@ namespace config { ("i2pcontrol.key", value()->default_value("i2pcontrol.key.pem"), "I2PCP connection cerificate key") ; + options_description precomputation("Precomputation options"); + precomputation.add_options() + ("precomputation.elgamal", +#if defined(__x86_64__) + value()->default_value(false), +#else + value()->default_value(true), +#endif + "Enable or disable elgamal precomputation table") + ; + m_OptionsDesc .add(general) .add(httpserver) @@ -188,6 +199,7 @@ namespace config { .add(sam) .add(bob) .add(i2pcontrol) + .add(precomputation) ; } diff --git a/Crypto.cpp b/Crypto.cpp index fe6dfa8f..f7c00595 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -150,12 +150,11 @@ namespace crypto const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226; const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1; const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048; - + const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8; + #define elgp GetCryptoConstants ().elgp #define elgg GetCryptoConstants ().elgg -#if !defined(__x86_64__) // use precalculated table - static BN_MONT_CTX * g_MontCtx = nullptr; static void PrecalculateElggTable (BIGNUM * table[][255], int len) // table is len's array of array of 255 bignums { @@ -226,9 +225,7 @@ namespace crypto return ret; } - BIGNUM * g_ElggTable[ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; - -#endif + static BIGNUM * (* g_ElggTable)[255] = nullptr; // DH @@ -253,12 +250,20 @@ namespace crypto #if !defined(__x86_64__) // use short exponent for non x64 m_DH->priv_key = BN_new (); BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1); - auto ctx = BN_CTX_new (); - m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); - BN_CTX_free (ctx); -#else - DH_generate_key (m_DH); #endif + if (g_ElggTable) + { +#if defined(__x86_64__) + m_DH->priv_key = BN_new (); + BN_rand (m_DH->priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1); +#endif + auto ctx = BN_CTX_new (); + m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx); + BN_CTX_free (ctx); + } + else + DH_generate_key (m_DH); + if (priv) bn2buf (m_DH->priv_key, priv, 256); if (pub) bn2buf (m_DH->pub_key, pub, 256); m_IsUpdated = true; @@ -291,14 +296,16 @@ namespace crypto BIGNUM * k = BN_new (); #if defined(__x86_64__) BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64 - // calculate a - a = BN_new (); - BN_mod_exp (a, elgg, k, elgp, ctx); #else BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits +#endif // calculate a - a = ElggPow (k, g_ElggTable, ctx); -#endif + a = BN_new (); + if (g_ElggTable) + a = ElggPow (k, g_ElggTable, ctx); + else + BN_mod_exp (a, elgg, k, elgp, ctx); + BIGNUM * y = BN_new (); BN_bin2bn (key, 256, y); // calculate b1 @@ -792,23 +799,37 @@ namespace crypto } }*/ - void InitCrypto () + void InitCrypto (bool precomputation) { SSL_library_init (); /* auto numLocks = CRYPTO_num_locks(); for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); CRYPTO_set_locking_callback (OpensslLockingCallback);*/ -#if !defined(__x86_64__) - PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); + if (precomputation) + { +#if defined(__x86_64__) + g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES); +#else + g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255]; + PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); #endif + } } void TerminateCrypto () { -#if !defined(__x86_64__) - DestroyElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES); -#endif + if (g_ElggTable) + { + DestroyElggTable (g_ElggTable, +#if defined(__x86_64__) + ELGAMAL_FULL_EXPONENT_NUM_BYTES +#else + ELGAMAL_SHORT_EXPONENT_NUM_BYTES +#endif + ); + } /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ } diff --git a/Crypto.h b/Crypto.h index e633f8bf..e333940e 100644 --- a/Crypto.h +++ b/Crypto.h @@ -273,7 +273,7 @@ namespace crypto #endif }; - void InitCrypto (); + void InitCrypto (bool precomputation); void TerminateCrypto (); } } diff --git a/Daemon.cpp b/Daemon.cpp index f15fe3e3..0924b236 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -117,7 +117,8 @@ namespace i2p LogPrint(eLogDebug, "FS: main config file: ", config); LogPrint(eLogDebug, "FS: data directory: ", datadir); - i2p::crypto::InitCrypto (); + bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation); + i2p::crypto::InitCrypto (precomputation); i2p::context.Init (); uint16_t port; i2p::config::GetOption("port", port); diff --git a/api.cpp b/api.cpp index 64648743..1828901b 100644 --- a/api.cpp +++ b/api.cpp @@ -28,7 +28,11 @@ namespace api i2p::fs::DetectDataDir(datadir, false); i2p::fs::Init(); - i2p::crypto::InitCrypto (); +#if defined(__x86_64__) + i2p::crypto::InitCrypto (false); +#else + i2p::crypto::InitCrypto (true); +#endif i2p::context.Init (); } From aff65083cc779dec6847bc900c65d27dc1cf39cc Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 17 Apr 2016 17:03:56 -0400 Subject: [PATCH 31/76] precomputation.elgamal --- docs/configuration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index ac5c4684..14db728a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -59,7 +59,9 @@ All options below still possible in cmdline, but better write it in config file: * --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 -* --i2pcontrol.enabled= - If I2P control is enabled. false by default +* --i2pcontrol.enabled= - If I2P control is enabled. false by default + +* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default Config files ------------ From c265bd6c4d455b89e443542571cbf3f9e5043dd5 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 18 Apr 2016 21:07:45 -0400 Subject: [PATCH 32/76] delete pre-calculated tablle upon termination --- Crypto.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Crypto.cpp b/Crypto.cpp index f7c00595..742296f5 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -828,7 +828,8 @@ namespace crypto #else ELGAMAL_SHORT_EXPONENT_NUM_BYTES #endif - ); + ); + delete[] g_ElggTable; g_ElggTable = nullptr; } /* CRYPTO_set_locking_callback (nullptr); m_OpenSSLMutexes.clear ();*/ From bb656ce44b638dd3e7822dacba4d840793329bb3 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:12:14 +0200 Subject: [PATCH 33/76] added some limits options --- Config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Config.cpp b/Config.cpp index d5ff2a46..41236014 100644 --- a/Config.cpp +++ b/Config.cpp @@ -130,6 +130,13 @@ namespace config { ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; + options_description limits("Limits options"); + limits.add_options() + ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") + ("limits.router", value()->default_value(4096), "Maximum active router sessions (default:4096)") + ("limits.client", value()->default_value(1024), "Maximum active client sessions (default:1024)") + ("limits.floodfill", value()->default_value(1024), "Maximum active floodfill sessions (default:1024)") + ; options_description httpserver("HTTP Server options"); httpserver.add_options() From 8456c8b47b56e37d655660c5d8c0e16a79aa19bc Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:22:04 +0200 Subject: [PATCH 34/76] limits options --- Config.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Config.cpp b/Config.cpp index 41236014..af399bd4 100644 --- a/Config.cpp +++ b/Config.cpp @@ -133,9 +133,6 @@ namespace config { options_description limits("Limits options"); limits.add_options() ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") - ("limits.router", value()->default_value(4096), "Maximum active router sessions (default:4096)") - ("limits.client", value()->default_value(1024), "Maximum active client sessions (default:1024)") - ("limits.floodfill", value()->default_value(1024), "Maximum active floodfill sessions (default:1024)") ; options_description httpserver("HTTP Server options"); From 9a860341626462d5c725bb14e4da0f57ffc33777 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 20 Apr 2016 19:24:50 +0200 Subject: [PATCH 35/76] limits options --- Config.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Config.cpp b/Config.cpp index af399bd4..922ce236 100644 --- a/Config.cpp +++ b/Config.cpp @@ -130,9 +130,10 @@ namespace config { ("close", value()->default_value("ask"), "Action on close: minimize, exit, ask") // TODO: add custom validator or something #endif ; + options_description limits("Limits options"); limits.add_options() - ("limits.transit", value()->default_value(2500), "Maximum active transit sessions (default:2500)") + ("limits.transittunnels", value()->default_value(2500), "Maximum active transit sessions (default:2500)") ; options_description httpserver("HTTP Server options"); From e120e9a78eb9eba3914f4e28e90006705c82703e Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Apr 2016 14:53:50 -0400 Subject: [PATCH 36/76] configurable transit tunnels limit --- Config.cpp | 1 + Daemon.cpp | 2 ++ I2NPProtocol.cpp | 12 +++++++++++- I2NPProtocol.h | 5 +++-- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Config.cpp b/Config.cpp index 922ce236..d7cef879 100644 --- a/Config.cpp +++ b/Config.cpp @@ -198,6 +198,7 @@ namespace config { m_OptionsDesc .add(general) + .add(limits) .add(httpserver) .add(httpproxy) .add(socksproxy) diff --git a/Daemon.cpp b/Daemon.cpp index 0924b236..81bbcdd5 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -141,6 +141,8 @@ namespace i2p i2p::context.SetSupportsV6 (ipv6); i2p::context.SetSupportsV4 (ipv4); i2p::context.SetAcceptsTunnels (!transit); + uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); + SetMaxNumTransitTunnels (transitTunnels); bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill); if (isFloodfill) { diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 7cebf96a..9674fdca 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -286,6 +286,16 @@ namespace i2p return !msg->GetPayload ()[DATABASE_STORE_TYPE_OFFSET]; // 0- RouterInfo } + static uint16_t g_MaxNumTransitTunnels = DEFAULT_MAX_NUM_TRANSIT_TUNNELS; // TODO: + void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels) + { + if (maxNumTransitTunnels > 0 && maxNumTransitTunnels <= 10000 && g_MaxNumTransitTunnels != maxNumTransitTunnels) + { + LogPrint (eLogDebug, "I2NP: Max number of transit tunnels set to ", maxNumTransitTunnels); + g_MaxNumTransitTunnels = maxNumTransitTunnels; + } + } + bool HandleBuildRequestRecords (int num, uint8_t * records, uint8_t * clearText) { for (int i = 0; i < num; i++) @@ -298,7 +308,7 @@ namespace i2p i2p::crypto::ElGamalDecrypt (i2p::context.GetEncryptionPrivateKey (), record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText); // replace record to reply if (i2p::context.AcceptsTunnels () && - i2p::tunnel::tunnels.GetTransitTunnels ().size () <= MAX_NUM_TRANSIT_TUNNELS && + i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && !i2p::transport::transports.IsBandwidthExceeded ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 6450e958..cf8f4266 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -97,8 +97,6 @@ namespace i2p const uint8_t DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP = 0x08; // 1000 const uint8_t DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP = 0x0C; // 1100 - const unsigned int MAX_NUM_TRANSIT_TUNNELS = 2500; - namespace tunnel { class InboundTunnel; @@ -259,6 +257,9 @@ namespace tunnel std::vector > m_TunnelMsgs, m_TunnelGatewayMsgs; }; + + const uint16_t DEFAULT_MAX_NUM_TRANSIT_TUNNELS = 2500; + void SetMaxNumTransitTunnels (uint16_t maxNumTransitTunnels); } #endif From 4431d5063541451258cf19bd8886f6107efb74a4 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 20 Apr 2016 15:02:11 -0400 Subject: [PATCH 37/76] limits.transittunnels --- docs/configuration.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 14db728a..2a639be3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -61,7 +61,9 @@ All options below still possible in cmdline, but better write it in config file: * --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified * --i2pcontrol.enabled= - If I2P control is enabled. false by default -* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default +* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default + +* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default Config files ------------ From d582c30f6e45f6a47bfcdc1e7608bb03ecd2dc6d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 24 Apr 2016 17:32:24 -0400 Subject: [PATCH 38/76] allow same port at different interfaces --- ClientContext.cpp | 5 +++-- ClientContext.h | 6 +++--- I2PService.h | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index 59f11f21..2eb81af2 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -328,7 +328,8 @@ namespace client localDestination = CreateNewLocalDestination (k, false, &options); } auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); - if (m_ClientTunnels.insert (std::make_pair (port, std::unique_ptr(clientTunnel))).second) + if (m_ClientTunnels.insert (std::make_pair (clientTunnel->GetAcceptor ().local_endpoint (), + std::unique_ptr(clientTunnel))).second) clientTunnel->Start (); else LogPrint (eLogError, "Clients: I2P client tunnel with port ", port, " already exists"); @@ -382,7 +383,7 @@ namespace client serverTunnel->SetAccessList (idents); } if (m_ServerTunnels.insert (std::make_pair ( - std::make_tuple (localDestination->GetIdentHash (), inPort), + std::make_pair (localDestination->GetIdentHash (), inPort), std::unique_ptr(serverTunnel))).second) serverTunnel->Start (); else diff --git a/ClientContext.h b/ClientContext.h index a05c2161..3381228b 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -2,9 +2,9 @@ #define CLIENT_CONTEXT_H__ #include -#include #include #include +#include #include "Destination.h" #include "HTTPProxy.h" #include "SOCKS.h" @@ -78,8 +78,8 @@ namespace client i2p::proxy::HTTPProxy * m_HttpProxy; i2p::proxy::SOCKSProxy * m_SocksProxy; - std::map > m_ClientTunnels; // port->tunnel - std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel + std::map > m_ClientTunnels; // local endpoint->tunnel + std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel SAMBridge * m_SamBridge; BOBCommandChannel * m_BOBCommandChannel; diff --git a/I2PService.h b/I2PService.h index 251a379a..2df11909 100644 --- a/I2PService.h +++ b/I2PService.h @@ -118,6 +118,9 @@ namespace client void Start (); //If you override this make sure you call it from the children void Stop (); + + const boost::asio::ip::tcp::acceptor& GetAcceptor () const { return m_Acceptor; }; + protected: virtual std::shared_ptr CreateHandler(std::shared_ptr socket) = 0; virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; } From 85840872ab50fe7e1af312d51912a3ebba3362f9 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Tue, 26 Apr 2016 19:39:10 +0200 Subject: [PATCH 39/76] family: volatile.crt --- contrib/certificates/family/volatile.crt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 contrib/certificates/family/volatile.crt diff --git a/contrib/certificates/family/volatile.crt b/contrib/certificates/family/volatile.crt new file mode 100644 index 00000000..928c7f39 --- /dev/null +++ b/contrib/certificates/family/volatile.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxDCCAWmgAwIBAgIJAJnJIdKHYwWcMAoGCCqGSM49BAMCMGcxCzAJBgNVBAYT +AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn +aXRzIFB0eSBMdGQxIDAeBgNVBAMMF3ZvbGF0aWxlLmZhbWlseS5pMnAubmV0MB4X +DTE2MDQyNjE1MjAyNloXDTI2MDQyNDE1MjAyNlowZzELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDEgMB4GA1UEAwwXdm9sYXRpbGUuZmFtaWx5LmkycC5uZXQwWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAARf6LBfbbfL6HInvC/4wAGaN3rj0eeLE/OdBpA93R3L +s8EUp0YTEJHWPo9APiKMmAwQSsMJfjhNrbp+UWEnnx2LMAoGCCqGSM49BAMCA0kA +MEYCIQDpQu2KPV5G1JOFLoZvdj+rcvEnjxM/FxkaqikwkVx8FAIhANP7DkUal+GT +SuiCtcqM4QyIBsfsCJBWEMzovft164Bo +-----END CERTIFICATE----- From a78caa2976d3d96f8ac2defb7622c48e456e0630 Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 00:31:33 +0200 Subject: [PATCH 40/76] added SetFamilyString(); GetFamilyString() and shows family in webiface --- HTTPServer.cpp | 1 + RouterContext.cpp | 12 ++++++++++++ RouterContext.h | 2 ++ 3 files changed, 15 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6c2c6112..08b67e22 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -417,6 +417,7 @@ namespace util default: s << "Unknown"; } s << "
\r\n"; + s << "Family: " << i2p::context.GetFamilyString() << "
\r\n"; s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "Received: "; s << std::fixed << std::setprecision(2); diff --git a/RouterContext.cpp b/RouterContext.cpp index f35d8426..4cdf13fe 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,11 +149,23 @@ namespace i2p UpdateRouterInfo (); } + std::string RouterContext::GetFamilyString () const + { + return m_FamilyString; + } + void RouterContext::SetFamily (const std::string& family) { + + m_FamilyString = family; + if (m_FamilyString.length() == 0) + m_FamilyString = "<undefined>"; + std::string signature; if (family.length () > 0) + { signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); + } if (signature.length () > 0) { m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); diff --git a/RouterContext.h b/RouterContext.h index 9766c66e..1b0f7ed2 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,6 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); + std::string GetFamilyString () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ bool AcceptsTunnels () const { return m_AcceptsTunnels; }; @@ -100,6 +101,7 @@ namespace i2p i2p::data::PrivateKeys m_Keys; uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; + std::string m_FamilyString; uint64_t m_StartupTime; // in seconds since epoch uint32_t m_BandwidthLimit; // allowed bandwidth RouterStatus m_Status; From 61e8becd38e2b1af4948fa56333f8ee82d66040b Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 00:48:23 +0200 Subject: [PATCH 41/76] wrong file version --- Daemon.cpp | 1 + RouterContext.cpp | 14 ++++++++------ RouterContext.h | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index 81bbcdd5..2a32ff04 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -189,6 +189,7 @@ namespace i2p std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); + i2p::context.SetFamilyString (family); if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); diff --git a/RouterContext.cpp b/RouterContext.cpp index 4cdf13fe..bc1f3fc1 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,6 +149,14 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::SetFamilyString (const std::string& family) + { + if (family.length() > 0) + m_FamilyString = family; + else + m_FamilyString = "<undefined>"; + } + std::string RouterContext::GetFamilyString () const { return m_FamilyString; @@ -157,15 +165,9 @@ namespace i2p void RouterContext::SetFamily (const std::string& family) { - m_FamilyString = family; - if (m_FamilyString.length() == 0) - m_FamilyString = "<undefined>"; - std::string signature; if (family.length () > 0) - { signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); - } if (signature.length () > 0) { m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); diff --git a/RouterContext.h b/RouterContext.h index 1b0f7ed2..def89383 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,6 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); + void SetFamilyString (const std::string& family); std::string GetFamilyString () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ From ebee94fb11b436add295ae791cb1fe53c6e99d7d Mon Sep 17 00:00:00 2001 From: weekendi2p Date: Wed, 27 Apr 2016 01:19:27 +0200 Subject: [PATCH 42/76] removed 1 blank line.. --- RouterContext.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index bc1f3fc1..29891169 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -164,7 +164,6 @@ namespace i2p void RouterContext::SetFamily (const std::string& family) { - std::string signature; if (family.length () > 0) signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); From 7cf171671db8de9f7dfb34029d2ec7c1db94709c Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 43/76] * HTTPConnection::reply : to_buffers() -> to_string() --- HTTPServer.cpp | 57 +++++++++++++++++++++----------------------------- HTTPServer.h | 4 ++-- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6c2c6112..6897a347 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -212,42 +212,32 @@ namespace util } // namespace misc_strings - std::vector HTTPConnection::reply::to_buffers(int status) + std::string HTTPConnection::reply::to_string(int code) { - std::vector buffers; + std::stringstream ss(""); if (headers.size () > 0) { - status_string = "HTTP/1.1 "; - status_string += std::to_string (status); - status_string += " "; - switch (status) + const char *status; + switch (code) { - case 105: status_string += "Name Not Resolved"; break; - case 200: status_string += "OK"; break; - case 400: status_string += "Bad Request"; break; - case 404: status_string += "Not Found"; break; - case 408: status_string += "Request Timeout"; break; - case 500: status_string += "Internal Server Error"; break; - case 502: status_string += "Bad Gateway"; break; - case 503: status_string += "Not Implemented"; break; - case 504: status_string += "Gateway Timeout"; break; - default: status_string += "WTF"; + case 105: status = "Name Not Resolved"; break; + case 200: status = "OK"; break; + case 400: status = "Bad Request"; break; + case 404: status = "Not Found"; break; + case 408: status = "Request Timeout"; break; + case 500: status = "Internal Server Error"; break; + case 502: status = "Bad Gateway"; break; + case 503: status = "Not Implemented"; break; + case 504: status = "Gateway Timeout"; break; + default: status = "WTF"; } - buffers.push_back(boost::asio::buffer(status_string, status_string.size())); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - - for (std::size_t i = 0; i < headers.size(); ++i) - { - header& h = headers[i]; - buffers.push_back(boost::asio::buffer(h.name)); - buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator)); - buffers.push_back(boost::asio::buffer(h.value)); - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - } - buffers.push_back(boost::asio::buffer(misc_strings::crlf)); - } - buffers.push_back(boost::asio::buffer(content)); - return buffers; + ss << "HTTP/1.1 " << code << "" << status << HTTP_CRLF; + for (header & h : headers) { + ss << h.name << HTTP_HEADER_KV_SEP << h.value << HTTP_CRLF; + } + ss << HTTP_CRLF; /* end of headers */ + } + return ss.str(); } void HTTPConnection::Terminate () @@ -914,8 +904,9 @@ namespace util m_Reply.headers[2].name = "Content-Type"; m_Reply.headers[2].value = "text/html"; } - - boost::asio::async_write (*m_Socket, m_Reply.to_buffers(status), + std::string res = m_Reply.to_string(status); + + boost::asio::async_write (*m_Socket, res, std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); } diff --git a/HTTPServer.h b/HTTPServer.h index 66083d85..889afca9 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -39,8 +39,8 @@ namespace util struct reply { std::vector
headers; - std::string status_string, content; - std::vector to_buffers (int status); + std::string status; + std::string to_string (int code); }; public: From 7a461c168490a98450e716d2972c46672740c6f0 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 44/76] * HTTPServer.{cpp,h}: move #include to one place --- HTTPServer.cpp | 7 +++++++ HTTPServer.h | 12 +----------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 6897a347..bf895ced 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -1,7 +1,13 @@ #include #include +#include +#include +#include + +#include #include #include + #include "Base.h" #include "FS.h" #include "Log.h" @@ -9,6 +15,7 @@ #include "TransitTunnel.h" #include "Transports.h" #include "NetDb.h" +#include "LeaseSet.h" #include "I2PEndian.h" #include "Streaming.h" #include "Destination.h" diff --git a/HTTPServer.h b/HTTPServer.h index 889afca9..ead03cde 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -1,14 +1,6 @@ #ifndef HTTP_SERVER_H__ #define HTTP_SERVER_H__ -#include -#include -#include -#include -#include -#include "LeaseSet.h" -#include "Streaming.h" - namespace i2p { namespace util @@ -135,6 +127,4 @@ namespace util } } -#endif - - +#endif /* HTTP_SERVER_H__ */ From 6ed709d6e6b2af7516de4ceea69753a73f82428c Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 45/76] * HTTPServer.{cpp,h}: extract itoopie{Image,Favicon} from HTTPConnection (!) class --- HTTPServer.cpp | 10 ++++++---- HTTPServer.h | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index bf895ced..2c0f3ea5 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -30,7 +30,7 @@ namespace i2p { namespace util { - const std::string HTTPConnection::itoopieImage = + const char *itoopieImage = "\"ICToopie"; - const std::string HTTPConnection::itoopieFavicon = + const char *itoopieFavicon = "data:image/png;base64," "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv" "8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My4wOGVynO" @@ -357,7 +357,7 @@ namespace util // Html5 head start s << "\r\n"; // TODO: Add support for locale. s << "\r\n\r\n"; // TODO: Find something to parse html/template system. This is horrible. - s << "\r\n"; + s << "\r\n"; s << "Purple I2P " << VERSION " Webconsole\r\n"; s << "\r\n"; + + const char HTTP_PAGE_TUNNELS[] = "tunnels"; + const char HTTP_PAGE_TRANSIT_TUNNELS[] = "transit_tunnels"; + const char HTTP_PAGE_TRANSPORTS[] = "transports"; + const char HTTP_PAGE_LOCAL_DESTINATIONS[] = "local_destinations"; + const char HTTP_PAGE_LOCAL_DESTINATION[] = "local_destination"; + const char HTTP_PAGE_SAM_SESSIONS[] = "sam_sessions"; + const char HTTP_PAGE_SAM_SESSION[] = "sam_session"; + const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels"; + const char HTTP_PAGE_JUMPSERVICES[] = "jumpservices"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; - const char HTTP_COMMAND_LOCAL_DESTINATIONS[] = "local_destinations"; - const char HTTP_COMMAND_LOCAL_DESTINATION[] = "local_destination"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; - const char HTTP_COMMAND_SAM_SESSIONS[] = "sam_sessions"; - const char HTTP_COMMAND_SAM_SESSION[] = "sam_session"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; - const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels"; - const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices="; const char HTTP_PARAM_ADDRESS[] = "address"; void HTTPConnection::Terminate () @@ -282,52 +299,53 @@ namespace http { { std::stringstream s; // Html5 head start - s << "\r\n"; // TODO: Add support for locale. - s << "\r\n\r\n"; // TODO: Find something to parse html/template system. This is horrible. - s << "\r\n"; - s << "Purple I2P " << VERSION " Webconsole\r\n"; - s << "\r\n\r\n\r\n"; - s << "
i2pd webconsole
"; - s << "
"; - s << "
\r\n"; - s << "Main page
\r\n
\r\n"; - s << "Local destinations
\r\n"; - s << "Tunnels
\r\n"; - s << "Transit tunnels
\r\n"; - s << "Transports
\r\n
\r\n"; - s << "I2P tunnels
\r\n"; + s << + "\r\n" + "\r\n" /* TODO: Add support for locale */ + " \r\n" + " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ + " \r\n" + " Purple I2P " VERSION " Webconsole\r\n" + << cssStyles << + "\r\n"; + s << + "\r\n" + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n
\r\n" + " Local destinations
\r\n" + " Tunnels
\r\n" + " Transit tunnels
\r\n" + " Transports
\r\n" + " I2P tunnels
\r\n" + " Jump services
\r\n" + ; if (i2p::client::context.GetSAMBridge ()) - s << "SAM sessions
\r\n
\r\n"; + s << " SAM sessions
\r\n"; + /* commands */ + s << "
\r\n"; + s << " Run peer test
\r\n"; if (i2p::context.AcceptsTunnels ()) - s << "Stop accepting tunnels
\r\n
\r\n"; + s << " Stop accepting tunnels
\r\n"; else - s << "Start accepting tunnels
\r\n
\r\n"; - s << "Run peer test
\r\n
\r\n"; - s << "Jump services
\r\n
\r\n"; - s << "
"; - if (request.uri.find("cmd=") != std::string::npos) + s << " Start accepting tunnels
\r\n"; + s << "
\r\n"; + s << "
"; + if (request.uri.find("page=") != std::string::npos) + HandlePage (s, request.uri); + else if (request.uri.find("cmd=") != std::string::npos) HandleCommand (s, request.uri); else - FillContent (s); - s << "
\r\n\r\n"; + ShowStatus (s); + s << + "
\r\n" + "\r\n" + "\r\n"; SendReply (s.str ()); } - void HTTPConnection::FillContent (std::stringstream& s) + void HTTPConnection::ShowStatus (std::stringstream& s) { s << "Uptime: " << boost::posix_time::to_simple_string ( boost::posix_time::time_duration (boost::posix_time::seconds ( @@ -396,40 +414,56 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } - void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) - { + void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) + { std::map params; - std::string cmd(""); + std::string page(""); URL url; url.parse(uri); url.parse_query(params); - cmd = params["cmd"]; + page = params["page"]; - if (cmd == HTTP_COMMAND_TRANSPORTS) + if (page == HTTP_PAGE_TRANSPORTS) ShowTransports (s); - else if (cmd == HTTP_COMMAND_TUNNELS) + else if (page == HTTP_PAGE_TUNNELS) ShowTunnels (s); - else if (cmd == HTTP_COMMAND_JUMPSERVICES) + else if (page == HTTP_PAGE_JUMPSERVICES) ShowJumpServices (s, params["address"]); - else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS) + else if (page == HTTP_PAGE_TRANSIT_TUNNELS) ShowTransitTunnels (s); - else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) - StartAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) - StopAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) - RunPeerTest (s); - else if (cmd == HTTP_COMMAND_LOCAL_DESTINATIONS) + else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) ShowLocalDestinations (s); - else if (cmd == HTTP_COMMAND_LOCAL_DESTINATION) + else if (page == HTTP_PAGE_LOCAL_DESTINATION) ShowLocalDestination (s, params["b32"]); - else if (cmd == HTTP_COMMAND_SAM_SESSIONS) + else if (page == HTTP_PAGE_SAM_SESSIONS) ShowSAMSessions (s); - else if (cmd == HTTP_COMMAND_SAM_SESSION) + else if (page == HTTP_PAGE_SAM_SESSION) ShowSAMSession (s, params["sam_id"]); - else if (cmd == HTTP_COMMAND_I2P_TUNNELS) + else if (page == HTTP_PAGE_I2P_TUNNELS) ShowI2PTunnels (s); + else + SendError("Unknown page: " + page); + } + + void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) + { + std::map params; + std::string cmd(""); + URL url; + + url.parse(uri); + url.parse_query(params); + cmd = params["cmd"]; + + if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) + StartAcceptingTunnels (s); + else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) + StopAcceptingTunnels (s); + else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) + RunPeerTest (s); + else + SendError("Unknown command: " + cmd); } void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) @@ -448,7 +482,7 @@ namespace http { for (auto& it: i2p::client::context.GetDestinations ()) { auto ident = it.second->GetIdentHash ();; - s << ""; + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; } } @@ -548,9 +582,9 @@ namespace http { it->Print (s); auto state = it->GetState (); if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; + s << " " << "Failed"; else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; + s << " " << "Expiring"; s << " " << (int)it->GetNumSentBytes () << "
\r\n"; s << std::endl; } @@ -560,9 +594,9 @@ namespace http { it->Print (s); auto state = it->GetState (); if (state == i2p::tunnel::eTunnelStateFailed) - s << " " << "Failed"; + s << " " << "Failed"; else if (state == i2p::tunnel::eTunnelStateExpiring) - s << " " << "Exp"; + s << " " << "Expiring"; s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; s << std::endl; } @@ -640,7 +674,7 @@ namespace http { { for (auto& it: sam->GetSessions ()) { - s << ""; + s << ""; s << it.first << "
\r\n" << std::endl; } } @@ -656,7 +690,7 @@ namespace http { if (session) { auto& ident = session->localDestination->GetIdentHash(); - s << ""; + s << ""; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; s << "Streams:
\r\n"; for (auto it: session->ListSockets()) @@ -688,7 +722,7 @@ namespace http { for (auto& it: i2p::client::context.GetClientTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇐ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << "
\r\n"<< std::endl; @@ -697,7 +731,7 @@ namespace http { for (auto& it: i2p::client::context.GetServerTunnels ()) { auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); - s << ""; + s << ""; s << it.second->GetName () << " ⇒ "; s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << ":" << it.second->GetLocalPort (); diff --git a/HTTPServer.h b/HTTPServer.h index 89df8fb5..57d6fa59 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -29,21 +29,24 @@ namespace http { void SendError (const std::string& message); void HandleRequest (const HTTPReq & request); - void HandleCommand (std::stringstream& s, const std::string& request); + void HandlePage (std::stringstream& s, const std::string& request); + void HandleCommand (std::stringstream& s, const std::string& request); + /* pages */ void ShowJumpServices (std::stringstream& s, const std::string& address); void ShowTransports (std::stringstream& s); void ShowTunnels (std::stringstream& s); + void ShowStatus (std::stringstream& s); void ShowTransitTunnels (std::stringstream& s); void ShowLocalDestinations (std::stringstream& s); void ShowLocalDestination (std::stringstream& s, const std::string& b32); void ShowSAMSessions (std::stringstream& s); void ShowSAMSession (std::stringstream& s, const std::string& id); void ShowI2PTunnels (std::stringstream& s); + /* commands */ void StartAcceptingTunnels (std::stringstream& s); void StopAcceptingTunnels (std::stringstream& s); void RunPeerTest (std::stringstream& s); - void FillContent (std::stringstream& s); protected: From 9bbff744e991cfa60cb4fa21684b84a06413d712 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 54/76] * HTTPServer.{cpp,h}: chg HandleRequest() signature --- HTTPServer.cpp | 12 ++++++------ HTTPServer.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 5673e468..80022897 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -271,7 +271,7 @@ namespace http { } if (ret == 0) return; /* need more data */ - HandleRequest (request); + HandleRequest (request.uri); } void HTTPConnection::HandleWriteReply (const boost::system::error_code& ecode) @@ -295,7 +295,7 @@ namespace http { AsyncStreamReceive (); } - void HTTPConnection::HandleRequest (const HTTPReq &request) + void HTTPConnection::HandleRequest (const std::string &uri) { std::stringstream s; // Html5 head start @@ -332,10 +332,10 @@ namespace http { s << " Start accepting tunnels
\r\n"; s << "\r\n"; s << "
"; - if (request.uri.find("page=") != std::string::npos) - HandlePage (s, request.uri); - else if (request.uri.find("cmd=") != std::string::npos) - HandleCommand (s, request.uri); + if (uri.find("page=") != std::string::npos) + HandlePage (s, uri); + else if (uri.find("cmd=") != std::string::npos) + HandleCommand (s, uri); else ShowStatus (s); s << diff --git a/HTTPServer.h b/HTTPServer.h index 57d6fa59..28962dde 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -28,7 +28,7 @@ namespace http { void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); - void HandleRequest (const HTTPReq & request); + void HandleRequest (const std::string& uri); void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); From 48b3959cfb9b71d5765c70439ab7a7b94a93dae6 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 55/76] * HTTPServer.{cpp,h}: cleanup --- HTTPServer.cpp | 18 ++++++++---------- HTTPServer.h | 4 ---- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 80022897..accca463 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -836,11 +836,10 @@ namespace http { { m_Acceptor.close(); m_Service.stop (); - if (m_Thread) - { - m_Thread->join (); - m_Thread = nullptr; - } + if (m_Thread) { + m_Thread->join (); + m_Thread = nullptr; + } } void HTTPServer::Run () @@ -858,11 +857,10 @@ namespace http { void HTTPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr newSocket) { - if (!ecode) - { - CreateConnection(newSocket); - Accept (); - } + if (ecode) + return; + CreateConnection(newSocket); + Accept (); } void HTTPServer::CreateConnection(std::shared_ptr newSocket) diff --git a/HTTPServer.h b/HTTPServer.h index 28962dde..a6ef52cc 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -6,7 +6,6 @@ namespace http { extern const char *itoopieImage; extern const char *itoopieFavicon; const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; - const int HTTP_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds class HTTPConnection: public std::enable_shared_from_this { @@ -59,9 +58,6 @@ namespace http { protected: virtual void RunRequest (); - - public: - }; class HTTPServer From 4fa4ba6301d4aadd19b5155218a9efc48832b745 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 56/76] * HTTPServer.cpp: move known jump services to std::map --- HTTPServer.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index accca463..73c9c791 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -226,7 +226,12 @@ namespace http { const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_ADDRESS[] = "address"; - + + std::map jumpservices = { + { "inr.i2p", "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/search/?q=" }, + { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, + }; + void HTTPConnection::Terminate () { if (!m_Stream) return; @@ -468,12 +473,16 @@ namespace http { void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) { - s << "
"; - s << ""; - s << "

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

\r\n"; + s << "Jump services for " << address << "\r\n\r\n"; } void HTTPConnection::ShowLocalDestinations (std::stringstream& s) From 2a1fe99a2981dbfe6966d60379155346b1c723c2 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 57/76] * HTTPServer.{cpp,h}: drop rest of streaming support --- HTTPServer.cpp | 52 +++----------------------------------------------- HTTPServer.h | 9 +++------ 2 files changed, 6 insertions(+), 55 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 73c9c791..5f195792 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -17,8 +17,6 @@ #include "NetDb.h" #include "HTTP.h" #include "LeaseSet.h" -#include "I2PEndian.h" -#include "Streaming.h" #include "Destination.h" #include "RouterContext.h" #include "ClientContext.h" @@ -234,9 +232,6 @@ namespace http { void HTTPConnection::Terminate () { - if (!m_Stream) return; - m_Stream->Close (); - m_Stream = nullptr; m_Socket->close (); } @@ -251,14 +246,9 @@ namespace http { { if (!ecode) { - if (!m_Stream) // new request - { - m_Buffer[bytes_transferred] = '\0'; - m_BufferLen = bytes_transferred; - RunRequest(); - } - else // follow-on - m_Stream->Send ((uint8_t *)m_Buffer, bytes_transferred); + m_Buffer[bytes_transferred] = '\0'; + m_BufferLen = bytes_transferred; + RunRequest(); Receive (); } else if (ecode != boost::asio::error::operation_aborted) @@ -289,17 +279,6 @@ namespace http { } } - void HTTPConnection::HandleWrite (const boost::system::error_code& ecode) - { - if (ecode || (m_Stream && !m_Stream->IsOpen ())) - { - if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - else // data keeps coming - AsyncStreamReceive (); - } - void HTTPConnection::HandleRequest (const std::string &uri) { std::stringstream s; @@ -769,31 +748,6 @@ namespace http { s << "Peer test is running" << std::endl; } - void HTTPConnection::AsyncStreamReceive () - { - if (m_Stream) - m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, 8192), - std::bind (&HTTPConnection::HandleStreamReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2), - 45); // 45 seconds timeout - } - - void HTTPConnection::HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - if (!ecode) - { - boost::asio::async_write (*m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), - std::bind (&HTTPConnection::HandleWrite, shared_from_this (), std::placeholders::_1)); - } - else - { - if (ecode == boost::asio::error::timed_out) - SendError ("Host not responding"); - else if (ecode != boost::asio::error::operation_aborted) - Terminate (); - } - } - void HTTPConnection::SendReply (const std::string& content, int code) { std::time_t time_now = std::time(nullptr); diff --git a/HTTPServer.h b/HTTPServer.h index a6ef52cc..cafa9b46 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -13,17 +13,15 @@ namespace http { HTTPConnection (std::shared_ptr socket): m_Socket (socket), m_Timer (socket->get_io_service ()), - m_Stream (nullptr), m_BufferLen (0) {}; + m_BufferLen (0) {}; void Receive (); private: void Terminate (); void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void AsyncStreamReceive (); - void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleWriteReply(const boost::system::error_code& ecode); - void HandleWrite (const boost::system::error_code& ecode); + void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); @@ -51,8 +49,7 @@ namespace http { std::shared_ptr m_Socket; boost::asio::deadline_timer m_Timer; - std::shared_ptr m_Stream; - char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1], m_StreamBuffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; + char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; protected: From fd928e8d12167c87ff63f540d7a2d0c9ff9cd78f Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 58/76] * HTTPServer.h: not virtual: not inherited anywhere --- HTTPServer.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/HTTPServer.h b/HTTPServer.h index cafa9b46..18c6bed8 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -25,6 +25,7 @@ namespace http { void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); + void RunRequest (); void HandleRequest (const std::string& uri); void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); @@ -45,16 +46,12 @@ namespace http { void StopAcceptingTunnels (std::stringstream& s); void RunPeerTest (std::stringstream& s); - protected: + private: std::shared_ptr m_Socket; boost::asio::deadline_timer m_Timer; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; - - protected: - - virtual void RunRequest (); }; class HTTPServer @@ -62,7 +59,7 @@ namespace http { public: HTTPServer (const std::string& address, int port); - virtual ~HTTPServer (); + ~HTTPServer (); void Start (); void Stop (); @@ -73,6 +70,7 @@ namespace http { void Accept (); void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr newSocket); + void CreateConnection(std::shared_ptr newSocket); private: @@ -80,9 +78,6 @@ namespace http { boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; boost::asio::ip::tcp::acceptor m_Acceptor; - - protected: - virtual void CreateConnection(std::shared_ptr newSocket); }; } // http } // i2p From 0c8fdfca7d9670a692891cebb25ef8848411a794 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 59/76] * HTTPServer.{cpp,h}: merge HandleWriteReply & Terminate : the same purpose --- HTTPServer.cpp | 36 +++++++++++++++--------------------- HTTPServer.h | 3 +-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 5f195792..c7b91fd0 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -230,11 +230,6 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; - void HTTPConnection::Terminate () - { - m_Socket->close (); - } - void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -244,15 +239,15 @@ namespace http { void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (!ecode) - { - m_Buffer[bytes_transferred] = '\0'; - m_BufferLen = bytes_transferred; - RunRequest(); - Receive (); + if (ecode) { + if (ecode != boost::asio::error::operation_aborted) + Terminate (ecode); + return; } - else if (ecode != boost::asio::error::operation_aborted) - Terminate (); + m_Buffer[bytes_transferred] = '\0'; + m_BufferLen = bytes_transferred; + RunRequest(); + Receive (); } void HTTPConnection::RunRequest () @@ -269,14 +264,13 @@ namespace http { HandleRequest (request.uri); } - void HTTPConnection::HandleWriteReply (const boost::system::error_code& ecode) + void HTTPConnection::Terminate (const boost::system::error_code& ecode) { - if (ecode != boost::asio::error::operation_aborted) - { - boost::system::error_code ignored_ec; - m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); - Terminate (); - } + if (ecode == boost::asio::error::operation_aborted) + return; + boost::system::error_code ignored_ec; + m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + m_Socket->close (); } void HTTPConnection::HandleRequest (const std::string &uri) @@ -767,7 +761,7 @@ namespace http { buffers.push_back(boost::asio::buffer(content)); boost::asio::async_write (*m_Socket, buffers, - std::bind (&HTTPConnection::HandleWriteReply, shared_from_this (), std::placeholders::_1)); + std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1)); } void HTTPConnection::SendError(const std::string& content) diff --git a/HTTPServer.h b/HTTPServer.h index 18c6bed8..f3070502 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -18,9 +18,8 @@ namespace http { private: - void Terminate (); void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandleWriteReply(const boost::system::error_code& ecode); + void Terminate (const boost::system::error_code& ecode); void SendReply (const std::string& content, int code = 200); void SendError (const std::string& message); From 4d98a64000bf3ccce04f5165a59c3deb3f29beac Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 60/76] * HTTPServer.{cpp,h}: extract html-rendering methods from class --- HTTPServer.cpp | 316 ++++++++++++++++++++++++------------------------- HTTPServer.h | 16 --- 2 files changed, 158 insertions(+), 174 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index c7b91fd0..98080808 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -230,100 +230,7 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; - void HTTPConnection::Receive () - { - m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), - std::bind(&HTTPConnection::HandleReceive, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); - } - - void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) - { - if (ecode) { - if (ecode != boost::asio::error::operation_aborted) - Terminate (ecode); - return; - } - m_Buffer[bytes_transferred] = '\0'; - m_BufferLen = bytes_transferred; - RunRequest(); - Receive (); - } - - void HTTPConnection::RunRequest () - { - HTTPReq request; - int ret = request.parse(m_Buffer); - if (ret < 0) { - m_Buffer[0] = '\0'; - m_BufferLen = 0; - return; /* error */ - } - if (ret == 0) - return; /* need more data */ - HandleRequest (request.uri); - } - - void HTTPConnection::Terminate (const boost::system::error_code& ecode) - { - if (ecode == boost::asio::error::operation_aborted) - return; - boost::system::error_code ignored_ec; - m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); - m_Socket->close (); - } - - void HTTPConnection::HandleRequest (const std::string &uri) - { - std::stringstream s; - // Html5 head start - s << - "\r\n" - "\r\n" /* TODO: Add support for locale */ - " \r\n" - " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ - " \r\n" - " Purple I2P " VERSION " Webconsole\r\n" - << cssStyles << - "\r\n"; - s << - "\r\n" - "
i2pd webconsole
\r\n" - "
\r\n" - "
\r\n" - " Main page
\r\n
\r\n" - " Local destinations
\r\n" - " Tunnels
\r\n" - " Transit tunnels
\r\n" - " Transports
\r\n" - " I2P tunnels
\r\n" - " Jump services
\r\n" - ; - if (i2p::client::context.GetSAMBridge ()) - s << " SAM sessions
\r\n"; - /* commands */ - s << "
\r\n"; - s << " Run peer test
\r\n"; - if (i2p::context.AcceptsTunnels ()) - s << " Stop accepting tunnels
\r\n"; - else - s << " Start accepting tunnels
\r\n"; - s << "
\r\n"; - s << "
"; - if (uri.find("page=") != std::string::npos) - HandlePage (s, uri); - else if (uri.find("cmd=") != std::string::npos) - HandleCommand (s, uri); - else - ShowStatus (s); - s << - "
\r\n" - "\r\n" - "\r\n"; - SendReply (s.str ()); - } - - void HTTPConnection::ShowStatus (std::stringstream& s) + void ShowStatus (std::stringstream& s) { s << "Uptime: " << boost::posix_time::to_simple_string ( boost::posix_time::time_duration (boost::posix_time::seconds ( @@ -392,59 +299,7 @@ namespace http { s << "Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n"; } - void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) - { - std::map params; - std::string page(""); - URL url; - - url.parse(uri); - url.parse_query(params); - page = params["page"]; - - if (page == HTTP_PAGE_TRANSPORTS) - ShowTransports (s); - else if (page == HTTP_PAGE_TUNNELS) - ShowTunnels (s); - else if (page == HTTP_PAGE_JUMPSERVICES) - ShowJumpServices (s, params["address"]); - else if (page == HTTP_PAGE_TRANSIT_TUNNELS) - ShowTransitTunnels (s); - else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) - ShowLocalDestinations (s); - else if (page == HTTP_PAGE_LOCAL_DESTINATION) - ShowLocalDestination (s, params["b32"]); - else if (page == HTTP_PAGE_SAM_SESSIONS) - ShowSAMSessions (s); - else if (page == HTTP_PAGE_SAM_SESSION) - ShowSAMSession (s, params["sam_id"]); - else if (page == HTTP_PAGE_I2P_TUNNELS) - ShowI2PTunnels (s); - else - SendError("Unknown page: " + page); - } - - void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) - { - std::map params; - std::string cmd(""); - URL url; - - url.parse(uri); - url.parse_query(params); - cmd = params["cmd"]; - - if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) - StartAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) - StopAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) - RunPeerTest (s); - else - SendError("Unknown command: " + cmd); - } - - void HTTPConnection::ShowJumpServices (std::stringstream& s, const std::string& address) + void ShowJumpServices (std::stringstream& s, const std::string& address) { s << "
"; s << ""; @@ -458,7 +313,7 @@ namespace http { s << "\r\n"; } - void HTTPConnection::ShowLocalDestinations (std::stringstream& s) + void ShowLocalDestinations (std::stringstream& s) { s << "Local Destinations:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetDestinations ()) @@ -469,7 +324,7 @@ namespace http { } } - void HTTPConnection::ShowLocalDestination (std::stringstream& s, const std::string& b32) + void ShowLocalDestination (std::stringstream& s, const std::string& b32) { s << "Local Destination:
\r\n
\r\n"; i2p::data::IdentHash ident; @@ -555,7 +410,7 @@ namespace http { } } - void HTTPConnection::ShowTunnels (std::stringstream& s) + void ShowTunnels (std::stringstream& s) { s << "Tunnels:
\r\n
\r\n"; s << "Queue size: " << i2p::tunnel::tunnels.GetQueueSize () << "
\r\n"; @@ -584,7 +439,7 @@ namespace http { } } - void HTTPConnection::ShowTransitTunnels (std::stringstream& s) + void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) @@ -599,7 +454,7 @@ namespace http { } } - void HTTPConnection::ShowTransports (std::stringstream& s) + void ShowTransports (std::stringstream& s) { s << "Transports:
\r\n
\r\n"; auto ntcpServer = i2p::transport::transports.GetNTCPServer (); @@ -648,7 +503,7 @@ namespace http { } } - void HTTPConnection::ShowSAMSessions (std::stringstream& s) + void ShowSAMSessions (std::stringstream& s) { s << "SAM Sessions:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); @@ -662,7 +517,7 @@ namespace http { } } - void HTTPConnection::ShowSAMSession (std::stringstream& s, const std::string& id) + void ShowSAMSession (std::stringstream& s, const std::string& id) { s << "SAM Session:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); @@ -698,7 +553,7 @@ namespace http { } } - void HTTPConnection::ShowI2PTunnels (std::stringstream& s) + void ShowI2PTunnels (std::stringstream& s) { s << "Client Tunnels:
\r\n
\r\n"; for (auto& it: i2p::client::context.GetClientTunnels ()) @@ -721,27 +576,172 @@ namespace http { } } - void HTTPConnection::StopAcceptingTunnels (std::stringstream& s) + void StopAcceptingTunnels (std::stringstream& s) { s << "Stop Accepting Tunnels:
\r\n
\r\n"; i2p::context.SetAcceptsTunnels (false); s << "Accepting tunnels stopped" << std::endl; } - void HTTPConnection::StartAcceptingTunnels (std::stringstream& s) + void StartAcceptingTunnels (std::stringstream& s) { s << "Start Accepting Tunnels:
\r\n
\r\n"; i2p::context.SetAcceptsTunnels (true); s << "Accepting tunnels started" << std::endl; } - void HTTPConnection::RunPeerTest (std::stringstream& s) + void RunPeerTest (std::stringstream& s) { s << "Run Peer Test:
\r\n
\r\n"; i2p::transport::transports.PeerTest (); s << "Peer test is running" << std::endl; } + void HTTPConnection::Receive () + { + m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), + std::bind(&HTTPConnection::HandleReceive, shared_from_this (), + std::placeholders::_1, std::placeholders::_2)); + } + + void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (ecode) { + if (ecode != boost::asio::error::operation_aborted) + Terminate (ecode); + return; + } + m_Buffer[bytes_transferred] = '\0'; + m_BufferLen = bytes_transferred; + RunRequest(); + Receive (); + } + + void HTTPConnection::RunRequest () + { + HTTPReq request; + int ret = request.parse(m_Buffer); + if (ret < 0) { + m_Buffer[0] = '\0'; + m_BufferLen = 0; + return; /* error */ + } + if (ret == 0) + return; /* need more data */ + HandleRequest (request.uri); + } + + void HTTPConnection::Terminate (const boost::system::error_code& ecode) + { + if (ecode == boost::asio::error::operation_aborted) + return; + boost::system::error_code ignored_ec; + m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec); + m_Socket->close (); + } + + void HTTPConnection::HandleRequest (const std::string &uri) + { + std::stringstream s; + // Html5 head start + s << + "\r\n" + "\r\n" /* TODO: Add support for locale */ + " \r\n" + " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ + " \r\n" + " Purple I2P " VERSION " Webconsole\r\n" + << cssStyles << + "\r\n"; + s << + "\r\n" + "
i2pd webconsole
\r\n" + "
\r\n" + "
\r\n" + " Main page
\r\n
\r\n" + " Local destinations
\r\n" + " Tunnels
\r\n" + " Transit tunnels
\r\n" + " Transports
\r\n" + " I2P tunnels
\r\n" + " Jump services
\r\n" + ; + if (i2p::client::context.GetSAMBridge ()) + s << " SAM sessions
\r\n"; + /* commands */ + s << "
\r\n"; + s << " Run peer test
\r\n"; + if (i2p::context.AcceptsTunnels ()) + s << " Stop accepting tunnels
\r\n"; + else + s << " Start accepting tunnels
\r\n"; + s << "
\r\n"; + s << "
"; + if (uri.find("page=") != std::string::npos) + HandlePage (s, uri); + else if (uri.find("cmd=") != std::string::npos) + HandleCommand (s, uri); + else + ShowStatus (s); + s << + "
\r\n" + "\r\n" + "\r\n"; + SendReply (s.str ()); + } + + void HTTPConnection::HandlePage (std::stringstream& s, const std::string & uri) + { + std::map params; + std::string page(""); + URL url; + + url.parse(uri); + url.parse_query(params); + page = params["page"]; + + if (page == HTTP_PAGE_TRANSPORTS) + ShowTransports (s); + else if (page == HTTP_PAGE_TUNNELS) + ShowTunnels (s); + else if (page == HTTP_PAGE_JUMPSERVICES) + ShowJumpServices (s, params["address"]); + else if (page == HTTP_PAGE_TRANSIT_TUNNELS) + ShowTransitTunnels (s); + else if (page == HTTP_PAGE_LOCAL_DESTINATIONS) + ShowLocalDestinations (s); + else if (page == HTTP_PAGE_LOCAL_DESTINATION) + ShowLocalDestination (s, params["b32"]); + else if (page == HTTP_PAGE_SAM_SESSIONS) + ShowSAMSessions (s); + else if (page == HTTP_PAGE_SAM_SESSION) + ShowSAMSession (s, params["sam_id"]); + else if (page == HTTP_PAGE_I2P_TUNNELS) + ShowI2PTunnels (s); + else + SendError("Unknown page: " + page); + } + + void HTTPConnection::HandleCommand (std::stringstream& s, const std::string & uri) + { + std::map params; + std::string cmd(""); + URL url; + + url.parse(uri); + url.parse_query(params); + cmd = params["cmd"]; + + if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) + StartAcceptingTunnels (s); + else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) + StopAcceptingTunnels (s); + else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) + RunPeerTest (s); + else + SendError("Unknown command: " + cmd); + } + void HTTPConnection::SendReply (const std::string& content, int code) { std::time_t time_now = std::time(nullptr); diff --git a/HTTPServer.h b/HTTPServer.h index f3070502..06fa4457 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -29,22 +29,6 @@ namespace http { void HandlePage (std::stringstream& s, const std::string& request); void HandleCommand (std::stringstream& s, const std::string& request); - /* pages */ - void ShowJumpServices (std::stringstream& s, const std::string& address); - void ShowTransports (std::stringstream& s); - void ShowTunnels (std::stringstream& s); - void ShowStatus (std::stringstream& s); - void ShowTransitTunnels (std::stringstream& s); - void ShowLocalDestinations (std::stringstream& s); - void ShowLocalDestination (std::stringstream& s, const std::string& b32); - void ShowSAMSessions (std::stringstream& s); - void ShowSAMSession (std::stringstream& s, const std::string& id); - void ShowI2PTunnels (std::stringstream& s); - /* commands */ - void StartAcceptingTunnels (std::stringstream& s); - void StopAcceptingTunnels (std::stringstream& s); - void RunPeerTest (std::stringstream& s); - private: std::shared_ptr m_Socket; From 849308e28d3f0852bf86873399bea809d16719fe Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 61/76] * HTTPServer.cpp: drop boost::date_time dep --- HTTPServer.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 98080808..d5a4622e 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -6,7 +6,6 @@ #include #include -#include #include "Base.h" #include "FS.h" @@ -230,11 +229,29 @@ namespace http { { "stats.i2p", "http://7tbay5p4kzeekxvyvbf6v7eauazemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p/cgi-bin/jump.cgi?a=" }, }; + void ShowUptime (std::stringstream& s, int seconds) { + int num; + + if ((num = seconds / 86400) > 0) { + s << num << " days, "; + seconds -= num; + } + if ((num = seconds / 3600) > 0) { + s << num << " hours, "; + seconds -= num; + } + if ((num = seconds / 60) > 0) { + s << num << " min, "; + seconds -= num; + } + s << seconds << " seconds"; + } + void ShowStatus (std::stringstream& s) { - s << "Uptime: " << boost::posix_time::to_simple_string ( - boost::posix_time::time_duration (boost::posix_time::seconds ( - i2p::context.GetUptime ()))) << "
\r\n"; + s << "Uptime: "; + ShowUptime(s, i2p::context.GetUptime ()); + s << "
\r\n"; s << "Status: "; switch (i2p::context.GetStatus ()) { From 65395516b0b087d09fc28ae3df9dd012f38160e0 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 62/76] * HTTPServer.cpp: drop separate function handlers for commands --- HTTPServer.cpp | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index d5a4622e..d3a57b50 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -593,27 +593,6 @@ namespace http { } } - void StopAcceptingTunnels (std::stringstream& s) - { - s << "Stop Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (false); - s << "Accepting tunnels stopped" << std::endl; - } - - void StartAcceptingTunnels (std::stringstream& s) - { - s << "Start Accepting Tunnels:
\r\n
\r\n"; - i2p::context.SetAcceptsTunnels (true); - s << "Accepting tunnels started" << std::endl; - } - - void RunPeerTest (std::stringstream& s) - { - s << "Run Peer Test:
\r\n
\r\n"; - i2p::transport::transports.PeerTest (); - s << "Peer test is running" << std::endl; - } - void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -749,14 +728,17 @@ namespace http { url.parse_query(params); cmd = params["cmd"]; - if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) - StartAcceptingTunnels (s); + if (cmd == HTTP_COMMAND_RUN_PEER_TEST) + i2p::transport::transports.PeerTest (); + else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) + i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) - StopAcceptingTunnels (s); - else if (cmd == HTTP_COMMAND_RUN_PEER_TEST) - RunPeerTest (s); - else + i2p::context.SetAcceptsTunnels (false); + else { SendError("Unknown command: " + cmd); + return; + } + s << "Command accepted"; } void HTTPConnection::SendReply (const std::string& content, int code) From 23b8df1c36a420f367b12bfa5e897bb163813e2a Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 63/76] * HTTPServer.cpp: move commands to separate page --- HTTPServer.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index d3a57b50..44841a91 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -217,6 +217,7 @@ namespace http { const char HTTP_PAGE_SAM_SESSION[] = "sam_session"; const char HTTP_PAGE_I2P_TUNNELS[] = "i2p_tunnels"; const char HTTP_PAGE_JUMPSERVICES[] = "jumpservices"; + const char HTTP_PAGE_COMMANDS[] = "commands"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; @@ -452,10 +453,20 @@ namespace http { else if (state == i2p::tunnel::eTunnelStateExpiring) s << " " << "Expiring"; s << " " << (int)it->GetNumReceivedBytes () << "
\r\n"; - s << std::endl; } } + void ShowCommands (std::stringstream& s) + { + /* commands */ + s << "Router Commands
\r\n"; + s << " Run peer test
\r\n"; + if (i2p::context.AcceptsTunnels ()) + s << " Stop accepting tunnels
\r\n"; + else + s << " Start accepting tunnels
\r\n"; + } + void ShowTransitTunnels (std::stringstream& s) { s << "Transit tunnels:
\r\n
\r\n"; @@ -655,22 +666,16 @@ namespace http { "
\r\n" "
\r\n" " Main page
\r\n
\r\n" + " Router commands
\r\n" " Local destinations
\r\n" " Tunnels
\r\n" " Transit tunnels
\r\n" " Transports
\r\n" " I2P tunnels
\r\n" - " Jump services
\r\n" + " Jump services
\r\n" ; if (i2p::client::context.GetSAMBridge ()) s << " SAM sessions
\r\n"; - /* commands */ - s << "
\r\n"; - s << " Run peer test
\r\n"; - if (i2p::context.AcceptsTunnels ()) - s << " Stop accepting tunnels
\r\n"; - else - s << " Start accepting tunnels
\r\n"; s << "
\r\n"; s << "
"; if (uri.find("page=") != std::string::npos) @@ -700,6 +705,8 @@ namespace http { ShowTransports (s); else if (page == HTTP_PAGE_TUNNELS) ShowTunnels (s); + else if (page == HTTP_PAGE_COMMANDS) + ShowCommands (s); else if (page == HTTP_PAGE_JUMPSERVICES) ShowJumpServices (s, params["address"]); else if (page == HTTP_PAGE_TRANSIT_TUNNELS) @@ -738,7 +745,8 @@ namespace http { SendError("Unknown command: " + cmd); return; } - s << "Command accepted"; + s << "Command accepted

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

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

\r\n"; s << "Back to commands list"; } - void HTTPConnection::SendReply (const std::string& content, int code) + void HTTPConnection::SendReply (HTTPRes& reply, std::string& content) { std::time_t time_now = std::time(nullptr); char time_buff[128]; std::strftime(time_buff, sizeof(time_buff), "%a, %d %b %Y %H:%M:%S GMT", std::gmtime(&time_now)); - HTTPRes reply; - reply.code = code; - reply.status = HTTPCodeToStatus(code); + reply.status = HTTPCodeToStatus(reply.code); reply.headers.insert(std::pair("Date", time_buff)); reply.headers.insert(std::pair("Content-Type", "text/html")); reply.headers.insert(std::pair("Content-Length", std::to_string(content.size()))); @@ -777,13 +787,6 @@ namespace http { std::bind (&HTTPConnection::Terminate, shared_from_this (), std::placeholders::_1)); } - void HTTPConnection::SendError(const std::string& content) - { - std::stringstream ss; - ss << "" << itoopieImage << "
\r\n" << content << ""; - SendReply (ss.str(), 504); - } - HTTPServer::HTTPServer (const std::string& address, int port): m_Thread (nullptr), m_Work (m_Service), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint (boost::asio::ip::address::from_string(address), port)) diff --git a/HTTPServer.h b/HTTPServer.h index 06fa4457..72a0c383 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -21,13 +21,11 @@ namespace http { void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void Terminate (const boost::system::error_code& ecode); - void SendReply (const std::string& content, int code = 200); - void SendError (const std::string& message); - void RunRequest (); - void HandleRequest (const std::string& uri); - void HandlePage (std::stringstream& s, const std::string& request); - void HandleCommand (std::stringstream& s, const std::string& request); + void HandleRequest (const HTTPReq & req); + void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); + void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); + void SendReply (HTTPRes & res, std::string & content); private: From 75db2867dcdd77452414e4cbfec6c19ef3c44619 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 67/76] * HTTPServer.cpp: protect SAM pages if disabled --- HTTPServer.cpp | 65 ++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index e5093bba..7dc8d910 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -573,15 +573,16 @@ namespace http { void ShowSAMSessions (std::stringstream& s) { - s << "SAM Sessions:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); - if (sam) - { - for (auto& it: sam->GetSessions ()) - { - s << ""; - s << it.first << "
\r\n" << std::endl; - } + if (!sam) { + ShowError(s, "SAM disabled"); + return; + } + s << "SAM Sessions:
\r\n
\r\n"; + for (auto& it: sam->GetSessions ()) + { + s << ""; + s << it.first << "
\r\n" << std::endl; } } @@ -589,35 +590,31 @@ namespace http { { s << "SAM Session:
\r\n
\r\n"; auto sam = i2p::client::context.GetSAMBridge (); - if (sam) + if (!sam) { + ShowError(s, "SAM disabled"); + return; + } + auto session = sam->FindSession (id); + if (!session) { + ShowError(s, "SAM session not found"); + return; + } + auto& ident = session->localDestination->GetIdentHash(); + s << ""; + s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n"; + s << "
\r\n"; + s << "Streams:
\r\n"; + for (auto it: session->ListSockets()) { - auto session = sam->FindSession (id); - if (session) + switch (it->GetSocketType ()) { - auto& ident = session->localDestination->GetIdentHash(); - s << ""; - s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl; - s << "Streams:
\r\n"; - for (auto it: session->ListSockets()) - { - switch (it->GetSocketType ()) - { - case i2p::client::eSAMSocketTypeSession: - s << "session"; - break; - case i2p::client::eSAMSocketTypeStream: - s << "stream"; - break; - case i2p::client::eSAMSocketTypeAcceptor: - s << "acceptor"; - break; - default: - s << "unknown"; - } - s << " [" << it->GetSocket ().remote_endpoint() << "]"; - s << "
\r\n" << std::endl; - } + case i2p::client::eSAMSocketTypeSession : s << "session"; break; + case i2p::client::eSAMSocketTypeStream : s << "stream"; break; + case i2p::client::eSAMSocketTypeAcceptor : s << "acceptor"; break; + default: s << "unknown"; break; } + s << " [" << it->GetSocket ().remote_endpoint() << "]"; + s << "
\r\n"; } } From e09386be445fde1a9e7fe63bbbabb6cff39ebff4 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 68/76] * add http.auth, http.user & http.pass options --- Config.cpp | 3 +++ docs/configuration.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Config.cpp b/Config.cpp index d7cef879..44dec286 100644 --- a/Config.cpp +++ b/Config.cpp @@ -141,6 +141,9 @@ namespace config { ("http.enabled", value()->default_value(true), "Enable or disable webconsole") ("http.address", value()->default_value("127.0.0.1"), "Webconsole listen address") ("http.port", value()->default_value(7070), "Webconsole listen port") + ("http.auth", value()->default_value(false), "Enable Basic HTTP auth for webconsole") + ("http.user", value()->default_value("i2pd"), "Username for basic auth") + ("http.pass", value()->default_value(""), "Password for basic auth (default: random, see logs)") ; options_description httpproxy("HTTP Proxy options"); diff --git a/docs/configuration.md b/docs/configuration.md index 2a639be3..11e8b4a8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -36,6 +36,9 @@ All options below still possible in cmdline, but better write it in config file: * --http.address= - The address to listen on (HTTP server) * --http.port= - The port to listen on (HTTP server) +* --http.auth - Enable basic HTTP auth for webconsole +* --http.user= - Username for basic auth (default: i2pd) +* --http.pass= - Password for basic auth (default: random, see logs) * --httpproxy.address= - The address to listen on (HTTP Proxy) * --httpproxy.port= - The port to listen on (HTTP Proxy) 4446 by default From 678650beaff02b59491233b43aee2ffc5e660e6d Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 69/76] * HTTPServer.{cpp,h}: basic auth --- HTTPServer.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++- HTTPServer.h | 8 ++++--- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7dc8d910..8d9be41f 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -10,6 +10,7 @@ #include "Base.h" #include "FS.h" #include "Log.h" +#include "Config.h" #include "Tunnel.h" #include "TransitTunnel.h" #include "Transports.h" @@ -640,7 +641,16 @@ namespace http { s << "
\r\n"<< std::endl; } } - + + HTTPConnection::HTTPConnection (std::shared_ptr socket): + m_Socket (socket), m_Timer (socket->get_io_service ()), m_BufferLen (0) + { + /* cache options */ + i2p::config::GetOption("http.auth", needAuth); + i2p::config::GetOption("http.user", user); + i2p::config::GetOption("http.pass", pass); + }; + void HTTPConnection::Receive () { m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE), @@ -672,6 +682,7 @@ namespace http { } if (ret == 0) return; /* need more data */ + HandleRequest (request); } @@ -684,11 +695,44 @@ namespace http { m_Socket->close (); } + bool HTTPConnection::CheckAuth (const HTTPReq & req) { + /* method #1: http://user:pass@127.0.0.1:7070/ */ + if (req.uri.find('@') != std::string::npos) { + URL url; + if (url.parse(req.uri) && url.user == user && url.pass == pass) + return true; + } + /* method #2: 'Authorization' header sent */ + if (req.headers.count("Authorization") > 0) { + std::string provided = req.headers.find("Authorization")->second; + std::string expected = user + ":" + pass; + char b64_creds[64]; + std::size_t len = 0; + len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, sizeof(b64_creds)); + b64_creds[len] = '\0'; + expected = "Basic "; + expected += b64_creds; + if (provided == expected) + return true; + } + + LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ()); + return false; + } + void HTTPConnection::HandleRequest (const HTTPReq & req) { std::stringstream s; std::string content; HTTPRes res; + + if (needAuth && !CheckAuth(req)) { + res.code = 401; + res.headers.insert(std::pair("WWW-Authenticate", "Basic realm=\"WebAdmin\"")); + SendReply(res, content); + return; + } + // Html5 head start ShowPageHead (s); if (req.uri.find("page=") != std::string::npos) @@ -797,6 +841,21 @@ namespace http { void HTTPServer::Start () { + bool needAuth; i2p::config::GetOption("http.auth", needAuth); + std::string user; i2p::config::GetOption("http.user", user); + std::string pass; i2p::config::GetOption("http.pass", pass); + /* generate pass if needed */ + if (needAuth && pass == "") { + char alnum[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + pass.resize(16); + for (size_t i = 0; i < pass.size(); i++) { + pass[i] = alnum[rand() % (sizeof(alnum) - 1)]; + } + i2p::config::SetOption("http.pass", pass); + LogPrint(eLogInfo, "HTTPServer: password set to ", pass); + } m_Thread = std::unique_ptr(new std::thread (std::bind (&HTTPServer::Run, this))); m_Acceptor.listen (); Accept (); diff --git a/HTTPServer.h b/HTTPServer.h index 72a0c383..2635c3be 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -11,9 +11,7 @@ namespace http { { public: - HTTPConnection (std::shared_ptr socket): - m_Socket (socket), m_Timer (socket->get_io_service ()), - m_BufferLen (0) {}; + HTTPConnection (std::shared_ptr socket); void Receive (); private: @@ -22,6 +20,7 @@ namespace http { void Terminate (const boost::system::error_code& ecode); void RunRequest (); + bool CheckAuth (const HTTPReq & req); void HandleRequest (const HTTPReq & req); void HandlePage (const HTTPReq & req, HTTPRes & res, std::stringstream& data); void HandleCommand (const HTTPReq & req, HTTPRes & res, std::stringstream& data); @@ -33,6 +32,9 @@ namespace http { boost::asio::deadline_timer m_Timer; char m_Buffer[HTTP_CONNECTION_BUFFER_SIZE + 1]; size_t m_BufferLen; + bool needAuth; + std::string user; + std::string pass; }; class HTTPServer From 8fd55a210a7613acc01f4467c1a91186028b0ab5 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 70/76] * HTTPServer.cpp: add 'Shutdown' commands --- HTTPServer.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 8d9be41f..36ff2a37 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -21,6 +21,7 @@ #include "RouterContext.h" #include "ClientContext.h" #include "HTTPServer.h" +#include "Daemon.h" // For image and info #include "version.h" @@ -221,6 +222,9 @@ namespace http { const char HTTP_PAGE_COMMANDS[] = "commands"; const char HTTP_COMMAND_START_ACCEPTING_TUNNELS[] = "start_accepting_tunnels"; const char HTTP_COMMAND_STOP_ACCEPTING_TUNNELS[] = "stop_accepting_tunnels"; + const char HTTP_COMMAND_SHUTDOWN_START[] = "shutdown_start"; + const char HTTP_COMMAND_SHUTDOWN_CANCEL[] = "shutdown_cancel"; + const char HTTP_COMMAND_SHUTDOWN_NOW[] = "terminate"; const char HTTP_COMMAND_RUN_PEER_TEST[] = "run_peer_test"; const char HTTP_PARAM_BASE32_ADDRESS[] = "b32"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; @@ -506,6 +510,14 @@ namespace http { s << " Stop accepting tunnels
\r\n"; else s << " Start accepting tunnels
\r\n"; + if (Daemon.gracefullShutdownInterval) { + s << " Cancel gracefull shutdown ("; + s << Daemon.gracefullShutdownInterval; + s << " seconds remains)
\r\n"; + } else { + s << " Start gracefull shutdown
\r\n"; + } + s << " Force shutdown
\r\n"; } void ShowTransitTunnels (std::stringstream& s) @@ -799,7 +811,15 @@ namespace http { i2p::context.SetAcceptsTunnels (true); else if (cmd == HTTP_COMMAND_STOP_ACCEPTING_TUNNELS) i2p::context.SetAcceptsTunnels (false); - else { + else if (cmd == HTTP_COMMAND_SHUTDOWN_START) { + i2p::context.SetAcceptsTunnels (false); + Daemon.gracefullShutdownInterval = 10*60; + } else if (cmd == HTTP_COMMAND_SHUTDOWN_CANCEL) { + i2p::context.SetAcceptsTunnels (true); + Daemon.gracefullShutdownInterval = 0; + } else if (cmd == HTTP_COMMAND_SHUTDOWN_NOW) { + Daemon.running = false; + } else { res.code = 400; ShowError(s, "Unknown command: " + cmd); return; From f131e319496739cd3983964cf7e048bec8663423 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 27 Apr 2016 00:00:00 +0000 Subject: [PATCH 71/76] * HTTPServer.cpp: add request logging --- HTTPServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 36ff2a37..b3efc57d 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -738,6 +738,8 @@ namespace http { std::string content; HTTPRes res; + LogPrint(eLogDebug, "HTTPServer: request: ", req.uri); + if (needAuth && !CheckAuth(req)) { res.code = 401; res.headers.insert(std::pair("WWW-Authenticate", "Basic realm=\"WebAdmin\"")); From 2373b94d3e7794dc19a95322a0c407fddf6ae8d9 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 27 Apr 2016 12:08:08 -0400 Subject: [PATCH 72/76] try fixing issue #482 --- Destination.cpp | 25 ++++++++++++++----------- util.h | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Destination.cpp b/Destination.cpp index 5893caff..1534cbf9 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -9,6 +9,7 @@ #include "Timestamp.h" #include "NetDb.h" #include "Destination.h" +#include "util.h" namespace i2p { @@ -35,28 +36,30 @@ namespace client { auto it = params->find (I2CP_PARAM_INBOUND_TUNNEL_LENGTH); if (it != params->end ()) - { - int len = boost::lexical_cast(it->second); + { + + int len = i2p::util::lexical_cast(it->second, inboundTunnelLen); if (len > 0) { - inboundTunnelLen = len; - LogPrint (eLogInfo, "Destination: Inbound tunnel length set to ", len); + inboundTunnelLen = len; } + LogPrint (eLogInfo, "Destination: Inbound tunnel length set to ", inboundTunnelLen); } it = params->find (I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH); if (it != params->end ()) { - int len = boost::lexical_cast(it->second); + + int len = i2p::util::lexical_cast(it->second, outboundTunnelLen); if (len > 0) { - outboundTunnelLen = len; - LogPrint (eLogInfo, "Destination: Outbound tunnel length set to ", len); + outboundTunnelLen = len; } + LogPrint (eLogInfo, "Destination: Outbound tunnel length set to ", outboundTunnelLen); } it = params->find (I2CP_PARAM_INBOUND_TUNNELS_QUANTITY); if (it != params->end ()) { - int quantity = boost::lexical_cast(it->second); + int quantity = i2p::util::lexical_cast(it->second, inboundTunnelsQuantity); if (quantity > 0) { inboundTunnelsQuantity = quantity; @@ -66,7 +69,7 @@ namespace client it = params->find (I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY); if (it != params->end ()) { - int quantity = boost::lexical_cast(it->second); + int quantity = i2p::util::lexical_cast(it->second, outboundTunnelsQuantity); if (quantity > 0) { outboundTunnelsQuantity = quantity; @@ -76,11 +79,11 @@ namespace client it = params->find (I2CP_PARAM_TAGS_TO_SEND); if (it != params->end ()) { - int tagsToSend = boost::lexical_cast(it->second); + int tagsToSend = i2p::util::lexical_cast(it->second, numTags); if (tagsToSend > 0) { numTags = tagsToSend; - LogPrint (eLogInfo, "Destination: Tags to send set to ", tagsToSend); + LogPrint (eLogInfo, "Destination: Tags to send set to ", tagsToSend); } } it = params->find (I2CP_PARAM_EXPLICIT_PEERS); diff --git a/util.h b/util.h index 13200591..f5dbc9aa 100644 --- a/util.h +++ b/util.h @@ -5,11 +5,25 @@ #include #include #include +#include namespace i2p { namespace util { + + /** + wrapper arround boost::lexical_cast that "never" fails + */ + template + T lexical_cast(const std::string & str, const T fallback) { + try { + return boost::lexical_cast(str); + } catch ( ... ) { + return fallback; + } + } + namespace http { // in (lower case) From 5e2dc14dd5564fda8f6458db0de38485edd9d6de Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 28 Apr 2016 18:16:11 -0400 Subject: [PATCH 73/76] get family string from local RouterInfo --- Daemon.cpp | 1 - HTTPServer.cpp | 4 +++- RouterContext.cpp | 12 ++---------- RouterContext.h | 4 +--- RouterInfo.cpp | 8 ++++++++ RouterInfo.h | 1 + 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Daemon.cpp b/Daemon.cpp index 2a32ff04..81bbcdd5 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -189,7 +189,6 @@ namespace i2p std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); - i2p::context.SetFamilyString (family); if (family.length () > 0) LogPrint(eLogInfo, "Daemon: family set to ", family); diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 08b67e22..458a717f 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -417,7 +417,9 @@ namespace util default: s << "Unknown"; } s << "
\r\n"; - s << "Family: " << i2p::context.GetFamilyString() << "
\r\n"; + auto family = i2p::context.GetFamily (); + if (family.length () > 0) + s << "Family: " << family << "
\r\n"; s << "Tunnel creation success rate: " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "Received: "; s << std::fixed << std::setprecision(2); diff --git a/RouterContext.cpp b/RouterContext.cpp index 29891169..5fa32a13 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -149,17 +149,9 @@ namespace i2p UpdateRouterInfo (); } - void RouterContext::SetFamilyString (const std::string& family) + std::string RouterContext::GetFamily () const { - if (family.length() > 0) - m_FamilyString = family; - else - m_FamilyString = "<undefined>"; - } - - std::string RouterContext::GetFamilyString () const - { - return m_FamilyString; + return m_RouterInfo.GetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY); } void RouterContext::SetFamily (const std::string& family) diff --git a/RouterContext.h b/RouterContext.h index def89383..5a72ad58 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -59,8 +59,7 @@ namespace i2p bool IsFloodfill () const { return m_IsFloodfill; }; void SetFloodfill (bool floodfill); void SetFamily (const std::string& family); - void SetFamilyString (const std::string& family); - std::string GetFamilyString () const; + std::string GetFamily () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ bool AcceptsTunnels () const { return m_AcceptsTunnels; }; @@ -102,7 +101,6 @@ namespace i2p i2p::data::PrivateKeys m_Keys; uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; - std::string m_FamilyString; uint64_t m_StartupTime; // in seconds since epoch uint32_t m_BandwidthLimit; // allowed bandwidth RouterStatus m_Status; diff --git a/RouterInfo.cpp b/RouterInfo.cpp index c27f8754..2e76127c 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -636,6 +636,14 @@ namespace data m_Properties.erase (key); } + std::string RouterInfo::GetProperty (const std::string& key) const + { + auto it = m_Properties.find (key); + if (it != m_Properties.end ()) + return it->second; + return ""; + } + bool RouterInfo::IsNTCP (bool v4only) const { if (v4only) diff --git a/RouterInfo.h b/RouterInfo.h index c9881dd2..a55924a8 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -128,6 +128,7 @@ namespace data bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only void DeleteProperty (const std::string& key); // called from RouterContext only + std::string GetProperty (const std::string& key) const; // called from RouterContext only void ClearProperties () { m_Properties.clear (); }; bool IsFloodfill () const { return m_Caps & Caps::eFloodfill; }; bool IsReachable () const { return m_Caps & Caps::eReachable; }; From 00cfdc7d9257cfdb0ada151b77bf14b52c4da729 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 4 May 2016 12:12:24 -0400 Subject: [PATCH 74/76] fix mac brew, use libressl and homebrew --- Makefile | 2 +- Makefile.homebrew | 29 +++++++++++++++++++++++++++++ docs/build_notes_unix.md | 15 +++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 Makefile.homebrew diff --git a/Makefile b/Makefile index ae49ae4f..db6da2df 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ USE_STATIC := no ifeq ($(UNAME),Darwin) DAEMON_SRC += DaemonLinux.cpp - include Makefile.osx + include Makefile.homebrew else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1) DAEMON_SRC += DaemonLinux.cpp include Makefile.bsd diff --git a/Makefile.homebrew b/Makefile.homebrew new file mode 100644 index 00000000..163b7950 --- /dev/null +++ b/Makefile.homebrew @@ -0,0 +1,29 @@ +# root directory holding homebrew +BREWROOT = /usr/local/ +BOOSTROOT = ${BREWROOT}/opt/boost +SSLROOT = ${BREWROOT}/opt/libressl +CXX = clang++ +CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX +INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include +LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib +LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_program_options -lpthread + +ifeq ($(USE_UPNP),1) + LDFLAGS += -ldl + CXXFLAGS += -DUSE_UPNP +endif + +# OSX Notes +# http://www.hutsby.net/2011/08/macs-with-aes-ni.html +# Seems like all recent Mac's have AES-NI, after firmware upgrade 2.2 +# Found no good way to detect it from command line. TODO: Might be some osx sysinfo magic +# note from psi: 2009 macbook does not have aesni +#ifeq ($(USE_AESNI),yes) +# CXXFLAGS += -maes -DAESNI +#endif + +# Disabled, since it will be the default make rule. I think its better +# to define the default rule in Makefile and not Makefile. - torkel +#install: all +# test -d ${PREFIX} || mkdir -p ${PREFIX}/ +# cp -r i2p ${PREFIX}/ diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index d02eb5df..d173d4ae 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -93,6 +93,21 @@ If you need UPnP support (don't forget to run CMake with `WITH_UPNP=ON`) miniupn miniupnpc-devel ``` +MAC OS X +-------- + +Requires homebrew + +```bash +brew install libressl boost +``` + +Then build: +```bash +make +``` + + FreeBSD ------- From ca36a6fe41afffc1f9f8f2fd69ded564a71e69a8 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 10 May 2016 15:55:48 -0400 Subject: [PATCH 75/76] update our IP after signture verification --- SSUSession.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/SSUSession.cpp b/SSUSession.cpp index aa534c56..a1bbf4d9 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -265,8 +265,6 @@ namespace transport uint16_t ourPort = bufbe16toh (payload); s.Insert (payload, 2); // our port payload += 2; // port - LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); - i2p::context.UpdateAddress (ourIP); if (m_RemoteEndpoint.address ().is_v4 ()) s.Insert (m_RemoteEndpoint.address ().to_v4 ().to_bytes ().data (), 4); // remote IP v4 else @@ -283,11 +281,18 @@ namespace transport //TODO: since we are accessing a uint8_t this is unlikely to crash due to alignment but should be improved m_SessionKeyDecryption.SetIV (((SSUHeader *)buf)->iv); m_SessionKeyDecryption.Decrypt (payload, signatureLen, payload); // TODO: non-const payload - // verify - if (!s.Verify (m_RemoteIdentity, payload)) + // verify signature + if (s.Verify (m_RemoteIdentity, payload)) + { + LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort); + i2p::context.UpdateAddress (ourIP); + SendSessionConfirmed (y, ourAddress, addressSize + 2); + } + else + { LogPrint (eLogError, "SSU: message 'created' signature verification failed"); - - SendSessionConfirmed (y, ourAddress, addressSize + 2); + Failed (); + } } void SSUSession::ProcessSessionConfirmed (const uint8_t * buf, size_t len) @@ -313,11 +318,17 @@ namespace transport paddingSize &= 0x0F; // %16 if (paddingSize > 0) paddingSize = 16 - paddingSize; payload += paddingSize; - // verify - if (m_SignedData && !m_SignedData->Verify (m_RemoteIdentity, payload)) + // verify signature + if (m_SignedData && m_SignedData->Verify (m_RemoteIdentity, payload)) + { + m_Data.Send (CreateDeliveryStatusMsg (0)); + Established (); + } + else + { LogPrint (eLogError, "SSU message 'confirmed' signature verification failed"); - m_Data.Send (CreateDeliveryStatusMsg (0)); - Established (); + Failed (); + } } void SSUSession::SendSessionRequest () From aa215f2a5a975742ad78410caf59be49c6759ce3 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 11 May 2016 07:08:02 -0400 Subject: [PATCH 76/76] regular/homebrew build selection for Mac OS X --- Makefile | 6 +++++- docs/build_notes_unix.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index db6da2df..e3807d93 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,11 @@ USE_STATIC := no ifeq ($(UNAME),Darwin) DAEMON_SRC += DaemonLinux.cpp - include Makefile.homebrew + ifeq ($(HOMEBREW),1) + include Makefile.homebrew + else + include Makefile.osx + endif else ifeq ($(shell echo $(UNAME) | $(GREP) -c FreeBSD),1) DAEMON_SRC += DaemonLinux.cpp include Makefile.bsd diff --git a/docs/build_notes_unix.md b/docs/build_notes_unix.md index d173d4ae..05605343 100644 --- a/docs/build_notes_unix.md +++ b/docs/build_notes_unix.md @@ -104,7 +104,7 @@ brew install libressl boost Then build: ```bash -make +make HOMEBREW=1 ```