mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
shared pointer for SSU
This commit is contained in:
parent
1a0957b571
commit
95524c8db3
53
SSU.cpp
53
SSU.cpp
@ -27,17 +27,15 @@ namespace transport
|
||||
|
||||
SSUServer::~SSUServer ()
|
||||
{
|
||||
for (auto it: m_Sessions)
|
||||
delete it.second;
|
||||
}
|
||||
|
||||
void SSUServer::Start ()
|
||||
{
|
||||
m_IsRunning = true;
|
||||
m_Thread = new std::thread (std::bind (&SSUServer::Run, this));
|
||||
m_Service.post (boost::bind (&SSUServer::Receive, this));
|
||||
m_Service.post (std::bind (&SSUServer::Receive, this));
|
||||
if (context.SupportsV6 ())
|
||||
m_Service.post (boost::bind (&SSUServer::ReceiveV6, this));
|
||||
m_Service.post (std::bind (&SSUServer::ReceiveV6, this));
|
||||
if (i2p::context.IsUnreachable ())
|
||||
ScheduleIntroducersUpdateTimer ();
|
||||
}
|
||||
@ -76,7 +74,7 @@ namespace transport
|
||||
m_Relays[tag] = relay;
|
||||
}
|
||||
|
||||
SSUSession * SSUServer::FindRelaySession (uint32_t tag)
|
||||
std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag)
|
||||
{
|
||||
auto it = m_Relays.find (tag);
|
||||
if (it != m_Relays.end ())
|
||||
@ -128,13 +126,13 @@ namespace transport
|
||||
|
||||
void SSUServer::HandleReceivedBuffer (boost::asio::ip::udp::endpoint& from, uint8_t * buf, std::size_t bytes_transferred)
|
||||
{
|
||||
SSUSession * session = nullptr;
|
||||
std::shared_ptr<SSUSession> session;
|
||||
auto it = m_Sessions.find (from);
|
||||
if (it != m_Sessions.end ())
|
||||
session = it->second;
|
||||
if (!session)
|
||||
{
|
||||
session = new SSUSession (*this, from);
|
||||
session = std::make_shared<SSUSession> (*this, from);
|
||||
session->WaitForConnect ();
|
||||
m_Sessions[from] = session;
|
||||
LogPrint ("New SSU session from ", from.address ().to_string (), ":", from.port (), " created");
|
||||
@ -142,7 +140,7 @@ namespace transport
|
||||
session->ProcessNextMessage (buf, bytes_transferred, from);
|
||||
}
|
||||
|
||||
SSUSession * SSUServer::FindSession (const i2p::data::RouterInfo * router) const
|
||||
std::shared_ptr<SSUSession> SSUServer::FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const
|
||||
{
|
||||
if (!router) return nullptr;
|
||||
auto address = router->GetSSUAddress (true); // v4 only
|
||||
@ -156,7 +154,7 @@ namespace transport
|
||||
return FindSession (boost::asio::ip::udp::endpoint (address->host, address->port));
|
||||
}
|
||||
|
||||
SSUSession * SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const
|
||||
std::shared_ptr<SSUSession> SSUServer::FindSession (const boost::asio::ip::udp::endpoint& e) const
|
||||
{
|
||||
auto it = m_Sessions.find (e);
|
||||
if (it != m_Sessions.end ())
|
||||
@ -165,9 +163,9 @@ namespace transport
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SSUSession * SSUServer::GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
|
||||
std::shared_ptr<SSUSession> SSUServer::GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
|
||||
{
|
||||
SSUSession * session = nullptr;
|
||||
std::shared_ptr<SSUSession> session;
|
||||
if (router)
|
||||
{
|
||||
auto address = router->GetSSUAddress (!context.SupportsV6 ());
|
||||
@ -180,7 +178,7 @@ namespace transport
|
||||
else
|
||||
{
|
||||
// otherwise create new session
|
||||
session = new SSUSession (*this, remoteEndpoint, router, peerTest);
|
||||
session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
||||
m_Sessions[remoteEndpoint] = session;
|
||||
|
||||
if (!router->UsesIntroducer ())
|
||||
@ -196,7 +194,7 @@ namespace transport
|
||||
int numIntroducers = address->introducers.size ();
|
||||
if (numIntroducers > 0)
|
||||
{
|
||||
SSUSession * introducerSession = nullptr;
|
||||
std::shared_ptr<SSUSession> introducerSession;
|
||||
const i2p::data::RouterInfo::Introducer * introducer = nullptr;
|
||||
// we might have a session to introducer already
|
||||
for (int i = 0; i < numIntroducers; i++)
|
||||
@ -217,7 +215,7 @@ namespace transport
|
||||
LogPrint ("Creating new session to introducer");
|
||||
introducer = &(address->introducers[0]); // TODO:
|
||||
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
|
||||
introducerSession = new SSUSession (*this, introducerEndpoint, router);
|
||||
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
|
||||
m_Sessions[introducerEndpoint] = introducerSession;
|
||||
}
|
||||
// introduce
|
||||
@ -232,8 +230,7 @@ namespace transport
|
||||
{
|
||||
LogPrint (eLogWarning, "Can't connect to unreachable router. No introducers presented");
|
||||
m_Sessions.erase (remoteEndpoint);
|
||||
delete session;
|
||||
session = nullptr;
|
||||
session.reset ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,30 +241,26 @@ namespace transport
|
||||
return session;
|
||||
}
|
||||
|
||||
void SSUServer::DeleteSession (SSUSession * session)
|
||||
void SSUServer::DeleteSession (std::shared_ptr<SSUSession> session)
|
||||
{
|
||||
if (session)
|
||||
{
|
||||
session->Close ();
|
||||
m_Sessions.erase (session->GetRemoteEndpoint ());
|
||||
delete session;
|
||||
}
|
||||
}
|
||||
|
||||
void SSUServer::DeleteAllSessions ()
|
||||
{
|
||||
for (auto it: m_Sessions)
|
||||
{
|
||||
it.second->Close ();
|
||||
delete it.second;
|
||||
}
|
||||
m_Sessions.clear ();
|
||||
}
|
||||
|
||||
template<typename Filter>
|
||||
SSUSession * SSUServer::GetRandomSession (Filter filter)
|
||||
std::shared_ptr<SSUSession> SSUServer::GetRandomSession (Filter filter)
|
||||
{
|
||||
std::vector<SSUSession *> filteredSessions;
|
||||
std::vector<std::shared_ptr<SSUSession> > filteredSessions;
|
||||
for (auto s :m_Sessions)
|
||||
if (filter (s.second)) filteredSessions.push_back (s.second);
|
||||
if (filteredSessions.size () > 0)
|
||||
@ -278,10 +271,10 @@ namespace transport
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SSUSession * SSUServer::GetRandomEstablishedSession (const SSUSession * excluded)
|
||||
std::shared_ptr<SSUSession> SSUServer::GetRandomEstablishedSession (std::shared_ptr<const SSUSession> excluded)
|
||||
{
|
||||
return GetRandomSession (
|
||||
[excluded](SSUSession * session)->bool
|
||||
[excluded](std::shared_ptr<SSUSession> session)->bool
|
||||
{
|
||||
return session->GetState () == eSessionStateEstablished &&
|
||||
session != excluded;
|
||||
@ -296,16 +289,16 @@ namespace transport
|
||||
for (int i = 0; i < maxNumIntroducers; i++)
|
||||
{
|
||||
auto session = GetRandomSession (
|
||||
[&ret, ts](SSUSession * session)->bool
|
||||
[&ret, ts](std::shared_ptr<SSUSession> session)->bool
|
||||
{
|
||||
return session->GetRelayTag () && !ret.count (session) &&
|
||||
return session->GetRelayTag () && !ret.count (session.get ()) &&
|
||||
session->GetState () == eSessionStateEstablished &&
|
||||
ts < session->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_DURATION;
|
||||
}
|
||||
);
|
||||
if (session)
|
||||
{
|
||||
ret.insert (session);
|
||||
ret.insert (session.get ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -315,8 +308,8 @@ namespace transport
|
||||
void SSUServer::ScheduleIntroducersUpdateTimer ()
|
||||
{
|
||||
m_IntroducersUpdateTimer.expires_from_now (boost::posix_time::seconds(SSU_KEEP_ALIVE_INTERVAL));
|
||||
m_IntroducersUpdateTimer.async_wait (boost::bind (&SSUServer::HandleIntroducersUpdateTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
m_IntroducersUpdateTimer.async_wait (std::bind (&SSUServer::HandleIntroducersUpdateTimer,
|
||||
this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
void SSUServer::HandleIntroducersUpdateTimer (const boost::system::error_code& ecode)
|
||||
|
16
SSU.h
16
SSU.h
@ -31,18 +31,18 @@ namespace transport
|
||||
~SSUServer ();
|
||||
void Start ();
|
||||
void Stop ();
|
||||
SSUSession * GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
|
||||
SSUSession * FindSession (const i2p::data::RouterInfo * router) const;
|
||||
SSUSession * FindSession (const boost::asio::ip::udp::endpoint& e) const;
|
||||
SSUSession * GetRandomEstablishedSession (const SSUSession * excluded);
|
||||
void DeleteSession (SSUSession * session);
|
||||
std::shared_ptr<SSUSession> GetSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
|
||||
std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const;
|
||||
std::shared_ptr<SSUSession> FindSession (const boost::asio::ip::udp::endpoint& e) const;
|
||||
std::shared_ptr<SSUSession> GetRandomEstablishedSession (std::shared_ptr<const SSUSession> excluded);
|
||||
void DeleteSession (std::shared_ptr<SSUSession> session);
|
||||
void DeleteAllSessions ();
|
||||
|
||||
boost::asio::io_service& GetService () { return m_Socket.get_io_service(); };
|
||||
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
|
||||
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
||||
void AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay);
|
||||
SSUSession * FindRelaySession (uint32_t tag);
|
||||
std::shared_ptr<SSUSession> FindRelaySession (uint32_t tag);
|
||||
|
||||
private:
|
||||
|
||||
@ -54,7 +54,7 @@ namespace transport
|
||||
void HandleReceivedBuffer (boost::asio::ip::udp::endpoint& from, uint8_t * buf, std::size_t bytes_transferred);
|
||||
|
||||
template<typename Filter>
|
||||
SSUSession * GetRandomSession (Filter filter);
|
||||
std::shared_ptr<SSUSession> GetRandomSession (Filter filter);
|
||||
|
||||
std::set<SSUSession *> FindIntroducers (int maxNumIntroducers);
|
||||
void ScheduleIntroducersUpdateTimer ();
|
||||
@ -73,7 +73,7 @@ namespace transport
|
||||
std::list<boost::asio::ip::udp::endpoint> m_Introducers; // introducers we are connected to
|
||||
i2p::crypto::AESAlignedBuffer<2*SSU_MTU_V4> m_ReceiveBuffer;
|
||||
i2p::crypto::AESAlignedBuffer<2*SSU_MTU_V6> m_ReceiveBufferV6;
|
||||
std::map<boost::asio::ip::udp::endpoint, SSUSession *> m_Sessions;
|
||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions;
|
||||
std::map<uint32_t, boost::asio::ip::udp::endpoint> m_Relays; // we are introducer
|
||||
|
||||
public:
|
||||
|
@ -401,8 +401,9 @@ namespace transport
|
||||
{
|
||||
m_ResendTimer.cancel ();
|
||||
m_ResendTimer.expires_from_now (boost::posix_time::seconds(RESEND_INTERVAL));
|
||||
m_ResendTimer.async_wait (boost::bind (&SSUData::HandleResendTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
auto s = m_Session.shared_from_this();
|
||||
m_ResendTimer.async_wait ([s](const boost::system::error_code& ecode)
|
||||
{ s->m_Data.HandleResendTimer (ecode); });
|
||||
}
|
||||
|
||||
void SSUData::HandleResendTimer (const boost::system::error_code& ecode)
|
||||
|
@ -109,7 +109,7 @@ namespace transport
|
||||
else
|
||||
{
|
||||
LogPrint (eLogError, "MAC verification failed ", len, " bytes from ", senderEndpoint);
|
||||
m_Server.DeleteSession (this);
|
||||
m_Server.DeleteSession (shared_from_this ());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -144,13 +144,13 @@ namespace transport
|
||||
case PAYLOAD_TYPE_SESSION_DESTROYED:
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU session destroy received");
|
||||
m_Server.DeleteSession (this); // delete this
|
||||
m_Server.DeleteSession (shared_from_this ());
|
||||
break;
|
||||
}
|
||||
case PAYLOAD_TYPE_RELAY_RESPONSE:
|
||||
ProcessRelayResponse (buf, len);
|
||||
if (m_State != eSessionStateEstablished)
|
||||
m_Server.DeleteSession (this);
|
||||
m_Server.DeleteSession (shared_from_this ());
|
||||
break;
|
||||
case PAYLOAD_TYPE_RELAY_REQUEST:
|
||||
LogPrint (eLogDebug, "SSU relay request received");
|
||||
@ -459,7 +459,7 @@ namespace transport
|
||||
buf += 32; // introkey
|
||||
uint32_t nonce = be32toh (*(uint32_t *)buf);
|
||||
SendRelayResponse (nonce, from, introKey, session->m_RemoteEndpoint);
|
||||
SendRelayIntro (session, from);
|
||||
SendRelayIntro (session.get (), from);
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,8 +711,8 @@ namespace transport
|
||||
{
|
||||
m_Timer.cancel ();
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SSUSession::HandleConnectTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
|
||||
shared_from_this (), std::placeholders::_1));
|
||||
}
|
||||
|
||||
void SSUSession::HandleConnectTimer (const boost::system::error_code& ecode)
|
||||
@ -731,8 +731,8 @@ namespace transport
|
||||
{
|
||||
// set connect timer
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SSUSession::HandleConnectTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
|
||||
shared_from_this (), std::placeholders::_1));
|
||||
}
|
||||
SendRelayRequest (iTag, iKey);
|
||||
}
|
||||
@ -742,8 +742,8 @@ namespace transport
|
||||
m_State = eSessionStateIntroduced;
|
||||
// set connect timer
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SSUSession::HandleConnectTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
|
||||
shared_from_this (), std::placeholders::_1));
|
||||
}
|
||||
|
||||
void SSUSession::Close ()
|
||||
@ -782,7 +782,7 @@ namespace transport
|
||||
if (m_State != eSessionStateFailed)
|
||||
{
|
||||
m_State = eSessionStateFailed;
|
||||
m_Server.DeleteSession (this); // delete this
|
||||
m_Server.DeleteSession (shared_from_this ());
|
||||
}
|
||||
}
|
||||
|
||||
@ -790,8 +790,8 @@ namespace transport
|
||||
{
|
||||
m_Timer.cancel ();
|
||||
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_TERMINATION_TIMEOUT));
|
||||
m_Timer.async_wait (boost::bind (&SSUSession::HandleTerminationTimer,
|
||||
this, boost::asio::placeholders::error));
|
||||
m_Timer.async_wait (std::bind (&SSUSession::HandleTerminationTimer,
|
||||
shared_from_this (), std::placeholders::_1));
|
||||
}
|
||||
|
||||
void SSUSession::HandleTerminationTimer (const boost::system::error_code& ecode)
|
||||
@ -821,7 +821,7 @@ namespace transport
|
||||
|
||||
void SSUSession::SendI2NPMessage (I2NPMessage * msg)
|
||||
{
|
||||
m_Server.GetService ().post (boost::bind (&SSUSession::PostI2NPMessage, this, msg));
|
||||
m_Server.GetService ().post (std::bind (&SSUSession::PostI2NPMessage, shared_from_this (), msg));
|
||||
}
|
||||
|
||||
void SSUSession::PostI2NPMessage (I2NPMessage * msg)
|
||||
@ -897,7 +897,7 @@ namespace transport
|
||||
else
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU peer test from Alice. We are Bob");
|
||||
auto session = m_Server.GetRandomEstablishedSession (this); // charlie
|
||||
auto session = m_Server.GetRandomEstablishedSession (shared_from_this ()); // charlie
|
||||
if (session)
|
||||
session->SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
||||
senderEndpoint.port (), introKey, false);
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <boost/asio.hpp>
|
||||
#include <memory>
|
||||
#include "aes.h"
|
||||
#include "hmac.h"
|
||||
#include "I2NPProtocol.h"
|
||||
@ -50,7 +50,7 @@ namespace transport
|
||||
};
|
||||
|
||||
class SSUServer;
|
||||
class SSUSession: public TransportSession
|
||||
class SSUSession: public TransportSession, public std::enable_shared_from_this<SSUSession>
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -280,7 +280,7 @@ namespace transport
|
||||
auto r = netdb.FindRouter (ident);
|
||||
if (r)
|
||||
{
|
||||
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (r.get ()) : nullptr;
|
||||
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (r) : nullptr;
|
||||
if (ssuSession)
|
||||
ssuSession->SendI2NPMessage (msg);
|
||||
else
|
||||
@ -337,13 +337,13 @@ namespace transport
|
||||
delete timer;
|
||||
}
|
||||
|
||||
void Transports::CloseSession (const i2p::data::RouterInfo * router)
|
||||
void Transports::CloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
|
||||
{
|
||||
if (!router) return;
|
||||
m_Service.post (boost::bind (&Transports::PostCloseSession, this, router));
|
||||
}
|
||||
|
||||
void Transports::PostCloseSession (const i2p::data::RouterInfo * router)
|
||||
void Transports::PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
|
||||
{
|
||||
auto ssuSession = m_SSUServer ? m_SSUServer->FindSession (router) : nullptr;
|
||||
if (ssuSession) // try SSU first
|
||||
|
@ -70,7 +70,7 @@ namespace transport
|
||||
NTCPSession * FindNTCPSession (const i2p::data::IdentHash& ident);
|
||||
|
||||
void SendMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg);
|
||||
void CloseSession (const i2p::data::RouterInfo * router);
|
||||
void CloseSession (std::shared_ptr<const i2p::data::RouterInfo> router);
|
||||
|
||||
private:
|
||||
|
||||
@ -80,7 +80,7 @@ namespace transport
|
||||
void HandleResendTimer (const boost::system::error_code& ecode, boost::asio::deadline_timer * timer,
|
||||
const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg);
|
||||
void PostMessage (const i2p::data::IdentHash& ident, i2p::I2NPMessage * msg);
|
||||
void PostCloseSession (const i2p::data::RouterInfo * router);
|
||||
void PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router);
|
||||
|
||||
void DetectExternalIP ();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user