tox-rs / tox

toxcore implementation in Rust
GNU General Public License v3.0
446 stars 32 forks source link

DHT Node human documentation. #22

Closed NamsooCho closed 6 years ago

NamsooCho commented 6 years ago

Description for dht_node

sk : Secret Key of this DHT node

pk : Public Key of this DHT node

kbucket : close peers list which contains PackedNode objects close to this DhtNode pk

getn_timeout : timeout queue for NodesRequest, when a node send a NodesRequest packet to a peer, it wait for response(NodesResponse) for 122 seconds.

This timeout queue will be replaced by future timer event.

If the response(NodesResponse) doesn't arrive for 122 seconds(timeout), the node consider the peer as offline and remove it from kbucket.

precomputed_cache : An hashmap for precomputed keys.

Precomputed keys are used in various place, so redundunt computing should be avoided.

When precomputed key is needed, first search this cache,

if the key exists in cache, the found key is used,

if not, new precomputed key is computed and stored in cache for later use.

peers : An hashmap for tx part of MPSC channel,

this channel is used for communication to peer via udp socket

ping_cache : An hashmap for ping_ids, a ping_id per a peer

nodes_cache : An hashmap for NodesRequest.ids, an id per a peer

nat_ping_cache : An hashmap for NatPingRequest.ping_ids, a ping_id per a peer

DHT Operation

When startup, DHT node sends NodesRequest packet to it's known friends list.

If the known friend is online, it responds with NodesResponse packet.

register peer : create MPSC channel. And then register tx part of channel to peers cache.

handle packet : process packet on it's packet kind and respond if needed. Packet kind is

Ping Request

PingRequest : Every 60 seconds, DHT node send PingRequest packet to peers to check whether it is alive.

When peer receives PingRequest, create_ping_resp(received PingRequest) is called.

create_ping_resp() does:

get_payload() does:

get_symmetric_key() does:

PingResponse::new() does:

send_to_peer() does:

DHT node stores 8 nodes closest to each of the public keys in its DHT friends list.

PingRequest has a ping-id which provide a method to check the response(PingResponse) is correct.

Ping Response

PingResponse : When a node receives a PingRequest packet, it responds with this packet.

When a node sent PingRequest receives PingResponse, future timeout completes and add or update peer's Socket address in kbucket and known friends list.

If PingResponse doesn't arrive for 122 seconds, future timeout results in error, then the peer removed from kbucket and marked as offline if the peer is known friend.

When a peer receives PingResponse, it calls handle_ping_resp()

handle_ping_resp() does:

Nodes Request

NodesRequest : Every 20 seconds, DHT node sends NodesRequest packet to a random node in kbucket and its known friends list.

DHT node runs future interval timer to send periodical packets. One of this interval timers is NodesRequest timer.

When NodesRequest timer expires:

create_nodes_req() does:

NodesRequest::new() does:

Nodes Response

When receiving NodesRequest:

create_nodes_res() does:

response() does:

get_closest() does:

try_add() does:

with_nodes() does:

NodesResponse::new() does:

When a node sent NodesRequest receives NodesResponse packet,

the timeout future completes and add or update peer's Socket address in kbucket or known friends list.

If NodesResponse doesn't arrive for 122 seconds,

the future timer result in error, then the peer removed from kbucket or marked as offline if the peer is known friend.

When receiving NodesResponse: handle_nodes_resp() is called.

handle_nodes_resp() does:

try_add() for kbucket does:

*note : kbucket is a vector of bucket, bucket is a vector of PackedNode.

DhtRequest

When hole-punching starts, every 3 seconds NatPingRequest packet is sent to known friend which is not connected directly.

If there is no response for 6 seconds, hole-punching will stop.

When a peer receives NatPingRequest from a friend, peer checks the Receiver's PK with own DHT PK.

If the two PKs are same, peer responds with NatPingResponse.

If not, peer search its kbucket and known friends list to find the PK which is same with Receiver's PK of NatPingRequest.

If peer found the PK in kbucket or friends list, it resends NatPingRequest to that peer.

NatPingRequest

When future timer inverval for NatPingRequest expires, DHT node calls create_nat_ping_req() and calls sent_to_peer().

create_nat_ping_req() does:

When a peer receives NatPingRequest, it calls handle_nat_ping_req().

handle_nat_ping_req() does:

create_nat_ping_resp() does:

search_matching_peer() does:

NatPingResponse

When a node sent NatPingRequest receives NatPingResponse calls handle_nat_ping_resp().

handle_nat_ping_resp() does:

kpp commented 6 years ago

Solved