diff --git a/SAM.cpp b/SAM.cpp index 6b622770..0fe0888c 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -12,7 +12,7 @@ namespace stream { SAMSocket::SAMSocket (SAMBridge& owner): m_Owner (owner), m_Socket (m_Owner.GetService ()), m_SocketType (eSAMSocketTypeUnknown), - m_Stream (nullptr) + m_IsSilent (false), m_Stream (nullptr) { } @@ -113,9 +113,17 @@ namespace stream void SAMSocket::SendMessageReply (const char * msg, size_t len, bool close) { - boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (), - boost::bind(&SAMSocket::HandleMessageReplySent, this, - boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, close)); + if (!m_IsSilent || m_SocketType == eSAMSocketTypeAcceptor) + boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (), + boost::bind(&SAMSocket::HandleMessageReplySent, this, + boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, close)); + else + { + if (close) + Terminate (); + else + Receive (); + } } void SAMSocket::HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred, bool close) @@ -213,6 +221,8 @@ namespace stream ExtractParams (buf, len, params); std::string& id = params[SAM_PARAM_ID]; std::string& destination = params[SAM_PARAM_DESTINATION]; + std::string& silent = params[SAM_PARAM_SILENT]; + if (silent == SAM_VALUE_TRUE) m_IsSilent = true; m_ID = id; auto session = m_Owner.FindSession (id); if (session) @@ -228,7 +238,7 @@ namespace stream session->sockets.push_back (this); m_Stream = session->localDestination->CreateNewOutgoingStream (*leaseSet); m_Stream->Send ((uint8_t *)m_Buffer, 0, 0); // connect - I2PReceive (); + I2PReceive (); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } else @@ -237,8 +247,8 @@ namespace stream 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); + else + SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); } void SAMSocket::ProcessStreamAccept (char * buf, size_t len) @@ -247,6 +257,8 @@ namespace stream std::map params; ExtractParams (buf, len, params); std::string& id = params[SAM_PARAM_ID]; + std::string& silent = params[SAM_PARAM_SILENT]; + if (silent == SAM_VALUE_TRUE) m_IsSilent = true; m_ID = id; auto session = m_Owner.FindSession (id); if (session) @@ -341,11 +353,23 @@ namespace stream void SAMSocket::HandleI2PAccept (i2p::stream::Stream * stream) { - m_Stream = stream; - auto session = m_Owner.FindSession (m_ID); - if (session) - session->localDestination->ResetAcceptor (); - I2PReceive (); + if (stream) + { + m_Stream = stream; + auto session = m_Owner.FindSession (m_ID); + if (session) + session->localDestination->ResetAcceptor (); + if (!m_IsSilent) + { + // send remote peer address + uint8_t ident[1024]; + size_t l = stream->GetRemoteIdentity ().ToBuffer (ident, 1024); + size_t l1 = i2p::data::ByteStreamToBase64 (ident, l, m_Buffer, SAM_SOCKET_BUFFER_SIZE); + m_Buffer[l1] = '\n'; + SendMessageReply (m_Buffer, l1 + 1, false); + } + I2PReceive (); + } } SAMBridge::SAMBridge (int port): diff --git a/SAM.h b/SAM.h index 66de1195..add16a90 100644 --- a/SAM.h +++ b/SAM.h @@ -28,8 +28,11 @@ namespace stream const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT"; const char SAM_PARAM_STYLE[] = "STYLE"; const char SAM_PARAM_ID[] = "ID"; + const char SAM_PARAM_SILENT[] = "SILENT"; const char SAM_PARAM_DESTINATION[] = "DESTINATION"; const char SAM_VALUE_TRANSIENT[] = "TRANSIENT"; + const char SAM_VALUE_TRUE[] = "true"; + const char SAM_VALUE_FALSE[] = "false"; enum SAMSocketType { @@ -79,6 +82,7 @@ namespace stream uint8_t m_StreamBuffer[SAM_SOCKET_BUFFER_SIZE]; SAMSocketType m_SocketType; std::string m_ID; // nickname + bool m_IsSilent; Stream * m_Stream; }; diff --git a/Streaming.h b/Streaming.h index e68f0254..b69828b2 100644 --- a/Streaming.h +++ b/Streaming.h @@ -86,6 +86,7 @@ namespace stream uint32_t GetSendStreamID () const { return m_SendStreamID; }; uint32_t GetRecvStreamID () const { return m_RecvStreamID; }; const i2p::data::LeaseSet * GetRemoteLeaseSet () const { return m_RemoteLeaseSet; }; + const i2p::data::IdentityEx& GetRemoteIdentity () const { return m_RemoteIdentity; }; bool IsOpen () const { return m_IsOpen; }; bool IsEstablished () const { return m_SendStreamID; }; StreamingDestination * GetLocalDestination () { return m_LocalDestination; };