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