\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 << "
\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: