Browse Source

Add/Remove subsession

pull/1656/head
orignal 3 years ago
parent
commit
d299cbaabd
  1. 80
      libi2pd_client/SAM.cpp
  2. 6
      libi2pd_client/SAM.h

80
libi2pd_client/SAM.cpp

@ -765,12 +765,69 @@ namespace client
void SAMSocket::ProcessSessionAdd (char * buf, size_t len) void SAMSocket::ProcessSessionAdd (char * buf, size_t len)
{ {
// TODO: implement auto session = m_Owner.FindSession(m_ID);
if (session && session->Type == eSAMSessionTypeMaster)
{
LogPrint (eLogDebug, "SAM: subsession add: ", buf);
auto masterSession = std::static_pointer_cast<SAMMasterSession>(session);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& id = params[SAM_PARAM_ID];
if (masterSession->subsessions.count (id) > 1)
{
// session exists
SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false);
return;
}
std::string& style = params[SAM_PARAM_STYLE];
SAMSessionType type = eSAMSessionTypeUnknown;
if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream;
// TODO: implement other styles
if (type == eSAMSessionTypeUnknown)
{
// unknown style
SendI2PError("Unsupported STYLE");
return;
}
auto fromPort = std::stoi(params[SAM_PARAM_FROM_PORT]);
if (fromPort == -1)
{
SendI2PError("Invalid from port");
return;
}
auto subsession = std::make_shared<SAMSubSession>(masterSession, id, type, fromPort);
if (m_Owner.AddSession (subsession))
{
masterSession->subsessions.insert (id);
SendSessionCreateReplyOk ();
}
else
SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false);
}
else
SendI2PError ("Wrong session type");
} }
void SAMSocket::ProcessSessionRemove (char * buf, size_t len) void SAMSocket::ProcessSessionRemove (char * buf, size_t len)
{ {
// TODO: implement auto session = m_Owner.FindSession(m_ID);
if (session && session->Type == eSAMSessionTypeMaster)
{
LogPrint (eLogDebug, "SAM: subsession remove: ", buf);
auto masterSession = std::static_pointer_cast<SAMMasterSession>(session);
std::map<std::string, std::string> params;
ExtractParams (buf, params);
std::string& id = params[SAM_PARAM_ID];
if (!masterSession->subsessions.erase (id))
{
SendMessageReply (SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), false);
return;
}
m_Owner.CloseSession (id);
SendSessionCreateReplyOk ();
}
else
SendI2PError ("Wrong session type");
} }
void SAMSocket::SendI2PError(const std::string & msg) void SAMSocket::SendI2PError(const std::string & msg)
@ -1153,6 +1210,14 @@ namespace client
localDestination->StopAcceptingStreams (); localDestination->StopAcceptingStreams ();
} }
void SAMMasterSession::Close ()
{
SAMSingleSession::Close ();
for (const auto& it: subsessions)
m_Bridge.CloseSession (it);
subsessions.clear ();
}
SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, int port): SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, int port):
SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port) SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port)
{ {
@ -1225,7 +1290,7 @@ namespace client
{ {
std::unique_lock<std::mutex> l(m_SessionsMutex); std::unique_lock<std::mutex> l(m_SessionsMutex);
for (auto& it: m_Sessions) for (auto& it: m_Sessions)
it.second->CloseStreams (); it.second->Close ();
m_Sessions.clear (); m_Sessions.clear ();
} }
StopIOService (); StopIOService ();
@ -1328,6 +1393,13 @@ namespace client
return nullptr; return nullptr;
} }
bool SAMBridge::AddSession (std::shared_ptr<SAMSession> session)
{
if (!session) return false;
auto ret = m_Sessions.emplace (session->Name, session);
return ret.second;
}
void SAMBridge::CloseSession (const std::string& id) void SAMBridge::CloseSession (const std::string& id)
{ {
std::shared_ptr<SAMSession> session; std::shared_ptr<SAMSession> session;
@ -1343,7 +1415,7 @@ namespace client
if (session) if (session)
{ {
session->StopLocalDestination (); session->StopLocalDestination ();
session->CloseStreams (); session->Close ();
if (m_IsSingleThread) if (m_IsSingleThread)
{ {
auto timer = std::make_shared<boost::asio::deadline_timer>(GetService ()); auto timer = std::make_shared<boost::asio::deadline_timer>(GetService ());

6
libi2pd_client/SAM.h

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <map> #include <map>
#include <list> #include <list>
#include <set>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <memory> #include <memory>
@ -74,6 +75,7 @@ namespace client
const char SAM_PARAM_SIZE[] = "SIZE"; const char SAM_PARAM_SIZE[] = "SIZE";
const char SAM_PARAM_HOST[] = "HOST"; const char SAM_PARAM_HOST[] = "HOST";
const char SAM_PARAM_PORT[] = "PORT"; const char SAM_PARAM_PORT[] = "PORT";
const char SAM_PARAM_FROM_PORT[] = "FROM_PORT";
const char SAM_VALUE_TRANSIENT[] = "TRANSIENT"; const char SAM_VALUE_TRANSIENT[] = "TRANSIENT";
const char SAM_VALUE_STREAM[] = "STREAM"; const char SAM_VALUE_STREAM[] = "STREAM";
const char SAM_VALUE_DATAGRAM[] = "DATAGRAM"; const char SAM_VALUE_DATAGRAM[] = "DATAGRAM";
@ -192,6 +194,7 @@ namespace client
virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0; virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0;
virtual void StopLocalDestination () = 0; virtual void StopLocalDestination () = 0;
virtual void Close () { CloseStreams (); };
void CloseStreams (); void CloseStreams ();
}; };
@ -209,8 +212,10 @@ namespace client
struct SAMMasterSession: public SAMSingleSession struct SAMMasterSession: public SAMSingleSession
{ {
std::set<std::string> subsessions;
SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest): SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest):
SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {};
void Close ();
}; };
struct SAMSubSession: public SAMSession struct SAMSubSession: public SAMSession
@ -237,6 +242,7 @@ namespace client
boost::asio::io_service& GetService () { return GetIOService (); }; boost::asio::io_service& GetService () { return GetIOService (); };
std::shared_ptr<SAMSession> CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient std::shared_ptr<SAMSession> CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient
const std::map<std::string, std::string> * params); const std::map<std::string, std::string> * params);
bool AddSession (std::shared_ptr<SAMSession> session);
void CloseSession (const std::string& id); void CloseSession (const std::string& id);
std::shared_ptr<SAMSession> FindSession (const std::string& id) const; std::shared_ptr<SAMSession> FindSession (const std::string& id) const;

Loading…
Cancel
Save