Skip to content

Commit

Permalink
Merge pull request #46 from tox-rs/improve-onion-docs
Browse files Browse the repository at this point in the history
Improve onion docs according to #37
  • Loading branch information
kpp committed Mar 9, 2018
2 parents 67c9938 + 9ab9dd8 commit 76d9e31
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 5 deletions.
41 changes: 40 additions & 1 deletion src/toxcore/onion/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,46 @@
along with Tox. If not, see <http://www.gnu.org/licenses/>.
*/

/*! 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.
<pre style="white-space:pre;">
+--------+ +--------+ +--------+ +--------+ +------------------+ +------------+
| | +---------------+ | | +---------------+ | | +---------------+ | | | AnnounceRequest | | |
| Sender |---| OnionRequest0 |-->| Node 1 |---| OnionRequest1 |-->| Node 2 |---| OnionRequest2 |-->| Node 3 |---+------------------+-->| Onion node |
| | +---------------+ | | +---------------+ | | +---------------+ | | | OnionDataRequest | | |
+--------+ +--------+ +--------+ +--------+ +------------------+ +------------+
</pre>
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.
<pre style="white-space:pre;">
+------------+ +--------+ +--------+ +--------+ +-------------------+ +----------+
| | +----------------+ | | +----------------+ | | +----------------+ | | | AnnounceResponse | | |
| Onion node |---| OnionResponse3 |-->| Node 3 |---| OnionResponse2 |-->| Node 2 |---| OnionResponse1 |-->| Node 1 |---+-------------------+-->| Receiver |
| | +----------------+ | | +----------------+ | | +----------------+ | | | OnionDataResponse | | |
+------------+ +--------+ +--------+ +--------+ +-------------------+ +----------+
</pre>
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.
*/

Expand Down
59 changes: 55 additions & 4 deletions src/toxcore/onion/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
-------- | ------
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
-------- | ------
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
-------- | ------
Expand Down Expand Up @@ -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
-------- | ------
Expand Down

0 comments on commit 76d9e31

Please sign in to comment.