1 /* SPDX-License-Identifier: GPL-3.0-or-later
2  * Copyright © 2016-2018 The TokTok team.
3  * Copyright © 2013 Tox project.
4  */
5 
6 /*
7  * An implementation of the DHT as seen in docs/updates/DHT.md
8  */
9 #ifndef C_TOXCORE_TOXCORE_DHT_H
10 #define C_TOXCORE_TOXCORE_DHT_H
11 
12 #include "crypto_core.h"
13 #include "logger.h"
14 #include "mono_time.h"
15 #include "network.h"
16 #include "ping_array.h"
17 
18 #include <stdbool.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /* Maximum number of clients stored per friend. */
25 #define MAX_FRIEND_CLIENTS 8
26 
27 #define LCLIENT_NODES MAX_FRIEND_CLIENTS
28 #define LCLIENT_LENGTH 128
29 
30 /* A list of the clients mathematically closest to ours. */
31 #define LCLIENT_LIST (LCLIENT_LENGTH * LCLIENT_NODES)
32 
33 #define MAX_CLOSE_TO_BOOTSTRAP_NODES 8
34 
35 /* The max number of nodes to send with send nodes. */
36 #define MAX_SENT_NODES 4
37 
38 /* Ping timeout in seconds */
39 #define PING_TIMEOUT 5
40 
41 /* size of DHT ping arrays. */
42 #define DHT_PING_ARRAY_SIZE 512
43 
44 /* Ping interval in seconds for each node in our lists. */
45 #define PING_INTERVAL 60
46 
47 /* The number of seconds for a non responsive node to become bad. */
48 #define PINGS_MISSED_NODE_GOES_BAD 1
49 #define PING_ROUNDTRIP 2
50 #define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * (PING_INTERVAL + PING_ROUNDTRIP))
51 
52 /* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
53 #define DHT_FAKE_FRIEND_NUMBER 2
54 
55 #define MAX_CRYPTO_REQUEST_SIZE 1024
56 
57 #define CRYPTO_PACKET_FRIEND_REQ    32  // Friend request crypto packet ID.
58 #define CRYPTO_PACKET_HARDENING     48  // Hardening crypto packet ID.
59 #define CRYPTO_PACKET_DHTPK         156
60 #define CRYPTO_PACKET_NAT_PING      254 // NAT ping crypto packet ID.
61 
62 /* Create a request to peer.
63  * send_public_key and send_secret_key are the pub/secret keys of the sender.
64  * recv_public_key is public key of receiver.
65  * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
66  * Data represents the data we send with the request with length being the length of the data.
67  * request_id is the id of the request (32 = friend request, 254 = ping request).
68  *
69  * return -1 on failure.
70  * return the length of the created packet on success.
71  */
72 int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
73                    const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id);
74 
75 /* puts the senders public key in the request in public_key, the data from the request
76  * in data if a friend or ping request was sent to us and returns the length of the data.
77  * packet is the request packet and length is its length
78  * return -1 if not valid request. */
79 int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
80                    uint8_t *request_id, const uint8_t *packet, uint16_t length);
81 
82 typedef struct IPPTs {
83     IP_Port     ip_port;
84     uint64_t    timestamp;
85 } IPPTs;
86 
87 typedef struct Hardening {
88     /* Node routes request correctly (true (1) or false/didn't check (0)) */
89     uint8_t     routes_requests_ok;
90     /* Time which we last checked this.*/
91     uint64_t    routes_requests_timestamp;
92     uint8_t     routes_requests_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
93     /* Node sends correct send_node (true (1) or false/didn't check (0)) */
94     uint8_t     send_nodes_ok;
95     /* Time which we last checked this.*/
96     uint64_t    send_nodes_timestamp;
97     uint8_t     send_nodes_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
98     /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */
99     uint8_t     testing_requests;
100     /* Time which we last checked this.*/
101     uint64_t    testing_timestamp;
102     uint8_t     testing_pingedid[CRYPTO_PUBLIC_KEY_SIZE];
103 } Hardening;
104 
105 typedef struct IPPTsPng {
106     IP_Port     ip_port;
107     uint64_t    timestamp;
108     uint64_t    last_pinged;
109 
110     Hardening hardening;
111     /* Returned by this node. Either our friend or us. */
112     IP_Port     ret_ip_port;
113     uint64_t    ret_timestamp;
114 } IPPTsPng;
115 
116 typedef struct Client_data {
117     uint8_t     public_key[CRYPTO_PUBLIC_KEY_SIZE];
118     IPPTsPng    assoc4;
119     IPPTsPng    assoc6;
120 } Client_data;
121 
122 /*----------------------------------------------------------------------------------*/
123 
124 typedef struct NAT {
125     /* 1 if currently hole punching, otherwise 0 */
126     uint8_t     hole_punching;
127     uint32_t    punching_index;
128     uint32_t    tries;
129     uint32_t    punching_index2;
130 
131     uint64_t    punching_timestamp;
132     uint64_t    recv_nat_ping_timestamp;
133     uint64_t    nat_ping_id;
134     uint64_t    nat_ping_timestamp;
135 } NAT;
136 
137 #define DHT_FRIEND_MAX_LOCKS 32
138 
139 typedef struct Node_format {
140     uint8_t     public_key[CRYPTO_PUBLIC_KEY_SIZE];
141     IP_Port     ip_port;
142 } Node_format;
143 
144 typedef struct DHT_Friend DHT_Friend;
145 
146 const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend);
147 const Client_data *dht_friend_client(const DHT_Friend *dht_friend, size_t index);
148 
149 /* Return packet size of packed node with ip_family on success.
150  * Return -1 on failure.
151  */
152 int packed_node_size(Family ip_family);
153 
154 /* Packs an IP_Port structure into data of max size length.
155  *
156  * Returns size of packed IP_Port data on success
157  * Return -1 on failure.
158  */
159 int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port);
160 
161 /* Unpack IP_Port structure from data of max size length into ip_port.
162  *
163  * Return size of unpacked ip_port on success.
164  * Return -1 on failure.
165  */
166 int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled);
167 
168 /* Pack number of nodes into data of maxlength length.
169  *
170  * return length of packed nodes on success.
171  * return -1 on failure.
172  */
173 int pack_nodes(uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number);
174 
175 /* Unpack data of length into nodes of size max_num_nodes.
176  * Put the length of the data processed in processed_data_len.
177  * tcp_enabled sets if TCP nodes are expected (true) or not (false).
178  *
179  * return number of unpacked nodes on success.
180  * return -1 on failure.
181  */
182 int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data,
183                  uint16_t length, bool tcp_enabled);
184 
185 
186 /*----------------------------------------------------------------------------------*/
187 /* struct to store some shared keys so we don't have to regenerate them for each request. */
188 #define MAX_KEYS_PER_SLOT 4
189 #define KEYS_TIMEOUT 600
190 
191 typedef struct Shared_Key {
192     uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
193     uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
194     uint32_t times_requested;
195     bool stored;
196     uint64_t time_last_requested;
197 } Shared_Key;
198 
199 typedef struct Shared_Keys {
200     Shared_Key keys[256 * MAX_KEYS_PER_SLOT];
201 } Shared_Keys;
202 
203 /*----------------------------------------------------------------------------------*/
204 
205 typedef int cryptopacket_handler_cb(void *object, IP_Port ip_port, const uint8_t *source_pubkey,
206                                     const uint8_t *data, uint16_t len, void *userdata);
207 
208 #define DHT_DEFINED
209 typedef struct DHT DHT;
210 
211 const uint8_t *dht_get_self_public_key(const DHT *dht);
212 const uint8_t *dht_get_self_secret_key(const DHT *dht);
213 void dht_set_self_public_key(DHT *dht, const uint8_t *key);
214 void dht_set_self_secret_key(DHT *dht, const uint8_t *key);
215 
216 Networking_Core *dht_get_net(const DHT *dht);
217 struct Ping *dht_get_ping(const DHT *dht);
218 const Client_data *dht_get_close_clientlist(const DHT *dht);
219 const Client_data *dht_get_close_client(const DHT *dht, uint32_t client_num);
220 uint16_t dht_get_num_friends(const DHT *dht);
221 
222 DHT_Friend *dht_get_friend(DHT *dht, uint32_t friend_num);
223 const uint8_t *dht_get_friend_public_key(const DHT *dht, uint32_t friend_num);
224 
225 /*----------------------------------------------------------------------------------*/
226 
227 /* Shared key generations are costly, it is therefore smart to store commonly used
228  * ones so that they can re used later without being computed again.
229  *
230  * If shared key is already in shared_keys, copy it to shared_key.
231  * else generate it into shared_key and copy it to shared_keys
232  */
233 void get_shared_key(const Mono_Time *mono_time, Shared_Keys *shared_keys, uint8_t *shared_key,
234                     const uint8_t *secret_key, const uint8_t *public_key);
235 
236 /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
237  * for packets that we receive.
238  */
239 void dht_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *public_key);
240 
241 /* Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key
242  * for packets that we send.
243  */
244 void dht_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *public_key);
245 
246 void dht_getnodes(DHT *dht, const IP_Port *from_ipp, const uint8_t *from_id, const uint8_t *which_id);
247 
248 typedef void dht_ip_cb(void *object, int32_t number, IP_Port ip_port);
249 
250 /* Add a new friend to the friends list.
251  * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
252  *
253  * ip_callback is the callback of a function that will be called when the ip address
254  * is found along with arguments data and number.
255  *
256  * lock_count will be set to a non zero number that must be passed to dht_delfriend()
257  * to properly remove the callback.
258  *
259  *  return 0 if success.
260  *  return -1 if failure (friends list is full).
261  */
262 int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback,
263                   void *data, int32_t number, uint16_t *lock_count);
264 
265 /* Delete a friend from the friends list.
266  * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
267  *
268  *  return 0 if success.
269  *  return -1 if failure (public_key not in friends list).
270  */
271 int dht_delfriend(DHT *dht, const uint8_t *public_key, uint16_t lock_count);
272 
273 /* Get ip of friend.
274  *  public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long.
275  *  ip must be 4 bytes long.
276  *  port must be 2 bytes long.
277  *
278  *  return -1, -- if public_key does NOT refer to a friend
279  *  return  0, -- if public_key refers to a friend and we failed to find the friend (yet)
280  *  return  1, ip if public_key refers to a friend and we found him
281  */
282 int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port);
283 
284 /* Compares pk1 and pk2 with pk.
285  *
286  *  return 0 if both are same distance.
287  *  return 1 if pk1 is closer.
288  *  return 2 if pk2 is closer.
289  */
290 int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2);
291 
292 /**
293  * Add node to the node list making sure only the nodes closest to cmp_pk are in the list.
294  *
295  * @return true iff the node was added to the list.
296  */
297 bool add_to_list(Node_format *nodes_list, uint32_t length, const uint8_t *pk, IP_Port ip_port,
298                  const uint8_t *cmp_pk);
299 
300 /* Return 1 if node can be added to close list, 0 if it can't.
301  */
302 bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, IP_Port ip_port);
303 
304 /* Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know
305  * and put them in nodes_list (must be MAX_SENT_NODES big).
306  *
307  * sa_family = family (IPv4 or IPv6) (0 if we don't care)?
308  * is_LAN = return some LAN ips (true or false)
309  * want_good = do we want tested nodes or not? (TODO(irungentoo))
310  *
311  * return the number of nodes returned.
312  *
313  */
314 int get_close_nodes(const DHT *dht, const uint8_t *public_key, Node_format *nodes_list, Family sa_family,
315                     bool is_LAN, uint8_t want_good);
316 
317 
318 /* Put up to max_num nodes in nodes from the random friends.
319  *
320  * return the number of nodes.
321  */
322 uint16_t randfriends_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
323 
324 /* Put up to max_num nodes in nodes from the closelist.
325  *
326  * return the number of nodes.
327  */
328 uint16_t closelist_nodes(DHT *dht, Node_format *nodes, uint16_t max_num);
329 
330 /* Run this function at least a couple times per second (It's the main loop). */
331 void do_dht(DHT *dht);
332 
333 /*
334  *  Use these two functions to bootstrap the client.
335  */
336 /* Sends a "get nodes" request to the given node with ip, port and public_key
337  *   to setup connections
338  */
339 void dht_bootstrap(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
340 /* Resolves address into an IP address. If successful, sends a "get nodes"
341  *   request to the given node with ip, port and public_key to setup connections
342  *
343  * address can be a hostname or an IP address (IPv4 or IPv6).
344  * if ipv6enabled is 0 (zero), the resolving sticks STRICTLY to IPv4 addresses
345  * if ipv6enabled is not 0 (zero), the resolving looks for IPv6 addresses first,
346  *   then IPv4 addresses.
347  *
348  *  returns 1 if the address could be converted into an IP address
349  *  returns 0 otherwise
350  */
351 int dht_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
352                                uint16_t port, const uint8_t *public_key);
353 
354 /* Start sending packets after DHT loaded_friends_list and loaded_clients_list are set.
355  *
356  * returns 0 if successful
357  * returns -1 otherwise
358  */
359 int dht_connect_after_load(DHT *dht);
360 
361 /* ROUTING FUNCTIONS */
362 
363 /* Send the given packet to node with public_key.
364  *
365  *  return -1 if failure.
366  */
367 int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length);
368 
369 /* Send the following packet to everyone who tells us they are connected to friend_id.
370  *
371  *  return number of nodes it sent the packet to.
372  */
373 int route_tofriend(const DHT *dht, const uint8_t *friend_id, const uint8_t *packet, uint16_t length);
374 
375 /* Function to handle crypto packets.
376  */
377 void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object);
378 
379 /* SAVE/LOAD functions */
380 
381 /* Get the size of the DHT (for saving). */
382 uint32_t dht_size(const DHT *dht);
383 
384 /* Save the DHT in data where data is an array of size dht_size(). */
385 void dht_save(const DHT *dht, uint8_t *data);
386 
387 /* Load the DHT from data of size size.
388  *
389  *  return -1 if failure.
390  *  return 0 if success.
391  */
392 int dht_load(DHT *dht, const uint8_t *data, uint32_t length);
393 
394 /* Initialize DHT. */
395 DHT *new_dht(const Logger *log, Mono_Time *mono_time, Networking_Core *net, bool holepunching_enabled);
396 
397 void kill_dht(DHT *dht);
398 
399 /*  return false if we are not connected to the DHT.
400  *  return true if we are.
401  */
402 bool dht_isconnected(const DHT *dht);
403 
404 /*  return false if we are not connected or only connected to lan peers with the DHT.
405  *  return true if we are.
406  */
407 bool dht_non_lan_connected(const DHT *dht);
408 
409 
410 uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key);
411 
412 #ifdef __cplusplus
413 }  // extern "C"
414 #endif
415 
416 #endif
417