| 2360 | } |
| 2361 | |
| 2362 | void SSU2Session::HandleRelayResponse (const uint8_t * buf, size_t len) |
| 2363 | { |
| 2364 | if (len < 6) return; |
| 2365 | uint32_t nonce = bufbe32toh (buf + 2); |
| 2366 | if (m_State == eSSU2SessionStateIntroduced) |
| 2367 | { |
| 2368 | // HolePunch from Charlie |
| 2369 | // TODO: verify address and signature |
| 2370 | // verify nonce |
| 2371 | if (~htobe64 (((uint64_t)nonce << 32) | nonce) != m_DestConnID) |
| 2372 | LogPrint (eLogWarning, "SSU2: Relay response nonce mismatch ", nonce, " connID=", m_DestConnID); |
| 2373 | if (len >= 8) |
| 2374 | { |
| 2375 | // new token |
| 2376 | uint64_t token; |
| 2377 | memcpy (&token, buf + len - 8, 8); |
| 2378 | m_Server.UpdateOutgoingToken (m_RemoteEndpoint, token, i2p::util::GetSecondsSinceEpoch () + SSU2_TOKEN_EXPIRATION_TIMEOUT); |
| 2379 | } |
| 2380 | return; |
| 2381 | } |
| 2382 | auto it = m_RelaySessions.find (nonce); |
| 2383 | if (it != m_RelaySessions.end ()) |
| 2384 | { |
| 2385 | auto relaySession = it->second.first; |
| 2386 | m_RelaySessions.erase (it); |
| 2387 | if (relaySession && relaySession->IsEstablished ()) |
| 2388 | { |
| 2389 | // we are Bob, message from Charlie |
| 2390 | auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); |
| 2391 | uint8_t * payload = packet->payload; |
| 2392 | payload[0] = eSSU2BlkRelayResponse; |
| 2393 | htobe16buf (payload + 1, len); |
| 2394 | memcpy (payload + 3, buf, len); // forward to Alice as is |
| 2395 | packet->payloadSize = len + 3; |
| 2396 | packet->payloadSize += CreatePaddingBlock (payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); |
| 2397 | uint32_t packetNum = relaySession->SendData (packet->payload, packet->payloadSize); |
| 2398 | if (m_RemoteVersion >= SSU2_MIN_RELAY_RESPONSE_RESEND_VERSION) |
| 2399 | { |
| 2400 | // sometimes Alice doesn't ack this RelayResponse in older versions |
| 2401 | packet->sendTime = i2p::util::GetMillisecondsSinceEpoch (); |
| 2402 | relaySession->m_SentPackets.emplace (packetNum, packet); |
| 2403 | } |
| 2404 | } |
| 2405 | else |
| 2406 | { |
| 2407 | // we are Alice, message from Bob |
| 2408 | if (!buf[1]) // status code accepted? |
| 2409 | { |
| 2410 | // verify signature |
| 2411 | uint8_t csz = (len >= 12) ? buf[11] : 0; |
| 2412 | if (csz + 12 + relaySession->GetRemoteIdentity ()->GetSignatureLen () > len) |
| 2413 | { |
| 2414 | LogPrint (eLogWarning, "SSU2: Malformed RelayResponse len=", len); |
| 2415 | relaySession->Done (); |
| 2416 | return; |
| 2417 | } |
| 2418 | SignedData<128> s; |
| 2419 | s.Insert ((const uint8_t *)"RelayAgreementOK", 16); // prologue |
nothing calls this directly
no test coverage detected