Browse Source

SAM single and master sessions

pull/1656/head
orignal 4 years ago
parent
commit
4018cf9d76
  1. 4
      daemon/HTTPServer.cpp
  2. 4
      daemon/I2PControl.cpp
  3. 68
      libi2pd_client/SAM.cpp
  4. 31
      libi2pd_client/SAM.h

4
daemon/HTTPServer.cpp

@ -842,7 +842,7 @@ namespace http {
s << "<b>SAM Sessions:</b><br>\r\n<div class=\"list\">\r\n"; s << "<b>SAM Sessions:</b><br>\r\n<div class=\"list\">\r\n";
for (auto& it: sam->GetSessions ()) for (auto& it: sam->GetSessions ())
{ {
auto& name = it.second->localDestination->GetNickname (); auto& name = it.second->GetLocalDestination ()->GetNickname ();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">"; s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
s << name << " (" << it.first << ")</a></div>\r\n" << std::endl; s << name << " (" << it.first << ")</a></div>\r\n" << std::endl;
} }
@ -868,7 +868,7 @@ namespace http {
std::string webroot; i2p::config::GetOption("http.webroot", webroot); std::string webroot; i2p::config::GetOption("http.webroot", webroot);
s << "<b>SAM Session:</b><br>\r\n<div class=\"list\">\r\n"; s << "<b>SAM Session:</b><br>\r\n<div class=\"list\">\r\n";
auto& ident = session->localDestination->GetIdentHash(); auto& ident = session->GetLocalDestination ()->GetIdentHash();
s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">"; s << "<div class=\"listitem\"><a href=\"" << webroot << "?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n"; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a></div>\r\n";
s << "<br>\r\n"; s << "<br>\r\n";

4
daemon/I2PControl.cpp

@ -714,8 +714,8 @@ namespace client
for (auto& it: sam->GetSessions ()) for (auto& it: sam->GetSessions ())
{ {
boost::property_tree::ptree sam_session, sam_session_sockets; boost::property_tree::ptree sam_session, sam_session_sockets;
auto& name = it.second->localDestination->GetNickname (); auto& name = it.second->GetLocalDestination ()->GetNickname ();
auto& ident = it.second->localDestination->GetIdentHash(); auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
sam_session.put("name", name); sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));

68
libi2pd_client/SAM.cpp

@ -58,8 +58,8 @@ namespace client
{ {
if (Session) if (Session)
{ {
if (m_IsAccepting && Session->localDestination) if (m_IsAccepting && Session->GetLocalDestination ())
Session->localDestination->StopAcceptingStreams (); Session->GetLocalDestination ()->StopAcceptingStreams ();
} }
break; break;
} }
@ -410,7 +410,7 @@ namespace client
if (type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw) if (type == eSAMSessionTypeDatagram || type == eSAMSessionTypeRaw)
{ {
session->UDPEndpoint = forward; session->UDPEndpoint = forward;
auto dest = session->localDestination->CreateDatagramDestination (); auto dest = session->GetLocalDestination ()->CreateDatagramDestination ();
if (type == eSAMSessionTypeDatagram) if (type == eSAMSessionTypeDatagram)
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); 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)); std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
} }
if (session->localDestination->IsReady ()) if (session->GetLocalDestination ()->IsReady ())
SendSessionCreateReplyOk (); SendSessionCreateReplyOk ();
else else
{ {
@ -439,7 +439,7 @@ namespace client
auto session = m_Owner.FindSession(m_ID); auto session = m_Owner.FindSession(m_ID);
if(session) if(session)
{ {
if (session->localDestination->IsReady ()) if (session->GetLocalDestination ()->IsReady ())
SendSessionCreateReplyOk (); SendSessionCreateReplyOk ();
else else
{ {
@ -458,7 +458,7 @@ namespace client
{ {
uint8_t buf[1024]; uint8_t buf[1024];
char priv[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); size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, priv, 1024);
priv[l1] = 0; priv[l1] = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -514,18 +514,18 @@ namespace client
{ {
if (addr->IsIdentHash ()) if (addr->IsIdentHash ())
{ {
auto leaseSet = session->localDestination->FindLeaseSet(addr->identHash); auto leaseSet = session->GetLocalDestination ()->FindLeaseSet(addr->identHash);
if (leaseSet) if (leaseSet)
Connect(leaseSet, session); Connect(leaseSet, session);
else else
{ {
session->localDestination->RequestDestination(addr->identHash, session->GetLocalDestination ()->RequestDestination(addr->identHash,
std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete,
shared_from_this(), std::placeholders::_1)); shared_from_this(), std::placeholders::_1));
} }
} }
else // B33 else // B33
session->localDestination->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey, session->GetLocalDestination ()->RequestDestinationWithEncryptedLeaseSet (addr->blindedPublicKey,
std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete, std::bind(&SAMSocket::HandleConnectLeaseSetRequestComplete,
shared_from_this(), std::placeholders::_1)); shared_from_this(), std::placeholders::_1));
} }
@ -542,7 +542,7 @@ namespace client
if (session) if (session)
{ {
m_SocketType = eSAMSocketTypeStream; m_SocketType = eSAMSocketTypeStream;
m_Stream = session->localDestination->CreateStream (remote); m_Stream = session->GetLocalDestination ()->CreateStream (remote);
if (m_Stream) if (m_Stream)
{ {
m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send
@ -586,10 +586,10 @@ namespace client
if (session) if (session)
{ {
m_SocketType = eSAMSocketTypeAcceptor; m_SocketType = eSAMSocketTypeAcceptor;
if (!session->localDestination->IsAcceptingStreams ()) if (!session->GetLocalDestination ()->IsAcceptingStreams ())
{ {
m_IsAccepting = true; 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); 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); SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true);
return; return;
} }
if (session->localDestination->IsAcceptingStreams ()) if (session->GetLocalDestination ()->IsAcceptingStreams ())
{ {
SendI2PError ("Already accepting"); SendI2PError ("Already accepting");
return; return;
@ -639,7 +639,7 @@ namespace client
m_IsAccepting = true; m_IsAccepting = true;
std::string& silent = params[SAM_PARAM_SILENT]; std::string& silent = params[SAM_PARAM_SILENT];
if (silent == SAM_VALUE_TRUE) m_IsSilent = true; 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)); shared_from_this (), std::placeholders::_1, ep));
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false); SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
} }
@ -655,7 +655,7 @@ namespace client
auto session = m_Owner.FindSession(m_ID); auto session = m_Owner.FindSession(m_ID);
if (session) if (session)
{ {
auto d = session->localDestination->GetDatagramDestination (); auto d = session->GetLocalDestination ()->GetDatagramDestination ();
if (d) if (d)
{ {
i2p::data::IdentityEx dest; i2p::data::IdentityEx dest;
@ -725,7 +725,7 @@ namespace client
std::shared_ptr<const i2p::data::IdentityEx> identity; std::shared_ptr<const i2p::data::IdentityEx> identity;
std::shared_ptr<const Address> addr; std::shared_ptr<const Address> addr;
auto session = m_Owner.FindSession(m_ID); 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") if (name == "ME")
SendNamingLookupReply (name, dest->GetIdentity ()); SendNamingLookupReply (name, dest->GetIdentity ());
else if ((identity = context.GetAddressBook ().GetFullAddress (name)) != nullptr) else if ((identity = context.GetAddressBook ().GetFullAddress (name)) != nullptr)
@ -971,7 +971,7 @@ namespace client
if (it->m_SocketType == eSAMSocketTypeAcceptor) if (it->m_SocketType == eSAMSocketTypeAcceptor)
{ {
it->m_IsAccepting = true; 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; break;
} }
} }
@ -1109,19 +1109,11 @@ namespace client
m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); 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<ClientDestination> dest): SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type):
m_Bridge(parent), m_Bridge(parent), Name(id), Type (type), UDPEndpoint(nullptr)
localDestination (dest),
UDPEndpoint(nullptr),
Name(id), Type (type)
{ {
} }
SAMSession::~SAMSession ()
{
i2p::client::context.DeleteLocalDestination (localDestination);
}
void SAMSession::CloseStreams () void SAMSession::CloseStreams ()
{ {
for(const auto & itr : m_Bridge.ListSockets(Name)) 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<ClientDestination> dest):
SAMSession (parent, name, type),
localDestination (dest)
{
}
SAMSingleSession::~SAMSingleSession ()
{
i2p::client::context.DeleteLocalDestination (localDestination);
}
SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread): SAMBridge::SAMBridge (const std::string& address, int port, bool singleThread):
RunnableService ("SAM"), m_IsSingleThread (singleThread), RunnableService ("SAM"), m_IsSingleThread (singleThread),
m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)), m_Acceptor (GetIOService (), boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(address), port)),
@ -1267,7 +1270,8 @@ namespace client
if (localDestination) if (localDestination)
{ {
localDestination->Acquire (); localDestination->Acquire ();
auto session = std::make_shared<SAMSession>(*this, id, type, localDestination); auto session = (type == eSAMSessionTypeMaster) ? std::make_shared<SAMMasterSession>(*this, id, localDestination) :
std::make_shared<SAMSingleSession>(*this, id, type, localDestination);
std::unique_lock<std::mutex> l(m_SessionsMutex); std::unique_lock<std::mutex> l(m_SessionsMutex);
auto ret = m_Sessions.insert (std::make_pair(id, session)); auto ret = m_Sessions.insert (std::make_pair(id, session));
if (!ret.second) if (!ret.second)
@ -1291,8 +1295,8 @@ namespace client
} }
if (session) if (session)
{ {
session->localDestination->Release (); session->GetLocalDestination ()->Release ();
session->localDestination->StopAcceptingStreams (); session->GetLocalDestination ()->StopAcceptingStreams ();
session->CloseStreams (); session->CloseStreams ();
if (m_IsSingleThread) if (m_IsSingleThread)
{ {
@ -1368,10 +1372,10 @@ namespace client
i2p::data::IdentityEx dest; i2p::data::IdentityEx dest;
dest.FromBase64 (destination); dest.FromBase64 (destination);
if (session->Type == eSAMSessionTypeDatagram) if (session->Type == eSAMSessionTypeDatagram)
session->localDestination->GetDatagramDestination ()-> session->GetLocalDestination ()->GetDatagramDestination ()->
SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ());
else // raw else // raw
session->localDestination->GetDatagramDestination ()-> session->GetLocalDestination ()->GetDatagramDestination ()->
SendRawDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ()); SendRawDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ());
} }
else else

31
libi2pd_client/SAM.h

@ -179,17 +179,34 @@ namespace client
struct SAMSession struct SAMSession
{ {
SAMBridge & m_Bridge; SAMBridge & m_Bridge;
std::shared_ptr<ClientDestination> localDestination;
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint;
std::string Name; std::string Name;
SAMSessionType Type; SAMSessionType Type;
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint; // TODO: move
SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr<ClientDestination> dest);
~SAMSession (); SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type);
virtual ~SAMSession () {};
virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0;
void CloseStreams (); void CloseStreams ();
}; };
struct SAMSingleSession: public SAMSession
{
std::shared_ptr<ClientDestination> localDestination;
SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr<ClientDestination> dest);
~SAMSingleSession ();
std::shared_ptr<ClientDestination> GetLocalDestination () { return localDestination; };
};
struct SAMMasterSession: public SAMSingleSession
{
SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest):
SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {};
};
class SAMBridge: private i2p::util::RunnableService class SAMBridge: private i2p::util::RunnableService
{ {
public: public:

Loading…
Cancel
Save