use std::string_view to extract params

This commit is contained in:
orignal 2025-07-05 21:06:49 -04:00
parent 1a6051e79b
commit 59d1695ee5
2 changed files with 103 additions and 98 deletions

View file

@ -11,6 +11,7 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include <charconv>
#include "Base.h" #include "Base.h"
#include "Identity.h" #include "Identity.h"
#include "Log.h" #include "Log.h"
@ -126,8 +127,7 @@ namespace client
if (separator) if (separator)
{ {
separator++; separator++;
std::map<std::string, std::string> params; auto params = ExtractParams (separator);
ExtractParams (separator, params);
auto it = params.find (SAM_PARAM_MAX); auto it = params.find (SAM_PARAM_MAX);
if (it != params.end ()) if (it != params.end ())
maxver = it->second; maxver = it->second;
@ -172,7 +172,7 @@ namespace client
} }
} }
bool SAMSocket::IsSession(const std::string & id) const bool SAMSocket::IsSession(std::string_view id) const
{ {
return id == m_ID; return id == m_ID;
} }
@ -314,7 +314,7 @@ namespace client
} }
} }
static bool IsAcceptableSessionName(const std::string & str) static bool IsAcceptableSessionName(std::string_view str)
{ {
auto itr = str.begin(); auto itr = str.begin();
while(itr != str.end()) while(itr != str.end())
@ -330,11 +330,10 @@ namespace client
void SAMSocket::ProcessSessionCreate (char * buf, size_t len) void SAMSocket::ProcessSessionCreate (char * buf, size_t len)
{ {
LogPrint (eLogDebug, "SAM: Session create: ", buf); LogPrint (eLogDebug, "SAM: Session create: ", buf);
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string_view style = params[SAM_PARAM_STYLE];
std::string& style = params[SAM_PARAM_STYLE]; std::string_view id = params[SAM_PARAM_ID];
std::string& id = params[SAM_PARAM_ID]; std::string_view destination = params[SAM_PARAM_DESTINATION];
std::string& destination = params[SAM_PARAM_DESTINATION];
if(!IsAcceptableSessionName(id)) if(!IsAcceptableSessionName(id))
{ {
@ -377,8 +376,10 @@ namespace client
return; return;
} }
auto port = std::stoi(params[SAM_PARAM_PORT]); uint16_t port = 0;
if (port == -1) std::string_view p = params[SAM_PARAM_PORT];
auto res = std::from_chars(p.data(), p.data() + p.size(), port);
if (res.ec != std::errc())
{ {
SendSessionI2PError("Invalid port"); SendSessionI2PError("Invalid port");
return; return;
@ -405,7 +406,7 @@ namespace client
} }
// create destination // create destination
auto session = m_Owner.CreateSession (id, type, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params); auto session = m_Owner.CreateSession (id, type, destination == SAM_VALUE_TRANSIENT ? "" : destination, params);
if (session) if (session)
{ {
m_SocketType = eSAMSocketTypeSession; m_SocketType = eSAMSocketTypeSession;
@ -413,7 +414,13 @@ namespace client
{ {
session->UDPEndpoint = forward; session->UDPEndpoint = forward;
auto dest = session->GetLocalDestination ()->CreateDatagramDestination (); auto dest = session->GetLocalDestination ()->CreateDatagramDestination ();
auto port = forward ? std::stoi(params[SAM_PARAM_PORT]) : 0; uint16_t port = 0;
if (forward)
{
std::string_view p = params[SAM_PARAM_PORT];
auto res = std::from_chars(p.data(), p.data() + p.size(), port);
if (res.ec != std::errc()) port = 0;
}
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),
@ -486,11 +493,10 @@ namespace client
SendSessionI2PError ("Socket already in use"); SendSessionI2PError ("Socket already in use");
return; return;
} }
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string_view id = params[SAM_PARAM_ID];
std::string& id = params[SAM_PARAM_ID]; std::string_view destination = params[SAM_PARAM_DESTINATION];
std::string& destination = params[SAM_PARAM_DESTINATION]; std::string_view 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;
m_ID = id; m_ID = id;
auto session = m_Owner.FindSession (id); auto session = m_Owner.FindSession (id);
@ -594,10 +600,9 @@ namespace client
SendSessionI2PError ("Socket already in use"); SendSessionI2PError ("Socket already in use");
return; return;
} }
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string_view id = params[SAM_PARAM_ID];
std::string& id = params[SAM_PARAM_ID]; std::string_view 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;
m_ID = id; m_ID = id;
auto session = m_Owner.FindSession (id); auto session = m_Owner.FindSession (id);
@ -640,17 +645,15 @@ namespace client
void SAMSocket::ProcessStreamForward(char* buf, size_t len) void SAMSocket::ProcessStreamForward(char* buf, size_t len)
{ {
LogPrint(eLogDebug, "SAM: Stream forward: ", buf); LogPrint(eLogDebug, "SAM: Stream forward: ", buf);
std::map<std::string, std::string> params; auto params = ExtractParams(buf);
ExtractParams(buf, params);
const auto itId = params.find(SAM_PARAM_ID); const auto itId = params.find(SAM_PARAM_ID);
if (itId == params.end()) if (itId == params.end())
{ {
SendSessionI2PError("Missing ID"); SendSessionI2PError("Missing ID");
return; return;
} }
const std::string& id = itId->second; std::string_view id = itId->second;
auto session = m_Owner.FindSession(id); auto session = m_Owner.FindSession(id);
if (!session) if (!session)
@ -671,15 +674,16 @@ namespace client
return; return;
} }
const std::string& portStr = itPort->second; std::string_view portStr = itPort->second;
if (!std::all_of(portStr.begin(), portStr.end(), ::isdigit)) if (!std::all_of(portStr.begin(), portStr.end(), ::isdigit))
{ {
SendSessionI2PError("Port must be numeric"); SendSessionI2PError("Port must be numeric");
return; return;
} }
int port = std::stoi(portStr); uint16_t port = 0;
if (port <= 0 || port >= 0xFFFF) auto res = std::from_chars(portStr.data(), portStr.data() + portStr.size(), port);
if (res.ec != std::errc())
{ {
SendSessionI2PError("Invalid port"); SendSessionI2PError("Invalid port");
return; return;
@ -729,9 +733,12 @@ namespace client
size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data) size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data)
{ {
LogPrint (eLogDebug, "SAM: Datagram send: ", buf, " ", len); LogPrint (eLogDebug, "SAM: Datagram send: ", buf, " ", len);
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); size_t size = 0;
size_t size = std::stoi(params[SAM_PARAM_SIZE]), offset = data - buf; std::string_view sizeStr = params[SAM_PARAM_SIZE];
auto res = std::from_chars(sizeStr.data(), sizeStr.data() + sizeStr.size(), size);
if (res.ec != std::errc()) size = 0;
size_t offset = data - buf;
if (offset + size <= len) if (offset + size <= len)
{ {
auto session = m_Owner.FindSession(m_ID); auto session = m_Owner.FindSession(m_ID);
@ -764,8 +771,7 @@ namespace client
void SAMSocket::ProcessDestGenerate (char * buf, size_t len) void SAMSocket::ProcessDestGenerate (char * buf, size_t len)
{ {
LogPrint (eLogDebug, "SAM: Dest generate"); LogPrint (eLogDebug, "SAM: Dest generate");
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params);
// extract signature type // extract signature type
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1; i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
@ -780,7 +786,7 @@ namespace client
{ {
try try
{ {
cryptoType = std::stoi(it->second); cryptoType = std::stoi(std::string (it->second));
} }
catch (const std::exception& ex) catch (const std::exception& ex)
{ {
@ -801,9 +807,8 @@ namespace client
void SAMSocket::ProcessNamingLookup (char * buf, size_t len) void SAMSocket::ProcessNamingLookup (char * buf, size_t len)
{ {
LogPrint (eLogDebug, "SAM: Naming lookup: ", buf); LogPrint (eLogDebug, "SAM: Naming lookup: ", buf);
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string name (params[SAM_PARAM_NAME]);
std::string& name = params[SAM_PARAM_NAME];
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);
@ -848,16 +853,15 @@ namespace client
{ {
LogPrint (eLogDebug, "SAM: Subsession add: ", buf); LogPrint (eLogDebug, "SAM: Subsession add: ", buf);
auto masterSession = std::static_pointer_cast<SAMMasterSession>(session); auto masterSession = std::static_pointer_cast<SAMMasterSession>(session);
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string_view id = params[SAM_PARAM_ID];
std::string& id = params[SAM_PARAM_ID];
if (masterSession->subsessions.count (id) > 1) if (masterSession->subsessions.count (id) > 1)
{ {
// session exists // session exists
SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false); SendMessageReply (SAM_SESSION_CREATE_DUPLICATED_ID, strlen(SAM_SESSION_CREATE_DUPLICATED_ID), false);
return; return;
} }
std::string& style = params[SAM_PARAM_STYLE]; std::string_view style = params[SAM_PARAM_STYLE];
SAMSessionType type = eSAMSessionTypeUnknown; SAMSessionType type = eSAMSessionTypeUnknown;
if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream; if (style == SAM_VALUE_STREAM) type = eSAMSessionTypeStream;
// TODO: implement other styles // TODO: implement other styles
@ -867,7 +871,7 @@ namespace client
SendSessionI2PError("Unsupported STYLE"); SendSessionI2PError("Unsupported STYLE");
return; return;
} }
auto fromPort = std::stoi(params[SAM_PARAM_FROM_PORT]); auto fromPort = std::stoi(std::string (params[SAM_PARAM_FROM_PORT]));
if (fromPort == -1) if (fromPort == -1)
{ {
SendSessionI2PError("Invalid from port"); SendSessionI2PError("Invalid from port");
@ -876,7 +880,7 @@ namespace client
auto subsession = std::make_shared<SAMSubSession>(masterSession, id, type, fromPort); auto subsession = std::make_shared<SAMSubSession>(masterSession, id, type, fromPort);
if (m_Owner.AddSession (subsession)) if (m_Owner.AddSession (subsession))
{ {
masterSession->subsessions.insert (id); masterSession->subsessions.insert (std::string (id));
SendSessionCreateReplyOk (); SendSessionCreateReplyOk ();
} }
else else
@ -893,9 +897,8 @@ namespace client
{ {
LogPrint (eLogDebug, "SAM: Subsession remove: ", buf); LogPrint (eLogDebug, "SAM: Subsession remove: ", buf);
auto masterSession = std::static_pointer_cast<SAMMasterSession>(session); auto masterSession = std::static_pointer_cast<SAMMasterSession>(session);
std::map<std::string, std::string> params; auto params = ExtractParams (buf);
ExtractParams (buf, params); std::string id(params[SAM_PARAM_ID]);
std::string& id = params[SAM_PARAM_ID];
if (!masterSession->subsessions.erase (id)) if (!masterSession->subsessions.erase (id))
{ {
SendMessageReply (SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), false); SendMessageReply (SAM_SESSION_STATUS_INVALID_KEY, strlen(SAM_SESSION_STATUS_INVALID_KEY), false);
@ -965,8 +968,9 @@ namespace client
SendMessageReply (m_Buffer, l, false); SendMessageReply (m_Buffer, l, false);
} }
void SAMSocket::ExtractParams (char * buf, std::map<std::string, std::string>& params) const std::map<std::string_view, std::string_view> SAMSocket::ExtractParams (char * buf)
{ {
std::map<std::string_view, std::string_view> params;
char * separator; char * separator;
do do
{ {
@ -977,11 +981,12 @@ namespace client
{ {
*value = 0; *value = 0;
value++; value++;
params[buf] = value; params.emplace (buf, value);
} }
buf = separator + 1; buf = separator + 1;
} }
while (separator); while (separator);
return params;
} }
void SAMSocket::Receive () void SAMSocket::Receive ()
@ -1289,7 +1294,7 @@ namespace client
boost::asio::post (m_Owner.GetService (), std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this())); boost::asio::post (m_Owner.GetService (), std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this()));
} }
SAMSession::SAMSession (SAMBridge & parent, const std::string & id, SAMSessionType type): SAMSession::SAMSession (SAMBridge & parent, std::string_view id, SAMSessionType type):
m_Bridge(parent), Name(id), Type (type), UDPEndpoint(nullptr) m_Bridge(parent), Name(id), Type (type), UDPEndpoint(nullptr)
{ {
} }
@ -1302,7 +1307,7 @@ namespace client
} }
} }
SAMSingleSession::SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr<ClientDestination> dest): SAMSingleSession::SAMSingleSession (SAMBridge & parent, std::string_view name, SAMSessionType type, std::shared_ptr<ClientDestination> dest):
SAMSession (parent, name, type), SAMSession (parent, name, type),
localDestination (dest) localDestination (dest)
{ {
@ -1331,7 +1336,7 @@ namespace client
subsessions.clear (); subsessions.clear ();
} }
SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, uint16_t port): SAMSubSession::SAMSubSession (std::shared_ptr<SAMMasterSession> master, std::string_view name, SAMSessionType type, uint16_t port):
SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port) SAMSession (master->m_Bridge, name, type), masterSession (master), inPort (port)
{ {
if (Type == eSAMSessionTypeStream) if (Type == eSAMSessionTypeStream)
@ -1452,37 +1457,38 @@ namespace client
Accept (); Accept ();
} }
std::shared_ptr<SAMSession> SAMBridge::CreateSession (const std::string& id, SAMSessionType type, std::shared_ptr<SAMSession> SAMBridge::CreateSession (std::string_view id, SAMSessionType type,
const std::string& destination, const std::map<std::string, std::string> * params) std::string_view destination, const std::map<std::string_view, std::string_view>& params)
{ {
std::map<std::string, std::string> p(params.begin (), params.end ());
std::shared_ptr<ClientDestination> localDestination = nullptr; std::shared_ptr<ClientDestination> localDestination = nullptr;
if (destination != "") if (destination != "")
{ {
i2p::data::PrivateKeys keys; i2p::data::PrivateKeys keys;
if (!keys.FromBase64 (destination)) return nullptr; if (!keys.FromBase64 (destination)) return nullptr;
localDestination = m_IsSingleThread ? localDestination = m_IsSingleThread ?
i2p::client::context.CreateNewLocalDestination (GetIOService (), keys, true, params) : i2p::client::context.CreateNewLocalDestination (GetIOService (), keys, true, &p) :
i2p::client::context.CreateNewLocalDestination (keys, true, params); i2p::client::context.CreateNewLocalDestination (keys, true, &p);
} }
else // transient else // transient
{ {
// extract signature type // extract signature type
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1; i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL; i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
if (params) if (!params.empty ())
{ {
auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); auto it = params.find (SAM_PARAM_SIGNATURE_TYPE);
if (it != params->end ()) if (it != params.end ())
{ {
if (!ResolveSignatureType (it->second, signatureType)) if (!ResolveSignatureType (it->second, signatureType))
LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second); LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, " is invalid ", it->second);
} }
it = params->find (SAM_PARAM_CRYPTO_TYPE); it = params.find (SAM_PARAM_CRYPTO_TYPE);
if (it != params->end ()) if (it != params.end ())
{ {
try try
{ {
cryptoType = std::stoi(it->second); cryptoType = std::stoi(std::string (it->second));
} }
catch (const std::exception& ex) catch (const std::exception& ex)
{ {
@ -1491,8 +1497,8 @@ namespace client
} }
} }
localDestination = m_IsSingleThread ? localDestination = m_IsSingleThread ?
i2p::client::context.CreateNewLocalDestination (GetIOService (), true, signatureType, cryptoType, params) : i2p::client::context.CreateNewLocalDestination (GetIOService (), true, signatureType, cryptoType, &p) :
i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, &p);
} }
if (localDestination) if (localDestination)
{ {
@ -1500,7 +1506,7 @@ namespace client
auto session = (type == eSAMSessionTypeMaster) ? std::make_shared<SAMMasterSession>(*this, id, localDestination) : auto session = (type == eSAMSessionTypeMaster) ? std::make_shared<SAMMasterSession>(*this, id, localDestination) :
std::make_shared<SAMSingleSession>(*this, id, type, 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.emplace (id, session);
if (!ret.second) if (!ret.second)
LogPrint (eLogWarning, "SAM: Session ", id, " already exists"); LogPrint (eLogWarning, "SAM: Session ", id, " already exists");
return ret.first->second; return ret.first->second;
@ -1515,7 +1521,7 @@ namespace client
return ret.second; return ret.second;
} }
void SAMBridge::CloseSession (const std::string& id) void SAMBridge::CloseSession (std::string_view id)
{ {
std::shared_ptr<SAMSession> session; std::shared_ptr<SAMSession> session;
{ {
@ -1565,7 +1571,7 @@ namespace client
// session's destructor is called here unless rescheduled // session's destructor is called here unless rescheduled
} }
std::shared_ptr<SAMSession> SAMBridge::FindSession (const std::string& id) const std::shared_ptr<SAMSession> SAMBridge::FindSession (std::string_view id) const
{ {
std::unique_lock<std::mutex> l(m_SessionsMutex); std::unique_lock<std::mutex> l(m_SessionsMutex);
auto it = m_Sessions.find (id); auto it = m_Sessions.find (id);
@ -1574,7 +1580,7 @@ namespace client
return nullptr; return nullptr;
} }
std::list<std::shared_ptr<SAMSocket> > SAMBridge::ListSockets(const std::string & id) const std::list<std::shared_ptr<SAMSocket> > SAMBridge::ListSockets(std::string_view id) const
{ {
std::list<std::shared_ptr<SAMSocket > > list; std::list<std::shared_ptr<SAMSocket > > list;
{ {
@ -1654,25 +1660,23 @@ namespace client
LogPrint (eLogError, "SAM: Datagram receive error: ", ecode.message ()); LogPrint (eLogError, "SAM: Datagram receive error: ", ecode.message ());
} }
bool SAMBridge::ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const bool SAMBridge::ResolveSignatureType (std::string_view name, i2p::data::SigningKeyType& type) const
{ {
try auto res = std::from_chars(name.data(), name.data() + name.size(), type);
if (res.ec != std::errc())
{ {
type = std::stoi (name); if (res.ec == std::errc::invalid_argument)
} {
catch (const std::invalid_argument& ex) // name is not numeric, resolving
{ auto it = m_SignatureTypes.find (name);
// name is not numeric, resolving if (it != m_SignatureTypes.end ())
auto it = m_SignatureTypes.find (name); type = it->second;
if (it != m_SignatureTypes.end ()) else
type = it->second; return false;
}
else else
return false; return false;
} }
catch (const std::exception& ex)
{
return false;
}
// name has been resolved // name has been resolved
return true; return true;
} }

View file

@ -11,6 +11,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <string> #include <string>
#include <string_view>
#include <map> #include <map>
#include <list> #include <list>
#include <set> #include <set>
@ -116,7 +117,7 @@ namespace client
void Terminate (const char* reason); void Terminate (const char* reason);
bool IsSession(const std::string & id) const; bool IsSession(std::string_view id) const;
private: private:
@ -151,7 +152,7 @@ namespace client
void SendStreamI2PError(const std::string & msg); void SendStreamI2PError(const std::string & msg);
void SendStreamCantReachPeer(const std::string & msg); void SendStreamCantReachPeer(const std::string & msg);
size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0
void ExtractParams (char * buf, std::map<std::string, std::string>& params); const std::map<std::string_view, std::string_view> ExtractParams (char * buf);
void Connect (std::shared_ptr<const i2p::data::LeaseSet> remote, std::shared_ptr<SAMSession> session = nullptr); void Connect (std::shared_ptr<const i2p::data::LeaseSet> remote, std::shared_ptr<SAMSession> session = nullptr);
void HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet); void HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet);
@ -199,7 +200,7 @@ namespace client
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint; // TODO: move std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint; // TODO: move
std::list<std::pair<std::shared_ptr<SAMSocket>, uint64_t> > acceptQueue; // socket, receive time in seconds std::list<std::pair<std::shared_ptr<SAMSocket>, uint64_t> > acceptQueue; // socket, receive time in seconds
SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type); SAMSession (SAMBridge & parent, std::string_view name, SAMSessionType type);
virtual ~SAMSession () {}; virtual ~SAMSession () {};
virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0; virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0;
@ -213,7 +214,7 @@ namespace client
{ {
std::shared_ptr<ClientDestination> localDestination; std::shared_ptr<ClientDestination> localDestination;
SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr<ClientDestination> dest); SAMSingleSession (SAMBridge & parent, std::string_view name, SAMSessionType type, std::shared_ptr<ClientDestination> dest);
~SAMSingleSession (); ~SAMSingleSession ();
std::shared_ptr<ClientDestination> GetLocalDestination () { return localDestination; }; std::shared_ptr<ClientDestination> GetLocalDestination () { return localDestination; };
@ -222,8 +223,8 @@ namespace client
struct SAMMasterSession: public SAMSingleSession struct SAMMasterSession: public SAMSingleSession
{ {
std::set<std::string> subsessions; std::set<std::string, std::less<> > subsessions;
SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest): SAMMasterSession (SAMBridge & parent, std::string_view name, std::shared_ptr<ClientDestination> dest):
SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {}; SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {};
void Close (); void Close ();
}; };
@ -233,7 +234,7 @@ namespace client
std::shared_ptr<SAMMasterSession> masterSession; std::shared_ptr<SAMMasterSession> masterSession;
uint16_t inPort; uint16_t inPort;
SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, uint16_t port); SAMSubSession (std::shared_ptr<SAMMasterSession> master, std::string_view name, SAMSessionType type, uint16_t port);
// implements SAMSession // implements SAMSession
std::shared_ptr<ClientDestination> GetLocalDestination (); std::shared_ptr<ClientDestination> GetLocalDestination ();
void StopLocalDestination (); void StopLocalDestination ();
@ -250,13 +251,13 @@ namespace client
void Stop (); void Stop ();
auto& GetService () { return GetIOService (); }; auto& 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 (std::string_view id, SAMSessionType type, std::string_view destination, // empty string means transient
const std::map<std::string, std::string> * params); const std::map<std::string_view, std::string_view>& params);
bool AddSession (std::shared_ptr<SAMSession> session); bool AddSession (std::shared_ptr<SAMSession> session);
void CloseSession (const std::string& id); void CloseSession (std::string_view id);
std::shared_ptr<SAMSession> FindSession (const std::string& id) const; std::shared_ptr<SAMSession> FindSession (std::string_view id) const;
std::list<std::shared_ptr<SAMSocket> > ListSockets(const std::string & id) const; std::list<std::shared_ptr<SAMSocket> > ListSockets(std::string_view id) const;
/** send raw data to remote endpoint from our UDP Socket */ /** send raw data to remote endpoint from our UDP Socket */
void SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep); void SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep);
@ -264,7 +265,7 @@ namespace client
void AddSocket(std::shared_ptr<SAMSocket> socket); void AddSocket(std::shared_ptr<SAMSocket> socket);
void RemoveSocket(const std::shared_ptr<SAMSocket> & socket); void RemoveSocket(const std::shared_ptr<SAMSocket> & socket);
bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const; bool ResolveSignatureType (std::string_view name, i2p::data::SigningKeyType& type) const;
private: private:
@ -285,11 +286,11 @@ namespace client
boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint; boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint;
boost::asio::ip::udp::socket m_DatagramSocket; boost::asio::ip::udp::socket m_DatagramSocket;
mutable std::mutex m_SessionsMutex; mutable std::mutex m_SessionsMutex;
std::map<std::string, std::shared_ptr<SAMSession> > m_Sessions; std::map<std::string, std::shared_ptr<SAMSession>, std::less<>> m_Sessions;
mutable std::mutex m_OpenSocketsMutex; mutable std::mutex m_OpenSocketsMutex;
std::list<std::shared_ptr<SAMSocket> > m_OpenSockets; std::list<std::shared_ptr<SAMSocket> > m_OpenSockets;
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1]; uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1];
std::map<std::string, i2p::data::SigningKeyType> m_SignatureTypes; const std::map<std::string_view, i2p::data::SigningKeyType> m_SignatureTypes;
public: public: