From 09a80ed6541ad69ad8a47c29cba14c056aea148d Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 29 May 2016 16:35:57 -0400 Subject: [PATCH 01/25] RequestVariableLeaseSetMessage --- I2CP.cpp | 17 +++++++++++++++-- I2CP.h | 13 ++++++++----- LeaseSet.cpp | 1 + LeaseSet.h | 5 ++++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index ee329d37..bb7c956b 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -2,6 +2,7 @@ #include "I2PEndian.h" #include "Log.h" #include "Timestamp.h" +#include "LeaseSet.h" #include "I2CP.h" namespace i2p @@ -14,13 +15,25 @@ namespace client { } + void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) + { + i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPublicKey, tunnels); + uint8_t * leases = ls.GetLeases (); + leases[-1] = tunnels.size (); + htobe16buf (leases - 3, m_Owner.GetSessionID ()); + size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); + m_Owner.SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); + + } + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), - m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0) + m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), + m_SessionID (0) { ReadProtocolByte (); } - + I2CPSession::~I2CPSession () { delete[] m_NextMessage; diff --git a/I2CP.h b/I2CP.h index f677b9ee..3de7d73e 100644 --- a/I2CP.h +++ b/I2CP.h @@ -21,7 +21,8 @@ namespace client const uint8_t I2CP_GET_DATE_MESSAGE = 32; const uint8_t I2CP_SET_DATE_MESSAGE = 33; const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1; - + const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; + class I2CPSession; class I2CPDestination: public LeaseSetDestination { @@ -38,7 +39,7 @@ namespace client // I2CP void HandleDataMessage (const uint8_t * buf, size_t len) { /* TODO */ }; - void CreateNewLeaseSet (std::vector > tunnels) { /* TODO */ }; + void CreateNewLeaseSet (std::vector > tunnels); private: @@ -55,6 +56,9 @@ namespace client I2CPSession (I2CPServer& owner, std::shared_ptr socket); ~I2CPSession (); + uint16_t GetSessionID () const { return m_SessionID; }; + void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); + // message handlers void GetDateMessageHandler (const uint8_t * buf, size_t len); void CreateSessionMessageHandler (const uint8_t * buf, size_t len); @@ -66,10 +70,8 @@ namespace client void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleNextMessage (const uint8_t * buf); void Terminate (); - - void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); + void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf); - std::string ExtractString (const uint8_t * buf, size_t len); size_t PutString (uint8_t * buf, size_t len, const std::string& str); @@ -81,6 +83,7 @@ namespace client size_t m_NextMessageLen, m_NextMessageOffset; std::shared_ptr m_Destination; + uint16_t m_SessionID; }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 5efe2b16..20861677 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -213,6 +213,7 @@ namespace data m_Buffer[offset] = num; offset++; // leases + m_Leases = m_Buffer + offset; auto currentTime = i2p::util::GetMillisecondsSinceEpoch (); for (int i = 0; i < num; i++) { diff --git a/LeaseSet.h b/LeaseSet.h index 289ae25c..6688fbf8 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "Identity.h" @@ -94,6 +95,8 @@ namespace data uint8_t * GetSignature () { return m_Buffer + m_BufferLen - GetSignatureLen (); }; size_t GetBufferLen () const { return m_BufferLen; }; size_t GetSignatureLen () const { return m_Identity->GetSignatureLen (); }; + uint8_t * GetLeases () { return m_Leases; }; + const IdentHash& GetIdentHash () const { return m_Identity->GetIdentHash (); }; bool IsExpired () const; bool operator== (const LeaseSet& other) const @@ -104,7 +107,7 @@ namespace data uint64_t m_ExpirationTime; // in milliseconds std::shared_ptr m_Identity; - uint8_t * m_Buffer; + uint8_t * m_Buffer, * m_Leases; size_t m_BufferLen; }; } From 5a2c4919c6c415bcb22aeae8cbd5f579aa90bcea Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 09:41:45 -0400 Subject: [PATCH 02/25] close previous file first upon repon --- Log.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Log.cpp b/Log.cpp index 36fcebf3..0518fb2e 100644 --- a/Log.cpp +++ b/Log.cpp @@ -130,10 +130,13 @@ namespace log { Process(); } - void Log::SendTo (const std::string& path) { + void Log::SendTo (const std::string& path) + { + if (m_LogStream) m_LogStream = nullptr; // close previous auto flags = std::ofstream::out | std::ofstream::app; auto os = std::make_shared (path, flags); - if (os->is_open ()) { + if (os->is_open ()) + { m_Logfile = path; m_Destination = eLogFile; m_LogStream = os; From 6a453bcc8a51c740a6a23edbae683f01aa5ba54c Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 12:08:20 -0400 Subject: [PATCH 03/25] check for null pointer --- Log.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Log.cpp b/Log.cpp index 0518fb2e..155efbe8 100644 --- a/Log.cpp +++ b/Log.cpp @@ -56,7 +56,7 @@ namespace log { #endif case eLogFile: case eLogStream: - m_LogStream->flush(); + if (m_LogStream) m_LogStream->flush(); break; default: /* do nothing */ @@ -107,10 +107,11 @@ namespace log { #endif case eLogFile: case eLogStream: - *m_LogStream << TimeAsString(msg->timestamp) - << "@" << short_tid - << "/" << g_LogLevelStr[msg->level] - << " - " << msg->text << std::endl; + if (m_LogStream) + *m_LogStream << TimeAsString(msg->timestamp) + << "@" << short_tid + << "/" << g_LogLevelStr[msg->level] + << " - " << msg->text << std::endl; break; case eLogStdout: default: From a062bca431e5ca9d36f79837b06956e78ea2ba27 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 12:56:42 -0400 Subject: [PATCH 04/25] CreateLeaseSetMessage --- Destination.h | 1 - I2CP.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++--- I2CP.h | 21 +++++++++++++++++---- Identity.h | 1 - LeaseSet.cpp | 8 ++++++++ LeaseSet.h | 3 +++ 6 files changed, 70 insertions(+), 9 deletions(-) diff --git a/Destination.h b/Destination.h index 56c83fb4..e64508c9 100644 --- a/Destination.h +++ b/Destination.h @@ -168,7 +168,6 @@ namespace client // implements LocalDestination const uint8_t * GetEncryptionPrivateKey () const { return m_EncryptionPrivateKey; }; - const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; }; std::shared_ptr GetIdentity () const { return m_Keys.GetPublic (); }; protected: diff --git a/I2CP.cpp b/I2CP.cpp index bb7c956b..b0e889ac 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #include #include "I2PEndian.h" #include "Log.h" @@ -15,9 +23,15 @@ namespace client { } + void I2CPDestination::SetEncryptionPrivateKey (const uint8_t * key) + { + memcpy (m_EncryptionPrivateKey, key, 256); + } + void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) { - i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPublicKey, tunnels); + i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPrivateKey, tunnels); // we don't care about encryption key + m_LeaseSetExpirationTime = ls.GetExpirationTime (); uint8_t * leases = ls.GetLeases (); leases[-1] = tunnels.size (); htobe16buf (leases - 3, m_Owner.GetSessionID ()); @@ -25,7 +39,14 @@ namespace client m_Owner.SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); } - + + void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) + { + auto ls = new i2p::data::LocalLeaseSet (m_Identity, buf, len); + ls->SetExpirationTime (m_LeaseSetExpirationTime); + SetLeaseSet (ls); + } + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), @@ -174,11 +195,29 @@ namespace client m_Destination = std::make_shared(*this, nullptr, false); } + void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len) + { + uint16_t sessionID = bufbe16toh (buf); + if (sessionID == m_SessionID) + { + size_t offset = 2; + if (m_Destination) + { + m_Destination->SetEncryptionPrivateKey (buf + offset); + offset += 256; + m_Destination->LeaseSetCreated (buf + offset, len - offset); + } + } + else + LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); + } + I2CPServer::I2CPServer (const std::string& interface, int port) { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; - m_MessagesHandlers[I2CP_CREATE_SESSION_MESSAGE ] = &I2CPSession::CreateSessionMessageHandler; + m_MessagesHandlers[I2CP_CREATE_SESSION_MESSAGE] = &I2CPSession::CreateSessionMessageHandler; + m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; } } } diff --git a/I2CP.h b/I2CP.h index 3de7d73e..73f63432 100644 --- a/I2CP.h +++ b/I2CP.h @@ -1,3 +1,11 @@ +/* +* Copyright (c) 2013-2016, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +*/ + #ifndef I2CP_H__ #define I2CP_H__ @@ -22,7 +30,8 @@ namespace client const uint8_t I2CP_SET_DATE_MESSAGE = 33; const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1; const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; - + const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; + class I2CPSession; class I2CPDestination: public LeaseSetDestination { @@ -30,11 +39,13 @@ namespace client I2CPDestination (I2CPSession& owner, std::shared_ptr identity, bool isPublic); + void SetEncryptionPrivateKey (const uint8_t * key); + void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession + protected: // implements LocalDestination const uint8_t * GetEncryptionPrivateKey () const { return m_EncryptionPrivateKey; }; - const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionPublicKey; }; std::shared_ptr GetIdentity () const { return m_Identity; }; // I2CP @@ -45,7 +56,8 @@ namespace client I2CPSession& m_Owner; std::shared_ptr m_Identity; - uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256]; + uint8_t m_EncryptionPrivateKey[256]; + uint64_t m_LeaseSetExpirationTime; }; class I2CPServer; @@ -62,6 +74,7 @@ namespace client // message handlers void GetDateMessageHandler (const uint8_t * buf, size_t len); void CreateSessionMessageHandler (const uint8_t * buf, size_t len); + void CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len); private: @@ -95,7 +108,7 @@ namespace client private: - I2CPMessageHandler m_MessagesHandlers[256]; + I2CPMessageHandler m_MessagesHandlers[256]; public: diff --git a/Identity.h b/Identity.h index 2a60ddd3..841acf65 100644 --- a/Identity.h +++ b/Identity.h @@ -179,7 +179,6 @@ namespace data virtual ~LocalDestination() {}; virtual const uint8_t * GetEncryptionPrivateKey () const = 0; - virtual const uint8_t * GetEncryptionPublicKey () const = 0; virtual std::shared_ptr GetIdentity () const = 0; const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 20861677..16a470e0 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -232,6 +232,14 @@ namespace data // we don't sign it yet. must be signed later on } + LocalLeaseSet::LocalLeaseSet (std::shared_ptr identity, const uint8_t * buf, size_t len): + m_ExpirationTime (0), m_Identity (identity) + { + m_BufferLen = len; + m_Buffer = new uint8_t[m_BufferLen]; + memcpy (m_Buffer, buf, len); + } + bool LocalLeaseSet::IsExpired () const { auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/LeaseSet.h b/LeaseSet.h index 6688fbf8..c174ac39 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -89,6 +89,7 @@ namespace data public: LocalLeaseSet (std::shared_ptr identity, const uint8_t * encryptionPublicKey, std::vector > tunnels); + LocalLeaseSet (std::shared_ptr identity, const uint8_t * buf, size_t len); ~LocalLeaseSet () { delete[] m_Buffer; }; const uint8_t * GetBuffer () const { return m_Buffer; }; @@ -99,6 +100,8 @@ namespace data const IdentHash& GetIdentHash () const { return m_Identity->GetIdentHash (); }; bool IsExpired () const; + uint64_t GetExpirationTime () const { return m_ExpirationTime; }; + void SetExpirationTime (uint64_t expirationTime) { m_ExpirationTime = expirationTime; }; bool operator== (const LeaseSet& other) const { return m_BufferLen == other.GetBufferLen () && !memcmp (other.GetBuffer (), other.GetBuffer (), m_BufferLen); }; From ae10793d0f2f559727d38b8e3769ac0e8b019824 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 14:31:56 -0400 Subject: [PATCH 05/25] SendMessageMessage --- I2CP.cpp | 31 ++++++++++++++++++++++++++++++- I2CP.h | 3 +++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/I2CP.cpp b/I2CP.cpp index b0e889ac..b74e9cc8 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -47,6 +47,17 @@ namespace client SetLeaseSet (ls); } + void I2CPDestination::SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident) + { + auto msg = NewI2NPMessage (); + uint8_t * buf = msg->GetPayload (); + htobe32buf (buf, len); + memcpy (buf + 4, payload, len); + msg->len += len + 4; + msg->FillI2NPMessageHeader (eI2NPData); + // TODO: send + } + I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), @@ -212,12 +223,30 @@ namespace client LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); } + void I2CPSession::SendMessageMessageHandler (const uint8_t * buf, size_t len) + { + uint16_t sessionID = bufbe16toh (buf); + if (sessionID == m_SessionID) + { + size_t offset = 2; + if (m_Destination) + { + i2p::data::IdentityEx identity; + offset += identity.FromBuffer (buf + offset, len - offset); + m_Destination->SendMsgTo (buf + offset, len - offset, identity.GetIdentHash ()); + } + } + else + LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); + } + I2CPServer::I2CPServer (const std::string& interface, int port) { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; m_MessagesHandlers[I2CP_CREATE_SESSION_MESSAGE] = &I2CPSession::CreateSessionMessageHandler; - m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; + m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; + m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; } } } diff --git a/I2CP.h b/I2CP.h index 73f63432..4e0f1caf 100644 --- a/I2CP.h +++ b/I2CP.h @@ -31,6 +31,7 @@ namespace client const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1; const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; + const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; class I2CPSession; class I2CPDestination: public LeaseSetDestination @@ -41,6 +42,7 @@ namespace client void SetEncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession + void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident); // called from I2CPSession protected: @@ -75,6 +77,7 @@ namespace client void GetDateMessageHandler (const uint8_t * buf, size_t len); void CreateSessionMessageHandler (const uint8_t * buf, size_t len); void CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len); + void SendMessageMessageHandler (const uint8_t * buf, size_t len); private: From eeffcea69e6fdabcc530ac6eb7f773bd728b5678 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 15:19:22 -0400 Subject: [PATCH 06/25] CreateSessionMessage --- I2CP.cpp | 28 ++++++++++++++++++++++++++-- I2CP.h | 3 +++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index b74e9cc8..8d0bedf1 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -7,6 +7,7 @@ */ #include +#include #include "I2PEndian.h" #include "Log.h" #include "Timestamp.h" @@ -202,8 +203,31 @@ namespace client void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len) { - // TODO - m_Destination = std::make_shared(*this, nullptr, false); + auto identity = std::make_shared(); + size_t offset = identity->FromBuffer (buf, len); + uint16_t optionsSize = bufbe16toh (buf + offset); + // TODO: extract options + offset += optionsSize; + offset += 8; // date + if (identity->Verify (buf, offset, buf + offset)) // signature + { + m_Destination = std::make_shared(*this, identity, false); + RAND_bytes ((uint8_t *)&m_SessionID, 2); + SendSessionStatusMessage (1); // created + } + else + { + LogPrint (eLogError, "I2CP: create session signature verification falied"); + SendSessionStatusMessage (3); // invalid + } + } + + void I2CPSession::SendSessionStatusMessage (uint8_t status) + { + uint8_t buf[3]; + htobe16buf (buf, m_SessionID); + buf[2] = status; + SendI2CPMessage (I2CP_SESSION_STATUS_MESSAGE, buf, 3); } void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len) diff --git a/I2CP.h b/I2CP.h index 4e0f1caf..fca3317d 100644 --- a/I2CP.h +++ b/I2CP.h @@ -29,6 +29,7 @@ namespace client const uint8_t I2CP_GET_DATE_MESSAGE = 32; const uint8_t I2CP_SET_DATE_MESSAGE = 33; const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1; + const uint8_t I2CP_SESSION_STATUS_MESSAGE = 20; const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; @@ -91,6 +92,8 @@ namespace client std::string ExtractString (const uint8_t * buf, size_t len); size_t PutString (uint8_t * buf, size_t len, const std::string& str); + void SendSessionStatusMessage (uint8_t status); + private: I2CPServer& m_Owner; From 23e019ec83db38b3f0b0f27aaa2eb02ba953469e Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 07/25] * debian/i2pd.openrc (working version) --- debian/i2pd.openrc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/debian/i2pd.openrc b/debian/i2pd.openrc index ddcb4003..6253cfa6 100644 --- a/debian/i2pd.openrc +++ b/debian/i2pd.openrc @@ -5,11 +5,9 @@ logfile="/var/log/i2pd.log" mainconf="/etc/i2pd/i2pd.conf" tunconf="/etc/i2pd/tunnels.conf" -. /etc/default/i2pd - name="i2pd" command="/usr/sbin/i2pd" -command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf" +command_args="--service --daemon --log=file --logfile=$logfile --conf=$mainconf --tunconf=$tunconf --pidfile=$pidfile" description="i2p router written in C++" required_dirs="/var/lib/i2pd" required_files="$mainconf" @@ -22,6 +20,22 @@ depend() { } start_pre() { - checkpath -f -o i2pd:adm -w $pidfile - checkpath -f -o i2pd:adm -w $logfile + if [ -r /etc/default/i2pd ]; then + . /etc/default/i2pd + fi + + if [ "x$I2PD_ENABLED" != "xyes" ]; then + ewarn "i2pd disabled in /etc/default/i2pd" + exit 1 + fi + + checkpath -f -o i2pd:adm $logfile + checkpath -f -o i2pd:adm $pidfile + + if [ -n "$I2PD_PORT" -a "$I2PD_PORT" -gt 0 ]; then + command_args="$command_args --port=$I2PD_PORT" + fi + if [ -n "$DAEMON_OPTS" ]; then + command_args="$command_args $DAEMON_OPTS" + fi } From 289b679e3c6153a70ae3193fba93dc7242f2c24e Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 08/25] * add doxygen support --- Makefile | 5 + docs/Doxyfile | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 docs/Doxyfile diff --git a/Makefile b/Makefile index e3807d93..4cc313a9 100644 --- a/Makefile +++ b/Makefile @@ -76,6 +76,7 @@ $(ARLIB_CLIENT): $(patsubst %.cpp,obj/%.o,$(LIB_CLIENT_SRC)) clean: rm -rf obj + rm -rf docs/generated $(RM) $(I2PD) $(SHLIB) $(ARLIB) $(SHLIB_CLIENT) $(ARLIB_CLIENT) strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB) @@ -86,9 +87,13 @@ dist: git archive --format=tar.gz -9 --worktree-attributes \ --prefix=i2pd_$(LATEST_TAG)/ $(LATEST_TAG) -o i2pd_$(LATEST_TAG).tar.gz +doxygen: + doxygen -s docs/Doxyfile + .PHONY: all .PHONY: clean .PHONY: deps +.PHONY: doxygen .PHONY: dist .PHONY: api .PHONY: api_client diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 00000000..f2e29995 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,259 @@ +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "i2pd" +PROJECT_NUMBER = +PROJECT_BRIEF = "load-balanced unspoofable packet switching network" +PROJECT_LOGO = +OUTPUT_DIRECTORY = docs/generated +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +INPUT = +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.cpp *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +CLANG_ASSISTED_PARSING = NO +CLANG_OPTIONS = +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES From c9836cf0f787c7ee8a0b3553653b80148299becb Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 09/25] * fix doxygen warnings --- Config.h | 4 ++-- HTTP.h | 16 +++++++++------- Log.cpp | 2 +- Log.h | 7 ++++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Config.h b/Config.h index d79a9c47..6b2af717 100644 --- a/Config.h +++ b/Config.h @@ -68,7 +68,7 @@ namespace config { * @param value Variable where to store option * @return this function returns false if parameter not found * - * @example uint16_t port; GetOption("sam.port", port); + * Example: uint16_t port; GetOption("sam.port", port); */ template bool GetOption(const char *name, T& value) { @@ -84,7 +84,7 @@ namespace config { * @param value New parameter value * @return true if value set up successful, false otherwise * - * @example uint16_t port = 2827; SetOption("bob.port", port); + * Example: uint16_t port = 2827; SetOption("bob.port", port); */ template bool SetOption(const char *name, const T& value) { diff --git a/HTTP.h b/HTTP.h index f227271f..8d10c231 100644 --- a/HTTP.h +++ b/HTTP.h @@ -38,7 +38,7 @@ namespace http { * @brief Tries to parse url from string * @return true on success, false on invalid url */ - bool parse (const char *str, size_t len = 0); + bool parse (const char *str, std::size_t len = 0); bool parse (const std::string& url); /** @@ -89,10 +89,12 @@ namespace http { std::string version; std::string status; unsigned short int code; - /** simplifies response generation - * If this variable is set: - * a) Content-Length header will be added if missing - * b) contents of body will be included in response + /** + * @brief Simplifies response generation + * + * If this variable is set, on @a to_string() call: + * * Content-Length header will be added if missing, + * * contents of @a body will be included in generated response */ std::string body; @@ -108,9 +110,9 @@ namespace http { /** * @brief Serialize HTTP response to string - * @note If version is set to HTTP/1.1, and Date header is missing, + * @note If @a version is set to HTTP/1.1, and Date header is missing, * it will be generated based on current time and added to headers - * @note If body member is set and Content-Length header is missing, + * @note If @a body is set and Content-Length header is missing, * this header will be added, based on body's length */ std::string to_string(); diff --git a/Log.cpp b/Log.cpp index 155efbe8..590f3d0f 100644 --- a/Log.cpp +++ b/Log.cpp @@ -12,7 +12,7 @@ namespace i2p { namespace log { Log logger; /** - * @enum Maps our loglevel to their symbolic name + * @brief Maps our loglevel to their symbolic name */ static const char * g_LogLevelStr[eNumLogLevels] = { diff --git a/Log.h b/Log.h index 33bd5868..6762899f 100644 --- a/Log.h +++ b/Log.h @@ -86,7 +86,7 @@ namespace log { LogLevel GetLogLevel () { return m_MinLevel; }; /** - * @brief Sets minimal alloed level for log messages + * @brief Sets minimal allowed level for log messages * @param level String with wanted minimal msg level */ void SetLogLevel (const std::string& level); @@ -101,7 +101,7 @@ namespace log { * @brief Sets log destination to given output stream * @param os Output stream */ - void SendTo (std::shared_ptr s); + void SendTo (std::shared_ptr os); #ifndef _WIN32 /** @@ -129,7 +129,8 @@ namespace log { }; /** - * @struct Log message container + * @struct LogMsg + * @brief Log message container * * We creating it somewhere with LogPrint(), * then put in MsgQueue for later processing. From a47417ff49f46c5a1f92819b54c43960607e206e Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 10/25] * I2PService.cpp: tune logs --- I2PService.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/I2PService.cpp b/I2PService.cpp index 0aefc172..6a0cd291 100644 --- a/I2PService.cpp +++ b/I2PService.cpp @@ -3,7 +3,6 @@ #include "ClientContext.h" #include "I2PService.h" - namespace i2p { namespace client @@ -71,7 +70,7 @@ namespace client std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else { - LogPrint(eLogError, "TCPIPPipe: no upstream socket for read"); + LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket"); } } @@ -82,14 +81,14 @@ namespace client std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } else { - LogPrint(eLogError, "TCPIPPipe: no downstream socket for read"); + LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket"); } } void TCPIPPipe::UpstreamWrite(const uint8_t * buf, size_t len) { if (m_up) { - LogPrint(eLogDebug, "TCPIPPipe: write upstream ", (int)len); + LogPrint(eLogDebug, "TCPIPPipe: upstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_up, boost::asio::buffer(buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleUpstreamWrite, @@ -97,14 +96,14 @@ namespace client std::placeholders::_1) ); } else { - LogPrint(eLogError, "tcpip pipe upstream socket null"); + LogPrint(eLogError, "TCPIPPipe: upstream write: no socket"); } } void TCPIPPipe::DownstreamWrite(const uint8_t * buf, size_t len) { if (m_down) { - LogPrint(eLogDebug, "TCPIPPipe: write downstream ", (int)len); + LogPrint(eLogDebug, "TCPIPPipe: downstream: ", (int) len, " bytes written"); boost::asio::async_write(*m_down, boost::asio::buffer(buf, len), boost::asio::transfer_all(), std::bind(&TCPIPPipe::HandleDownstreamWrite, @@ -112,16 +111,16 @@ namespace client std::placeholders::_1) ); } else { - LogPrint(eLogError, "tcpip pipe downstream socket null"); + LogPrint(eLogError, "TCPIPPipe: downstream write: no socket"); } } void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { - LogPrint(eLogDebug, "TCPIPPipe downstream got ", (int) bytes_transfered); + LogPrint(eLogDebug, "TCPIPPipe: downstream: ", (int) bytes_transfered, " bytes received"); if (ecode) { - LogPrint(eLogError, "TCPIPPipe Downstream read error:" , ecode.message()); + LogPrint(eLogError, "TCPIPPipe: downstream read error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } else { @@ -135,7 +134,7 @@ namespace client void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) { if (ecode) { - LogPrint(eLogError, "TCPIPPipe Downstream write error:" , ecode.message()); + LogPrint(eLogError, "TCPIPPipe: downstream write error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } @@ -143,7 +142,7 @@ namespace client void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) { if (ecode) { - LogPrint(eLogError, "TCPIPPipe Upstream write error:" , ecode.message()); + LogPrint(eLogError, "TCPIPPipe: upstream write error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } @@ -151,9 +150,9 @@ namespace client void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { - LogPrint(eLogDebug, "TCPIPPipe upstream got ", (int) bytes_transfered); + LogPrint(eLogDebug, "TCPIPPipe: upstream ", (int) bytes_transfered, , " bytes received"); if (ecode) { - LogPrint(eLogError, "TCPIPPipe Upstream read error:" , ecode.message()); + LogPrint(eLogError, "TCPIPPipe: upstream read error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) Terminate(); } else { @@ -206,6 +205,5 @@ namespace client LogPrint (eLogError, "I2PService: ", GetName(), " closing socket on accept because: ", ecode.message ()); } } - } } From f66f4ffee6f845ecf4c3c6218051bec393e724bd Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 11/25] * add generic changelog (#502) --- ChangeLog | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 ChangeLog diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..9a32e42f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,86 @@ +# for this file format description, +# see https://github.com/olivierlacan/keep-a-changelog + +## [2.8.0] - UNRELEASED +### Changed +- Proxy refactoring & speedup +- I2PControl refactoring & fixes (proper jsonrpc responses on errors) +- boost::regex no more needed + +### Fixed +- initscripts: added openrc one, in sysv-ish make I2PD_PORT optional + +## [2.7.0] - 2016-05-18 +### Added +- Precomputed El-Gamal/DH tables +- Configurable limit of transit tunnels + +### Changed +- Speed-up of assymetric crypto for non-x64 platforms +- Refactoring of web-console + +## [2.6.0] - 2016-03-31 +### Added +- Gracefull shutdown on SIGINT +- Numeric bandwidth limits (was: by router class) +- Jumpservices in web-console +- Logging to syslog +- Tray icon for windows application + +### Changed +- Logs refactoring +- Improved statistics in web-console + +### Deprecated: +- Renamed main/tunnels config files (will use old, if found, but emits warning) + +## [2.5.1] - 2016-03-10 +### Fixed +- Doesn't create ~/.i2pd dir if missing + +## [2.5.0] - 2016-03-04 +### Added +- IRC server tunnels +- SOCKS outproxy support +- Support for gzipped addressbook updates +- Support for router families + +### Changed +- Shared RTT/RTO between streams +- Filesystem work refactoring + +## [2.4.0] - 2016-02-03 +### Added +- X-I2P-* headers for server http-tunnels +- I2CP options for I2P tunnels +- Show I2P tunnels in webconsole + +### Changed +- Refactoring of cmdline/config parsing + +## [2.3.0] - 2016-01-12 +### Added +- Support for new router bandwidth class codes (P and X) +- I2PControl supports external webui +- Added --pidfile and --notransit parameters +- Ability to specify signature type for i2p tunnel + +### Changed +- Fixed multiple floodfill-related bugs +- New webconsole layout + +## [2.2.0] - 2015-12-22 +### Added +- Ability to connect to router without ip via introducer + +### Changed +- Persist temporary encryption keys for local destinations +- Performance improvements for EdDSA +- New addressbook structure + +## [2.1.0] - 2015-11-12 +### Added +- Implementation of EdDSA + +### Changed +- EdDSA is default signature type for new RouterInfos From f9718bccb9c06e94ee412afdb5a378f8acfbeff6 Mon Sep 17 00:00:00 2001 From: hagen Date: Tue, 31 May 2016 00:00:00 +0000 Subject: [PATCH 12/25] * update debian changelog (closes #502) --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 52bca793..5ac732e0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.7.0-1) unstable; urgency=low + + * updated to version 2.7.0/0.9.25 + + -- hagen Wed, 18 May 2016 01:11:04 +0000 + i2pd (2.2.0-2) unstable; urgency=low * updated to version 2.2.0 From 846ff46b2e2bf243411bfc2586f37b08e2e725ec Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 30 May 2016 21:42:25 -0400 Subject: [PATCH 13/25] fixed build error --- I2PService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/I2PService.cpp b/I2PService.cpp index 6a0cd291..9bbe1521 100644 --- a/I2PService.cpp +++ b/I2PService.cpp @@ -150,7 +150,7 @@ namespace client void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered) { - LogPrint(eLogDebug, "TCPIPPipe: upstream ", (int) bytes_transfered, , " bytes received"); + LogPrint(eLogDebug, "TCPIPPipe: upstream ", (int)bytes_transfered, " bytes received"); if (ecode) { LogPrint(eLogError, "TCPIPPipe: upstream read error:" , ecode.message()); if (ecode != boost::asio::error::operation_aborted) From 025eec1782994d01c46a28ac9be973be5a8200dd Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 May 2016 11:54:45 -0400 Subject: [PATCH 14/25] I2CP configuration --- ClientContext.cpp | 26 +++++++++++++ Config.cpp | 8 ++++ I2CP.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++-- I2CP.h | 23 +++++++++++ 4 files changed, 151 insertions(+), 4 deletions(-) diff --git a/ClientContext.cpp b/ClientContext.cpp index df0de4e5..db1c8e6a 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -114,6 +114,24 @@ namespace client } } + // I2CP + bool i2cp; i2p::config::GetOption("i2cp.enabled", i2cp); + if (i2cp) + { + std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr); + uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort); + LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort); + try + { + m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort); + m_I2CPServer->Start (); + } + catch (std::exception& e) + { + LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what()); + } + } + m_AddressBook.StartResolvers (); } @@ -165,6 +183,14 @@ namespace client m_BOBCommandChannel = nullptr; } + if (m_I2CPServer) + { + LogPrint(eLogInfo, "Clients: stopping I2CP"); + m_I2CPServer->Stop (); + delete m_I2CPServer; + m_I2CPServer = nullptr; + } + LogPrint(eLogInfo, "Clients: stopping AddressBook"); m_AddressBook.Stop (); for (auto it: m_Destinations) diff --git a/Config.cpp b/Config.cpp index 44dec286..d9b4091d 100644 --- a/Config.cpp +++ b/Config.cpp @@ -178,6 +178,13 @@ namespace config { ("bob.port", value()->default_value(2827), "BOB listen port") ; + options_description i2cp("I2CP options"); + bob.add_options() + ("i2cp.enabled", value()->default_value(false), "Enable or disable I2CP") + ("i2cp.address", value()->default_value("127.0.0.1"), "I2CP listen address") + ("i2cp.port", value()->default_value(7654), "I2CP listen port") + ; + options_description i2pcontrol("I2PControl options"); i2pcontrol.add_options() ("i2pcontrol.enabled", value()->default_value(false), "Enable or disable I2P Control Protocol") @@ -207,6 +214,7 @@ namespace config { .add(socksproxy) .add(sam) .add(bob) + .add(i2cp) .add(i2pcontrol) .add(precomputation) ; diff --git a/I2CP.cpp b/I2CP.cpp index 8d0bedf1..94d5db7f 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -61,9 +61,9 @@ namespace client I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), - m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), - m_SessionID (0) + m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0) { + RAND_bytes ((uint8_t *)&m_SessionID, 2); ReadProtocolByte (); } @@ -72,6 +72,10 @@ namespace client delete[] m_NextMessage; } + void I2CPSession::Close () + { + } + void I2CPSession::ReadProtocolByte () { if (m_Socket) @@ -148,6 +152,12 @@ namespace client void I2CPSession::Terminate () { + if (m_Destination) + { + m_Destination->Stop (); + m_Destination = nullptr; + } + m_Owner.RemoveSession (GetSessionID ()); } void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) @@ -212,7 +222,7 @@ namespace client if (identity->Verify (buf, offset, buf + offset)) // signature { m_Destination = std::make_shared(*this, identity, false); - RAND_bytes ((uint8_t *)&m_SessionID, 2); + m_Destination->Start (); SendSessionStatusMessage (1); // created } else @@ -264,7 +274,9 @@ namespace client LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); } - I2CPServer::I2CPServer (const std::string& interface, int port) + I2CPServer::I2CPServer (const std::string& interface, int port): + m_IsRunning (false), m_Thread (nullptr), + m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) { memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; @@ -272,6 +284,84 @@ namespace client m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; } + + I2CPServer::~I2CPServer () + { + if (m_IsRunning) + Stop (); + } + + void I2CPServer::Start () + { + Accept (); + m_IsRunning = true; + m_Thread = new std::thread (std::bind (&I2CPServer::Run, this)); + } + + void I2CPServer::Stop () + { + m_IsRunning = false; + m_Acceptor.cancel (); + for (auto it: m_Sessions) + it.second->Close (); + m_Sessions.clear (); + m_Service.stop (); + if (m_Thread) + { + m_Thread->join (); + delete m_Thread; + m_Thread = nullptr; + } + } + + void I2CPServer::Run () + { + while (m_IsRunning) + { + try + { + m_Service.run (); + } + catch (std::exception& ex) + { + LogPrint (eLogError, "I2CP: runtime exception: ", ex.what ()); + } + } + } + + void I2CPServer::Accept () + { + auto newSocket = std::make_shared (m_Service); + m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this, + std::placeholders::_1, newSocket)); + } + + void I2CPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket) + { + if (!ecode && socket) + { + boost::system::error_code ec; + auto ep = socket->remote_endpoint (ec); + if (!ec) + { + LogPrint (eLogDebug, "I2CP: new connection from ", ep); + auto session = std::make_shared(*this, socket); + m_Sessions[session->GetSessionID ()] = session; + } + else + LogPrint (eLogError, "I2CP: incoming connection error ", ec.message ()); + } + else + LogPrint (eLogError, "I2CP: accept error: ", ecode.message ()); + + if (ecode != boost::asio::error::operation_aborted) + Accept (); + } + + void I2CPServer::RemoveSession (uint16_t sessionID) + { + m_Sessions.erase (sessionID); + } } } diff --git a/I2CP.h b/I2CP.h index fca3317d..74ccb3f2 100644 --- a/I2CP.h +++ b/I2CP.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include "Destination.h" @@ -72,6 +74,7 @@ namespace client ~I2CPSession (); uint16_t GetSessionID () const { return m_SessionID; }; + void Close (); void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); // message handlers @@ -111,10 +114,30 @@ namespace client public: I2CPServer (const std::string& interface, int port); + ~I2CPServer (); + + void Start (); + void Stop (); + boost::asio::io_service& GetService () { return m_Service; }; + + void RemoveSession (uint16_t sessionID); + + private: + + void Run (); + + void Accept (); + void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket); private: I2CPMessageHandler m_MessagesHandlers[256]; + std::map > m_Sessions; + + bool m_IsRunning; + std::thread * m_Thread; + boost::asio::io_service m_Service; + boost::asio::ip::tcp::acceptor m_Acceptor; public: From f62d25fa5f9fc36c9e048df43eaf88169f18339b Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 15/25] * Config.cpp : fix wrong group for options & code style --- Config.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Config.cpp b/Config.cpp index d9b4091d..da4f160b 100644 --- a/Config.cpp +++ b/Config.cpp @@ -178,11 +178,11 @@ namespace config { ("bob.port", value()->default_value(2827), "BOB listen port") ; - options_description i2cp("I2CP options"); - bob.add_options() + options_description i2cp("I2CP options"); + i2cp.add_options() ("i2cp.enabled", value()->default_value(false), "Enable or disable I2CP") ("i2cp.address", value()->default_value("127.0.0.1"), "I2CP listen address") - ("i2cp.port", value()->default_value(7654), "I2CP listen port") + ("i2cp.port", value()->default_value(7654), "I2CP listen port") ; options_description i2pcontrol("I2PControl options"); @@ -208,15 +208,15 @@ namespace config { m_OptionsDesc .add(general) - .add(limits) .add(httpserver) .add(httpproxy) .add(socksproxy) .add(sam) .add(bob) - .add(i2cp) + .add(i2cp) .add(i2pcontrol) - .add(precomputation) + .add(precomputation) + .add(limits) ; } From 1b2ac38a507c16a47474145b53f865084f5229dd Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 16/25] * fix compilation warnings --- AddressBook.cpp | 2 +- Daemon.cpp | 4 ++-- Daemon.h | 2 -- DaemonLinux.cpp | 2 +- DaemonWin32.cpp | 2 +- HTTP.cpp | 3 +-- HTTPServer.cpp | 2 +- NetDb.cpp | 3 ++- RouterInfo.cpp | 2 +- Transports.cpp | 2 +- Tunnel.cpp | 2 +- Tunnel.h | 2 +- 12 files changed, 13 insertions(+), 15 deletions(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index 5a07b3c8..0dbb42d7 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -159,7 +159,7 @@ namespace client int AddressBookFilesystemStorage::Save (const std::map& addresses) { - if (addresses.size() == 0) { + if (addresses.empty()) { LogPrint(eLogWarning, "Addressbook: not saving empty addressbook"); return 0; } diff --git a/Daemon.cpp b/Daemon.cpp index c98bce05..7ca28a6f 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -45,10 +45,10 @@ namespace i2p #endif }; - Daemon_Singleton::Daemon_Singleton() : running(1), d(*new Daemon_Singleton_Private()) {}; + Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} Daemon_Singleton::~Daemon_Singleton() { delete &d; - }; + } bool Daemon_Singleton::IsService () const { diff --git a/Daemon.h b/Daemon.h index 031686f7..977d9258 100644 --- a/Daemon.h +++ b/Daemon.h @@ -22,9 +22,7 @@ namespace i2p virtual bool stop(); virtual void run () {}; - bool isLogging; bool isDaemon; - bool running; protected: diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index b408fc70..a3848c8b 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -45,7 +45,7 @@ namespace i2p { bool DaemonLinux::start() { - if (isDaemon == 1) + if (isDaemon) { pid_t pid; pid = fork(); diff --git a/DaemonWin32.cpp b/DaemonWin32.cpp index a6d91da4..3afb70ce 100644 --- a/DaemonWin32.cpp +++ b/DaemonWin32.cpp @@ -45,7 +45,7 @@ namespace i2p return false; } - if (isDaemon == 1) + if (isDaemon) { LogPrint(eLogDebug, "Daemon: running as service"); I2PService service(SERVICE_NAME); diff --git a/HTTP.cpp b/HTTP.cpp index 3f6fd937..ee1010ec 100644 --- a/HTTP.cpp +++ b/HTTP.cpp @@ -406,11 +406,10 @@ namespace http { bool MergeChunkedResponse (std::istream& in, std::ostream& out) { std::string hexLen; - long int len; while (!in.eof ()) { std::getline (in, hexLen); errno = 0; - len = strtoul(hexLen.c_str(), (char **) NULL, 16); + long int len = strtoul(hexLen.c_str(), (char **) NULL, 16); if (errno != 0) return false; /* conversion error */ if (len == 0) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 2af92057..fba4a1be 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -667,7 +667,7 @@ namespace http { i2p::config::GetOption("http.auth", needAuth); i2p::config::GetOption("http.user", user); i2p::config::GetOption("http.pass", pass); - }; + } void HTTPConnection::Receive () { diff --git a/NetDb.cpp b/NetDb.cpp index 3aeff92f..d2afc50a 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -849,7 +849,8 @@ namespace data template std::shared_ptr NetDb::GetRandomRouter (Filter filter) const { - if (!m_RouterInfos.size ()) return 0; + if (m_RouterInfos.empty()) + return 0; uint32_t ind = rand () % m_RouterInfos.size (); for (int j = 0; j < 2; j++) { diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 2e76127c..0ef2f623 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -353,7 +353,7 @@ namespace data if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable if (m_Caps & eUnreachable) caps += CAPS_FLAG_UNREACHABLE; // unreachable - SetProperty ("caps", caps.c_str ()); + SetProperty ("caps", caps); } void RouterInfo::WriteToStream (std::ostream& s) diff --git a/Transports.cpp b/Transports.cpp index 057e2472..2d3d423f 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -606,7 +606,7 @@ namespace transport std::shared_ptr Transports::GetRandomPeer () const { - if (!m_Peers.size ()) return nullptr; + if (m_Peers.empty ()) return nullptr; std::unique_lock l(m_PeersMutex); auto it = m_Peers.begin (); std::advance (it, rand () % m_Peers.size ()); diff --git a/Tunnel.cpp b/Tunnel.cpp index ebaf98c8..1403330b 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -358,7 +358,7 @@ namespace tunnel std::shared_ptr Tunnels::GetNextOutboundTunnel () { - if (!m_OutboundTunnels.size ()) return nullptr; + if (m_OutboundTunnels.empty ()) return nullptr; uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0; std::shared_ptr tunnel; for (auto it: m_OutboundTunnels) diff --git a/Tunnel.h b/Tunnel.h index fe6022ac..43417e5d 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -73,7 +73,7 @@ namespace tunnel bool HandleTunnelBuildResponse (uint8_t * msg, size_t len); - virtual void Print (std::stringstream& s) const {}; + virtual void Print (std::stringstream&) const {}; // implements TunnelBase void SendTunnelDataMsg (std::shared_ptr msg); From f7ca44cad833060de81008d06a4928be101ac440 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 17/25] * fix compile warnings: reopen() usage --- DaemonLinux.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DaemonLinux.cpp b/DaemonLinux.cpp index a3848c8b..1cc0fa85 100644 --- a/DaemonLinux.cpp +++ b/DaemonLinux.cpp @@ -73,10 +73,10 @@ namespace i2p return false; } - // close stdin/stdout/stderr descriptors - freopen("/dev/null", "r", stdin); - freopen("/dev/null", "w", stdout); - freopen("/dev/null", "w", stderr); + // point std{in,out,err} descriptors to /dev/null + stdin = freopen("/dev/null", "r", stdin); + stdout = freopen("/dev/null", "w", stdout); + stderr = freopen("/dev/null", "w", stderr); } // Pidfile From ca2e148ad7388c68891b7ec7684bb7d240913002 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 18/25] * enable -Wextra for linux builds --- Makefile.linux | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.linux b/Makefile.linux index 70307267..e00fd705 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -1,5 +1,5 @@ # set defaults instead redefine -CXXFLAGS ?= -g -Wall +CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic INCFLAGS ?= ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time From 8589493581b761c5764a233b2fb246e7a58e1d94 Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 19/25] * add test for MergeChunkedResponse() (#432) --- tests/Makefile | 3 ++- tests/test-http-merge_chunked.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/test-http-merge_chunked.cpp diff --git a/tests/Makefile b/tests/Makefile index 199b7353..957d4632 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,6 +1,7 @@ CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1 -TESTS = test-http-url test-http-req test-http-res test-http-url_decode +TESTS = test-http-url test-http-req test-http-res test-http-url_decode \ + test-http-merge_chunked all: $(TESTS) run diff --git a/tests/test-http-merge_chunked.cpp b/tests/test-http-merge_chunked.cpp new file mode 100644 index 00000000..ba587a45 --- /dev/null +++ b/tests/test-http-merge_chunked.cpp @@ -0,0 +1,25 @@ +#include +#include "../HTTP.h" + +using namespace i2p::http; + +int main() { + const char *buf = + "4\r\n" + "HTTP\r\n" + "A\r\n" + " response \r\n" + "E\r\n" + "with \r\n" + "chunks.\r\n" + "0\r\n" + "\r\n" + ; + std::stringstream in(buf); + std::stringstream out; + + assert(MergeChunkedResponse(in, out) == true); + assert(out.str() == "HTTP response with \r\nchunks."); + + return 0; +} From cd237219e451b9bec8e13bc852c6726da92e02bc Mon Sep 17 00:00:00 2001 From: hagen Date: Wed, 1 Jun 2016 00:00:00 +0000 Subject: [PATCH 20/25] * extract unused image to separate file --- HTTPServer.cpp | 150 ------------------------------------------ HTTPServer.h | 1 - docs/itoopieImage.png | Bin 0 -> 8712 bytes 3 files changed, 151 deletions(-) create mode 100644 docs/itoopieImage.png diff --git a/HTTPServer.cpp b/HTTPServer.cpp index fba4a1be..7b7b8bcc 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -27,156 +27,6 @@ namespace i2p { namespace http { - const char *itoopieImage = - "\"ICToopie"; - const char *itoopieFavicon = "data:image/png;base64," "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv" diff --git a/HTTPServer.h b/HTTPServer.h index 2635c3be..bf7f5c65 100644 --- a/HTTPServer.h +++ b/HTTPServer.h @@ -3,7 +3,6 @@ namespace i2p { namespace http { - extern const char *itoopieImage; extern const char *itoopieFavicon; const size_t HTTP_CONNECTION_BUFFER_SIZE = 8192; diff --git a/docs/itoopieImage.png b/docs/itoopieImage.png new file mode 100644 index 0000000000000000000000000000000000000000..a5dc7b680ba9dee30161ffb1c9fcd17bbd6ddd84 GIT binary patch literal 8712 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 literal 0 HcmV?d00001 From 689432f627125644c8589e98577f700880bf8e5f Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 31 May 2016 21:37:32 -0400 Subject: [PATCH 21/25] fixed typo --- Config.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Config.cpp b/Config.cpp index da4f160b..e6d44d59 100644 --- a/Config.cpp +++ b/Config.cpp @@ -178,11 +178,11 @@ namespace config { ("bob.port", value()->default_value(2827), "BOB listen port") ; - options_description i2cp("I2CP options"); + options_description i2cp("I2CP options"); i2cp.add_options() ("i2cp.enabled", value()->default_value(false), "Enable or disable I2CP") ("i2cp.address", value()->default_value("127.0.0.1"), "I2CP listen address") - ("i2cp.port", value()->default_value(7654), "I2CP listen port") + ("i2cp.port", value()->default_value(7654), "I2CP listen port") ; options_description i2pcontrol("I2PControl options"); @@ -208,15 +208,15 @@ namespace config { m_OptionsDesc .add(general) + .add(limits) .add(httpserver) .add(httpproxy) .add(socksproxy) .add(sam) .add(bob) - .add(i2cp) + .add(i2cp) .add(i2pcontrol) - .add(precomputation) - .add(limits) + .add(precomputation) ; } From 153d883aebffc2066def97802d7dc1f6571c3df1 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jun 2016 10:05:40 -0400 Subject: [PATCH 22/25] SessionDestoryedMessage --- I2CP.cpp | 21 ++++++++++++++++++--- I2CP.h | 5 ++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 94d5db7f..fd98ce44 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -64,7 +64,6 @@ namespace client m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0) { RAND_bytes ((uint8_t *)&m_SessionID, 2); - ReadProtocolByte (); } I2CPSession::~I2CPSession () @@ -72,7 +71,12 @@ namespace client delete[] m_NextMessage; } - void I2CPSession::Close () + void I2CPSession::Start () + { + ReadProtocolByte (); + } + + void I2CPSession::Stop () { } @@ -216,6 +220,7 @@ namespace client auto identity = std::make_shared(); size_t offset = identity->FromBuffer (buf, len); uint16_t optionsSize = bufbe16toh (buf + offset); + offset += 2; // TODO: extract options offset += optionsSize; offset += 8; // date @@ -224,6 +229,7 @@ namespace client m_Destination = std::make_shared(*this, identity, false); m_Destination->Start (); SendSessionStatusMessage (1); // created + LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " created"); } else { @@ -232,6 +238,13 @@ namespace client } } + void I2CPSession::DestroySessionMessageHandler (const uint8_t * buf, size_t len) + { + SendSessionStatusMessage (0); // destroy + LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " destroyed"); + Terminate (); + } + void I2CPSession::SendSessionStatusMessage (uint8_t status) { uint8_t buf[3]; @@ -281,6 +294,7 @@ namespace client memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; m_MessagesHandlers[I2CP_CREATE_SESSION_MESSAGE] = &I2CPSession::CreateSessionMessageHandler; + m_MessagesHandlers[I2CP_DESTROY_SESSION_MESSAGE] = &I2CPSession::DestroySessionMessageHandler; m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; } @@ -303,7 +317,7 @@ namespace client m_IsRunning = false; m_Acceptor.cancel (); for (auto it: m_Sessions) - it.second->Close (); + it.second->Stop (); m_Sessions.clear (); m_Service.stop (); if (m_Thread) @@ -347,6 +361,7 @@ namespace client LogPrint (eLogDebug, "I2CP: new connection from ", ep); auto session = std::make_shared(*this, socket); m_Sessions[session->GetSessionID ()] = session; + session->Start (); } else LogPrint (eLogError, "I2CP: incoming connection error ", ec.message ()); diff --git a/I2CP.h b/I2CP.h index 74ccb3f2..f68c4809 100644 --- a/I2CP.h +++ b/I2CP.h @@ -32,6 +32,7 @@ namespace client const uint8_t I2CP_SET_DATE_MESSAGE = 33; const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1; const uint8_t I2CP_SESSION_STATUS_MESSAGE = 20; + const uint8_t I2CP_DESTROY_SESSION_MESSAGE = 3; const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; @@ -73,13 +74,15 @@ namespace client I2CPSession (I2CPServer& owner, std::shared_ptr socket); ~I2CPSession (); + void Start (); + void Stop (); uint16_t GetSessionID () const { return m_SessionID; }; - void Close (); void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); // message handlers void GetDateMessageHandler (const uint8_t * buf, size_t len); void CreateSessionMessageHandler (const uint8_t * buf, size_t len); + void DestroySessionMessageHandler (const uint8_t * buf, size_t len); void CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len); void SendMessageMessageHandler (const uint8_t * buf, size_t len); From 6538a2e673bbf14a56e9fbf52679b039bd4eee20 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jun 2016 11:11:18 -0400 Subject: [PATCH 23/25] HostLookupMessage --- I2CP.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- I2CP.h | 6 +++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index fd98ce44..7cef9013 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -287,6 +287,66 @@ namespace client LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); } + void I2CPSession::HostLookupMessageHandler (const uint8_t * buf, size_t len) + { + uint16_t sessionID = bufbe16toh (buf); + if (sessionID == m_SessionID) + { + uint32_t requestID = bufbe32toh (buf + 2); + //uint32_t timeout = bufbe32toh (buf + 6); + if (!buf[10]) // request type = 0 (hash) + { + if (m_Destination) + { + auto ls = m_Destination->FindLeaseSet (buf + 11); + if (ls) + SendHostReplyMessage (requestID, ls->GetIdentity ()); + else + { + auto s = shared_from_this (); + m_Destination->RequestDestination (buf + 11, + [s, requestID](std::shared_ptr leaseSet) + { + s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr); + }); + } + } + else + SendHostReplyMessage (requestID, nullptr); + } + else + { + LogPrint (eLogError, "I2CP: request type ", (int)buf[8], " is not supported"); + SendHostReplyMessage (requestID, nullptr); + } + } + else + LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); + } + + void I2CPSession::SendHostReplyMessage (uint32_t requestID, std::shared_ptr identity) + { + if (identity) + { + size_t l = identity->GetFullLen () + 7; + uint8_t * buf = new uint8_t[l]; + htobe16buf (buf, m_SessionID); + htobe32buf (buf + 2, requestID); + buf[6] = 0; // result code + identity->ToBuffer (buf + 7, l - 7); + SendI2CPMessage (I2CP_HOST_REPLY_MESSAGE, buf, l); + delete[] buf; + } + else + { + uint8_t buf[7]; + htobe16buf (buf, m_SessionID); + htobe32buf (buf + 2, requestID); + buf[6] = 1; // result code + SendI2CPMessage (I2CP_HOST_REPLY_MESSAGE, buf, 7); + } + } + I2CPServer::I2CPServer (const std::string& interface, int port): m_IsRunning (false), m_Thread (nullptr), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) @@ -296,7 +356,8 @@ namespace client m_MessagesHandlers[I2CP_CREATE_SESSION_MESSAGE] = &I2CPSession::CreateSessionMessageHandler; m_MessagesHandlers[I2CP_DESTROY_SESSION_MESSAGE] = &I2CPSession::DestroySessionMessageHandler; m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; - m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; + m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; + m_MessagesHandlers[I2CP_HOST_LOOKUP_MESSAGE] = &I2CPSession::HostLookupMessageHandler; } I2CPServer::~I2CPServer () diff --git a/I2CP.h b/I2CP.h index f68c4809..f3a88c9a 100644 --- a/I2CP.h +++ b/I2CP.h @@ -35,7 +35,9 @@ namespace client const uint8_t I2CP_DESTROY_SESSION_MESSAGE = 3; const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; - const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; + const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; + const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38; + const uint8_t I2CP_HOST_REPLY_MESSAGE = 39; class I2CPSession; class I2CPDestination: public LeaseSetDestination @@ -85,6 +87,7 @@ namespace client void DestroySessionMessageHandler (const uint8_t * buf, size_t len); void CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len); void SendMessageMessageHandler (const uint8_t * buf, size_t len); + void HostLookupMessageHandler (const uint8_t * buf, size_t len); private: @@ -99,6 +102,7 @@ namespace client size_t PutString (uint8_t * buf, size_t len, const std::string& str); void SendSessionStatusMessage (uint8_t status); + void SendHostReplyMessage (uint32_t requestID, std::shared_ptr identity); private: From d79c6b8f06d4435016ccee337a1de9a1ddf5b6da Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jun 2016 14:38:13 -0400 Subject: [PATCH 24/25] MessagePayloadMessage --- I2CP.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- I2CP.h | 14 ++++++++++-- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 7cef9013..5d0f2865 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include "I2PEndian.h" #include "Log.h" @@ -29,6 +30,13 @@ namespace client memcpy (m_EncryptionPrivateKey, key, 256); } + void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len) + { + uint32_t length = bufbe32toh (buf); + if (length > len - 4) length = len - 4; + m_Owner.SendMessagePayloadMessage (buf + 4, length); + } + void I2CPDestination::CreateNewLeaseSet (std::vector > tunnels) { i2p::data::LocalLeaseSet ls (m_Identity, m_EncryptionPrivateKey, tunnels); // we don't care about encryption key @@ -38,7 +46,6 @@ namespace client htobe16buf (leases - 3, m_Owner.GetSessionID ()); size_t l = 2/*sessionID*/ + 1/*num leases*/ + i2p::data::LEASE_SIZE*tunnels.size (); m_Owner.SendI2CPMessage (I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE, leases - 3, l); - } void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) @@ -56,12 +63,50 @@ namespace client memcpy (buf + 4, payload, len); msg->len += len + 4; msg->FillI2NPMessageHeader (eI2NPData); - // TODO: send + auto remote = FindLeaseSet (ident); + if (remote) + GetService ().post (std::bind (&I2CPDestination::SendMsg, GetSharedFromThis (), msg, remote)); + else + { + auto s = GetSharedFromThis (); + RequestDestination (ident, + [s, msg](std::shared_ptr ls) + { + if (ls) s->SendMsg (msg, ls); + }); + } + } + + void I2CPDestination::SendMsg (std::shared_ptr msg, std::shared_ptr remote) + { + auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (); + auto leases = remote->GetNonExpiredLeases (); + if (!leases.empty () && outboundTunnel) + { + std::vector msgs; + uint32_t i = rand () % leases.size (); + auto garlic = WrapMessage (remote, msg, true); + msgs.push_back (i2p::tunnel::TunnelMessageBlock + { + i2p::tunnel::eDeliveryTypeTunnel, + leases[i]->tunnelGateway, leases[i]->tunnelID, + garlic + }); + outboundTunnel->SendTunnelDataMsg (msgs); + } + else + { + if (outboundTunnel) + LogPrint (eLogWarning, "I2CP: Failed to send message. All leases expired"); + else + LogPrint (eLogWarning, "I2CP: Failed to send message. No outbound tunnels"); + } } I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), - m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0) + m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), + m_MessageID (0) { RAND_bytes ((uint8_t *)&m_SessionID, 2); } @@ -347,6 +392,21 @@ namespace client } } + void I2CPSession::SendMessagePayloadMessage (const uint8_t * payload, size_t len) + { + // we don't use SendI2CPMessage to eliminate additional copy + auto l = len + 6 + I2CP_HEADER_SIZE; + uint8_t * buf = new uint8_t[l]; + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 6); + buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; + htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); + htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); + memcpy (buf + I2CP_HEADER_SIZE + 6, payload, len); + boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2, buf)); + } + I2CPServer::I2CPServer (const std::string& interface, int port): m_IsRunning (false), m_Thread (nullptr), m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port)) diff --git a/I2CP.h b/I2CP.h index f3a88c9a..b3693d3d 100644 --- a/I2CP.h +++ b/I2CP.h @@ -36,6 +36,7 @@ namespace client const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37; const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; + const uint8_t I2CP_MESSAGE_PAYLOAD_MESSAGE = 31; const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38; const uint8_t I2CP_HOST_REPLY_MESSAGE = 39; @@ -57,9 +58,15 @@ namespace client std::shared_ptr GetIdentity () const { return m_Identity; }; // I2CP - void HandleDataMessage (const uint8_t * buf, size_t len) { /* TODO */ }; + void HandleDataMessage (const uint8_t * buf, size_t len); void CreateNewLeaseSet (std::vector > tunnels); + private: + + std::shared_ptr GetSharedFromThis () + { return std::static_pointer_cast(shared_from_this ()); } + void SendMsg (std::shared_ptr msg, std::shared_ptr remote); + private: I2CPSession& m_Owner; @@ -79,8 +86,10 @@ namespace client void Start (); void Stop (); uint16_t GetSessionID () const { return m_SessionID; }; + void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); - + void SendMessagePayloadMessage (const uint8_t * payload, size_t len); // called from I2CPDestination + // message handlers void GetDateMessageHandler (const uint8_t * buf, size_t len); void CreateSessionMessageHandler (const uint8_t * buf, size_t len); @@ -113,6 +122,7 @@ namespace client std::shared_ptr m_Destination; uint16_t m_SessionID; + uint32_t m_MessageID; }; typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len); From ace3e86546efcca0f96ced93a02f31f93344901d Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 1 Jun 2016 15:30:57 -0400 Subject: [PATCH 25/25] MessageStatusMessage --- I2CP.cpp | 44 ++++++++++++++++++++++++++++++++++---------- I2CP.h | 17 ++++++++++++++--- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 5d0f2865..77330af4 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -55,7 +55,7 @@ namespace client SetLeaseSet (ls); } - void I2CPDestination::SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident) + void I2CPDestination::SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce) { auto msg = NewI2NPMessage (); uint8_t * buf = msg->GetPayload (); @@ -70,14 +70,20 @@ namespace client { auto s = GetSharedFromThis (); RequestDestination (ident, - [s, msg](std::shared_ptr ls) + [s, msg, nonce](std::shared_ptr ls) { - if (ls) s->SendMsg (msg, ls); + if (ls) + { + bool sent = s->SendMsg (msg, ls); + s->m_Owner.SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure); + } + else + s->m_Owner.SendMessageStatusMessage (nonce, eI2CPMessageStatusNoLeaseSet); }); } } - void I2CPDestination::SendMsg (std::shared_ptr msg, std::shared_ptr remote) + bool I2CPDestination::SendMsg (std::shared_ptr msg, std::shared_ptr remote) { auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (); auto leases = remote->GetNonExpiredLeases (); @@ -93,6 +99,7 @@ namespace client garlic }); outboundTunnel->SendTunnelDataMsg (msgs); + return true; } else { @@ -100,13 +107,14 @@ namespace client LogPrint (eLogWarning, "I2CP: Failed to send message. All leases expired"); else LogPrint (eLogWarning, "I2CP: Failed to send message. No outbound tunnels"); + return false; } } I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), - m_MessageID (0) + m_MessageID (0) { RAND_bytes ((uint8_t *)&m_SessionID, 2); } @@ -298,6 +306,17 @@ namespace client SendI2CPMessage (I2CP_SESSION_STATUS_MESSAGE, buf, 3); } + void I2CPSession::SendMessageStatusMessage (uint32_t nonce, I2CPMessageStatus status) + { + uint8_t buf[15]; + htobe16buf (buf, m_SessionID); + htobe32buf (buf + 2, m_MessageID++); + buf[6] = (uint8_t)status; + memset (buf + 7, 0, 4); // size + htobe32buf (buf + 11, nonce); + SendI2CPMessage (I2CP_MESSAGE_STATUS_MESSAGE, buf, 15); + } + void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len) { uint16_t sessionID = bufbe16toh (buf); @@ -325,7 +344,11 @@ namespace client { i2p::data::IdentityEx identity; offset += identity.FromBuffer (buf + offset, len - offset); - m_Destination->SendMsgTo (buf + offset, len - offset, identity.GetIdentHash ()); + uint32_t payloadLen = bufbe32toh (buf + offset); + offset += 4; + uint32_t nonce = bufbe32toh (buf + offset + payloadLen); + SendMessageStatusMessage (nonce, eI2CPMessageStatusAccepted); // accepted + m_Destination->SendMsgTo (buf + offset, payloadLen, identity.GetIdentHash (), nonce); } } else @@ -395,13 +418,14 @@ namespace client void I2CPSession::SendMessagePayloadMessage (const uint8_t * payload, size_t len) { // we don't use SendI2CPMessage to eliminate additional copy - auto l = len + 6 + I2CP_HEADER_SIZE; + auto l = len + 10 + I2CP_HEADER_SIZE; uint8_t * buf = new uint8_t[l]; - htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 6); + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len + 10); buf[I2CP_HEADER_TYPE_OFFSET] = I2CP_MESSAGE_PAYLOAD_MESSAGE; htobe16buf (buf + I2CP_HEADER_SIZE, m_SessionID); - htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); - memcpy (buf + I2CP_HEADER_SIZE + 6, payload, len); + htobe32buf (buf + I2CP_HEADER_SIZE + 2, m_MessageID++); + htobe32buf (buf + I2CP_HEADER_SIZE + 6, len); + memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len); boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, buf)); diff --git a/I2CP.h b/I2CP.h index b3693d3d..4d50b5ef 100644 --- a/I2CP.h +++ b/I2CP.h @@ -37,9 +37,18 @@ namespace client const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4; const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5; const uint8_t I2CP_MESSAGE_PAYLOAD_MESSAGE = 31; + const uint8_t I2CP_MESSAGE_STATUS_MESSAGE = 22; const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38; const uint8_t I2CP_HOST_REPLY_MESSAGE = 39; + enum I2CPMessageStatus + { + eI2CPMessageStatusAccepted = 1, + eI2CPMessageStatusGuaranteedSuccess = 4, + eI2CPMessageStatusGuaranteedFailure = 5, + eI2CPMessageStatusNoLeaseSet = 21 + }; + class I2CPSession; class I2CPDestination: public LeaseSetDestination { @@ -49,7 +58,7 @@ namespace client void SetEncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession - void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident); // called from I2CPSession + void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession protected: @@ -65,7 +74,7 @@ namespace client std::shared_ptr GetSharedFromThis () { return std::static_pointer_cast(shared_from_this ()); } - void SendMsg (std::shared_ptr msg, std::shared_ptr remote); + bool SendMsg (std::shared_ptr msg, std::shared_ptr remote); private: @@ -87,8 +96,10 @@ namespace client void Stop (); uint16_t GetSessionID () const { return m_SessionID; }; + // called from I2CPDestination void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); - void SendMessagePayloadMessage (const uint8_t * payload, size_t len); // called from I2CPDestination + void SendMessagePayloadMessage (const uint8_t * payload, size_t len); + void SendMessageStatusMessage (uint32_t nonce, I2CPMessageStatus status); // message handlers void GetDateMessageHandler (const uint8_t * buf, size_t len);