Line | Count | Source |
1 | | /* SPDX-License-Identifier: GPL-3.0-or-later |
2 | | * Copyright © 2016-2018 The TokTok team. |
3 | | * Copyright © 2013 Tox project. |
4 | | */ |
5 | | |
6 | | /** @file |
7 | | * @brief 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 <stdbool.h> |
13 | | |
14 | | #include "attributes.h" |
15 | | #include "crypto_core.h" |
16 | | #include "logger.h" |
17 | | #include "mem.h" |
18 | | #include "mono_time.h" |
19 | | #include "network.h" |
20 | | #include "ping_array.h" |
21 | | |
22 | | #ifdef __cplusplus |
23 | | extern "C" { |
24 | | #endif |
25 | | |
26 | | /* Encryption and signature keys definition */ |
27 | 649k | #define ENC_PUBLIC_KEY_SIZE CRYPTO_PUBLIC_KEY_SIZE |
28 | 1.60k | #define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE |
29 | 75.2k | #define SIG_PUBLIC_KEY_SIZE CRYPTO_SIGN_PUBLIC_KEY_SIZE |
30 | 2.08k | #define SIG_SECRET_KEY_SIZE CRYPTO_SIGN_SECRET_KEY_SIZE |
31 | | |
32 | | /* Size of the group chat_id */ |
33 | 30.3k | #define CHAT_ID_SIZE SIG_PUBLIC_KEY_SIZE |
34 | | |
35 | | /* Extended keys for group chats */ |
36 | 1.60k | #define EXT_SECRET_KEY_SIZE (ENC_SECRET_KEY_SIZE + SIG_SECRET_KEY_SIZE) |
37 | 9.44k | #define EXT_PUBLIC_KEY_SIZE (ENC_PUBLIC_KEY_SIZE + SIG_PUBLIC_KEY_SIZE) |
38 | | |
39 | | |
40 | | /* Maximum size of a signature (may be smaller) */ |
41 | 19.6k | #define SIGNATURE_SIZE CRYPTO_SIGNATURE_SIZE |
42 | | /** Maximum number of clients stored per friend. */ |
43 | 59.2M | #define MAX_FRIEND_CLIENTS 8 |
44 | | |
45 | 56.0M | #define LCLIENT_NODES MAX_FRIEND_CLIENTS |
46 | 52.8M | #define LCLIENT_LENGTH 128 |
47 | | |
48 | | /** A list of the clients mathematically closest to ours. */ |
49 | 52.1M | #define LCLIENT_LIST (LCLIENT_LENGTH * LCLIENT_NODES) |
50 | | |
51 | 18.6k | #define MAX_CLOSE_TO_BOOTSTRAP_NODES 8 |
52 | | |
53 | | /** The max number of nodes to send with send nodes. */ |
54 | 178M | #define MAX_SENT_NODES 4 |
55 | | |
56 | | /** Ping timeout in seconds */ |
57 | 8.19k | #define PING_TIMEOUT 5 |
58 | | |
59 | | /** size of DHT ping arrays. */ |
60 | 4.05k | #define DHT_PING_ARRAY_SIZE 512 |
61 | | |
62 | | /** Ping interval in seconds for each node in our lists. */ |
63 | 603M | #define PING_INTERVAL 60 |
64 | | |
65 | | /** The number of seconds for a non responsive node to become bad. */ |
66 | 276M | #define PINGS_MISSED_NODE_GOES_BAD 1 |
67 | 276M | #define PING_ROUNDTRIP 2 |
68 | 276M | #define BAD_NODE_TIMEOUT (PING_INTERVAL + PINGS_MISSED_NODE_GOES_BAD * (PING_INTERVAL + PING_ROUNDTRIP)) |
69 | | |
70 | | /** |
71 | | * The number of "fake" friends to add. |
72 | | * |
73 | | * (for optimization purposes and so our paths for the onion part are more random) |
74 | | */ |
75 | 191k | #define DHT_FAKE_FRIEND_NUMBER 2 |
76 | | |
77 | | /** Maximum packet size for a DHT request packet. */ |
78 | 24.3k | #define MAX_CRYPTO_REQUEST_SIZE 1024 |
79 | | |
80 | 15.6k | #define CRYPTO_PACKET_FRIEND_REQ 32 // Friend request crypto packet ID. |
81 | 31.2k | #define CRYPTO_PACKET_DHTPK 156 |
82 | 8.44k | #define CRYPTO_PACKET_NAT_PING 254 // NAT ping crypto packet ID. |
83 | | |
84 | | /* Max size of a packed node for IPV4 and IPV6 respectively */ |
85 | 2.87k | #define PACKED_NODE_SIZE_IP4 (1 + SIZE_IP4 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE) |
86 | 78.4k | #define PACKED_NODE_SIZE_IP6 (1 + SIZE_IP6 + sizeof(uint16_t) + CRYPTO_PUBLIC_KEY_SIZE) |
87 | | |
88 | | /** |
89 | | * This define can eventually be removed; it is necessary if a significant |
90 | | * proportion of dht nodes do not implement the dht announcements protocol. |
91 | | */ |
92 | | #define CHECK_ANNOUNCE_NODE |
93 | | |
94 | | /** |
95 | | * @brief Create a request to peer. |
96 | | * |
97 | | * Packs the data and sender public key and encrypts the packet. |
98 | | * |
99 | | * @param[in] send_public_key public key of the sender. |
100 | | * @param[in] send_secret_key secret key of the sender. |
101 | | * @param[out] packet an array of @ref MAX_CRYPTO_REQUEST_SIZE big. |
102 | | * @param[in] recv_public_key public key of the receiver. |
103 | | * @param[in] data represents the data we send with the request. |
104 | | * @param[in] data_length the length of the data. |
105 | | * @param[in] request_id the id of the request (32 = friend request, 254 = ping request). |
106 | | * |
107 | | * @attention Constraints: |
108 | | * @code |
109 | | * sizeof(packet) >= MAX_CRYPTO_REQUEST_SIZE |
110 | | * @endcode |
111 | | * |
112 | | * @retval -1 on failure. |
113 | | * @return the length of the created packet on success. |
114 | | */ |
115 | | non_null() |
116 | | int create_request(const Random *rng, const uint8_t *send_public_key, const uint8_t *send_secret_key, |
117 | | uint8_t *packet, const uint8_t *recv_public_key, |
118 | | const uint8_t *data, uint32_t data_length, uint8_t request_id); |
119 | | |
120 | | /** |
121 | | * @brief Decrypts and unpacks a DHT request packet. |
122 | | * |
123 | | * Puts the senders public key in the request in @p public_key, the data from |
124 | | * the request in @p data. |
125 | | * |
126 | | * @param[in] self_public_key public key of the receiver (us). |
127 | | * @param[in] self_secret_key secret key of the receiver (us). |
128 | | * @param[out] public_key public key of the sender, copied from the input packet. |
129 | | * @param[out] data decrypted request data, copied from the input packet, must |
130 | | * have room for @ref MAX_CRYPTO_REQUEST_SIZE bytes. |
131 | | * @param[in] packet is the request packet. |
132 | | * @param[in] packet_length length of the packet. |
133 | | * |
134 | | * @attention Constraints: |
135 | | * @code |
136 | | * sizeof(data) >= MAX_CRYPTO_REQUEST_SIZE |
137 | | * @endcode |
138 | | * |
139 | | * @retval -1 if not valid request. |
140 | | * @return the length of the unpacked data. |
141 | | */ |
142 | | non_null() |
143 | | int handle_request( |
144 | | const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, |
145 | | uint8_t *request_id, const uint8_t *packet, uint16_t packet_length); |
146 | | |
147 | | typedef struct IPPTs { |
148 | | IP_Port ip_port; |
149 | | uint64_t timestamp; |
150 | | } IPPTs; |
151 | | |
152 | | typedef struct IPPTsPng { |
153 | | IP_Port ip_port; |
154 | | uint64_t timestamp; |
155 | | uint64_t last_pinged; |
156 | | |
157 | | /* Returned by this node */ |
158 | | IP_Port ret_ip_port; |
159 | | uint64_t ret_timestamp; |
160 | | /* true if this ip_port is ours */ |
161 | | bool ret_ip_self; |
162 | | } IPPTsPng; |
163 | | |
164 | | typedef struct Client_data { |
165 | | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
166 | | IPPTsPng assoc4; |
167 | | IPPTsPng assoc6; |
168 | | |
169 | | #ifdef CHECK_ANNOUNCE_NODE |
170 | | /* Responded to data search? */ |
171 | | bool announce_node; |
172 | | #endif /* CHECK_ANNOUNCE_NODE */ |
173 | | } Client_data; |
174 | | |
175 | | /*----------------------------------------------------------------------------------*/ |
176 | | |
177 | | typedef struct NAT { |
178 | | /* true if currently hole punching */ |
179 | | bool hole_punching; |
180 | | uint32_t punching_index; |
181 | | uint32_t tries; |
182 | | uint32_t punching_index2; |
183 | | |
184 | | uint64_t punching_timestamp; |
185 | | uint64_t recv_nat_ping_timestamp; |
186 | | uint64_t nat_ping_id; |
187 | | uint64_t nat_ping_timestamp; |
188 | | } NAT; |
189 | | |
190 | | typedef struct Node_format { |
191 | | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; |
192 | | IP_Port ip_port; |
193 | | } Node_format; |
194 | | |
195 | | extern const Node_format empty_node_format; |
196 | | |
197 | | typedef struct DHT_Friend DHT_Friend; |
198 | | |
199 | | non_null() const uint8_t *dht_friend_public_key(const DHT_Friend *dht_friend); |
200 | | non_null() const Client_data *dht_friend_client(const DHT_Friend *dht_friend, size_t index); |
201 | | |
202 | | /** @return packet size of packed node with ip_family on success. |
203 | | * @retval -1 on failure. |
204 | | */ |
205 | | int packed_node_size(Family ip_family); |
206 | | |
207 | | /** @brief Pack an IP_Port structure into data of max size length. |
208 | | * |
209 | | * Packed_length is the offset of data currently packed. |
210 | | * |
211 | | * @return size of packed IP_Port data on success. |
212 | | * @retval -1 on failure. |
213 | | */ |
214 | | non_null() |
215 | | int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_Port *ip_port); |
216 | | |
217 | | /** @brief Unpack IP_Port structure from data of max size length into ip_port. |
218 | | * |
219 | | * len_processed is the offset of data currently unpacked. |
220 | | * |
221 | | * @return size of unpacked ip_port on success. |
222 | | * @retval -1 on failure. |
223 | | */ |
224 | | non_null() |
225 | | int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, bool tcp_enabled); |
226 | | |
227 | | /** @brief Encrypt plain and write resulting DHT packet into packet with max size length. |
228 | | * |
229 | | * @return size of packet on success. |
230 | | * @retval -1 on failure. |
231 | | */ |
232 | | non_null() |
233 | | int dht_create_packet(const Memory *mem, const Random *rng, |
234 | | const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], |
235 | | const uint8_t *shared_key, uint8_t type, |
236 | | const uint8_t *plain, size_t plain_length, |
237 | | uint8_t *packet, size_t length); |
238 | | |
239 | | /** @brief Pack number of nodes into data of maxlength length. |
240 | | * |
241 | | * @return length of packed nodes on success. |
242 | | * @retval -1 on failure. |
243 | | */ |
244 | | non_null() |
245 | | int pack_nodes(const Logger *logger, uint8_t *data, uint16_t length, const Node_format *nodes, uint16_t number); |
246 | | |
247 | | /** @brief Unpack data of length into nodes of size max_num_nodes. |
248 | | * Put the length of the data processed in processed_data_len. |
249 | | * tcp_enabled sets if TCP nodes are expected (true) or not (false). |
250 | | * |
251 | | * @return number of unpacked nodes on success. |
252 | | * @retval -1 on failure. |
253 | | */ |
254 | | non_null(1, 4) nullable(3) |
255 | | int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, const uint8_t *data, |
256 | | uint16_t length, bool tcp_enabled); |
257 | | |
258 | | /*----------------------------------------------------------------------------------*/ |
259 | | |
260 | | typedef int cryptopacket_handler_cb(void *object, const IP_Port *source, const uint8_t *source_pubkey, |
261 | | const uint8_t *packet, uint16_t length, void *userdata); |
262 | | |
263 | | typedef struct DHT DHT; |
264 | | |
265 | | non_null() const uint8_t *dht_get_self_public_key(const DHT *dht); |
266 | | non_null() const uint8_t *dht_get_self_secret_key(const DHT *dht); |
267 | | non_null() void dht_set_self_public_key(DHT *dht, const uint8_t *key); |
268 | | non_null() void dht_set_self_secret_key(DHT *dht, const uint8_t *key); |
269 | | |
270 | | non_null() Networking_Core *dht_get_net(const DHT *dht); |
271 | | non_null() struct Ping *dht_get_ping(const DHT *dht); |
272 | | non_null() const Client_data *dht_get_close_clientlist(const DHT *dht); |
273 | | non_null() const Client_data *dht_get_close_client(const DHT *dht, uint32_t client_num); |
274 | | non_null() uint16_t dht_get_num_friends(const DHT *dht); |
275 | | |
276 | | non_null() DHT_Friend *dht_get_friend(DHT *dht, uint32_t friend_num); |
277 | | non_null() const uint8_t *dht_get_friend_public_key(const DHT *dht, uint32_t friend_num); |
278 | | |
279 | | /*----------------------------------------------------------------------------------*/ |
280 | | |
281 | | /** |
282 | | * Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key |
283 | | * for packets that we receive. |
284 | | */ |
285 | | non_null() |
286 | | const uint8_t *dht_get_shared_key_recv(DHT *dht, const uint8_t *public_key); |
287 | | |
288 | | /** |
289 | | * Copy shared_key to encrypt/decrypt DHT packet from public_key into shared_key |
290 | | * for packets that we send. |
291 | | */ |
292 | | non_null() |
293 | | const uint8_t *dht_get_shared_key_sent(DHT *dht, const uint8_t *public_key); |
294 | | |
295 | | /** |
296 | | * Sends a getnodes request to `ip_port` with the public key `public_key` for nodes |
297 | | * that are close to `client_id`. |
298 | | * |
299 | | * @retval true on success. |
300 | | */ |
301 | | non_null() |
302 | | bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *client_id); |
303 | | |
304 | | typedef void dht_ip_cb(void *object, int32_t number, const IP_Port *ip_port); |
305 | | |
306 | | typedef void dht_get_nodes_response_cb(const DHT *dht, const Node_format *node, void *user_data); |
307 | | |
308 | | /** Sets the callback to be triggered on a getnodes response. */ |
309 | | non_null(1) nullable(2) |
310 | | void dht_callback_get_nodes_response(DHT *dht, dht_get_nodes_response_cb *function); |
311 | | |
312 | | /** @brief Add a new friend to the friends list. |
313 | | * @param public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. |
314 | | * |
315 | | * @param ip_callback is the callback of a function that will be called when the ip address |
316 | | * is found along with arguments data and number. |
317 | | * @param data User data for the callback |
318 | | * @param number Will be passed to ip_callback |
319 | | * |
320 | | * @param lock_token will be set to a non zero number that must be passed to `dht_delfriend()` |
321 | | * to properly remove the callback. |
322 | | * |
323 | | * @retval 0 if success. |
324 | | * @retval -1 if failure (friends list is full). |
325 | | */ |
326 | | non_null(1, 2, 6) nullable(3, 4) |
327 | | int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, |
328 | | void *data, int32_t number, uint32_t *lock_token); |
329 | | |
330 | | /** @brief Delete a friend from the friends list. |
331 | | * public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. |
332 | | * @param dht The DHT object |
333 | | * @param public_key The public key of the friend |
334 | | * @param lock_token The token received by dht_addfriend(...) |
335 | | * |
336 | | * @retval 0 if success. |
337 | | * @retval -1 if failure (public_key not in friends list). |
338 | | */ |
339 | | non_null() |
340 | | int dht_delfriend(DHT *dht, const uint8_t *public_key, uint32_t lock_token); |
341 | | |
342 | | /** @brief Get ip of friend. |
343 | | * |
344 | | * @param public_key must be CRYPTO_PUBLIC_KEY_SIZE bytes long. |
345 | | * |
346 | | * @retval -1 if public_key does NOT refer to a friend |
347 | | * @retval 0 if public_key refers to a friend and we failed to find the friend (yet) |
348 | | * @retval 1 if public_key refers to a friend and we found him |
349 | | */ |
350 | | non_null() |
351 | | int dht_getfriendip(const DHT *dht, const uint8_t *public_key, IP_Port *ip_port); |
352 | | |
353 | | /** @brief Compares pk1 and pk2 with pk. |
354 | | * |
355 | | * @retval 0 if both are same distance. |
356 | | * @retval 1 if pk1 is closer. |
357 | | * @retval 2 if pk2 is closer. |
358 | | */ |
359 | | non_null() |
360 | | int id_closest(const uint8_t *pk, const uint8_t *pk1, const uint8_t *pk2); |
361 | | |
362 | | /** Return index of first unequal bit number between public keys pk1 and pk2. */ |
363 | | non_null() |
364 | | unsigned int bit_by_bit_cmp(const uint8_t *pk1, const uint8_t *pk2); |
365 | | |
366 | | /** |
367 | | * Add node to the node list making sure only the nodes closest to cmp_pk are in the list. |
368 | | * |
369 | | * @return true iff the node was added to the list. |
370 | | */ |
371 | | non_null() |
372 | | bool add_to_list( |
373 | | Node_format *nodes_list, uint32_t length, const uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE], |
374 | | const IP_Port *ip_port, const uint8_t cmp_pk[CRYPTO_PUBLIC_KEY_SIZE]); |
375 | | |
376 | | /** Return 1 if node can be added to close list, 0 if it can't. */ |
377 | | non_null() |
378 | | bool node_addable_to_close_list(DHT *dht, const uint8_t *public_key, const IP_Port *ip_port); |
379 | | |
380 | | #ifdef CHECK_ANNOUNCE_NODE |
381 | | /** Set node as announce node. */ |
382 | | non_null() |
383 | | void set_announce_node(DHT *dht, const uint8_t *public_key); |
384 | | #endif /* CHECK_ANNOUNCE_NODE */ |
385 | | |
386 | | /** |
387 | | * @brief Get the (maximum MAX_SENT_NODES) closest nodes to public_key we know |
388 | | * and put them in nodes_list (must be MAX_SENT_NODES big). |
389 | | * |
390 | | * @param sa_family family (IPv4 or IPv6) (0 if we don't care)? |
391 | | * @param is_lan return some LAN ips (true or false). |
392 | | * @param want_announce return only nodes which implement the dht announcements protocol. |
393 | | * |
394 | | * @return the number of nodes returned. |
395 | | */ |
396 | | non_null() |
397 | | int get_close_nodes( |
398 | | const DHT *dht, const uint8_t *public_key, |
399 | | Node_format nodes_list[MAX_SENT_NODES], Family sa_family, |
400 | | bool is_lan, bool want_announce); |
401 | | |
402 | | |
403 | | /** @brief Put up to max_num nodes in nodes from the random friends. |
404 | | * |
405 | | * Important: this function relies on the first two DHT friends *not* being real |
406 | | * friends to avoid leaking information about real friends into the onion paths. |
407 | | * |
408 | | * @return the number of nodes. |
409 | | */ |
410 | | non_null() |
411 | | uint16_t randfriends_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num); |
412 | | |
413 | | /** @brief Put up to max_num nodes in nodes from the closelist. |
414 | | * |
415 | | * @return the number of nodes. |
416 | | */ |
417 | | non_null() |
418 | | uint16_t closelist_nodes(const DHT *dht, Node_format *nodes, uint16_t max_num); |
419 | | |
420 | | /** Run this function at least a couple times per second (It's the main loop). */ |
421 | | non_null() |
422 | | void do_dht(DHT *dht); |
423 | | |
424 | | /* |
425 | | * Use these two functions to bootstrap the client. |
426 | | */ |
427 | | /** |
428 | | * @brief Sends a "get nodes" request to the given node with ip, port and public_key |
429 | | * to setup connections |
430 | | */ |
431 | | non_null() |
432 | | bool dht_bootstrap(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key); |
433 | | |
434 | | /** @brief Resolves address into an IP address. |
435 | | * |
436 | | * If successful, sends a "get nodes" request to the given node with ip, port |
437 | | * and public_key to setup connections |
438 | | * |
439 | | * @param address can be a hostname or an IP address (IPv4 or IPv6). |
440 | | * @param ipv6enabled if false, the resolving sticks STRICTLY to IPv4 addresses. |
441 | | * Otherwise, the resolving looks for IPv6 addresses first, then IPv4 addresses. |
442 | | * |
443 | | * @retval 1 if the address could be converted into an IP address |
444 | | * @retval 0 otherwise |
445 | | */ |
446 | | non_null() |
447 | | int dht_bootstrap_from_address(DHT *dht, const char *address, bool ipv6enabled, |
448 | | uint16_t port, const uint8_t *public_key); |
449 | | |
450 | | /** @brief Start sending packets after DHT loaded_friends_list and loaded_clients_list are set. |
451 | | * |
452 | | * @retval 0 if successful |
453 | | * @retval -1 otherwise |
454 | | */ |
455 | | non_null() |
456 | | int dht_connect_after_load(DHT *dht); |
457 | | |
458 | | /* ROUTING FUNCTIONS */ |
459 | | |
460 | | /** @brief Send the given packet to node with public_key. |
461 | | * |
462 | | * @return number of bytes sent. |
463 | | * @retval -1 if failure. |
464 | | */ |
465 | | non_null() |
466 | | int route_packet(const DHT *dht, const uint8_t *public_key, const uint8_t *packet, uint16_t length); |
467 | | |
468 | | /** |
469 | | * Send the following packet to everyone who tells us they are connected to friend_id. |
470 | | * |
471 | | * @return ip for friend. |
472 | | * @return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4). |
473 | | */ |
474 | | non_null() |
475 | | uint32_t route_to_friend(const DHT *dht, const uint8_t *friend_id, const Packet *packet); |
476 | | |
477 | | /** Function to handle crypto packets. */ |
478 | | non_null(1) nullable(3, 4) |
479 | | void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_cb *cb, void *object); |
480 | | |
481 | | /* SAVE/LOAD functions */ |
482 | | |
483 | | /** Get the size of the DHT (for saving). */ |
484 | | non_null() |
485 | | uint32_t dht_size(const DHT *dht); |
486 | | |
487 | | /** Save the DHT in data where data is an array of size `dht_size()`. */ |
488 | | non_null() |
489 | | void dht_save(const DHT *dht, uint8_t *data); |
490 | | |
491 | | /** @brief Load the DHT from data of size size. |
492 | | * |
493 | | * @retval -1 if failure. |
494 | | * @retval 0 if success. |
495 | | */ |
496 | | non_null() |
497 | | int dht_load(DHT *dht, const uint8_t *data, uint32_t length); |
498 | | |
499 | | /** Initialize DHT. */ |
500 | | non_null() |
501 | | DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, |
502 | | Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled); |
503 | | |
504 | | nullable(1) |
505 | | void kill_dht(DHT *dht); |
506 | | |
507 | | /** |
508 | | * @retval false if we are not connected to the DHT. |
509 | | * @retval true if we are. |
510 | | */ |
511 | | non_null() |
512 | | bool dht_isconnected(const DHT *dht); |
513 | | |
514 | | /** |
515 | | * @retval false if we are not connected or only connected to lan peers with the DHT. |
516 | | * @retval true if we are. |
517 | | */ |
518 | | non_null() |
519 | | bool dht_non_lan_connected(const DHT *dht); |
520 | | |
521 | | /** |
522 | | * This function returns the ratio of close dht nodes that are known to support announce/store. |
523 | | * This function returns the number of DHT nodes in the closelist. |
524 | | * |
525 | | * @return number |
526 | | */ |
527 | | non_null() |
528 | | uint16_t dht_get_num_closelist(const DHT *dht); |
529 | | |
530 | | /** |
531 | | * This function returns the number of DHT nodes in the closelist, |
532 | | * that are capable to store annouce data (introduced in version 0.2.18). |
533 | | * |
534 | | * @return number |
535 | | */ |
536 | | non_null() |
537 | | uint16_t dht_get_num_closelist_announce_capable(const DHT *dht); |
538 | | |
539 | | /** @brief Attempt to add client with ip_port and public_key to the friends client list |
540 | | * and close_clientlist. |
541 | | * |
542 | | * @return 1+ if the item is used in any list, 0 else |
543 | | */ |
544 | | non_null() |
545 | | uint32_t addto_lists(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key); |
546 | | |
547 | | /** @brief Copies our own ip_port structure to `dest`. |
548 | | * |
549 | | * WAN addresses take priority over LAN addresses. |
550 | | * |
551 | | * This function will zero the `dest` buffer before use. |
552 | | * |
553 | | * @retval 0 if our ip port can't be found (this usually means we're not connected to the DHT). |
554 | | * @retval 1 if IP is a WAN address. |
555 | | * @retval 2 if IP is a LAN address. |
556 | | */ |
557 | | non_null() |
558 | | unsigned int ipport_self_copy(const DHT *dht, IP_Port *dest); |
559 | | |
560 | | #ifdef __cplusplus |
561 | | } /* extern "C" */ |
562 | | #endif |
563 | | |
564 | | #endif /* C_TOXCORE_TOXCORE_DHT_H */ |