mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
introducer session
This commit is contained in:
parent
6d42cccadc
commit
31f906240e
97
SSU.cpp
97
SSU.cpp
@ -75,18 +75,14 @@ namespace ssu
|
||||
case eSessionRelayRequestSent:
|
||||
// relay response
|
||||
ProcessRelayResponse (buf,len);
|
||||
m_Server.DeleteSession (this);
|
||||
break;
|
||||
case eSessionRelayResponseReceived:
|
||||
case eSessionIntroduced:
|
||||
// HolePunch received
|
||||
LogPrint ("SSU HolePuch of ", len, " bytes received");
|
||||
m_State = eSessionStateEstablished;
|
||||
Established ();
|
||||
break;
|
||||
case eSessionRelayRequestReceived:
|
||||
// HolePunch
|
||||
m_State = eSessionStateUnknown;
|
||||
Connect ();
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
LogPrint ("SSU state not implemented yet");
|
||||
}
|
||||
@ -151,7 +147,7 @@ namespace ssu
|
||||
if (!Validate (buf, len, introKey))
|
||||
{
|
||||
LogPrint ("MAC verification intro key failed");
|
||||
Failed ();
|
||||
m_Server.DeleteSession (this);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -273,7 +269,7 @@ namespace ssu
|
||||
m_Server.Send (buf, 304, m_RemoteEndpoint);
|
||||
}
|
||||
|
||||
void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer)
|
||||
void SSUSession::SendRelayRequest (uint32_t iTag, const uint8_t * iKey)
|
||||
{
|
||||
auto address = i2p::context.GetRouterInfo ().GetSSUAddress ();
|
||||
if (!address)
|
||||
@ -284,7 +280,7 @@ namespace ssu
|
||||
|
||||
uint8_t buf[96 + 18];
|
||||
uint8_t * payload = buf + sizeof (SSUHeader);
|
||||
*(uint32_t *)payload = htobe32 (introducer.iTag);
|
||||
*(uint32_t *)payload = htobe32 (iTag);
|
||||
payload += 4;
|
||||
*payload = 0; // no address
|
||||
payload++;
|
||||
@ -299,7 +295,7 @@ namespace ssu
|
||||
|
||||
uint8_t iv[16];
|
||||
rnd.GenerateBlock (iv, 16); // random iv
|
||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey);
|
||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, iKey, iv, iKey);
|
||||
m_State = eSessionRelayRequestSent;
|
||||
m_Server.Send (buf, 96, m_RemoteEndpoint);
|
||||
}
|
||||
@ -404,27 +400,22 @@ namespace ssu
|
||||
{
|
||||
Decrypt (buf, len, address->key);
|
||||
SSUHeader * header = (SSUHeader *)buf;
|
||||
if ((header->flag >> 4) == PAYLOAD_TYPE_RELAY_RESPONSE)
|
||||
if (header->GetPayloadType () == PAYLOAD_TYPE_RELAY_RESPONSE)
|
||||
{
|
||||
LogPrint ("Relay response received");
|
||||
m_State = eSessionRelayRequestReceived;
|
||||
uint8_t * payload = buf + sizeof (SSUHeader);
|
||||
payload++;
|
||||
boost::asio::ip::address_v4 remoteIP (be32toh (*(uint32_t* )(payload)));
|
||||
payload += 4;
|
||||
uint16_t remotePort = be16toh (*(uint16_t *)(payload));
|
||||
payload += 2;
|
||||
boost::asio::ip::udp::endpoint newRemoteEndpoint(remoteIP, remotePort);
|
||||
m_Server.ReassignSession (m_RemoteEndpoint, newRemoteEndpoint);
|
||||
m_RemoteEndpoint = newRemoteEndpoint;
|
||||
payload++;
|
||||
payload++; // remote size
|
||||
//boost::asio::ip::address_v4 remoteIP (be32toh (*(uint32_t* )(payload)));
|
||||
payload += 4; // remote address
|
||||
//uint16_t remotePort = be16toh (*(uint16_t *)(payload));
|
||||
payload += 2; // remote port
|
||||
payload++; // our size
|
||||
boost::asio::ip::address_v4 ourIP (be32toh (*(uint32_t* )(payload)));
|
||||
payload += 4;
|
||||
payload += 4; // our address
|
||||
uint16_t ourPort = be16toh (*(uint16_t *)(payload));
|
||||
payload += 2;
|
||||
payload += 2; // our port
|
||||
LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort);
|
||||
i2p::context.UpdateAddress (ourIP.to_string ().c_str ());
|
||||
m_State= eSessionRelayResponseReceived;
|
||||
}
|
||||
else
|
||||
LogPrint ("Unexpected payload type ", (int)(header->flag >> 4));
|
||||
@ -524,7 +515,7 @@ namespace ssu
|
||||
}
|
||||
}
|
||||
|
||||
void SSUSession::ConnectThroughIntroducer (const i2p::data::RouterInfo::Introducer& introducer)
|
||||
void SSUSession::Introduce (uint32_t iTag, const uint8_t * iKey)
|
||||
{
|
||||
if (m_State == eSessionStateUnknown)
|
||||
{
|
||||
@ -532,10 +523,19 @@ namespace ssu
|
||||
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));
|
||||
SendRelayRequest (introducer);
|
||||
SendRelayRequest (iTag, iKey);
|
||||
}
|
||||
}
|
||||
|
||||
void SSUSession::WaitForIntroduction ()
|
||||
{
|
||||
m_State = eSessionIntroduced;
|
||||
// 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));
|
||||
}
|
||||
|
||||
void SSUSession::Close ()
|
||||
{
|
||||
SendSesionDestroyed ();
|
||||
@ -977,11 +977,12 @@ namespace ssu
|
||||
else
|
||||
{
|
||||
// otherwise create new session
|
||||
session = new SSUSession (*this, remoteEndpoint, router, peerTest);
|
||||
m_Sessions[remoteEndpoint] = session;
|
||||
|
||||
if (!router->UsesIntroducer ())
|
||||
{
|
||||
// connect directly
|
||||
session = new SSUSession (*this, remoteEndpoint, router, peerTest);
|
||||
m_Sessions[remoteEndpoint] = session;
|
||||
// connect directly
|
||||
LogPrint ("Creating new SSU session to [", router->GetIdentHashAbbreviation (), "] ",
|
||||
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
|
||||
session->Connect ();
|
||||
@ -989,24 +990,27 @@ namespace ssu
|
||||
else
|
||||
{
|
||||
// connect through introducer
|
||||
session->WaitForIntroduction ();
|
||||
if (address->introducers.size () > 0)
|
||||
{
|
||||
auto& introducer = address->introducers[0]; // TODO:
|
||||
boost::asio::ip::udp::endpoint introducerEndpoint (introducer.iHost, introducer.iPort);
|
||||
it = m_Sessions.find (introducerEndpoint);
|
||||
if (it == m_Sessions.end ())
|
||||
{
|
||||
session = new SSUSession (*this, introducerEndpoint, router);
|
||||
m_Sessions[introducerEndpoint] = session;
|
||||
LogPrint ("Creating new SSU session to [", router->GetIdentHashAbbreviation (),
|
||||
LogPrint ("Creating new SSU session to [", router->GetIdentHashAbbreviation (),
|
||||
"] through introducer ", introducerEndpoint.address ().to_string (), ":", introducerEndpoint.port ());
|
||||
session->ConnectThroughIntroducer (introducer);
|
||||
}
|
||||
else
|
||||
it = m_Sessions.find (introducerEndpoint);
|
||||
SSUSession * introducerSession = nullptr;
|
||||
if (it != m_Sessions.end ())
|
||||
{
|
||||
LogPrint ("Session to introducer already exists");
|
||||
// TODO:
|
||||
introducerSession = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint ("New session to introducer created");
|
||||
introducerSession = new SSUSession (*this, introducerEndpoint, router);
|
||||
m_Sessions[introducerEndpoint] = introducerSession;
|
||||
}
|
||||
introducerSession->Introduce (introducer.iTag, introducer.iKey);
|
||||
}
|
||||
else
|
||||
LogPrint ("Router is unreachable, but not introducers presentd. Ignored");
|
||||
@ -1038,19 +1042,6 @@ namespace ssu
|
||||
}
|
||||
m_Sessions.clear ();
|
||||
}
|
||||
|
||||
void SSUServer::ReassignSession (const boost::asio::ip::udp::endpoint& oldEndpoint, const boost::asio::ip::udp::endpoint& newEndpoint)
|
||||
{
|
||||
auto it = m_Sessions.find (oldEndpoint);
|
||||
if (it != m_Sessions.end ())
|
||||
{
|
||||
auto session = it->second;
|
||||
m_Sessions.erase (it);
|
||||
m_Sessions[newEndpoint] = session;
|
||||
LogPrint ("SSU session reassigned from ", oldEndpoint.address ().to_string (), ":", oldEndpoint.port (),
|
||||
" to ", newEndpoint.address ().to_string (), ":", newEndpoint.port ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
8
SSU.h
8
SSU.h
@ -62,7 +62,7 @@ namespace ssu
|
||||
eSessionStateConfirmedReceived,
|
||||
eSessionRelayRequestSent,
|
||||
eSessionRelayRequestReceived,
|
||||
eSessionRelayResponseReceived,
|
||||
eSessionIntroduced,
|
||||
eSessionStateEstablished,
|
||||
eSessionStateFailed
|
||||
};
|
||||
@ -78,7 +78,8 @@ namespace ssu
|
||||
~SSUSession ();
|
||||
|
||||
void Connect ();
|
||||
void ConnectThroughIntroducer (const i2p::data::RouterInfo::Introducer& introducer);
|
||||
void Introduce (uint32_t iTag, const uint8_t * iKey);
|
||||
void WaitForIntroduction ();
|
||||
void Close ();
|
||||
boost::asio::ip::udp::endpoint& GetRemoteEndpoint () { return m_RemoteEndpoint; };
|
||||
const i2p::data::RouterInfo * GetRemoteRouter () const { return m_RemoteRouter; };
|
||||
@ -94,7 +95,7 @@ namespace ssu
|
||||
|
||||
void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
|
||||
void SendSessionRequest ();
|
||||
void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer);
|
||||
void SendRelayRequest (uint32_t iTag, const uint8_t * iKey);
|
||||
void ProcessSessionCreated (uint8_t * buf, size_t len);
|
||||
void SendSessionCreated (const uint8_t * x);
|
||||
void ProcessSessionConfirmed (uint8_t * buf, size_t len);
|
||||
@ -153,7 +154,6 @@ namespace ssu
|
||||
boost::asio::io_service& GetService () { return m_Socket.get_io_service(); };
|
||||
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
|
||||
void Send (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
|
||||
void ReassignSession (const boost::asio::ip::udp::endpoint& oldEndpoint, const boost::asio::ip::udp::endpoint& newEndpoint);
|
||||
|
||||
private:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user