mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
full implementation of peer test
This commit is contained in:
parent
34e31f3d78
commit
51aea367c3
22
SSU.cpp
22
SSU.cpp
@ -463,12 +463,28 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::NewPeerTest (uint32_t nonce)
|
void SSUServer::NewPeerTest (uint32_t nonce, PeerTestParticipant role)
|
||||||
{
|
{
|
||||||
m_PeerTests[nonce] = i2p::util::GetMillisecondsSinceEpoch ();
|
m_PeerTests[nonce] = { i2p::util::GetMillisecondsSinceEpoch (), role };
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUServer::PeerTestComplete (uint32_t nonce)
|
PeerTestParticipant SSUServer::GetPeerTestParticipant (uint32_t nonce)
|
||||||
|
{
|
||||||
|
auto it = m_PeerTests.find (nonce);
|
||||||
|
if (it != m_PeerTests.end ())
|
||||||
|
return it->second.role;
|
||||||
|
else
|
||||||
|
return ePeerTestParticipantUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSUServer::UpdatePeerTest (uint32_t nonce, PeerTestParticipant role)
|
||||||
|
{
|
||||||
|
auto it = m_PeerTests.find (nonce);
|
||||||
|
if (it != m_PeerTests.end ())
|
||||||
|
it->second.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSUServer::RemovePeerTest (uint32_t nonce)
|
||||||
{
|
{
|
||||||
m_PeerTests.erase (nonce);
|
m_PeerTests.erase (nonce);
|
||||||
}
|
}
|
||||||
|
14
SSU.h
14
SSU.h
@ -53,8 +53,10 @@ namespace transport
|
|||||||
void AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay);
|
void AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay);
|
||||||
std::shared_ptr<SSUSession> FindRelaySession (uint32_t tag);
|
std::shared_ptr<SSUSession> FindRelaySession (uint32_t tag);
|
||||||
|
|
||||||
void NewPeerTest (uint32_t nonce);
|
void NewPeerTest (uint32_t nonce, PeerTestParticipant role);
|
||||||
void PeerTestComplete (uint32_t nonce);
|
PeerTestParticipant GetPeerTestParticipant (uint32_t nonce);
|
||||||
|
void UpdatePeerTest (uint32_t nonce, PeerTestParticipant role);
|
||||||
|
void RemovePeerTest (uint32_t nonce);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -76,6 +78,12 @@ namespace transport
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
struct PeerTest
|
||||||
|
{
|
||||||
|
uint64_t creationTime;
|
||||||
|
PeerTestParticipant role;
|
||||||
|
};
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread;
|
std::thread * m_Thread, * m_ThreadV6, * m_ReceiversThread;
|
||||||
boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService;
|
boost::asio::io_service m_Service, m_ServiceV6, m_ReceiversService;
|
||||||
@ -87,7 +95,7 @@ namespace transport
|
|||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<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
|
std::map<uint32_t, boost::asio::ip::udp::endpoint> m_Relays; // we are introducer
|
||||||
std::map<uint32_t, uint64_t> m_PeerTests; // nonce -> creation time in milliseconds
|
std::map<uint32_t, PeerTest> m_PeerTests; // nonce -> creation time in milliseconds
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
|
@ -896,62 +896,80 @@ namespace transport
|
|||||||
LogPrint (eLogWarning, "Address of ", size, " bytes not supported");
|
LogPrint (eLogWarning, "Address of ", size, " bytes not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_PeerTestNonces.count (nonce) > 0)
|
switch (m_Server.GetPeerTestParticipant (nonce))
|
||||||
{
|
{
|
||||||
// existing test
|
// existing test
|
||||||
if (m_PeerTest) // Alice
|
case ePeerTestParticipantAlice1:
|
||||||
{
|
{
|
||||||
if (m_State == eSessionStateEstablished)
|
if (m_State == eSessionStateEstablished)
|
||||||
LogPrint (eLogDebug, "SSU peer test from Bob. We are Alice");
|
LogPrint (eLogDebug, "SSU peer test from Bob. We are Alice");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SSU first peer test from Charlie. We are Alice");
|
LogPrint (eLogDebug, "SSU first peer test from Charlie. We are Alice");
|
||||||
m_PeerTest = false;
|
m_Server.UpdatePeerTest (nonce, ePeerTestParticipantAlice2);
|
||||||
m_PeerTestNonces.erase (nonce);
|
|
||||||
m_Server.PeerTestComplete (nonce);
|
|
||||||
SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
||||||
senderEndpoint.port (), introKey, true, false); // to Charlie
|
senderEndpoint.port (), introKey, true, false); // to Charlie
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (port) // Bob
|
}
|
||||||
|
case ePeerTestParticipantAlice2:
|
||||||
|
{
|
||||||
|
if (m_State == eSessionStateEstablished)
|
||||||
|
LogPrint (eLogDebug, "SSU peer test from Bob. We are Alice");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// peer test successive
|
||||||
|
LogPrint (eLogDebug, "SSU second peer test from Charlie. We are Alice");
|
||||||
|
m_Server.RemovePeerTest (nonce);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ePeerTestParticipantBob:
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SSU peer test from Charlie. We are Bob");
|
LogPrint (eLogDebug, "SSU peer test from Charlie. We are Bob");
|
||||||
m_PeerTestNonces.erase (nonce); // nonce has been used
|
m_Server.RemovePeerTest (nonce); // nonce has been used
|
||||||
boost::asio::ip::udp::endpoint ep (boost::asio::ip::address_v4 (be32toh (address)), be16toh (port)); // Alice's address/port
|
boost::asio::ip::udp::endpoint ep (boost::asio::ip::address_v4 (be32toh (address)), be16toh (port)); // Alice's address/port
|
||||||
auto session = m_Server.FindSession (ep); // find session with Alice
|
auto session = m_Server.FindSession (ep); // find session with Alice
|
||||||
if (session)
|
if (session)
|
||||||
session->Send (PAYLOAD_TYPE_PEER_TEST, buf1, len); // back to Alice
|
session->Send (PAYLOAD_TYPE_PEER_TEST, buf1, len); // back to Alice
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else // Charlie
|
case ePeerTestParticipantCharlie:
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SSU peer test from Alice. We are Charlie");
|
LogPrint (eLogDebug, "SSU peer test from Alice. We are Charlie");
|
||||||
|
m_Server.RemovePeerTest (nonce); // nonce has been used
|
||||||
SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
||||||
senderEndpoint.port (), introKey); // to Alice with her actual address
|
senderEndpoint.port (), introKey); // to Alice with her actual address
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
// test not found
|
||||||
else
|
case ePeerTestParticipantUnknown:
|
||||||
{
|
|
||||||
if (m_State == eSessionStateEstablished)
|
|
||||||
{
|
{
|
||||||
// new test
|
if (m_State == eSessionStateEstablished)
|
||||||
m_PeerTestNonces.insert (nonce);
|
|
||||||
if (port)
|
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SSU peer test from Bob. We are Charlie");
|
// new test
|
||||||
Send (PAYLOAD_TYPE_PEER_TEST, buf1, len); // back to Bob
|
if (port)
|
||||||
SendPeerTest (nonce, be32toh (address), be16toh (port), introKey); // to Alice with her address received from Bob
|
{
|
||||||
|
LogPrint (eLogDebug, "SSU peer test from Bob. We are Charlie");
|
||||||
|
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
|
||||||
|
Send (PAYLOAD_TYPE_PEER_TEST, buf1, len); // back to Bob
|
||||||
|
SendPeerTest (nonce, be32toh (address), be16toh (port), introKey); // to Alice with her address received from Bob
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "SSU peer test from Alice. We are Bob");
|
||||||
|
auto session = m_Server.GetRandomEstablishedSession (shared_from_this ()); // Charlie
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
m_Server.NewPeerTest (nonce, ePeerTestParticipantBob);
|
||||||
|
session->SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
||||||
|
senderEndpoint.port (), introKey, false); // to Charlie with Alice's actual address
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
LogPrint (eLogError, "SSU unexpected peer test");
|
||||||
LogPrint (eLogDebug, "SSU peer test from Alice. We are Bob");
|
|
||||||
auto session = m_Server.GetRandomEstablishedSession (shared_from_this ()); // Charlie
|
|
||||||
if (session)
|
|
||||||
session->SendPeerTest (nonce, senderEndpoint.address ().to_v4 ().to_ulong (),
|
|
||||||
senderEndpoint.port (), introKey, false); // to Charlie with Alice's actual address
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogDebug, "SSU second peer test from Charlie. We are Alice");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,8 +1041,8 @@ namespace transport
|
|||||||
}
|
}
|
||||||
uint32_t nonce = i2p::context.GetRandomNumberGenerator ().GenerateWord32 ();
|
uint32_t nonce = i2p::context.GetRandomNumberGenerator ().GenerateWord32 ();
|
||||||
if (!nonce) nonce = 1;
|
if (!nonce) nonce = 1;
|
||||||
m_PeerTestNonces.insert (nonce);
|
m_PeerTest = false;
|
||||||
m_Server.NewPeerTest (nonce);
|
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1);
|
||||||
SendPeerTest (nonce, 0, 0, address->key, false, false); // address and port always zero for Alice
|
SendPeerTest (nonce, 0, 0, address->key, false, false); // address and port always zero for Alice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
SSUSession.h
10
SSUSession.h
@ -49,6 +49,15 @@ namespace transport
|
|||||||
eSessionStateFailed
|
eSessionStateFailed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PeerTestParticipant
|
||||||
|
{
|
||||||
|
ePeerTestParticipantUnknown = 0,
|
||||||
|
ePeerTestParticipantAlice1,
|
||||||
|
ePeerTestParticipantAlice2,
|
||||||
|
ePeerTestParticipantBob,
|
||||||
|
ePeerTestParticipantCharlie
|
||||||
|
};
|
||||||
|
|
||||||
class SSUServer;
|
class SSUServer;
|
||||||
class SSUSession: public TransportSession, public std::enable_shared_from_this<SSUSession>
|
class SSUSession: public TransportSession, public std::enable_shared_from_this<SSUSession>
|
||||||
{
|
{
|
||||||
@ -133,7 +142,6 @@ namespace transport
|
|||||||
SessionState m_State;
|
SessionState m_State;
|
||||||
bool m_IsSessionKey;
|
bool m_IsSessionKey;
|
||||||
uint32_t m_RelayTag;
|
uint32_t m_RelayTag;
|
||||||
std::set<uint32_t> m_PeerTestNonces;
|
|
||||||
i2p::crypto::CBCEncryption m_SessionKeyEncryption;
|
i2p::crypto::CBCEncryption m_SessionKeyEncryption;
|
||||||
i2p::crypto::CBCDecryption m_SessionKeyDecryption;
|
i2p::crypto::CBCDecryption m_SessionKeyDecryption;
|
||||||
i2p::crypto::AESKey m_SessionKey;
|
i2p::crypto::AESKey m_SessionKey;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user