From 4018cf9d76f330cceb92ab51a35dd28bbafa1d64 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Apr 2021 21:11:36 -0400 Subject: [PATCH] SAM single and master sessions --- daemon/HTTPServer.cpp | 4 +-- daemon/I2PControl.cpp | 4 +-- libi2pd_client/SAM.cpp | 68 ++++++++++++++++++++++-------------------- libi2pd_client/SAM.h | 31 ++++++++++++++----- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index c263cea9..6410a044 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -842,7 +842,7 @@ namespace http { s << "SAM Sessions:
\r\n
\r\n"; for (auto& it: sam->GetSessions ()) { - auto& name = it.second->localDestination->GetNickname (); + auto& name = it.second->GetLocalDestination ()->GetNickname (); s << "\r\n" << std::endl; } @@ -868,7 +868,7 @@ namespace http { std::string webroot; i2p::config::GetOption("http.webroot", webroot); s << "SAM Session:
\r\n
\r\n"; - auto& ident = session->localDestination->GetIdentHash(); + auto& ident = session->GetLocalDestination ()->GetIdentHash(); s << "\r\n"; s << "
\r\n"; diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp index 3f0033e5..d71a9f1c 100644 --- a/daemon/I2PControl.cpp +++ b/daemon/I2PControl.cpp @@ -714,8 +714,8 @@ namespace client for (auto& it: sam->GetSessions ()) { boost::property_tree::ptree sam_session, sam_session_sockets; - auto& name = it.second->localDestination->GetNickname (); - auto& ident = it.second->localDestination->GetIdentHash(); + auto& name = it.second->GetLocalDestination ()->GetNickname (); + auto& ident = it.second->GetLocalDestination ()->GetIdentHash(); sam_session.put("name", name); sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index 41d08147..c9c88709 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -58,8 +58,8 @@ namespace client { if (Session) { - if (m_IsAccepting && Session->localDestination) - Session->localDestination->StopAcceptingStreams (); + if (m_IsAccepting && Session->GetLocalDestination ()) + Session->GetLocalDestination ()->StopAcceptingStreams (); } break; } @@ -410,7 +410,7 @@ namespace client if (type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) { session->UDPEndpoint = forward; - auto dest = session->localDestination->CreateDatagramDestination (); + auto dest = session->GetLocalDestination ()->CreateDatagramDestination (); if (type == eSAMSessionTypeDatagram) dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); @@ -419,7 +419,7 @@ namespace client std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); } - if (session->localDestination->IsReady ()) + if (session->GetLocalDestination ()->IsReady ()) SendSessionCreateReplyOk (); else { @@ -439,7 +439,7 @@ namespace client auto session = m_Owner.FindSession(m_ID); if(session) { - if (session->localDestination->IsReady ()) + if (session->GetLocalDestination ()->IsReady ()) SendSessionCreateReplyOk (); else { @@ -458,7 +458,7 @@ namespace client { uint8_t buf[1024]; char priv[1024]; - size_t l = session->localDestination->GetPrivateKeys ().ToBuffer (buf, 1024); + size_t l = session->GetLocalDestination ()->GetPrivateKeys ().ToBuffer (buf, 1024); size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024); priv[l1] = 0; #ifdef _MSC_VER @@ -514,18 +514,18 @@ namespace client { if (addr->IsIdentHash ()) { - auto leaseSet = session->localDestination->FindLeaseSet(addr->identHash); + auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash); if (leaseSet) Connect(leaseSet, session); else { - session->localDestination->RequestDestination(addr->identHash, + session->GetLocalDestination ()->RequestDestination(addr->identHash, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, shared_from_this(), std::placeholders::_1)); } } else // B33 - session->localDestination->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, + session->GetLocalDestination ()->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, shared_from_this(), std::placeholders::_1)); } @@ -542,7 +542,7 @@ namespace client if (session) { m_SocketType = eSAMSocketTypeStream; - m_Stream = session->localDestination->CreateStream (remote); + m_Stream = session->GetLocalDestination ()->CreateStream (remote); if (m_Stream) { m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send @@ -586,10 +586,10 @@ namespace client if (session) { m_SocketType = eSAMSocketTypeAcceptor; - if (!session->localDestination->IsAcceptingStreams ()) + if (!session->GetLocalDestination ()->IsAcceptingStreams ()) { m_IsAccepting = true; - session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1)); } SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } @@ -609,7 +609,7 @@ namespace client SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); return; } - if (session->localDestination->IsAcceptingStreams ()) + if (session->GetLocalDestination ()->IsAcceptingStreams ()) { SendI2PError ("Already accepting"); return; @@ -639,7 +639,7 @@ namespace client m_IsAccepting = true; std::string& silent = params[SAM_PARAM_SILENT]; if (silent == SAM_VALUE_TRUE) m_IsSilent = true; - session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PForward, + session->GetLocalDestination ()->AcceptStreams (std::bind (&SAMSocket::HandleI2PForward, shared_from_this (), std::placeholders::_1, ep)); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); } @@ -655,7 +655,7 @@ namespace client auto session = m_Owner.FindSession(m_ID); if (session) { - auto d = session->localDestination->GetDatagramDestination (); + auto d = session->GetLocalDestination ()->GetDatagramDestination (); if (d) { i2p::data::IdentityEx dest; @@ -725,7 +725,7 @@ namespace client std::shared_ptr identity; std::shared_ptr addr; auto session = m_Owner.FindSession(m_ID); - auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->localDestination; + auto dest = session == nullptr ? context.GetSharedLocalDestination() : session->GetLocalDestination (); if (name == "ME") SendNamingLookupReply (name, dest->GetIdentity ()); else if ((identity = context.GetAddressBook ().GetFullAddress (name)) != nullptr) @@ -971,7 +971,7 @@ namespace client if (it->m_SocketType == eSAMSocketTypeAcceptor) { it->m_IsAccepting = true; - session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1)); + session->GetLocalDestination ()->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1)); break; } } @@ -1109,19 +1109,11 @@ namespace client m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); } - SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type, std::shared_ptr dest): - m_Bridge(parent), - localDestination (dest), - UDPEndpoint(nullptr), - Name(id), Type (type) + SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type): + m_Bridge(parent), Name(id), Type (type), UDPEndpoint(nullptr) { } - SAMSession::~SAMSession () - { - i2p::client::context.DeleteLocalDestination (localDestination); - } - void SAMSession::CloseStreams () { for(const auto & itr : m_Bridge.ListSockets(Name)) @@ -1130,6 +1122,17 @@ namespace client } } + SAMSingleSession::SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest): + SAMSession (parent, name, type), + localDestination (dest) + { + } + + SAMSingleSession::~SAMSingleSession () + { + i2p::client::context.DeleteLocalDestination (localDestination); + } + SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): RunnableService ("SAM"), m_IsSingleThread (singleThread), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), @@ -1267,7 +1270,8 @@ namespace client if (localDestination) { localDestination->Acquire (); - auto session = std::make_shared(*this, id, type, localDestination); + auto session = (type == eSAMSessionTypeMaster) ? std::make_shared(*this, id, localDestination) : + std::make_shared(*this, id, type, localDestination); std::unique_lock l(m_SessionsMutex); auto ret = m_Sessions.insert (std::make_pair(id, session)); if (!ret.second) @@ -1291,8 +1295,8 @@ namespace client } if (session) { - session->localDestination->Release (); - session->localDestination->StopAcceptingStreams (); + session->GetLocalDestination ()->Release (); + session->GetLocalDestination ()->StopAcceptingStreams (); session->CloseStreams (); if (m_IsSingleThread) { @@ -1368,10 +1372,10 @@ namespace client i2p::data::IdentityEx dest; dest.FromBase64 (destination); if (session->Type == eSAMSessionTypeDatagram) - session->localDestination->GetDatagramDestination ()-> + session->GetLocalDestination ()->GetDatagramDestination ()-> SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); else // raw - session->localDestination->GetDatagramDestination ()-> + session->GetLocalDestination ()->GetDatagramDestination ()-> SendRawDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); } else diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 8969c50e..2c2729cf 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -179,17 +179,34 @@ namespace client struct SAMSession { SAMBridge & m_Bridge; - std::shared_ptr localDestination; - std::shared_ptr UDPEndpoint; std::string Name; SAMSessionType Type; - - SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest); - ~SAMSession (); - + std::shared_ptr UDPEndpoint; // TODO: move + + SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type); + virtual ~SAMSession () {}; + + virtual std::shared_ptr GetLocalDestination () = 0; + void CloseStreams (); }; - + + struct SAMSingleSession: public SAMSession + { + std::shared_ptr localDestination; + + SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr dest); + ~SAMSingleSession (); + + std::shared_ptr GetLocalDestination () { return localDestination; }; + }; + + struct SAMMasterSession: public SAMSingleSession + { + SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr dest): + SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; + }; + class SAMBridge: private i2p::util::RunnableService { public: