| 72 | } |
| 73 | |
| 74 | void SSU2PeerTestSession::HandlePeerTest (const uint8_t * buf, size_t len) |
| 75 | { |
| 76 | // msgs 5-7 |
| 77 | if (len < 8) return; |
| 78 | uint8_t msg = buf[0]; |
| 79 | if (msg <= m_MsgNumReceived) |
| 80 | { |
| 81 | LogPrint (eLogDebug, "SSU2: PeerTest msg num ", msg, " received after ", m_MsgNumReceived, ". Ignored"); |
| 82 | return; |
| 83 | } |
| 84 | size_t offset = 3; // points to signed data after msg + code + flag |
| 85 | uint32_t nonce = bufbe32toh (buf + offset + 1); // 1 - ver |
| 86 | switch (msg) // msg |
| 87 | { |
| 88 | case 5: // Alice from Charlie 1 |
| 89 | { |
| 90 | if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ()) |
| 91 | { |
| 92 | m_PeerTestResendTimer.cancel (); // cancel delayed msg 6 if any |
| 93 | if (GetServer ().IsForcedFirewalled (GetRemoteEndpoint ().address().is_v4())) |
| 94 | // we assume that msg 5 was not received if forced firewalled |
| 95 | return; |
| 96 | m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ()); |
| 97 | if (GetAddress ()) |
| 98 | { |
| 99 | if (!m_IsConnectedRecently) |
| 100 | SetRouterStatus (eRouterStatusOK); |
| 101 | else if (m_IsStatusChanged && GetRouterStatus () == eRouterStatusFirewalled) |
| 102 | SetRouterStatus (eRouterStatusUnknown); |
| 103 | SendPeerTest (6, buf + offset, len - offset); |
| 104 | } |
| 105 | } |
| 106 | else |
| 107 | LogPrint (eLogWarning, "SSU2: Peer test 5 nonce mismatch ", nonce, " connID=", GetSourceConnID ()); |
| 108 | break; |
| 109 | } |
| 110 | case 6: // Charlie from Alice |
| 111 | { |
| 112 | m_PeerTestResendTimer.cancel (); // no more msg 5 resends |
| 113 | if (GetAddress ()) |
| 114 | SendPeerTest (7, buf + offset, len - offset); |
| 115 | else |
| 116 | LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6"); |
| 117 | GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ()); |
| 118 | GetServer ().RequestRemoveSession (GetConnID ()); |
| 119 | break; |
| 120 | } |
| 121 | case 7: // Alice from Charlie 2 |
| 122 | { |
| 123 | m_PeerTestResendTimer.cancel (); // no more msg 6 resends |
| 124 | if (m_MsgNumReceived < 5 && m_OurEndpoint.port ()) // msg 5 was not received |
| 125 | { |
| 126 | if (m_OurEndpoint.address ().is_v4 ()) // ipv4 |
| 127 | { |
| 128 | if (i2p::context.GetStatus () == eRouterStatusFirewalled) |
| 129 | { |
| 130 | if (m_OurEndpoint.port () != GetServer ().GetPort (true)) |
| 131 | i2p::context.SetError (eRouterErrorSymmetricNAT); |
nothing calls this directly
no test coverage detected