From 9b0e8f6a71ef94d068ffe0be9ee04df9deb3493c Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 2 Oct 2014 12:42:28 -0400 Subject: [PATCH] request destination LeaseSet and wait for 5 seconds if not found --- SAM.cpp | 42 +++++++++++++++++++++++++++++++----------- SAM.h | 8 ++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/SAM.cpp b/SAM.cpp index 8312449d..cf5a88aa 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -12,8 +12,8 @@ namespace i2p namespace stream { SAMSocket::SAMSocket (SAMBridge& owner): - m_Owner (owner), m_Socket (m_Owner.GetService ()), m_SocketType (eSAMSocketTypeUnknown), - m_IsSilent (false), m_Stream (nullptr) + m_Owner (owner), m_Socket (m_Owner.GetService ()), m_Timer (m_Owner.GetService ()), + m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false), m_Stream (nullptr) { } @@ -245,22 +245,42 @@ namespace stream dest.FromBuffer (ident, l); auto leaseSet = i2p::data::netdb.FindLeaseSet (dest.GetIdentHash ()); if (leaseSet) + Connect (*leaseSet, session); + else { - m_SocketType = eSAMSocketTypeStream; - session->sockets.push_back (this); - m_Stream = session->localDestination->CreateNewOutgoingStream (*leaseSet); - m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect - I2PReceive (); - SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); + 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, + this, boost::asio::placeholders::error, dest.GetIdentHash (), session)); } + } + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); + } + + void SAMSocket::Connect (const i2p::data::LeaseSet& remote, SAMSession * session) + { + m_SocketType = eSAMSocketTypeStream; + session->sockets.push_back (this); + m_Stream = session->localDestination->CreateNewOutgoingStream (remote); + m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect + I2PReceive (); + 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) + { + if (!ecode) // timeout expired + { + auto leaseSet = i2p::data::netdb.FindLeaseSet (ident); + if (leaseSet) + Connect (*leaseSet, session); else { - i2p::data::netdb.Subscribe (dest.GetIdentHash ()); + LogPrint ("SAM destination to connect not found"); SendMessageReply (SAM_STREAM_STATUS_CANT_REACH_PEER, strlen(SAM_STREAM_STATUS_CANT_REACH_PEER), true); } } - else - SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } void SAMSocket::ProcessStreamAccept (char * buf, size_t len) diff --git a/SAM.h b/SAM.h index 41227368..9d48c3b3 100644 --- a/SAM.h +++ b/SAM.h @@ -7,6 +7,8 @@ #include #include #include +#include "Identity.h" +#include "LeaseSet.h" #include "Streaming.h" namespace i2p @@ -15,6 +17,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 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"; @@ -47,6 +50,7 @@ namespace stream }; class SAMBridge; + class SAMSession; class SAMSocket { public: @@ -79,10 +83,14 @@ namespace stream void ProcessDestGenerate (); 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); + private: SAMBridge& m_Owner; boost::asio::ip::tcp::socket m_Socket; + boost::asio::deadline_timer m_Timer; char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1]; uint8_t m_StreamBuffer[SAM_SOCKET_BUFFER_SIZE]; SAMSocketType m_SocketType;