Browse Source

connect through introducer

moduled
orignal 3 years ago
parent
commit
5aebefe73f
  1. 61
      libi2pd/SSU2.cpp
  2. 14
      libi2pd/SSU2.h

61
libi2pd/SSU2.cpp

@ -28,7 +28,7 @@ namespace transport
} }
SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter, SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr, bool peerTest): std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT), TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT),
m_Server (server), m_Address (addr), m_DestConnID (0), m_SourceConnID (0), m_Server (server), m_Address (addr), m_DestConnID (0), m_SourceConnID (0),
m_State (eSSU2SessionStateUnknown), m_SendPacketNum (0), m_ReceivePacketNum (0), m_State (eSSU2SessionStateUnknown), m_SendPacketNum (0), m_ReceivePacketNum (0),
@ -52,6 +52,7 @@ namespace transport
SSU2Session::~SSU2Session () SSU2Session::~SSU2Session ()
{ {
Terminate ();
} }
void SSU2Session::Connect () void SSU2Session::Connect ()
@ -135,6 +136,7 @@ namespace transport
m_SessionConfirmedFragment1.reset (nullptr); m_SessionConfirmedFragment1.reset (nullptr);
SetTerminationTimeout (SSU2_TERMINATION_TIMEOUT); SetTerminationTimeout (SSU2_TERMINATION_TIMEOUT);
transports.PeerConnected (shared_from_this ()); transports.PeerConnected (shared_from_this ());
if (m_OnEstablished) m_OnEstablished ();
} }
void SSU2Session::Done () void SSU2Session::Done ()
@ -1810,7 +1812,9 @@ namespace transport
{ {
if (router && address) if (router && address)
{ {
if (address->UsesIntroducer ()) return false; // not implemented yet if (address->UsesIntroducer ())
GetService ().post (std::bind (&SSU2Server::ConnectThroughIntroducer, this, router, address));
else
GetService ().post ( GetService ().post (
[this, router, address]() [this, router, address]()
{ {
@ -1823,6 +1827,59 @@ namespace transport
return true; return true;
} }
void SSU2Server::ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address)
{
auto session = std::make_shared<SSU2Session> (*this, router, address);
session->SetState (eSSU2SessionStateIntroduced);
// try to find existing session first
for (auto& it: address->ssu->introducers)
{
auto it1 = m_SessionsByRouterHash.find (it.iKey);
if (it1 != m_SessionsByRouterHash.end ())
{
it1->second->Introduce (session, it.iTag);
return;
}
}
// we have to start a new session to an introducer
std::shared_ptr<i2p::data::RouterInfo> r;
uint32_t relayTag = 0;
for (auto& it: address->ssu->introducers)
{
r = i2p::data::netdb.FindRouter (it.iKey);
if (r)
{
relayTag = it.iTag;
if (relayTag) break;
}
}
if (r)
{
if (relayTag)
{
// introducer and tag found connect to it through SSU2
auto addr = address->IsV6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
if (addr)
{
auto s = std::make_shared<SSU2Session> (*this, r, addr);
s->SetOnEstablished (
[session, s, relayTag]()
{
s->Introduce (session, relayTag);
});
s->Connect ();
}
}
}
else
{
// introducers not found, try to request them
for (auto& it: address->ssu->introducers)
i2p::data::netdb.RequestDestination (it.iKey);
}
}
void SSU2Server::ScheduleTermination () void SSU2Server::ScheduleTermination ()
{ {
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU2_TERMINATION_CHECK_TIMEOUT)); m_TerminationTimer.expires_from_now (boost::posix_time::seconds(SSU2_TERMINATION_CHECK_TIMEOUT));

14
libi2pd/SSU2.h

@ -10,6 +10,7 @@
#define SSU2_H__ #define SSU2_H__
#include <memory> #include <memory>
#include <functional>
#include <map> #include <map>
#include <set> #include <set>
#include <unordered_map> #include <unordered_map>
@ -131,14 +132,17 @@ namespace transport
size_t payloadSize; size_t payloadSize;
}; };
typedef std::function<void ()> OnEstablished;
public: public:
SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr, SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr = nullptr, bool peerTest = false); std::shared_ptr<const i2p::data::RouterInfo::Address> addr = nullptr);
~SSU2Session (); ~SSU2Session ();
void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; }; void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; }; const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
void Connect (); void Connect ();
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag); bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
@ -151,6 +155,8 @@ namespace transport
void Resend (uint64_t ts); void Resend (uint64_t ts);
bool IsEstablished () const { return m_State == eSSU2SessionStateEstablished; }; bool IsEstablished () const { return m_State == eSSU2SessionStateEstablished; };
uint64_t GetConnID () const { return m_SourceConnID; }; uint64_t GetConnID () const { return m_SourceConnID; };
SSU2SessionState GetState () const { return m_State; };
void SetState (SSU2SessionState state) { m_State = state; };
void ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len); void ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
bool ProcessSessionCreated (uint8_t * buf, size_t len); bool ProcessSessionCreated (uint8_t * buf, size_t len);
@ -222,7 +228,8 @@ namespace transport
i2p::I2NPMessagesHandler m_Handler; i2p::I2NPMessagesHandler m_Handler;
bool m_IsDataReceived; bool m_IsDataReceived;
size_t m_WindowSize; size_t m_WindowSize;
uint32_t m_RelayTag; uint32_t m_RelayTag; // between Bob and Charlie
OnEstablished m_OnEstablished; // callback from Established
}; };
class SSU2Server: private i2p::util::RunnableServiceWithWork class SSU2Server: private i2p::util::RunnableServiceWithWork
@ -291,6 +298,9 @@ namespace transport
void ScheduleResend (); void ScheduleResend ();
void HandleResendTimer (const boost::system::error_code& ecode); void HandleResendTimer (const boost::system::error_code& ecode);
void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address);
private: private:
ReceiveService m_ReceiveService; ReceiveService m_ReceiveService;

Loading…
Cancel
Save