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);