diff --git a/src/toxcore/onion/mod.rs b/src/toxcore/onion/mod.rs index 468fd3f98..84d0e06a2 100644 --- a/src/toxcore/onion/mod.rs +++ b/src/toxcore/onion/mod.rs @@ -18,7 +18,46 @@ along with Tox. If not, see . */ -/*! Onion packets handling +/*! Onion module allows nodes to announce their long term public keys and find +friends by their long term public keys. + +There are two basic onion requests - `AnnounceRequest` and `OnionDataRequest`. +They are enclosed to OnionRequest packets and sent though the onion path to +prevent nodes finding out long term public key when they know only temporary +DHT public key. There are three types of OnionRequest packets: `OnionRequest0`, +`OnionRequest1` and `OnionRequest2`. `AnnounceRequest` and `OnionDataRequest` +when created are enclosed to `OnionRequest2`, `OnionRequest2` is enclosed to +`OnionRequest1` and `OnionRequest1` is enclosed to `OnionRequest0`. When DHT +node receives OnionRequest packet it decrypts inner packet and sends it to the +next node. + +
++--------+                       +--------+                       +--------+                       +--------+   +------------------+   +------------+
+|        |   +---------------+   |        |   +---------------+   |        |   +---------------+   |        |   | AnnounceRequest  |   |            |
+| Sender |---| OnionRequest0 |-->| Node 1 |---| OnionRequest1 |-->| Node 2 |---| OnionRequest2 |-->| Node 3 |---+------------------+-->| Onion node |
+|        |   +---------------+   |        |   +---------------+   |        |   +---------------+   |        |   | OnionDataRequest |   |            |
++--------+                       +--------+                       +--------+                       +--------+   +------------------+   +------------+
+
+ +Similarly to requests there are responses `AnnounceResponse` and +`OnionDataResponse` that enclosed to three kind of OnionRespose packets: +`OnionResponse3`, `OnionResponse2` and `OnionResponse1`. OnionResponse +packets are processed in the same way but with reverse ordering. + +
++------------+                        +--------+                        +--------+                        +--------+   +-------------------+   +----------+
+|            |   +----------------+   |        |   +----------------+   |        |   +----------------+   |        |   | AnnounceResponse  |   |          |
+| Onion node |---| OnionResponse3 |-->| Node 3 |---| OnionResponse2 |-->| Node 2 |---| OnionResponse1 |-->| Node 1 |---+-------------------+-->| Receiver |
+|            |   +----------------+   |        |   +----------------+   |        |   +----------------+   |        |   | OnionDataResponse |   |          |
++------------+                        +--------+                        +--------+                        +--------+   +-------------------+   +----------+
+
+ +When onion node handles `AnnounceRequest` packet it sends answer to original +sender using the same onion path with the help of received onion return +addresses. But when it handles `OnionDataRequest` packet it should send +response packet to another destination node by its long term public key. +That means that when onion node should store long term public keys of announced +node along with onion return addresses. */ diff --git a/src/toxcore/onion/packet.rs b/src/toxcore/onion/packet.rs index ba7abaf65..1a62d893b 100644 --- a/src/toxcore/onion/packet.rs +++ b/src/toxcore/onion/packet.rs @@ -107,6 +107,12 @@ impl ToBytes for IpPort { /** Encrypted onion return addresses. Payload contains encrypted with symmetric key `IpPort` and possibly inner `OnionReturn`. +When DHT node receives OnionRequest packet it appends `OnionReturn` to the end +of the next request packet it will send. So when DHT node receives OnionResponse +packet it will know where to send the next response packet by decrypting +`OnionReturn` from received packet. If node can't decrypt `OnionReturn` that +means that onion path is expired and packet should be dropped. + Serialized form: Length | Content @@ -367,7 +373,20 @@ impl ToBytes for OnionRequest2 { } } -/** Serialized form: +/** It's used for announcing ourselves to onion node and for looking for other +announced nodes. + +If we want to announce ourselves we should send one `AnnounceRequest` packet with +PingId set to 0 to acquire correct PingId of onion node. Then using this PingId +we can send another `AnnounceRequest` to be added to onion nodes list. If +`AnnounceRequest` succeed we will get `AnnounceResponse` with is_stored set to 2. +Otherwise is_stored will be set to 0. + +If we are looking for another node we should send `AnnounceRequest` packet with +PingId set to 0 and with `PublicKey` of this node. If node is found we will get +`AnnounceResponse` with is_stored set to 1. Otherwise is_stored will be set to 0. + +Serialized form: Length | Content -------- | ------ @@ -415,6 +434,8 @@ impl ToBytes for InnerAnnounceRequest { /** Same as `InnerAnnounceRequest` but with `OnionReturn` addresses. It's sent from the third node from onion chain to the destination node. +See [`InnerAnnounceRequest`](./struct.InnerAnnounceRequest.html) for additional docs. + Serialized form: Length | Content @@ -455,7 +476,15 @@ impl ToBytes for AnnounceRequest { } } -/** Serialized form: +/** It's used to send data requests to dht node using onion paths. + +When DHT node receives `OnionDataRequest` it sends `OnionDataResponse` to +destination node for which data request is intended. Thus, data request will +go through 7 intermediate nodes until destination node gets it - 3 nodes with +OnionRequests, onion node that handles `OnionDataRequest` and 3 nodes with +OnionResponses. + +Serialized form: Length | Content -------- | ------ @@ -509,6 +538,8 @@ impl ToBytes for InnerOnionDataRequest { /** Same as `InnerOnionDataRequest` but with `OnionReturn` addresses. It's sent from the third node from onion chain to the destination node. +See [`InnerOnionDataRequest`](./struct.InnerOnionDataRequest.html) for additional docs. + Serialized form: Length | Content @@ -550,7 +581,11 @@ impl ToBytes for OnionDataRequest { } } -/** Serialized form: +/** When onion node receives `OnionDataRequest` packet it converts it to +`OnionDataResponse` and sends to destination node if it announced itself +and is contained in onion nodes list. + +Serialized form: Length | Content -------- | ------ @@ -595,7 +630,23 @@ impl ToBytes for OnionDataResponse { } } -/** Serialized form: +/** It's used to respond to AnnounceRequest packet. + +sendback_data is the data from `AnnounceRequest` that should be sent in the +response as is. It's used in onion client to match onion response with sent +request. + +is_stored variable from payload contains the result of sent request. It might +have values: +- 0: failed to announce ourselves of find requested node +- 1: requested node is found by it's real PublicKey +- 2: we successfully announces ourselves + +In case of is_stored is equal to 1 ping_id from payload will contain pk that +should be used to send data packets to the requested node. In other cases it +will contain ping id that should be used for announcing ourselves. + +Serialized form: Length | Content -------- | ------