Browse Source

handle RelayResponse

pull/308/head
orignal 9 years ago
parent
commit
6096d572f3
  1. 2
      SSU.cpp
  2. 4
      SSU.h
  3. 39
      SSUSession.cpp
  4. 6
      SSUSession.h

2
SSU.cpp

@ -384,7 +384,7 @@ namespace transport
uint8_t buf[1]; uint8_t buf[1];
Send (buf, 0, remoteEndpoint); // send HolePunch Send (buf, 0, remoteEndpoint); // send HolePunch
} }
introducerSession->Introduce (*introducer); introducerSession->Introduce (*introducer, router);
} }
else else
LogPrint (eLogWarning, "Can't connect to unreachable router. No introducers presented"); LogPrint (eLogWarning, "Can't connect to unreachable router. No introducers presented");

4
SSU.h

@ -43,6 +43,7 @@ namespace transport
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false); void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, void CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
const boost::asio::ip::address& addr, int port, bool peerTest = false); const boost::asio::ip::address& addr, int port, bool peerTest = false);
void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest);
std::shared_ptr<SSUSession> FindSession (std::shared_ptr<const i2p::data::RouterInfo> router) const; 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> FindSession (const boost::asio::ip::udp::endpoint& e) const;
std::shared_ptr<SSUSession> GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded); std::shared_ptr<SSUSession> GetRandomEstablishedV4Session (std::shared_ptr<const SSUSession> excluded);
@ -74,8 +75,7 @@ namespace transport
void HandleReceivedPackets (std::vector<SSUPacket *> packets, void HandleReceivedPackets (std::vector<SSUPacket *> packets,
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> >* sessions); std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> >* sessions);
void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false); void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
void CreateDirectSession (std::shared_ptr<const i2p::data::RouterInfo> router, boost::asio::ip::udp::endpoint remoteEndpoint, bool peerTest);
template<typename Filter> template<typename Filter>
std::shared_ptr<SSUSession> GetRandomV4Session (Filter filter); std::shared_ptr<SSUSession> GetRandomV4Session (Filter filter);

39
SSUSession.cpp

@ -308,7 +308,7 @@ namespace transport
m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint); m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint);
} }
void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer) void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce)
{ {
auto address = i2p::context.GetRouterInfo ().GetSSUAddress (); auto address = i2p::context.GetRouterInfo ().GetSSUAddress ();
if (!address) if (!address)
@ -329,7 +329,7 @@ namespace transport
payload++; payload++;
memcpy (payload, (const uint8_t *)address->key, 32); memcpy (payload, (const uint8_t *)address->key, 32);
payload += 32; payload += 32;
RAND_bytes (payload, 4); // nonce htobe32buf (payload, nonce); // nonce
uint8_t iv[16]; uint8_t iv[16];
RAND_bytes (iv, 16); // random iv RAND_bytes (iv, 16); // random iv
@ -568,9 +568,9 @@ namespace transport
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
uint8_t remoteSize = *payload; uint8_t remoteSize = *payload;
payload++; // remote size payload++; // remote size
//boost::asio::ip::address_v4 remoteIP (bufbe32toh (payload)); boost::asio::ip::address_v4 remoteIP (bufbe32toh (payload));
payload += remoteSize; // remote address payload += remoteSize; // remote address
//uint16_t remotePort = bufbe16toh (payload); uint16_t remotePort = bufbe16toh (payload);
payload += 2; // remote port payload += 2; // remote port
uint8_t ourSize = *payload; uint8_t ourSize = *payload;
payload++; // our size payload++; // our size
@ -592,6 +592,27 @@ namespace transport
payload += 2; // our port payload += 2; // our port
LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort); LogPrint ("Our external address is ", ourIP.to_string (), ":", ourPort);
i2p::context.UpdateAddress (ourIP); i2p::context.UpdateAddress (ourIP);
uint32_t nonce = bufbe32toh (payload);
payload += 4; // nonce
auto it = m_RelayRequests.find (nonce);
if (it != m_RelayRequests.end ())
{
// check if we are waiting for introduction
boost::asio::ip::udp::endpoint remoteEndpoint (remoteIP, remotePort);
if (!m_Server.FindSession (remoteEndpoint))
{
// we didn't have correct endpoint when sent relay request
// now we do
LogPrint (eLogInfo, "RelayReponse connecting to endpoint ", remoteEndpoint);
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch
m_Server.CreateDirectSession (it->second, remoteEndpoint, false);
}
// delete request
m_RelayRequests.erase (it);
}
else
LogPrint (eLogError, "Unsolicited RelayResponse, nonce=", nonce);
} }
void SSUSession::ProcessRelayIntro (uint8_t * buf, size_t len) void SSUSession::ProcessRelayIntro (uint8_t * buf, size_t len)
@ -748,7 +769,8 @@ namespace transport
} }
} }
void SSUSession::Introduce (const i2p::data::RouterInfo::Introducer& introducer) void SSUSession::Introduce (const i2p::data::RouterInfo::Introducer& introducer,
std::shared_ptr<const i2p::data::RouterInfo> to)
{ {
if (m_State == eSessionStateUnknown) if (m_State == eSessionStateUnknown)
{ {
@ -756,8 +778,11 @@ namespace transport
m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT)); m_Timer.expires_from_now (boost::posix_time::seconds(SSU_CONNECT_TIMEOUT));
m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer, m_Timer.async_wait (std::bind (&SSUSession::HandleConnectTimer,
shared_from_this (), std::placeholders::_1)); shared_from_this (), std::placeholders::_1));
} }
SendRelayRequest (introducer); uint32_t nonce;
RAND_bytes ((uint8_t *)&nonce, 4);
m_RelayRequests[nonce] = to;
SendRelayRequest (introducer, nonce);
} }
void SSUSession::WaitForIntroduction () void SSUSession::WaitForIntroduction ()

6
SSUSession.h

@ -71,7 +71,8 @@ namespace transport
void Connect (); void Connect ();
void WaitForConnect (); void WaitForConnect ();
void Introduce (const i2p::data::RouterInfo::Introducer& introducer); void Introduce (const i2p::data::RouterInfo::Introducer& introducer,
std::shared_ptr<const i2p::data::RouterInfo> to); // Alice to Charlie
void WaitForIntroduction (); void WaitForIntroduction ();
void Close (); void Close ();
void Done (); void Done ();
@ -100,7 +101,7 @@ namespace transport
void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session void ProcessMessage (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); // call for established session
void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint); void ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint);
void SendSessionRequest (); void SendSessionRequest ();
void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer); void SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce);
void ProcessSessionCreated (uint8_t * buf, size_t len); void ProcessSessionCreated (uint8_t * buf, size_t len);
void SendSessionCreated (const uint8_t * x); void SendSessionCreated (const uint8_t * x);
void ProcessSessionConfirmed (uint8_t * buf, size_t len); void ProcessSessionConfirmed (uint8_t * buf, size_t len);
@ -150,6 +151,7 @@ namespace transport
SSUData m_Data; SSUData m_Data;
bool m_IsDataReceived; bool m_IsDataReceived;
std::unique_ptr<SignedData> m_SignedData; // we need it for SessionConfirmed only std::unique_ptr<SignedData> m_SignedData; // we need it for SessionConfirmed only
std::map<uint32_t, std::shared_ptr<const i2p::data::RouterInfo> > m_RelayRequests; // nonce->Charlie
}; };

Loading…
Cancel
Save