diff options
Diffstat (limited to 'toxcore/DHT.c')
-rw-r--r-- | toxcore/DHT.c | 587 |
1 files changed, 318 insertions, 269 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 870e6ca2..7534387a 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -165,15 +165,15 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, uint8_t *secr | |||
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
168 | /* Copy shared_key to decrypt DHT packet from client_id into shared_key | 168 | /* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key |
169 | * for packets that we recieve. | 169 | * for packets that we receive. |
170 | */ | 170 | */ |
171 | void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id) | 171 | void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, uint8_t *client_id) |
172 | { | 172 | { |
173 | return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id); | 173 | return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id); |
174 | } | 174 | } |
175 | 175 | ||
176 | /* Copy shared_key to decrypt DHT packet from client_id into shared_key | 176 | /* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key |
177 | * for packets that we send. | 177 | * for packets that we send. |
178 | */ | 178 | */ |
179 | void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id) | 179 | void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id) |
@@ -181,6 +181,155 @@ void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, uint8_t *client_id) | |||
181 | return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id); | 181 | return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id); |
182 | } | 182 | } |
183 | 183 | ||
184 | void to_net_family(IP *ip) | ||
185 | { | ||
186 | if (ip->family == AF_INET) | ||
187 | ip->family = TOX_AF_INET; | ||
188 | else if (ip->family == AF_INET6) | ||
189 | ip->family = TOX_AF_INET6; | ||
190 | } | ||
191 | |||
192 | void to_host_family(IP *ip) | ||
193 | { | ||
194 | if (ip->family == TOX_AF_INET) | ||
195 | ip->family = AF_INET; | ||
196 | else if (ip->family == TOX_AF_INET6) | ||
197 | ip->family = AF_INET6; | ||
198 | } | ||
199 | |||
200 | /* Pack number of nodes into data of maxlength length. | ||
201 | * | ||
202 | * return length of packed nodes on success. | ||
203 | * return -1 on failure. | ||
204 | */ | ||
205 | int pack_nodes(uint8_t *data, uint16_t length, Node_format *nodes, uint16_t number) | ||
206 | { | ||
207 | uint32_t i, packed_length = 0; | ||
208 | |||
209 | for (i = 0; i < number; ++i) { | ||
210 | int ipv6 = -1; | ||
211 | uint8_t net_family; | ||
212 | |||
213 | if (nodes[i].ip_port.ip.family == AF_INET) { | ||
214 | ipv6 = 0; | ||
215 | net_family = TOX_AF_INET; | ||
216 | } else if (nodes[i].ip_port.ip.family == TCP_INET) { | ||
217 | ipv6 = 0; | ||
218 | net_family = TOX_TCP_INET; | ||
219 | } else if (nodes[i].ip_port.ip.family == AF_INET6) { | ||
220 | ipv6 = 1; | ||
221 | net_family = TOX_AF_INET6; | ||
222 | } else if (nodes[i].ip_port.ip.family == TCP_INET6) { | ||
223 | ipv6 = 1; | ||
224 | net_family = TOX_TCP_INET6; | ||
225 | } else { | ||
226 | return -1; | ||
227 | } | ||
228 | |||
229 | if (ipv6 == 0) { | ||
230 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; | ||
231 | |||
232 | if (packed_length + size > length) | ||
233 | return -1; | ||
234 | |||
235 | data[packed_length] = net_family; | ||
236 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip4, sizeof(IP4)); | ||
237 | memcpy(data + packed_length + 1 + sizeof(IP4), &nodes[i].ip_port.port, sizeof(uint16_t)); | ||
238 | memcpy(data + packed_length + 1 + sizeof(IP4) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); | ||
239 | packed_length += size; | ||
240 | } else if (ipv6 == 1) { | ||
241 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; | ||
242 | |||
243 | if (packed_length + size > length) | ||
244 | return -1; | ||
245 | |||
246 | data[packed_length] = net_family; | ||
247 | memcpy(data + packed_length + 1, &nodes[i].ip_port.ip.ip6, sizeof(IP6)); | ||
248 | memcpy(data + packed_length + 1 + sizeof(IP6), &nodes[i].ip_port.port, sizeof(uint16_t)); | ||
249 | memcpy(data + packed_length + 1 + sizeof(IP6) + sizeof(uint16_t), nodes[i].client_id, CLIENT_ID_SIZE); | ||
250 | packed_length += size; | ||
251 | } else { | ||
252 | return -1; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | return packed_length; | ||
257 | } | ||
258 | |||
259 | /* Unpack data of length into nodes of size max_num_nodes. | ||
260 | * Put the length of the data processed in processed_data_len. | ||
261 | * tcp_enabled sets if TCP nodes are expected (true) or not (false). | ||
262 | * | ||
263 | * return number of unpacked nodes on success. | ||
264 | * return -1 on failure. | ||
265 | */ | ||
266 | int unpack_nodes(Node_format *nodes, uint16_t max_num_nodes, uint16_t *processed_data_len, uint8_t *data, | ||
267 | uint16_t length, uint8_t tcp_enabled) | ||
268 | { | ||
269 | uint32_t num = 0, len_processed = 0; | ||
270 | |||
271 | while (num < max_num_nodes && len_processed < length) { | ||
272 | int ipv6 = -1; | ||
273 | uint8_t host_family; | ||
274 | |||
275 | if (data[len_processed] == TOX_AF_INET) { | ||
276 | ipv6 = 0; | ||
277 | host_family = AF_INET; | ||
278 | } else if (data[len_processed] == TOX_TCP_INET) { | ||
279 | if (!tcp_enabled) | ||
280 | return -1; | ||
281 | |||
282 | ipv6 = 0; | ||
283 | host_family = TCP_INET; | ||
284 | } else if (data[len_processed] == TOX_AF_INET6) { | ||
285 | ipv6 = 1; | ||
286 | host_family = AF_INET6; | ||
287 | } else if (data[len_processed] == TOX_TCP_INET6) { | ||
288 | if (!tcp_enabled) | ||
289 | return -1; | ||
290 | |||
291 | ipv6 = 1; | ||
292 | host_family = TCP_INET6; | ||
293 | } else { | ||
294 | return -1; | ||
295 | } | ||
296 | |||
297 | if (ipv6 == 0) { | ||
298 | uint32_t size = 1 + sizeof(IP4) + sizeof(uint16_t) + CLIENT_ID_SIZE; | ||
299 | |||
300 | if (len_processed + size > length) | ||
301 | return -1; | ||
302 | |||
303 | nodes[num].ip_port.ip.family = host_family; | ||
304 | memcpy(&nodes[num].ip_port.ip.ip4, data + len_processed + 1, sizeof(IP4)); | ||
305 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP4), sizeof(uint16_t)); | ||
306 | memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP4) + sizeof(uint16_t), CLIENT_ID_SIZE); | ||
307 | len_processed += size; | ||
308 | ++num; | ||
309 | } else if (ipv6 == 1) { | ||
310 | uint32_t size = 1 + sizeof(IP6) + sizeof(uint16_t) + CLIENT_ID_SIZE; | ||
311 | |||
312 | if (len_processed + size > length) | ||
313 | return -1; | ||
314 | |||
315 | nodes[num].ip_port.ip.family = host_family; | ||
316 | memcpy(&nodes[num].ip_port.ip.ip6, data + len_processed + 1, sizeof(IP6)); | ||
317 | memcpy(&nodes[num].ip_port.port, data + len_processed + 1 + sizeof(IP6), sizeof(uint16_t)); | ||
318 | memcpy(nodes[num].client_id, data + len_processed + 1 + sizeof(IP6) + sizeof(uint16_t), CLIENT_ID_SIZE); | ||
319 | len_processed += size; | ||
320 | ++num; | ||
321 | } else { | ||
322 | return -1; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | if (processed_data_len) | ||
327 | *processed_data_len = len_processed; | ||
328 | |||
329 | return num; | ||
330 | } | ||
331 | |||
332 | |||
184 | 333 | ||
185 | /* Check if client with client_id is already in list of length length. | 334 | /* Check if client with client_id is already in list of length length. |
186 | * If it is then set its corresponding timestamp to current time. | 335 | * If it is then set its corresponding timestamp to current time. |
@@ -266,7 +415,7 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t | |||
266 | /* Check if client with client_id is already in node format list of length length. | 415 | /* Check if client with client_id is already in node format list of length length. |
267 | * | 416 | * |
268 | * return 1 if true. | 417 | * return 1 if true. |
269 | * return 2 if false. | 418 | * return 0 if false. |
270 | */ | 419 | */ |
271 | static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) | 420 | static int client_in_nodelist(Node_format *list, uint32_t length, uint8_t *client_id) |
272 | { | 421 | { |
@@ -310,15 +459,15 @@ static uint8_t hardening_correct(Hardening *h) | |||
310 | /* | 459 | /* |
311 | * helper for get_close_nodes(). argument list is a monster :D | 460 | * helper for get_close_nodes(). argument list is a monster :D |
312 | */ | 461 | */ |
313 | static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nodes_list, | 462 | static void get_close_nodes_inner(uint8_t *client_id, Node_format *nodes_list, |
314 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, | 463 | sa_family_t sa_family, Client_data *client_list, uint32_t client_list_length, |
315 | uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) | 464 | uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) |
316 | { | 465 | { |
317 | if ((sa_family != AF_INET) && (sa_family != AF_INET6)) | 466 | if ((sa_family != AF_INET) && (sa_family != AF_INET6) && (sa_family != 0)) |
318 | return; | 467 | return; |
319 | 468 | ||
320 | uint32_t num_nodes = *num_nodes_ptr; | 469 | uint32_t num_nodes = *num_nodes_ptr; |
321 | int ipv46x, j, closest; | 470 | int j, closest; |
322 | uint32_t i; | 471 | uint32_t i; |
323 | 472 | ||
324 | for (i = 0; i < client_list_length; i++) { | 473 | for (i = 0; i < client_list_length; i++) { |
@@ -330,39 +479,22 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod | |||
330 | 479 | ||
331 | IPPTsPng *ipptp = NULL; | 480 | IPPTsPng *ipptp = NULL; |
332 | 481 | ||
333 | if (sa_family == AF_INET) | 482 | if (sa_family == AF_INET) { |
334 | ipptp = &client->assoc4; | 483 | ipptp = &client->assoc4; |
335 | else | 484 | } else if (sa_family == AF_INET6) { |
336 | ipptp = &client->assoc6; | 485 | ipptp = &client->assoc6; |
486 | } else { | ||
487 | if (client->assoc4.timestamp >= client->assoc6.timestamp) { | ||
488 | ipptp = &client->assoc4; | ||
489 | } else { | ||
490 | ipptp = &client->assoc6; | ||
491 | } | ||
492 | } | ||
337 | 493 | ||
338 | /* node not in a good condition? */ | 494 | /* node not in a good condition? */ |
339 | if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) | 495 | if (is_timeout(ipptp->timestamp, BAD_NODE_TIMEOUT)) |
340 | continue; | 496 | continue; |
341 | 497 | ||
342 | IP *client_ip = &ipptp->ip_port.ip; | ||
343 | |||
344 | /* | ||
345 | * Careful: AF_INET isn't seen as AF_INET on dual-stack sockets for | ||
346 | * our connections, instead we have to look if it is an embedded | ||
347 | * IPv4-in-IPv6 here and convert it down in sendnodes(). | ||
348 | */ | ||
349 | sa_family_t ip_treat_as_family = client_ip->family; | ||
350 | |||
351 | if ((dht->net->family == AF_INET6) && | ||
352 | (client_ip->family == AF_INET6)) { | ||
353 | /* socket is AF_INET6, address claims AF_INET6: | ||
354 | * check for embedded IPv4-in-IPv6 (shouldn't happen anymore, | ||
355 | * all storing functions should already convert down to IPv4) */ | ||
356 | if (IN6_IS_ADDR_V4MAPPED(&client_ip->ip6.in6_addr)) | ||
357 | ip_treat_as_family = AF_INET; | ||
358 | } | ||
359 | |||
360 | ipv46x = !(sa_family == ip_treat_as_family); | ||
361 | |||
362 | /* node address of the wrong family? */ | ||
363 | if (ipv46x) | ||
364 | continue; | ||
365 | |||
366 | /* don't send LAN ips to non LAN peers */ | 498 | /* don't send LAN ips to non LAN peers */ |
367 | if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) | 499 | if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) |
368 | continue; | 500 | continue; |
@@ -416,7 +548,7 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n | |||
416 | uint8_t is_LAN, uint8_t want_good) | 548 | uint8_t is_LAN, uint8_t want_good) |
417 | { | 549 | { |
418 | uint32_t num_nodes = 0, i; | 550 | uint32_t num_nodes = 0, i; |
419 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 551 | get_close_nodes_inner(client_id, nodes_list, sa_family, |
420 | dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); | 552 | dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); |
421 | 553 | ||
422 | /*TODO uncomment this when hardening is added to close friend clients | 554 | /*TODO uncomment this when hardening is added to close friend clients |
@@ -426,7 +558,7 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n | |||
426 | &num_nodes, is_LAN, want_good); | 558 | &num_nodes, is_LAN, want_good); |
427 | */ | 559 | */ |
428 | for (i = 0; i < dht->num_friends; ++i) | 560 | for (i = 0; i < dht->num_friends; ++i) |
429 | get_close_nodes_inner(dht, client_id, nodes_list, sa_family, | 561 | get_close_nodes_inner(client_id, nodes_list, sa_family, |
430 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, | 562 | dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, |
431 | &num_nodes, is_LAN, 0); | 563 | &num_nodes, is_LAN, 0); |
432 | 564 | ||
@@ -444,6 +576,7 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa | |||
444 | return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); | 576 | return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); |
445 | 577 | ||
446 | #ifdef ENABLE_ASSOC_DHT | 578 | #ifdef ENABLE_ASSOC_DHT |
579 | //TODO: assoc, sa_family 0 (don't care if ipv4 or ipv6) support. | ||
447 | Client_data *result[MAX_SENT_NODES]; | 580 | Client_data *result[MAX_SENT_NODES]; |
448 | 581 | ||
449 | Assoc_close_entries request; | 582 | Assoc_close_entries request; |
@@ -581,7 +714,7 @@ static int replace_possible_bad( Client_data *list, | |||
581 | 714 | ||
582 | sort_list(list, length, comp_client_id); | 715 | sort_list(list, length, comp_client_id); |
583 | 716 | ||
584 | /* TODO: decide if the folowing lines should stay commented or not. | 717 | /* TODO: decide if the following lines should stay commented or not. |
585 | if (id_closest(comp_client_id, list[0].client_id, client_id) == 1) | 718 | if (id_closest(comp_client_id, list[0].client_id, client_id) == 1) |
586 | return 0;*/ | 719 | return 0;*/ |
587 | 720 | ||
@@ -823,7 +956,7 @@ end: | |||
823 | return 0; | 956 | return 0; |
824 | } | 957 | } |
825 | 958 | ||
826 | #define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_secretbox_MACBYTES) | 959 | #define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_box_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_box_MACBYTES) |
827 | 960 | ||
828 | /* Send a getnodes request. | 961 | /* Send a getnodes request. |
829 | sendback_node is the node that it will send back the response to (set to NULL to disable this) */ | 962 | sendback_node is the node that it will send back the response to (set to NULL to disable this) */ |
@@ -842,23 +975,23 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
842 | 975 | ||
843 | uint64_t temp_time = unix_time(); | 976 | uint64_t temp_time = unix_time(); |
844 | memcpy(plain_message, &temp_time, sizeof(temp_time)); | 977 | memcpy(plain_message, &temp_time, sizeof(temp_time)); |
845 | Node_format reciever; | 978 | Node_format receiver; |
846 | memcpy(reciever.client_id, public_key, CLIENT_ID_SIZE); | 979 | memcpy(receiver.client_id, public_key, CLIENT_ID_SIZE); |
847 | reciever.ip_port = ip_port; | 980 | receiver.ip_port = ip_port; |
848 | memcpy(plain_message + sizeof(temp_time), &reciever, sizeof(reciever)); | 981 | memcpy(plain_message + sizeof(temp_time), &receiver, sizeof(receiver)); |
849 | 982 | ||
850 | if (sendback_node != NULL) | 983 | if (sendback_node != NULL) |
851 | memcpy(plain_message + sizeof(temp_time) + sizeof(reciever), sendback_node, sizeof(Node_format)); | 984 | memcpy(plain_message + sizeof(temp_time) + sizeof(receiver), sendback_node, sizeof(Node_format)); |
852 | else | 985 | else |
853 | memset(plain_message + sizeof(temp_time) + sizeof(reciever), 0, sizeof(Node_format)); | 986 | memset(plain_message + sizeof(temp_time) + sizeof(receiver), 0, sizeof(Node_format)); |
854 | 987 | ||
855 | int len_m = encrypt_data_symmetric(dht->secret_symmetric_key, | 988 | int len_m = encrypt_data_symmetric(dht->secret_symmetric_key, |
856 | nonce, | 989 | nonce, |
857 | plain_message, | 990 | plain_message, |
858 | sizeof(temp_time) + sizeof(reciever) + sizeof(Node_format), | 991 | sizeof(temp_time) + sizeof(receiver) + sizeof(Node_format), |
859 | encrypted_message + crypto_secretbox_NONCEBYTES); | 992 | encrypted_message + crypto_box_NONCEBYTES); |
860 | 993 | ||
861 | if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES) | 994 | if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_box_NONCEBYTES) |
862 | return -1; | 995 | return -1; |
863 | 996 | ||
864 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | 997 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; |
@@ -871,11 +1004,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
871 | 1004 | ||
872 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | 1005 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
873 | DHT_get_shared_key_sent(dht, shared_key, public_key); | 1006 | DHT_get_shared_key_sent(dht, shared_key, public_key); |
874 | int len = encrypt_data_fast( shared_key, | 1007 | int len = encrypt_data_symmetric( shared_key, |
875 | nonce, | 1008 | nonce, |
876 | plain, | 1009 | plain, |
877 | CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, | 1010 | CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, |
878 | encrypt ); | 1011 | encrypt ); |
879 | 1012 | ||
880 | if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) | 1013 | if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) |
881 | return -1; | 1014 | return -1; |
@@ -888,132 +1021,46 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli | |||
888 | return sendpacket(dht->net, ip_port, data, sizeof(data)); | 1021 | return sendpacket(dht->net, ip_port, data, sizeof(data)); |
889 | } | 1022 | } |
890 | 1023 | ||
891 | /* Send a send nodes response. */ | 1024 | /* Send a send nodes response: message for IPv6 nodes */ |
892 | /* because of BINARY compatibility, the Node_format MUST BE Node4_format, | 1025 | static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *sendback_data, |
893 | * IPv6 nodes are sent in a different message | 1026 | uint16_t length, uint8_t *shared_encryption_key) |
894 | * encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH */ | ||
895 | static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data, | ||
896 | uint8_t *shared_encryption_key) | ||
897 | { | 1027 | { |
898 | /* Check if packet is going to be sent to ourself. */ | 1028 | /* Check if packet is going to be sent to ourself. */ |
899 | if (id_equal(public_key, dht->self_public_key)) | 1029 | if (id_equal(public_key, dht->self_public_key)) |
900 | return -1; | 1030 | return -1; |
901 | 1031 | ||
902 | size_t Node4_format_size = sizeof(Node4_format); | 1032 | if (length > NODES_ENCRYPTED_MESSAGE_LENGTH || length == 0) |
903 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | ||
904 | + Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | ||
905 | |||
906 | Node_format nodes_list[MAX_SENT_NODES]; | ||
907 | uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0, 1); | ||
908 | |||
909 | if (num_nodes == 0) | ||
910 | return 0; | ||
911 | |||
912 | uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
913 | uint8_t encrypt[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | ||
914 | uint8_t nonce[crypto_box_NONCEBYTES]; | ||
915 | new_nonce(nonce); | ||
916 | |||
917 | Node4_format *nodes4_list = (Node4_format *)(plain); | ||
918 | uint32_t i, num_nodes_ok = 0; | ||
919 | |||
920 | for (i = 0; i < num_nodes; i++) { | ||
921 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); | ||
922 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; | ||
923 | |||
924 | IP *node_ip = &nodes_list[i].ip_port.ip; | ||
925 | |||
926 | if ((node_ip->family == AF_INET6) && IN6_IS_ADDR_V4MAPPED(&node_ip->ip6.in6_addr)) | ||
927 | /* embedded IPv4-in-IPv6 address: return it in regular sendnodes packet */ | ||
928 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip6.uint32[3]; | ||
929 | else if (node_ip->family == AF_INET) | ||
930 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = node_ip->ip4.uint32; | ||
931 | else /* shouldn't happen */ | ||
932 | continue; | ||
933 | |||
934 | num_nodes_ok++; | ||
935 | } | ||
936 | |||
937 | if (num_nodes_ok < num_nodes) { | ||
938 | /* shouldn't happen */ | ||
939 | num_nodes = num_nodes_ok; | ||
940 | } | ||
941 | |||
942 | memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); | ||
943 | int len = encrypt_data_fast( shared_encryption_key, | ||
944 | nonce, | ||
945 | plain, | ||
946 | num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, | ||
947 | encrypt ); | ||
948 | |||
949 | if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + | ||
950 | crypto_box_MACBYTES) | ||
951 | return -1; | ||
952 | |||
953 | data[0] = NET_PACKET_SEND_NODES; | ||
954 | memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE); | ||
955 | memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); | ||
956 | memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); | ||
957 | |||
958 | return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); | ||
959 | } | ||
960 | |||
961 | void to_net_family(IP *ip) | ||
962 | { | ||
963 | ip->padding[0] = 0; | ||
964 | ip->padding[1] = 0; | ||
965 | ip->padding[2] = 0; | ||
966 | |||
967 | if (ip->family == AF_INET) | ||
968 | ip->family = TOX_AF_INET; | ||
969 | else if (ip->family == AF_INET6) | ||
970 | ip->family = TOX_AF_INET6; | ||
971 | } | ||
972 | |||
973 | void to_host_family(IP *ip) | ||
974 | { | ||
975 | if (ip->family == TOX_AF_INET) | ||
976 | ip->family = AF_INET; | ||
977 | else if (ip->family == TOX_AF_INET6) | ||
978 | ip->family = AF_INET6; | ||
979 | } | ||
980 | /* Send a send nodes response: message for IPv6 nodes */ | ||
981 | static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data, | ||
982 | uint8_t *shared_encryption_key) | ||
983 | { | ||
984 | /* Check if packet is going to be sent to ourself. */ | ||
985 | if (id_equal(public_key, dht->self_public_key)) | ||
986 | return -1; | 1033 | return -1; |
987 | 1034 | ||
988 | size_t Node_format_size = sizeof(Node_format); | 1035 | size_t Node_format_size = sizeof(Node_format); |
989 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES | 1036 | uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES |
990 | + Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | 1037 | + Node_format_size * MAX_SENT_NODES + length + crypto_box_MACBYTES]; |
991 | 1038 | ||
992 | Node_format nodes_list[MAX_SENT_NODES]; | 1039 | Node_format nodes_list[MAX_SENT_NODES]; |
993 | uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0, 1); | 1040 | uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, LAN_ip(ip_port.ip) == 0, 1); |
994 | 1041 | ||
995 | if (num_nodes == 0) | 1042 | if (num_nodes == 0) |
996 | return 0; | 1043 | return 0; |
997 | 1044 | ||
998 | uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | 1045 | uint8_t plain[1 + Node_format_size * MAX_SENT_NODES + length]; |
999 | uint8_t encrypt[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES]; | 1046 | uint8_t encrypt[sizeof(plain) + crypto_box_MACBYTES]; |
1000 | uint8_t nonce[crypto_box_NONCEBYTES]; | 1047 | uint8_t nonce[crypto_box_NONCEBYTES]; |
1001 | new_nonce(nonce); | 1048 | new_nonce(nonce); |
1002 | 1049 | ||
1003 | uint32_t i; | 1050 | int nodes_length = pack_nodes(plain + 1, Node_format_size * MAX_SENT_NODES, nodes_list, num_nodes); |
1004 | 1051 | ||
1005 | for (i = 0; i < num_nodes; ++i) | 1052 | if (nodes_length <= 0) |
1006 | to_net_family(&nodes_list[i].ip_port.ip); | 1053 | return -1; |
1007 | 1054 | ||
1008 | memcpy(plain, nodes_list, num_nodes * Node_format_size); | 1055 | plain[0] = num_nodes; |
1009 | memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); | 1056 | memcpy(plain + 1 + nodes_length, sendback_data, length); |
1010 | int len = encrypt_data_fast( shared_encryption_key, | 1057 | int len = encrypt_data_symmetric( shared_encryption_key, |
1011 | nonce, | 1058 | nonce, |
1012 | plain, | 1059 | plain, |
1013 | num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, | 1060 | 1 + nodes_length + length, |
1014 | encrypt ); | 1061 | encrypt ); |
1015 | 1062 | ||
1016 | if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES) | 1063 | if (len != 1 + nodes_length + length + crypto_box_MACBYTES) |
1017 | return -1; | 1064 | return -1; |
1018 | 1065 | ||
1019 | data[0] = NET_PACKET_SEND_NODES_IPV6; | 1066 | data[0] = NET_PACKET_SEND_NODES_IPV6; |
@@ -1026,35 +1073,38 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_ | |||
1026 | 1073 | ||
1027 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 1074 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
1028 | { | 1075 | { |
1029 | DHT *dht = object; | 1076 | uint32_t cmp_len = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + crypto_box_MACBYTES; |
1077 | |||
1078 | if (length <= cmp_len) | ||
1079 | return 1; | ||
1030 | 1080 | ||
1031 | if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + | 1081 | if (length > cmp_len + NODES_ENCRYPTED_MESSAGE_LENGTH) |
1032 | crypto_box_MACBYTES )) | ||
1033 | return 1; | 1082 | return 1; |
1034 | 1083 | ||
1084 | uint16_t sendback_data_length = length - cmp_len; | ||
1085 | |||
1086 | DHT *dht = object; | ||
1087 | |||
1035 | /* Check if packet is from ourself. */ | 1088 | /* Check if packet is from ourself. */ |
1036 | if (id_equal(packet + 1, dht->self_public_key)) | 1089 | if (id_equal(packet + 1, dht->self_public_key)) |
1037 | return 1; | 1090 | return 1; |
1038 | 1091 | ||
1039 | uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH]; | 1092 | uint8_t plain[CLIENT_ID_SIZE + sendback_data_length]; |
1040 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | 1093 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
1041 | 1094 | ||
1042 | DHT_get_shared_key_recv(dht, shared_key, packet + 1); | 1095 | DHT_get_shared_key_recv(dht, shared_key, packet + 1); |
1043 | int len = decrypt_data_fast( shared_key, | 1096 | int len = decrypt_data_symmetric( shared_key, |
1044 | packet + 1 + CLIENT_ID_SIZE, | 1097 | packet + 1 + CLIENT_ID_SIZE, |
1045 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 1098 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
1046 | CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, | 1099 | CLIENT_ID_SIZE + sendback_data_length + crypto_box_MACBYTES, |
1047 | plain ); | 1100 | plain ); |
1048 | 1101 | ||
1049 | if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH) | 1102 | if (len != CLIENT_ID_SIZE + sendback_data_length) |
1050 | return 1; | 1103 | return 1; |
1051 | 1104 | ||
1052 | sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE, shared_key); | 1105 | sendnodes_ipv6(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE, sendback_data_length, shared_key); |
1053 | sendnodes_ipv6(dht, source, packet + 1, plain, | ||
1054 | plain + CLIENT_ID_SIZE, shared_key); /* TODO: prevent possible amplification attacks */ | ||
1055 | 1106 | ||
1056 | add_to_ping(dht->ping, packet + 1, source); | 1107 | add_to_ping(dht->ping, packet + 1, source); |
1057 | //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ | ||
1058 | 1108 | ||
1059 | return 0; | 1109 | return 0; |
1060 | } | 1110 | } |
@@ -1066,8 +1116,8 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i | |||
1066 | { | 1116 | { |
1067 | uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH]; | 1117 | uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH]; |
1068 | 1118 | ||
1069 | if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_secretbox_NONCEBYTES, | 1119 | if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_box_NONCEBYTES, |
1070 | NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, | 1120 | NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_box_NONCEBYTES, |
1071 | plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) | 1121 | plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) |
1072 | return 0; | 1122 | return 0; |
1073 | 1123 | ||
@@ -1089,124 +1139,87 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i | |||
1089 | } | 1139 | } |
1090 | 1140 | ||
1091 | /* Function is needed in following functions. */ | 1141 | /* Function is needed in following functions. */ |
1092 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, Node_format *list, | 1142 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, uint8_t *nodes_data, |
1093 | uint16_t num_nodes); | 1143 | uint16_t nodes_data_length); |
1094 | 1144 | ||
1095 | static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length, | 1145 | static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet, uint32_t length, |
1096 | size_t node_format_size, uint8_t *plain, uint16_t plain_length, uint32_t *num_nodes_out, Node_format *sendback_node) | 1146 | Node_format *plain_nodes, uint16_t size_plain_nodes, uint32_t *num_nodes_out) |
1097 | { | 1147 | { |
1098 | if (plain_length != MAX_SENT_NODES * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | ||
1099 | return 1; | ||
1100 | |||
1101 | DHT *dht = object; | 1148 | DHT *dht = object; |
1102 | uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES; | 1149 | uint32_t cid_size = 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + 1 + NODES_ENCRYPTED_MESSAGE_LENGTH + |
1150 | crypto_box_MACBYTES; | ||
1103 | 1151 | ||
1104 | if (length <= cid_size) /* too short */ | 1152 | if (length <= cid_size) /* too short */ |
1105 | return 1; | 1153 | return 1; |
1106 | 1154 | ||
1107 | uint32_t data_size = length - cid_size; | 1155 | uint32_t data_size = length - cid_size; |
1108 | 1156 | ||
1109 | if ((data_size % node_format_size) != 0) /* invalid length */ | 1157 | if (data_size == 0) |
1110 | return 1; | 1158 | return 1; |
1111 | 1159 | ||
1112 | uint32_t num_nodes = data_size / node_format_size; | 1160 | if (data_size > sizeof(Node_format) * MAX_SENT_NODES) /* invalid length */ |
1113 | |||
1114 | if (num_nodes > MAX_SENT_NODES) /* too long */ | ||
1115 | return 1; | 1161 | return 1; |
1116 | 1162 | ||
1163 | uint8_t plain[1 + data_size + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
1117 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | 1164 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
1118 | DHT_get_shared_key_sent(dht, shared_key, packet + 1); | 1165 | DHT_get_shared_key_sent(dht, shared_key, packet + 1); |
1119 | int len = decrypt_data_fast( | 1166 | int len = decrypt_data_symmetric( |
1120 | shared_key, | 1167 | shared_key, |
1121 | packet + 1 + CLIENT_ID_SIZE, | 1168 | packet + 1 + CLIENT_ID_SIZE, |
1122 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, | 1169 | packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, |
1123 | num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, | 1170 | 1 + data_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, |
1124 | plain); | 1171 | plain); |
1125 | 1172 | ||
1126 | if ((unsigned int)len != num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH) | 1173 | if ((unsigned int)len != sizeof(plain)) |
1127 | return 1; | 1174 | return 1; |
1128 | 1175 | ||
1129 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * node_format_size, sendback_node)) | 1176 | if (plain[0] > size_plain_nodes || plain[0] == 0) |
1130 | return 1; | 1177 | return 1; |
1131 | 1178 | ||
1132 | /* store the address the *request* was sent to */ | ||
1133 | addto_lists(dht, source, packet + 1); | ||
1134 | |||
1135 | *num_nodes_out = num_nodes; | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
1141 | { | ||
1142 | DHT *dht = object; | ||
1143 | size_t node4_format_size = sizeof(Node4_format); | ||
1144 | uint8_t plain[node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
1145 | uint32_t num_nodes; | ||
1146 | |||
1147 | Node_format sendback_node; | 1179 | Node_format sendback_node; |
1148 | 1180 | ||
1149 | if (handle_sendnodes_core(object, source, packet, length, node4_format_size, plain, sizeof(plain), &num_nodes, | 1181 | if (!sent_getnode_to_node(dht, packet + 1, source, plain + 1 + data_size, &sendback_node)) |
1150 | &sendback_node)) | ||
1151 | return 1; | 1182 | return 1; |
1152 | 1183 | ||
1153 | if (num_nodes == 0) | 1184 | uint16_t length_nodes = 0; |
1154 | return 0; | 1185 | int num_nodes = unpack_nodes(plain_nodes, plain[0], &length_nodes, plain + 1, data_size, 0); |
1155 | |||
1156 | Node4_format *nodes4_list = (Node4_format *)(plain); | ||
1157 | |||
1158 | uint64_t time_now = unix_time(); | ||
1159 | IPPTs ippts; | ||
1160 | ippts.ip_port.ip.family = AF_INET; | ||
1161 | ippts.timestamp = time_now; | ||
1162 | |||
1163 | uint32_t i; | ||
1164 | 1186 | ||
1165 | Node_format nodes_list[MAX_SENT_NODES]; | 1187 | if (length_nodes != data_size) |
1188 | return 1; | ||
1166 | 1189 | ||
1167 | for (i = 0; i < num_nodes; i++) | 1190 | if (num_nodes != plain[0]) |
1168 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != (uint32_t)~0)) { | 1191 | return 1; |
1169 | ippts.ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; | ||
1170 | ippts.ip_port.port = nodes4_list[i].ip_port.port; | ||
1171 | 1192 | ||
1172 | send_ping_request(dht->ping, ippts.ip_port, nodes4_list[i].client_id); | 1193 | if (num_nodes <= 0) |
1173 | returnedip_ports(dht, ippts.ip_port, nodes4_list[i].client_id, packet + 1); | 1194 | return 1; |
1174 | 1195 | ||
1175 | memcpy(nodes_list[i].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); | 1196 | /* store the address the *request* was sent to */ |
1176 | ipport_copy(&nodes_list[i].ip_port, &ippts.ip_port); | 1197 | addto_lists(dht, source, packet + 1); |
1177 | 1198 | ||
1178 | } | 1199 | *num_nodes_out = num_nodes; |
1179 | 1200 | ||
1180 | send_hardening_getnode_res(dht, &sendback_node, packet + 1, nodes_list, num_nodes); | 1201 | send_hardening_getnode_res(dht, &sendback_node, packet + 1, plain + 1, data_size); |
1181 | return 0; | 1202 | return 0; |
1182 | } | 1203 | } |
1183 | 1204 | ||
1184 | static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 1205 | static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) |
1185 | { | 1206 | { |
1186 | DHT *dht = object; | 1207 | DHT *dht = object; |
1187 | size_t node_format_size = sizeof(Node_format); | 1208 | Node_format plain_nodes[MAX_SENT_NODES]; |
1188 | uint8_t plain[node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH]; | ||
1189 | uint32_t num_nodes; | 1209 | uint32_t num_nodes; |
1190 | 1210 | ||
1191 | Node_format sendback_node; | 1211 | if (handle_sendnodes_core(object, source, packet, length, plain_nodes, MAX_SENT_NODES, &num_nodes)) |
1192 | |||
1193 | if (handle_sendnodes_core(object, source, packet, length, node_format_size, plain, sizeof(plain), &num_nodes, | ||
1194 | &sendback_node)) | ||
1195 | return 1; | 1212 | return 1; |
1196 | 1213 | ||
1197 | if (num_nodes == 0) | 1214 | if (num_nodes == 0) |
1198 | return 0; | 1215 | return 0; |
1199 | 1216 | ||
1200 | Node_format *nodes_list = (Node_format *)(plain); | ||
1201 | uint32_t i; | 1217 | uint32_t i; |
1202 | send_hardening_getnode_res(dht, &sendback_node, packet + 1, nodes_list, num_nodes); | ||
1203 | 1218 | ||
1204 | for (i = 0; i < num_nodes; i++) { | 1219 | for (i = 0; i < num_nodes; i++) { |
1205 | to_host_family(&nodes_list[i].ip_port.ip); | 1220 | if (ipport_isset(&plain_nodes[i].ip_port)) { |
1206 | 1221 | send_ping_request(dht->ping, plain_nodes[i].ip_port, plain_nodes[i].client_id); | |
1207 | if (ipport_isset(&nodes_list[i].ip_port)) { | 1222 | returnedip_ports(dht, plain_nodes[i].ip_port, plain_nodes[i].client_id, packet + 1); |
1208 | send_ping_request(dht->ping, nodes_list[i].ip_port, nodes_list[i].client_id); | ||
1209 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | ||
1210 | } | 1223 | } |
1211 | } | 1224 | } |
1212 | 1225 | ||
@@ -1595,7 +1608,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | |||
1595 | /* Send the following packet to everyone who tells us they are connected to friend_id. | 1608 | /* Send the following packet to everyone who tells us they are connected to friend_id. |
1596 | * | 1609 | * |
1597 | * return ip for friend. | 1610 | * return ip for friend. |
1598 | * return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 2). | 1611 | * return number of nodes the packet was sent to. (Only works if more than (MAX_FRIEND_CLIENTS / 4). |
1599 | */ | 1612 | */ |
1600 | int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) | 1613 | int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t length) |
1601 | { | 1614 | { |
@@ -1724,7 +1737,7 @@ int friend_ips(DHT *dht, IP_Port *ip_portlist, uint8_t *friend_id) | |||
1724 | static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) | 1737 | static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t type) |
1725 | { | 1738 | { |
1726 | uint8_t data[sizeof(uint64_t) + 1]; | 1739 | uint8_t data[sizeof(uint64_t) + 1]; |
1727 | uint8_t packet[MAX_DATA_SIZE]; | 1740 | uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; |
1728 | 1741 | ||
1729 | int num = 0; | 1742 | int num = 0; |
1730 | 1743 | ||
@@ -1935,7 +1948,7 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8 | |||
1935 | if (length > HARDREQ_DATA_SIZE - 1) | 1948 | if (length > HARDREQ_DATA_SIZE - 1) |
1936 | return -1; | 1949 | return -1; |
1937 | 1950 | ||
1938 | uint8_t packet[MAX_DATA_SIZE]; | 1951 | uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; |
1939 | uint8_t data[HARDREQ_DATA_SIZE] = {0}; | 1952 | uint8_t data[HARDREQ_DATA_SIZE] = {0}; |
1940 | data[0] = type; | 1953 | data[0] = type; |
1941 | memcpy(data + 1, contents, length); | 1954 | memcpy(data + 1, contents, length); |
@@ -1958,17 +1971,17 @@ static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format * | |||
1958 | } | 1971 | } |
1959 | 1972 | ||
1960 | /* Send a get node hardening response */ | 1973 | /* Send a get node hardening response */ |
1961 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, Node_format *list, | 1974 | static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *queried_client_id, uint8_t *nodes_data, |
1962 | uint16_t num_nodes) | 1975 | uint16_t nodes_data_length) |
1963 | { | 1976 | { |
1964 | if (!ip_isset(&sendto->ip_port.ip)) | 1977 | if (!ip_isset(&sendto->ip_port.ip)) |
1965 | return -1; | 1978 | return -1; |
1966 | 1979 | ||
1967 | uint8_t packet[MAX_DATA_SIZE]; | 1980 | uint8_t packet[MAX_CRYPTO_REQUEST_SIZE]; |
1968 | uint8_t data[1 + CLIENT_ID_SIZE + num_nodes * sizeof(Node_format)]; | 1981 | uint8_t data[1 + CLIENT_ID_SIZE + nodes_data_length]; |
1969 | data[0] = CHECK_TYPE_GETNODE_RES; | 1982 | data[0] = CHECK_TYPE_GETNODE_RES; |
1970 | memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); | 1983 | memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); |
1971 | memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format)); | 1984 | memcpy(data + 1 + CLIENT_ID_SIZE, nodes_data, nodes_data_length); |
1972 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, | 1985 | int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data, |
1973 | sizeof(data), CRYPTO_PACKET_HARDENING); | 1986 | sizeof(data), CRYPTO_PACKET_HARDENING); |
1974 | 1987 | ||
@@ -2056,28 +2069,22 @@ static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey | |||
2056 | if (length <= CLIENT_ID_SIZE + 1) | 2069 | if (length <= CLIENT_ID_SIZE + 1) |
2057 | return 1; | 2070 | return 1; |
2058 | 2071 | ||
2059 | if ((length - 1 - CLIENT_ID_SIZE) % sizeof(Node_format) != 0) | 2072 | if (length > 1 + CLIENT_ID_SIZE + sizeof(Node_format) * MAX_SENT_NODES) |
2060 | return 1; | 2073 | return 1; |
2061 | 2074 | ||
2062 | uint16_t num = (length - 1 - CLIENT_ID_SIZE) / sizeof(Node_format); | 2075 | uint16_t length_nodes = length - 1 - CLIENT_ID_SIZE; |
2076 | Node_format nodes[MAX_SENT_NODES]; | ||
2077 | int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, packet + 1 + CLIENT_ID_SIZE, length_nodes, 0); | ||
2063 | 2078 | ||
2064 | /* TODO: MAX_SENT_NODES nodes should be returned at all times | 2079 | /* TODO: MAX_SENT_NODES nodes should be returned at all times |
2065 | (right now we have a small network size so it could cause problems for testing and etc..) */ | 2080 | (right now we have a small network size so it could cause problems for testing and etc..) */ |
2066 | if (num > MAX_SENT_NODES || num == 0) | 2081 | if (num_nodes <= 0) |
2067 | return 1; | 2082 | return 1; |
2068 | 2083 | ||
2069 | Node_format nodes[num]; | ||
2070 | memcpy(nodes, packet + 1 + CLIENT_ID_SIZE, sizeof(Node_format)*num); | ||
2071 | uint32_t i; | ||
2072 | |||
2073 | for (i = 0; i < num; ++i) | ||
2074 | to_host_family(&nodes[i].ip_port.ip); | ||
2075 | |||
2076 | /* NOTE: This should work for now but should be changed to something better. */ | 2084 | /* NOTE: This should work for now but should be changed to something better. */ |
2077 | if (have_nodes_closelist(dht, nodes, num) < (uint32_t)((num + 2) / 2)) | 2085 | if (have_nodes_closelist(dht, nodes, num_nodes) < (uint32_t)((num_nodes + 2) / 2)) |
2078 | return 1; | 2086 | return 1; |
2079 | 2087 | ||
2080 | |||
2081 | IPPTsPng *temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family); | 2088 | IPPTsPng *temp = get_closelist_IPPTsPng(dht, packet + 1, nodes[0].ip_port.ip.family); |
2082 | 2089 | ||
2083 | if (temp == NULL) | 2090 | if (temp == NULL) |
@@ -2204,6 +2211,8 @@ static int random_node_fromlist(Client_data *list, uint16_t list_size, Node_form | |||
2204 | * return the number of nodes. | 2211 | * return the number of nodes. |
2205 | * | 2212 | * |
2206 | * NOTE:this is used to pick nodes for paths. | 2213 | * NOTE:this is used to pick nodes for paths. |
2214 | * | ||
2215 | * TODO: remove the LAN stuff from this. | ||
2207 | */ | 2216 | */ |
2208 | uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num) | 2217 | uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num) |
2209 | { | 2218 | { |
@@ -2287,12 +2296,54 @@ void do_hardening(DHT *dht) | |||
2287 | 2296 | ||
2288 | /*----------------------------------------------------------------------------------*/ | 2297 | /*----------------------------------------------------------------------------------*/ |
2289 | 2298 | ||
2290 | DHT *new_DHT(Net_Crypto *c) | 2299 | void cryptopacket_registerhandler(DHT *dht, uint8_t byte, cryptopacket_handler_callback cb, void *object) |
2300 | { | ||
2301 | dht->cryptopackethandlers[byte].function = cb; | ||
2302 | dht->cryptopackethandlers[byte].object = object; | ||
2303 | } | ||
2304 | |||
2305 | static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, uint32_t length) | ||
2306 | { | ||
2307 | DHT *dht = object; | ||
2308 | |||
2309 | if (packet[0] == NET_PACKET_CRYPTO) { | ||
2310 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES || | ||
2311 | length > MAX_CRYPTO_REQUEST_SIZE + crypto_box_MACBYTES) | ||
2312 | return 1; | ||
2313 | |||
2314 | if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. | ||
2315 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
2316 | uint8_t data[MAX_CRYPTO_REQUEST_SIZE]; | ||
2317 | uint8_t number; | ||
2318 | int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length); | ||
2319 | |||
2320 | if (len == -1 || len == 0) | ||
2321 | return 1; | ||
2322 | |||
2323 | if (!dht->cryptopackethandlers[number].function) return 1; | ||
2324 | |||
2325 | return dht->cryptopackethandlers[number].function(dht->cryptopackethandlers[number].object, source, public_key, | ||
2326 | data, len); | ||
2327 | |||
2328 | } else { /* If request is not for us, try routing it. */ | ||
2329 | int retval = route_packet(dht, packet + 1, packet, length); | ||
2330 | |||
2331 | if ((unsigned int)retval == length) | ||
2332 | return 0; | ||
2333 | } | ||
2334 | } | ||
2335 | |||
2336 | return 1; | ||
2337 | } | ||
2338 | |||
2339 | /*----------------------------------------------------------------------------------*/ | ||
2340 | |||
2341 | DHT *new_DHT(Networking_Core *net) | ||
2291 | { | 2342 | { |
2292 | /* init time */ | 2343 | /* init time */ |
2293 | unix_time_update(); | 2344 | unix_time_update(); |
2294 | 2345 | ||
2295 | if (c == NULL) | 2346 | if (net == NULL) |
2296 | return NULL; | 2347 | return NULL; |
2297 | 2348 | ||
2298 | DHT *dht = calloc(1, sizeof(DHT)); | 2349 | DHT *dht = calloc(1, sizeof(DHT)); |
@@ -2300,8 +2351,7 @@ DHT *new_DHT(Net_Crypto *c) | |||
2300 | if (dht == NULL) | 2351 | if (dht == NULL) |
2301 | return NULL; | 2352 | return NULL; |
2302 | 2353 | ||
2303 | dht->c = c; | 2354 | dht->net = net; |
2304 | dht->net = c->lossless_udp->net; | ||
2305 | dht->ping = new_ping(dht); | 2355 | dht->ping = new_ping(dht); |
2306 | 2356 | ||
2307 | if (dht->ping == NULL) { | 2357 | if (dht->ping == NULL) { |
@@ -2310,11 +2360,10 @@ DHT *new_DHT(Net_Crypto *c) | |||
2310 | } | 2360 | } |
2311 | 2361 | ||
2312 | networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); | 2362 | networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); |
2313 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); | ||
2314 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); | 2363 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); |
2315 | init_cryptopackets(dht); | 2364 | networking_registerhandler(dht->net, NET_PACKET_CRYPTO, &cryptopacket_handle, dht); |
2316 | cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); | 2365 | cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); |
2317 | cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); | 2366 | cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); |
2318 | 2367 | ||
2319 | new_symmetric_key(dht->secret_symmetric_key); | 2368 | new_symmetric_key(dht->secret_symmetric_key); |
2320 | crypto_box_keypair(dht->self_public_key, dht->self_secret_key); | 2369 | crypto_box_keypair(dht->self_public_key, dht->self_secret_key); |
@@ -2361,8 +2410,8 @@ void kill_DHT(DHT *dht) | |||
2361 | networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL); | 2410 | networking_registerhandler(dht->net, NET_PACKET_GET_NODES, NULL, NULL); |
2362 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL); | 2411 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, NULL, NULL); |
2363 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL); | 2412 | networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, NULL, NULL); |
2364 | cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_NAT_PING, NULL, NULL); | 2413 | cryptopacket_registerhandler(dht, CRYPTO_PACKET_NAT_PING, NULL, NULL); |
2365 | cryptopacket_registerhandler(dht->c, CRYPTO_PACKET_HARDENING, NULL, NULL); | 2414 | cryptopacket_registerhandler(dht, CRYPTO_PACKET_HARDENING, NULL, NULL); |
2366 | kill_ping(dht->ping); | 2415 | kill_ping(dht->ping); |
2367 | free(dht->friends_list); | 2416 | free(dht->friends_list); |
2368 | free(dht); | 2417 | free(dht); |