From 26a6c9e932837a3c54e235bd8a9b6327e85e033c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Jun 2016 13:26:41 -0400 Subject: [PATCH 1/7] procee session options --- I2CP.cpp | 38 +++++++++++++++++++++++++++++++++----- I2CP.h | 8 ++++++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 77330af4..13a658a1 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -20,8 +20,8 @@ namespace i2p namespace client { - I2CPDestination::I2CPDestination (I2CPSession& owner, std::shared_ptr identity, bool isPublic): - LeaseSetDestination (isPublic), m_Owner (owner), m_Identity (identity) + I2CPDestination::I2CPDestination (I2CPSession& owner, std::shared_ptr identity, bool isPublic, const std::map& params): + LeaseSetDestination (isPublic, ¶ms), m_Owner (owner), m_Identity (identity) { } @@ -141,7 +141,7 @@ namespace client m_Socket->async_read_some (boost::asio::buffer (m_Buffer, 1), [s](const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (!ecode && bytes_transferred > 0 && s->m_Buffer[0] == I2CP_PRTOCOL_BYTE) + if (!ecode && bytes_transferred > 0 && s->m_Buffer[0] == I2CP_PROTOCOL_BYTE) s->Receive (); else s->Terminate (); @@ -253,6 +253,30 @@ namespace client return l + 1; } + void I2CPSession::ExtractMapping (const uint8_t * buf, size_t len, std::map& mapping) + // TODO: move to Base.cpp + { + size_t offset = 0; + while (offset < len) + { + auto semicolon = (const uint8_t *)memchr (buf + offset, ';', len - offset); + if (semicolon) + { + auto l = semicolon - buf - offset + 1; + auto equal = (const uint8_t *)memchr (buf + offset, '=', l); + if (equal) + { + auto l1 = equal - buf - offset + 1; + mapping.insert (std::make_pair (std::string ((const char *)(buf + offset), l1 -1), + std::string ((const char *)(buf + offset + l1), l - l1 - 2))); + } + offset += l; + } + else + break; + } + } + void I2CPSession::GetDateMessageHandler (const uint8_t * buf, size_t len) { // get version @@ -274,12 +298,16 @@ namespace client size_t offset = identity->FromBuffer (buf, len); uint16_t optionsSize = bufbe16toh (buf + offset); offset += 2; - // TODO: extract options + + std::map params; + ExtractMapping (buf + offset, optionsSize, params); offset += optionsSize; offset += 8; // date if (identity->Verify (buf, offset, buf + offset)) // signature { - m_Destination = std::make_shared(*this, identity, false); + bool isPublic = true; + if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "false") isPublic = false; + m_Destination = std::make_shared(*this, identity, isPublic, params); m_Destination->Start (); SendSessionStatusMessage (1); // created LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " created"); diff --git a/I2CP.h b/I2CP.h index 4d50b5ef..47e6f750 100644 --- a/I2CP.h +++ b/I2CP.h @@ -21,7 +21,7 @@ namespace i2p { namespace client { - const uint8_t I2CP_PRTOCOL_BYTE = 0x2A; + const uint8_t I2CP_PROTOCOL_BYTE = 0x2A; const size_t I2CP_SESSION_BUFFER_SIZE = 4096; const size_t I2CP_HEADER_LENGTH_OFFSET = 0; @@ -49,12 +49,15 @@ namespace client eI2CPMessageStatusNoLeaseSet = 21 }; + // params + const char I2CP_PARAM_DONT_PUBLISH_LEASESET[] = "i2cp.dontPublishLeaseSet "; + class I2CPSession; class I2CPDestination: public LeaseSetDestination { public: - I2CPDestination (I2CPSession& owner, std::shared_ptr identity, bool isPublic); + I2CPDestination (I2CPSession& owner, std::shared_ptr identity, bool isPublic, const std::map& params); void SetEncryptionPrivateKey (const uint8_t * key); void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession @@ -120,6 +123,7 @@ namespace client 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); + void ExtractMapping (const uint8_t * buf, size_t len, std::map& mapping); void SendSessionStatusMessage (uint8_t status); void SendHostReplyMessage (uint32_t requestID, std::shared_ptr identity); From aa6bc8042a5edc8beeaa20edfaec7ab2f6ab9bf0 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Jun 2016 15:49:14 -0400 Subject: [PATCH 2/7] address lookup --- I2CP.cpp | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 13a658a1..6cdc4ec9 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -13,6 +13,7 @@ #include "Log.h" #include "Timestamp.h" #include "LeaseSet.h" +#include "ClientContext.h" #include "I2CP.h" namespace i2p @@ -390,31 +391,46 @@ namespace client { uint32_t requestID = bufbe32toh (buf + 2); //uint32_t timeout = bufbe32toh (buf + 6); - if (!buf[10]) // request type = 0 (hash) + i2p::data::IdentHash ident; + switch (buf[10]) { - if (m_Destination) + case 0: // hash + ident = i2p::data::IdentHash (buf + 11); + break; + case 1: // address { - auto ls = m_Destination->FindLeaseSet (buf + 11); - if (ls) - SendHostReplyMessage (requestID, ls->GetIdentity ()); - else + auto name = ExtractString (buf + 11, len - 11); + if (!i2p::client::context.GetAddressBook ().GetIdentHash (name, ident)) { - auto s = shared_from_this (); - m_Destination->RequestDestination (buf + 11, - [s, requestID](std::shared_ptr leaseSet) - { - s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr); - }); - } + LogPrint (eLogError, "I2CP: address ", name, " not found"); + SendHostReplyMessage (requestID, nullptr); + return; + } + break; } - else + default: + LogPrint (eLogError, "I2CP: request type ", (int)buf[10], " is not supported"); SendHostReplyMessage (requestID, nullptr); + return; + } + + if (m_Destination) + { + auto ls = m_Destination->FindLeaseSet (ident); + if (ls) + SendHostReplyMessage (requestID, ls->GetIdentity ()); + else + { + auto s = shared_from_this (); + m_Destination->RequestDestination (ident, + [s, requestID](std::shared_ptr leaseSet) + { + s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr); + }); + } } else - { - LogPrint (eLogError, "I2CP: request type ", (int)buf[8], " is not supported"); SendHostReplyMessage (requestID, nullptr); - } } else LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); From 26284260840d6eaefbe6e33dc9442e907095fb2c Mon Sep 17 00:00:00 2001 From: hagen Date: Fri, 3 Jun 2016 00:00:00 +0000 Subject: [PATCH 3/7] * http proxy : fix converted request (#508) --- HTTPProxy.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index cc534470..265d36e5 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -189,6 +189,12 @@ namespace proxy { return true; } SanitizeHTTPRequest(req); + /* convert proxy-style http req to ordinary one: */ + /* 1) replace Host header, 2) make relative url */ + req.add_header("Host", url.host, true); + url.schema = ""; + url.host = ""; + req.uri = url.to_string(); /* drop original request from input buffer */ m_recv_buf.erase(m_recv_buf.begin(), m_recv_buf.begin() + req_len); From aa764fbd1ccb50ce8ec58c2345eed4f4f4849f5b Mon Sep 17 00:00:00 2001 From: hagen Date: Fri, 3 Jun 2016 00:00:00 +0000 Subject: [PATCH 4/7] * HTTPProxy: fix converted request (#508) * I2PService: reword log message, to avoid ambiguity --- HTTPProxy.cpp | 5 ++++- I2PService.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 265d36e5..6bf33664 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -189,6 +189,9 @@ namespace proxy { return true; } SanitizeHTTPRequest(req); + + std::string dest_host = url.host; + uint16_t dest_host = url.port; /* convert proxy-style http req to ordinary one: */ /* 1) replace Host header, 2) make relative url */ req.add_header("Host", url.host, true); @@ -206,7 +209,7 @@ namespace proxy { /* connect to destination */ GetOwner()->CreateStream (std::bind (&HTTPReqHandler::HandleStreamRequestComplete, - shared_from_this(), std::placeholders::_1), url.host, url.port); + shared_from_this(), std::placeholders::_1), dest_host, dest_port); return true; } diff --git a/I2PService.cpp b/I2PService.cpp index 9bbe1521..4f907f18 100644 --- a/I2PService.cpp +++ b/I2PService.cpp @@ -27,7 +27,7 @@ namespace client m_LocalDestination->CreateStream (streamRequestComplete, identHash, port); else { - LogPrint (eLogWarning, "I2PService: Remote destination ", dest, " not found"); + LogPrint (eLogWarning, "I2PService: Remote destination not found: ", dest); streamRequestComplete (nullptr); } } From e50c35d38c81314be5d674a197334da3df5e86fa Mon Sep 17 00:00:00 2001 From: hagen Date: Fri, 3 Jun 2016 00:00:00 +0000 Subject: [PATCH 5/7] * fix mistype --- HTTPProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 6bf33664..934dbbf5 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -191,7 +191,7 @@ namespace proxy { SanitizeHTTPRequest(req); std::string dest_host = url.host; - uint16_t dest_host = url.port; + uint16_t dest_port = url.port; /* convert proxy-style http req to ordinary one: */ /* 1) replace Host header, 2) make relative url */ req.add_header("Host", url.host, true); From c8d6425123e00083d6fb3d674348b9c298dde733 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jun 2016 11:49:39 -0400 Subject: [PATCH 6/7] DestLookupMessage --- I2CP.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- I2CP.h | 3 +++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 6cdc4ec9..afd10466 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -307,7 +307,7 @@ namespace client if (identity->Verify (buf, offset, buf + offset)) // signature { bool isPublic = true; - if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "false") isPublic = false; + if (params[I2CP_PARAM_DONT_PUBLISH_LEASESET] == "true") isPublic = false; m_Destination = std::make_shared(*this, identity, isPublic, params); m_Destination->Start (); SendSessionStatusMessage (1); // created @@ -459,6 +459,43 @@ namespace client } } + void I2CPSession::DestLookupMessageHandler (const uint8_t * buf, size_t len) + { + if (m_Destination) + { + auto ls = m_Destination->FindLeaseSet (buf); + if (ls) + { + auto l = ls->GetIdentity ()->GetFullLen (); + uint8_t * identBuf = new uint8_t[l]; + ls->GetIdentity ()->ToBuffer (identBuf, l); + SendI2CPMessage (I2CP_DEST_REPLY_MESSAGE, identBuf, l); + delete[] identBuf; + } + else + { + auto s = shared_from_this (); + i2p::data::IdentHash ident (buf); + m_Destination->RequestDestination (ident, + [s, ident](std::shared_ptr leaseSet) + { + if (leaseSet) // found + { + auto l = leaseSet->GetIdentity ()->GetFullLen (); + uint8_t * identBuf = new uint8_t[l]; + leaseSet->GetIdentity ()->ToBuffer (identBuf, l); + s->SendI2CPMessage (I2CP_DEST_REPLY_MESSAGE, identBuf, l); + delete[] identBuf; + } + else + s->SendI2CPMessage (I2CP_DEST_REPLY_MESSAGE, ident, 32); // not found + }); + } + } + else + SendI2CPMessage (I2CP_DEST_REPLY_MESSAGE, buf, 32); + } + void I2CPSession::SendMessagePayloadMessage (const uint8_t * payload, size_t len) { // we don't use SendI2CPMessage to eliminate additional copy @@ -485,7 +522,8 @@ namespace client 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_HOST_LOOKUP_MESSAGE] = &I2CPSession::HostLookupMessageHandler; + m_MessagesHandlers[I2CP_HOST_LOOKUP_MESSAGE] = &I2CPSession::HostLookupMessageHandler; + m_MessagesHandlers[I2CP_DEST_LOOKUP_MESSAGE] = &I2CPSession::DestLookupMessageHandler; } I2CPServer::~I2CPServer () diff --git a/I2CP.h b/I2CP.h index 47e6f750..a3e0dde0 100644 --- a/I2CP.h +++ b/I2CP.h @@ -40,6 +40,8 @@ namespace client const uint8_t I2CP_MESSAGE_STATUS_MESSAGE = 22; const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38; const uint8_t I2CP_HOST_REPLY_MESSAGE = 39; + const uint8_t I2CP_DEST_LOOKUP_MESSAGE = 34; + const uint8_t I2CP_DEST_REPLY_MESSAGE = 35; enum I2CPMessageStatus { @@ -111,6 +113,7 @@ namespace client 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); + void DestLookupMessageHandler (const uint8_t * buf, size_t len); private: From 444539b8263d899927e26ecc8cf25915ec009eed Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Jun 2016 12:03:36 -0400 Subject: [PATCH 7/7] SendMessageExpires --- I2CP.cpp | 6 ++++++ I2CP.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/I2CP.cpp b/I2CP.cpp index afd10466..b2685e80 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -384,6 +384,11 @@ namespace client LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); } + void I2CPSession::SendMessageExpiresMessageHandler (const uint8_t * buf, size_t len) + { + SendMessageMessageHandler (buf, len - 8); // ignore flags(2) and expiration(6) + } + void I2CPSession::HostLookupMessageHandler (const uint8_t * buf, size_t len) { uint16_t sessionID = bufbe16toh (buf); @@ -522,6 +527,7 @@ namespace client 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_EXPIRES_MESSAGE] = &I2CPSession::SendMessageExpiresMessageHandler; m_MessagesHandlers[I2CP_HOST_LOOKUP_MESSAGE] = &I2CPSession::HostLookupMessageHandler; m_MessagesHandlers[I2CP_DEST_LOOKUP_MESSAGE] = &I2CPSession::DestLookupMessageHandler; } diff --git a/I2CP.h b/I2CP.h index a3e0dde0..273dcb65 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_SEND_MESSAGE_EXPIRES_MESSAGE = 36; const uint8_t I2CP_MESSAGE_PAYLOAD_MESSAGE = 31; const uint8_t I2CP_MESSAGE_STATUS_MESSAGE = 22; const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38; @@ -112,6 +113,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 SendMessageExpiresMessageHandler (const uint8_t * buf, size_t len); void HostLookupMessageHandler (const uint8_t * buf, size_t len); void DestLookupMessageHandler (const uint8_t * buf, size_t len);