mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
handle PeerTest msg 1
This commit is contained in:
parent
0640bec026
commit
2e4d8cdc8b
@ -244,6 +244,31 @@ namespace transport
|
|||||||
return it->second;
|
return it->second;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<SSU2Session> SSU2Server::GetRandomSession (i2p::data::RouterInfo::CompatibleTransports remoteTransports) const
|
||||||
|
{
|
||||||
|
if (m_Sessions.empty ()) return nullptr;
|
||||||
|
uint16_t ind;
|
||||||
|
RAND_bytes ((uint8_t *)&ind, sizeof (ind));
|
||||||
|
ind %= m_Sessions.size ();
|
||||||
|
auto it = m_Sessions.begin ();
|
||||||
|
std::advance (it, ind);
|
||||||
|
while (it != m_Sessions.end ())
|
||||||
|
{
|
||||||
|
if (it->second->GetRemoteTransports () & remoteTransports)
|
||||||
|
return it->second;
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
// not found, try from begining
|
||||||
|
it = m_Sessions.begin ();
|
||||||
|
while (it != m_Sessions.end () && ind)
|
||||||
|
{
|
||||||
|
if (it->second->GetRemoteTransports () & remoteTransports)
|
||||||
|
return it->second;
|
||||||
|
it++; ind--;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void SSU2Server::AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay)
|
void SSU2Server::AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +54,7 @@ namespace transport
|
|||||||
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
|
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
|
||||||
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
|
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
|
||||||
std::shared_ptr<SSU2Session> FindSession (const i2p::data::IdentHash& ident) const;
|
std::shared_ptr<SSU2Session> FindSession (const i2p::data::IdentHash& ident) const;
|
||||||
|
std::shared_ptr<SSU2Session> GetRandomSession (i2p::data::RouterInfo::CompatibleTransports remoteTransports) const;
|
||||||
|
|
||||||
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
|
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
|
||||||
void RemoveRelay (uint32_t tag);
|
void RemoveRelay (uint32_t tag);
|
||||||
|
@ -22,9 +22,10 @@ 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):
|
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_RemoteTransports (0),
|
||||||
m_State (eSSU2SessionStateUnknown), m_SendPacketNum (0), m_ReceivePacketNum (0),
|
m_DestConnID (0), m_SourceConnID (0), m_State (eSSU2SessionStateUnknown),
|
||||||
m_IsDataReceived (false), m_WindowSize (SSU2_MAX_WINDOW_SIZE), m_RelayTag (0)
|
m_SendPacketNum (0), m_ReceivePacketNum (0), m_IsDataReceived (false),
|
||||||
|
m_WindowSize (SSU2_MAX_WINDOW_SIZE), m_RelayTag (0)
|
||||||
{
|
{
|
||||||
m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState);
|
m_NoiseState.reset (new i2p::crypto::NoiseSymmetricState);
|
||||||
if (in_RemoteRouter && m_Address)
|
if (in_RemoteRouter && m_Address)
|
||||||
@ -32,6 +33,7 @@ namespace transport
|
|||||||
// outgoing
|
// outgoing
|
||||||
InitNoiseXKState1 (*m_NoiseState, m_Address->s);
|
InitNoiseXKState1 (*m_NoiseState, m_Address->s);
|
||||||
m_RemoteEndpoint = boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port);
|
m_RemoteEndpoint = boost::asio::ip::udp::endpoint (m_Address->host, m_Address->port);
|
||||||
|
m_RemoteTransports = in_RemoteRouter->GetCompatibleTransports (false);
|
||||||
RAND_bytes ((uint8_t *)&m_DestConnID, 8);
|
RAND_bytes ((uint8_t *)&m_DestConnID, 8);
|
||||||
RAND_bytes ((uint8_t *)&m_SourceConnID, 8);
|
RAND_bytes ((uint8_t *)&m_SourceConnID, 8);
|
||||||
}
|
}
|
||||||
@ -612,6 +614,7 @@ namespace transport
|
|||||||
LogPrint (eLogError, "SSU2: No SSU2 address with static key found in SessionConfirmed");
|
LogPrint (eLogError, "SSU2: No SSU2 address with static key found in SessionConfirmed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
m_RemoteTransports = ri->GetCompatibleTransports (false);
|
||||||
i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, ri->GetBuffer (), ri->GetBufferLen ())); // TODO: should insert ri
|
i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, ri->GetBuffer (), ri->GetBufferLen ())); // TODO: should insert ri
|
||||||
// handle other blocks
|
// handle other blocks
|
||||||
HandlePayload (decryptedPayload.data () + riSize + 3, decryptedPayload.size () - riSize - 3);
|
HandlePayload (decryptedPayload.data () + riSize + 3, decryptedPayload.size () - riSize - 3);
|
||||||
@ -1333,12 +1336,37 @@ namespace transport
|
|||||||
{
|
{
|
||||||
case 1: // Bob from Alice
|
case 1: // Bob from Alice
|
||||||
{
|
{
|
||||||
// TODO: find Charlie
|
auto session = m_Server.GetRandomSession ((buf[12] == 6) ? i2p::data::RouterInfo::eSSU2V4 : i2p::data::RouterInfo::eSSU2V6);
|
||||||
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE], zeroHash[32] = {0};
|
if (session) // session with Charlie
|
||||||
size_t payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4,
|
{
|
||||||
eSSU2PeerTestCodeBobNoCharlieAvailable, zeroHash, buf + 3, len - 3);
|
session->m_PeerTests.emplace (nonce, std::make_pair (shared_from_this (), i2p::util::GetSecondsSinceEpoch ()));
|
||||||
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
SendData (payload, payloadSize);
|
// Alice's RouterInfo
|
||||||
|
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ());
|
||||||
|
size_t payloadSize = r ? CreateRouterInfoBlock (payload, SSU2_MAX_PAYLOAD_SIZE - len - 32, r) : 0;
|
||||||
|
if (!payloadSize && r)
|
||||||
|
session->SendFragmentedMessage (CreateDatabaseStoreMsg (r));
|
||||||
|
if (payloadSize + len + 48 > SSU2_MAX_PAYLOAD_SIZE)
|
||||||
|
{
|
||||||
|
// doesn't fit one message, send RouterInfo in separate message
|
||||||
|
session->SendData (payload, payloadSize);
|
||||||
|
payloadSize = 0;
|
||||||
|
}
|
||||||
|
// PeerTest to Charlie
|
||||||
|
payloadSize += CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE - payloadSize, 2,
|
||||||
|
eSSU2PeerTestCodeAccept, GetRemoteIdentity ()->GetIdentHash (), buf + 3, len - 3);
|
||||||
|
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
|
||||||
|
session->SendData (payload, payloadSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Charlie not found, send error back to Alice
|
||||||
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE], zeroHash[32] = {0};
|
||||||
|
size_t payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4,
|
||||||
|
eSSU2PeerTestCodeBobNoCharlieAvailable, zeroHash, buf + 3, len - 3);
|
||||||
|
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
|
||||||
|
SendData (payload, payloadSize);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: // Charlie from Bob
|
case 2: // Charlie from Bob
|
||||||
@ -1401,7 +1429,19 @@ namespace transport
|
|||||||
if (it != m_PeerTests.end () && it->second.first)
|
if (it != m_PeerTests.end () && it->second.first)
|
||||||
{
|
{
|
||||||
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
|
||||||
size_t payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4,
|
// Charlie's RouterInfo
|
||||||
|
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ());
|
||||||
|
size_t payloadSize = r ? CreateRouterInfoBlock (payload, SSU2_MAX_PAYLOAD_SIZE - len - 32, r) : 0;
|
||||||
|
if (!payloadSize && r)
|
||||||
|
it->second.first->SendFragmentedMessage (CreateDatabaseStoreMsg (r));
|
||||||
|
if (payloadSize + len + 16 > SSU2_MAX_PAYLOAD_SIZE)
|
||||||
|
{
|
||||||
|
// doesn't fit one message, send RouterInfo in separate message
|
||||||
|
it->second.first->SendData (payload, payloadSize);
|
||||||
|
payloadSize = 0;
|
||||||
|
}
|
||||||
|
// PeerTest to Alice
|
||||||
|
payloadSize = CreatePeerTestBlock (payload, SSU2_MAX_PAYLOAD_SIZE, 4,
|
||||||
(SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + 3, len - 3);
|
(SSU2PeerTestCode)buf[1], GetRemoteIdentity ()->GetIdentHash (), buf + 3, len - 3);
|
||||||
if (payloadSize < SSU2_MAX_PAYLOAD_SIZE)
|
if (payloadSize < SSU2_MAX_PAYLOAD_SIZE)
|
||||||
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
|
payloadSize += CreatePaddingBlock (payload + payloadSize, SSU2_MAX_PAYLOAD_SIZE - payloadSize);
|
||||||
|
@ -160,6 +160,7 @@ namespace transport
|
|||||||
|
|
||||||
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; };
|
||||||
|
i2p::data::RouterInfo::CompatibleTransports GetRemoteTransports () const { return m_RemoteTransports; };
|
||||||
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
|
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
|
||||||
|
|
||||||
void Connect ();
|
void Connect ();
|
||||||
@ -244,6 +245,7 @@ namespace transport
|
|||||||
std::unique_ptr<SessionConfirmedFragment> m_SessionConfirmedFragment1; // for Bob if applicable
|
std::unique_ptr<SessionConfirmedFragment> m_SessionConfirmedFragment1; // for Bob if applicable
|
||||||
std::shared_ptr<const i2p::data::RouterInfo::Address> m_Address;
|
std::shared_ptr<const i2p::data::RouterInfo::Address> m_Address;
|
||||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||||
|
i2p::data::RouterInfo::CompatibleTransports m_RemoteTransports; // for peer tests
|
||||||
uint64_t m_DestConnID, m_SourceConnID;
|
uint64_t m_DestConnID, m_SourceConnID;
|
||||||
SSU2SessionState m_State;
|
SSU2SessionState m_State;
|
||||||
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
||||||
|
Loading…
Reference in New Issue
Block a user