From e954d06edff3b3dff8ae0a18ebc54f2b121d7949 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 3 Oct 2014 15:08:41 -0400 Subject: [PATCH] NAMING LOOKUP for .b32 addresses --- LeaseSet.h | 4 ++-- SAM.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++----------- SAM.h | 8 ++++++-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/LeaseSet.h b/LeaseSet.h index ea4f04d1..f8976a69 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -46,7 +46,8 @@ namespace data LeaseSet (const i2p::tunnel::TunnelPool& pool); LeaseSet& operator=(const LeaseSet& ) = default; void Update (const uint8_t * buf, int len); - + const IdentityEx& GetIdentity () const { return m_Identity; }; + const uint8_t * GetBuffer () const { return m_Buffer; }; size_t GetBufferLen () const { return m_BufferLen; }; @@ -54,7 +55,6 @@ namespace data void SetUnsolicited (bool unsolicited) { m_IsUnsolicited = unsolicited; }; // implements RoutingDestination - const Identity& GetIdentity () const { return m_Identity.GetStandardIdentity (); }; const IdentHash& GetIdentHash () const { return m_Identity.GetIdentHash (); }; const std::vector& GetLeases () const { return m_Leases; }; const std::vector GetNonExpiredLeases () const; diff --git a/SAM.cpp b/SAM.cpp index b038c1a4..458f7a12 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -253,7 +253,7 @@ namespace stream { i2p::data::netdb.Subscribe (dest.GetIdentHash (), session->localDestination->GetTunnelPool ()); m_Timer.expires_from_now (boost::posix_time::seconds(SAM_CONNECT_TIMEOUT)); - m_Timer.async_wait (boost::bind (&SAMSocket::HandleDestinationRequestTimer, + m_Timer.async_wait (boost::bind (&SAMSocket::HandleStreamDestinationRequestTimer, this, boost::asio::placeholders::error, dest.GetIdentHash (), session)); } } @@ -271,7 +271,7 @@ namespace stream SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } - void SAMSocket::HandleDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident, SAMSession * session) + void SAMSocket::HandleStreamDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident, SAMSession * session) { if (!ecode) // timeout expired { @@ -286,6 +286,22 @@ namespace stream } } + void SAMSocket::HandleNamingLookupDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident) + { + if (!ecode) // timeout expired + { + auto leaseSet = i2p::data::netdb.FindLeaseSet (ident); + if (leaseSet) + SendNamingLookupReply (leaseSet); + else + { + LogPrint ("SAM name destination not found"); + size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_KEY_NOT_FOUND, (ident.ToBase32 () + ".b32.i2p").c_str ()); + SendMessageReply (m_Buffer, len, false); + } + } + } + void SAMSocket::ProcessStreamAccept (char * buf, size_t len) { LogPrint ("SAM stream accept: ", buf); @@ -340,23 +356,41 @@ namespace stream std::map params; ExtractParams (buf, len, params); std::string& name = params[SAM_PARAM_NAME]; - if (name == "ME" && m_Session) + i2p::data::IdentHash ident; + if (name == "ME") + SendNamingLookupReply (nullptr); + else if (i2p::data::netdb.GetAddressBook ().GetIdentHash (name, ident)) { - uint8_t buf[1024]; - char pub[1024]; - size_t l = m_Session->localDestination->GetIdentity ().ToBuffer (buf, 1024); - size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, pub, 1024); - pub[l1] = 0; - size_t l2 = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, pub); - SendMessageReply (m_Buffer, l2, false); + auto leaseSet = i2p::data::netdb.FindLeaseSet (ident); + if (leaseSet) + SendNamingLookupReply (leaseSet); + else + { + i2p::data::netdb.Subscribe (ident, m_Session->localDestination->GetTunnelPool ()); + m_Timer.expires_from_now (boost::posix_time::seconds(SAM_NAMING_LOOKUP_TIMEOUT)); + m_Timer.async_wait (boost::bind (&SAMSocket::HandleNamingLookupDestinationRequestTimer, + this, boost::asio::placeholders::error, ident)); + } } else { size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY_INVALID_KEY, name.c_str()); - SendMessageReply (m_Buffer, len, true); + SendMessageReply (m_Buffer, len, false); } } + void SAMSocket::SendNamingLookupReply (i2p::data::LeaseSet * leaseSet) + { + uint8_t buf[1024]; + char pub[1024]; + const i2p::data::IdentityEx& identity = leaseSet ? leaseSet->GetIdentity () : m_Session->localDestination->GetIdentity (); + size_t l = identity.ToBuffer (buf, 1024); + size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, pub, 1024); + pub[l1] = 0; + size_t l2 = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_NAMING_REPLY, pub); + SendMessageReply (m_Buffer, l2, false); + } + void SAMSocket::ExtractParams (char * buf, size_t len, std::map& params) { char * separator; diff --git a/SAM.h b/SAM.h index 685bd236..883c817c 100644 --- a/SAM.h +++ b/SAM.h @@ -18,6 +18,7 @@ namespace stream const size_t SAM_SOCKET_BUFFER_SIZE = 4096; const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds const int SAM_CONNECT_TIMEOUT = 5; // in seconds + const int SAM_NAMING_LOOKUP_TIMEOUT = 5; // in seconds const char SAM_HANDSHAKE[] = "HELLO VERSION"; const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=3.1\n"; const char SAM_SESSION_CREATE[] = "SESSION CREATE"; @@ -35,7 +36,8 @@ namespace stream const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n"; const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP"; const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; - const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; + const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; + const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; const char SAM_PARAM_STYLE[] = "STYLE"; const char SAM_PARAM_ID[] = "ID"; const char SAM_PARAM_SILENT[] = "SILENT"; @@ -89,7 +91,9 @@ namespace stream void ExtractParams (char * buf, size_t len, std::map& params); void Connect (const i2p::data::LeaseSet& remote, SAMSession * session); - void HandleDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident, SAMSession * session); + void HandleStreamDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident, SAMSession * session); + void HandleNamingLookupDestinationRequestTimer (const boost::system::error_code& ecode, i2p::data::IdentHash ident); + void SendNamingLookupReply (i2p::data::LeaseSet * leaseSet); private: