| 2456 | } |
| 2457 | |
| 2458 | void SSU2Session::HandlePeerTest (const uint8_t * buf, size_t len) |
| 2459 | { |
| 2460 | // msgs 1-4 |
| 2461 | if (len < 3) return; |
| 2462 | uint8_t msg = buf[0]; |
| 2463 | size_t offset = 3; // points to signed data |
| 2464 | if (msg == 2 || msg == 4) offset += 32; // hash is presented for msg 2 and 4 only |
| 2465 | if (len < offset + 5) return; |
| 2466 | auto ts = i2p::util::GetMillisecondsSinceEpoch (); |
| 2467 | uint32_t nonce = bufbe32toh (buf + offset + 1); |
| 2468 | switch (msg) // msg |
| 2469 | { |
| 2470 | case 1: // Bob from Alice |
| 2471 | { |
| 2472 | auto session = m_Server.GetRandomPeerTestSession ((buf[12] == 6) ? i2p::data::RouterInfo::eSSU2V4 : i2p::data::RouterInfo::eSSU2V6, |
| 2473 | GetRemoteIdentity ()->GetIdentHash ()); |
| 2474 | if (session) // session with Charlie |
| 2475 | { |
| 2476 | if (m_Server.AddPeerTest (nonce, shared_from_this (), ts/1000)) |
| 2477 | { |
| 2478 | auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); |
| 2479 | // Alice's RouterInfo |
| 2480 | auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ()); |
| 2481 | if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr; |
| 2482 | packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0; |
| 2483 | if (!packet->payloadSize && r) |
| 2484 | session->SendFragmentedMessage (CreateDatabaseStoreMsg (r)); |
| 2485 | if (packet->payloadSize + len + 48 > m_MaxPayloadSize) |
| 2486 | { |
| 2487 | // doesn't fit one message, send RouterInfo in separate message |
| 2488 | uint32_t packetNum = session->SendData (packet->payload, packet->payloadSize, SSU2_FLAG_IMMEDIATE_ACK_REQUESTED); |
| 2489 | packet->sendTime = ts; |
| 2490 | session->m_SentPackets.emplace (packetNum, packet); |
| 2491 | packet = m_Server.GetSentPacketsPool ().AcquireShared (); // new packet |
| 2492 | } |
| 2493 | // PeerTest to Charlie |
| 2494 | packet->payloadSize += CreatePeerTestBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize, 2, |
| 2495 | eSSU2PeerTestCodeAccept, GetRemoteIdentity ()->GetIdentHash (), buf + offset, len - offset); |
| 2496 | packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); |
| 2497 | uint32_t packetNum = session->SendData (packet->payload, packet->payloadSize, SSU2_FLAG_IMMEDIATE_ACK_REQUESTED); |
| 2498 | packet->sendTime = ts; |
| 2499 | session->m_SentPackets.emplace (packetNum, packet); |
| 2500 | } |
| 2501 | else |
| 2502 | LogPrint (eLogInfo, "SSU2: Peer test 1 nonce ", nonce, " already exists. Ignored"); |
| 2503 | } |
| 2504 | else |
| 2505 | { |
| 2506 | // Charlie not found, send error back to Alice |
| 2507 | auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); |
| 2508 | uint8_t zeroHash[32] = {0}; |
| 2509 | packet->payloadSize = CreatePeerTestBlock (packet->payload, m_MaxPayloadSize, 4, |
| 2510 | eSSU2PeerTestCodeBobNoCharlieAvailable, zeroHash, buf + offset, len - offset); |
| 2511 | packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); |
| 2512 | uint32_t packetNum = SendData (packet->payload, packet->payloadSize); |
| 2513 | packet->sendTime = ts; |
| 2514 | m_SentPackets.emplace (packetNum, packet); |
| 2515 | } |
nothing calls this directly
no test coverage detected