| 157 | } |
| 158 | |
| 159 | bool SSU2Session::Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag) |
| 160 | { |
| 161 | // we are Alice |
| 162 | if (!session || !relayTag) return false; |
| 163 | // find local address to introduce |
| 164 | auto localAddress = session->FindLocalAddress (); |
| 165 | if (!localAddress || localAddress->host.is_unspecified () || !localAddress->port) |
| 166 | { |
| 167 | // can't introduce invalid endpoint |
| 168 | LogPrint (eLogWarning, "SSU2: Can't find local address to introduce"); |
| 169 | return false; |
| 170 | } |
| 171 | // create nonce |
| 172 | uint32_t nonce; |
| 173 | RAND_bytes ((uint8_t *)&nonce, 4); |
| 174 | auto ts = i2p::util::GetMillisecondsSinceEpoch (); |
| 175 | // payload |
| 176 | auto packet = m_Server.GetSentPacketsPool ().AcquireShared (); |
| 177 | uint8_t * payload = packet->payload; |
| 178 | payload[0] = eSSU2BlkRelayRequest; |
| 179 | payload[3] = 0; // flag |
| 180 | htobe32buf (payload + 4, nonce); |
| 181 | htobe32buf (payload + 8, relayTag); |
| 182 | htobe32buf (payload + 12, ts/1000); |
| 183 | payload[16] = m_Version; // ver |
| 184 | size_t asz = CreateEndpoint (payload + 18, m_MaxPayloadSize - 18, boost::asio::ip::udp::endpoint (localAddress->host, localAddress->port)); |
| 185 | if (!asz) return false; |
| 186 | payload[17] = asz; |
| 187 | packet->payloadSize = asz + 18; |
| 188 | SignedData<128> s; |
| 189 | s.Insert ((const uint8_t *)"RelayRequestData", 16); // prologue |
| 190 | s.Insert (GetRemoteIdentity ()->GetIdentHash (), 32); // bhash |
| 191 | s.Insert (session->GetRemoteIdentity ()->GetIdentHash (), 32); // chash |
| 192 | s.Insert (payload + 4, 14 + asz); // nonce, relay tag, timestamp, ver, asz and Alice's endpoint |
| 193 | s.Sign (i2p::context.GetPrivateKeys (), payload + packet->payloadSize); |
| 194 | packet->payloadSize += i2p::context.GetIdentity ()->GetSignatureLen (); |
| 195 | htobe16buf (payload + 1, packet->payloadSize - 3); // size |
| 196 | packet->payloadSize += CreatePaddingBlock (payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize); |
| 197 | // send |
| 198 | m_RelaySessions.emplace (nonce, std::make_pair (session, ts/1000)); |
| 199 | session->m_SourceConnID = htobe64 (((uint64_t)nonce << 32) | nonce); |
| 200 | session->m_DestConnID = ~session->m_SourceConnID; |
| 201 | m_Server.AddSession (session); |
| 202 | int32_t packetNum = SendData (packet->payload, packet->payloadSize); |
| 203 | packet->sendTime = ts; |
| 204 | m_SentPackets.emplace (packetNum, packet); |
| 205 | |
| 206 | return true; |
| 207 | } |
| 208 | |
| 209 | void SSU2Session::WaitForIntroduction () |
| 210 | { |
no test coverage detected