summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/crypto_test.c26
-rw-r--r--testing/crypto_speed_test.c2
-rw-r--r--toxcore/DHT.c455
-rw-r--r--toxcore/DHT.h51
-rw-r--r--toxcore/Lossless_UDP.c3
-rw-r--r--toxcore/misc_tools.h16
-rw-r--r--toxcore/net_crypto.c58
-rw-r--r--toxcore/net_crypto.h21
-rw-r--r--toxcore/network.c19
-rw-r--r--toxcore/network.h5
-rw-r--r--toxcore/ping.c20
-rw-r--r--toxcore/ping.h2
-rw-r--r--toxcore/util.c2
-rw-r--r--toxcore/util.h2
14 files changed, 374 insertions, 308 deletions
diff --git a/auto_tests/crypto_test.c b/auto_tests/crypto_test.c
index 9d3e2e82..806ea7b8 100644
--- a/auto_tests/crypto_test.c
+++ b/auto_tests/crypto_test.c
@@ -95,8 +95,8 @@ START_TEST(test_known)
95 unsigned char m[131]; 95 unsigned char m[131];
96 int clen, mlen; 96 int clen, mlen;
97 97
98 ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), 98 ck_assert_msg(sizeof(c) == sizeof(m) + crypto_box_MACBYTES * sizeof(unsigned char),
99 "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); 99 "cyphertext should be crypto_box_MACBYTES bytes longer than plaintext");
100 ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); 100 ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
101 ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); 101 ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
102 102
@@ -121,8 +121,8 @@ START_TEST(test_fast_known)
121 121
122 encrypt_precompute(bobpk, alicesk, k); 122 encrypt_precompute(bobpk, alicesk, k);
123 123
124 ck_assert_msg(sizeof(c) == sizeof(m) + ENCRYPTION_PADDING * sizeof(unsigned char), 124 ck_assert_msg(sizeof(c) == sizeof(m) + crypto_box_MACBYTES * sizeof(unsigned char),
125 "cyphertext should be ENCRYPTION_PADDING bytes longer than plaintext"); 125 "cyphertext should be crypto_box_MACBYTES bytes longer than plaintext");
126 ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed"); 126 ck_assert_msg(sizeof(test_c) == sizeof(c), "sanity check failed");
127 ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed"); 127 ck_assert_msg(sizeof(test_m) == sizeof(m), "sanity check failed");
128 128
@@ -151,10 +151,10 @@ START_TEST(test_endtoend)
151 unsigned char n[crypto_box_NONCEBYTES]; 151 unsigned char n[crypto_box_NONCEBYTES];
152 152
153 unsigned char m[500]; 153 unsigned char m[500];
154 unsigned char c1[sizeof(m) + ENCRYPTION_PADDING]; 154 unsigned char c1[sizeof(m) + crypto_box_MACBYTES];
155 unsigned char c2[sizeof(m) + ENCRYPTION_PADDING]; 155 unsigned char c2[sizeof(m) + crypto_box_MACBYTES];
156 unsigned char c3[sizeof(m) + ENCRYPTION_PADDING]; 156 unsigned char c3[sizeof(m) + crypto_box_MACBYTES];
157 unsigned char c4[sizeof(m) + ENCRYPTION_PADDING]; 157 unsigned char c4[sizeof(m) + crypto_box_MACBYTES];
158 unsigned char m1[sizeof(m)]; 158 unsigned char m1[sizeof(m)];
159 unsigned char m2[sizeof(m)]; 159 unsigned char m2[sizeof(m)];
160 unsigned char m3[sizeof(m)]; 160 unsigned char m3[sizeof(m)];
@@ -190,7 +190,7 @@ START_TEST(test_endtoend)
190 c4len = encrypt_data_fast(k2, n, m, mlen, c4); 190 c4len = encrypt_data_fast(k2, n, m, mlen, c4);
191 191
192 ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ"); 192 ck_assert_msg(c1len == c2len && c1len == c3len && c1len == c4len, "cyphertext lengths differ");
193 ck_assert_msg(c1len == mlen + (int)ENCRYPTION_PADDING, "wrong cyphertext length"); 193 ck_assert_msg(c1len == mlen + (int)crypto_box_MACBYTES, "wrong cyphertext length");
194 ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0 194 ck_assert_msg(memcmp(c1, c2, c1len) == 0 && memcmp(c1, c3, c1len) == 0
195 && memcmp(c1, c4, c1len) == 0, "crypertexts differ"); 195 && memcmp(c1, c4, c1len) == 0, "crypertexts differ");
196 196
@@ -215,12 +215,12 @@ START_TEST(test_large_data)
215 215
216 unsigned char n[crypto_box_NONCEBYTES]; 216 unsigned char n[crypto_box_NONCEBYTES];
217 217
218 unsigned char m1[MAX_DATA_SIZE - ENCRYPTION_PADDING]; 218 unsigned char m1[MAX_DATA_SIZE - crypto_box_MACBYTES];
219 unsigned char c1[sizeof(m1) + ENCRYPTION_PADDING]; 219 unsigned char c1[sizeof(m1) + crypto_box_MACBYTES];
220 unsigned char m1prime[sizeof(m1)]; 220 unsigned char m1prime[sizeof(m1)];
221 221
222 unsigned char m2[MAX_DATA_SIZE]; 222 unsigned char m2[MAX_DATA_SIZE];
223 unsigned char c2[sizeof(m2) + ENCRYPTION_PADDING]; 223 unsigned char c2[sizeof(m2) + crypto_box_MACBYTES];
224 224
225 int c1len, c2len; 225 int c1len, c2len;
226 int m1plen; 226 int m1plen;
@@ -236,7 +236,7 @@ START_TEST(test_large_data)
236 c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1); 236 c1len = encrypt_data_fast(k, n, m1, sizeof(m1), c1);
237 c2len = encrypt_data_fast(k, n, m2, sizeof(m2), c2); 237 c2len = encrypt_data_fast(k, n, m2, sizeof(m2), c2);
238 238
239 ck_assert_msg(c1len == sizeof(m1) + ENCRYPTION_PADDING, "could not encrypt max size"); 239 ck_assert_msg(c1len == sizeof(m1) + crypto_box_MACBYTES, "could not encrypt max size");
240 ck_assert_msg(c2len == -1, "incorrectly succeeded encrypting massive size"); 240 ck_assert_msg(c2len == -1, "incorrectly succeeded encrypting massive size");
241 241
242 m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime); 242 m1plen = decrypt_data_fast(k, n, c1, c1len, m1prime);
diff --git a/testing/crypto_speed_test.c b/testing/crypto_speed_test.c
index bc8052da..ddf9f512 100644
--- a/testing/crypto_speed_test.c
+++ b/testing/crypto_speed_test.c
@@ -61,7 +61,7 @@ int main(int argc, char *argv[])
61 unsigned char n[crypto_box_NONCEBYTES]; 61 unsigned char n[crypto_box_NONCEBYTES];
62 62
63 unsigned char m[500]; 63 unsigned char m[500];
64 unsigned char c[sizeof(m) + ENCRYPTION_PADDING]; 64 unsigned char c[sizeof(m) + crypto_box_MACBYTES];
65 65
66 unsigned char k[crypto_box_BEFORENMBYTES]; 66 unsigned char k[crypto_box_BEFORENMBYTES];
67 67
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index c286567f..5232deed 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -41,7 +41,7 @@
41#define MAX_SENT_NODES 8 41#define MAX_SENT_NODES 8
42 42
43/* Ping timeout in seconds */ 43/* Ping timeout in seconds */
44#define PING_TIMEOUT 5 44#define PING_TIMEOUT 3
45 45
46/* The timeout after which a node is discarded completely. */ 46/* The timeout after which a node is discarded completely. */
47#define KILL_NODE_TIMEOUT 300 47#define KILL_NODE_TIMEOUT 300
@@ -120,6 +120,7 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id
120 uint32_t i; 120 uint32_t i;
121 121
122 for (i = 0; i < length; i++) 122 for (i = 0; i < length; i++)
123
123 /* Dead nodes are considered dead (not in the list)*/ 124 /* Dead nodes are considered dead (not in the list)*/
124 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) || 125 if (!is_timeout(list[i].assoc4.timestamp, KILL_NODE_TIMEOUT) ||
125 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT)) 126 !is_timeout(list[i].assoc6.timestamp, KILL_NODE_TIMEOUT))
@@ -278,6 +279,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
278 continue; 279 continue;
279 280
280 IPPTsPng *ipptp = NULL; 281 IPPTsPng *ipptp = NULL;
282
281 if (sa_family == AF_INET) 283 if (sa_family == AF_INET)
282 ipptp = &client->assoc4; 284 ipptp = &client->assoc4;
283 else 285 else
@@ -311,7 +313,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
311 if (ipv46x) 313 if (ipv46x)
312 continue; 314 continue;
313 315
314 if (!LAN_ip(ipptp->ip_port.ip) && !is_LAN) 316 /* don't send LAN ips to non LAN peers */
317 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
315 continue; 318 continue;
316 319
317 if (num_nodes < MAX_SENT_NODES) { 320 if (num_nodes < MAX_SENT_NODES) {
@@ -570,78 +573,58 @@ static void returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint
570 } 573 }
571} 574}
572 575
573static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) 576#define NODES_ENCRYPTED_MESSAGE_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint64_t) + sizeof(Node_format) + sizeof(Node_format) + crypto_secretbox_MACBYTES)
574{
575 uint32_t i;
576 uint8_t pinging;
577
578 for (i = 0; i < LSEND_NODES_ARRAY; ++i ) {
579 if (!is_timeout(dht->send_nodes[i].timestamp, PING_TIMEOUT)) {
580 pinging = 0;
581
582 if (ping_id != 0 && dht->send_nodes[i].id == ping_id)
583 ++pinging;
584
585 if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port))
586 ++pinging;
587
588 if (pinging == (ping_id != 0) + ip_isset(&ip_port.ip))
589 return 1;
590 }
591 }
592
593 return 0;
594}
595
596/* Same but for get node requests. */
597static uint64_t add_gettingnodes(DHT *dht, IP_Port ip_port)
598{
599 uint32_t i, j;
600 uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
601
602 for (i = 0; i < PING_TIMEOUT; ++i ) {
603 for (j = 0; j < LSEND_NODES_ARRAY; ++j ) {
604 if (is_timeout(dht->send_nodes[j].timestamp, PING_TIMEOUT - i)) {
605 dht->send_nodes[j].timestamp = unix_time();
606 dht->send_nodes[j].ip_port = ip_port;
607 dht->send_nodes[j].id = ping_id;
608 return ping_id;
609 }
610 }
611 }
612
613 return 0;
614}
615 577
616/* Send a getnodes request. */ 578/* Send a getnodes request.
617static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id) 579 sendback_node is the node that it will send back the response to (set to NULL to disable this) */
580static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node)
618{ 581{
619 /* Check if packet is going to be sent to ourself. */ 582 /* Check if packet is going to be sent to ourself. */
620 if (id_equal(public_key, dht->c->self_public_key) || is_gettingnodes(dht, ip_port, 0)) 583 if (id_equal(public_key, dht->c->self_public_key))
621 return -1; 584 return -1;
622 585
623 uint64_t ping_id = add_gettingnodes(dht, ip_port); 586 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0};
587 uint8_t encrypted_message[NODES_ENCRYPTED_MESSAGE_LENGTH];
588 uint8_t nonce[crypto_box_NONCEBYTES];
589
590 new_nonce(nonce);
591 memcpy(encrypted_message, nonce, crypto_box_NONCEBYTES);
624 592
625 if (ping_id == 0) 593 uint64_t temp_time = unix_time();
594 memcpy(plain_message, &temp_time, sizeof(temp_time));
595 Node_format reciever;
596 memcpy(reciever.client_id, public_key, CLIENT_ID_SIZE);
597 reciever.ip_port = ip_port;
598 memcpy(plain_message + sizeof(temp_time), &reciever, sizeof(reciever));
599
600 if (sendback_node != NULL)
601 memcpy(plain_message + sizeof(temp_time) + sizeof(reciever), sendback_node, sizeof(Node_format));
602
603 int len_m = encrypt_data_symmetric(dht->secret_symmetric_key,
604 nonce,
605 plain_message,
606 sizeof(temp_time) + sizeof(reciever) + sizeof(Node_format),
607 encrypted_message + crypto_secretbox_NONCEBYTES);
608
609 if (len_m != NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES)
626 return -1; 610 return -1;
627 611
628 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 612 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
629 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 613 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
630 uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING]; 614 uint8_t encrypt[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
631 uint8_t nonce[crypto_box_NONCEBYTES]; 615
632 new_nonce(nonce);
633 616
634 memcpy(plain, &ping_id, sizeof(ping_id)); 617 memcpy(plain, client_id, CLIENT_ID_SIZE);
635 memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE); 618 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);
636 619
637 int len = encrypt_data( public_key, 620 int len = encrypt_data( public_key,
638 dht->c->self_secret_key, 621 dht->c->self_secret_key,
639 nonce, 622 nonce,
640 plain, 623 plain,
641 sizeof(ping_id) + CLIENT_ID_SIZE, 624 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
642 encrypt ); 625 encrypt );
643 626
644 if (len != sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING) 627 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
645 return -1; 628 return -1;
646 629
647 data[0] = NET_PACKET_GET_NODES; 630 data[0] = NET_PACKET_GET_NODES;
@@ -652,18 +635,20 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
652 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); 635 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data));
653} 636}
654 637
638
655/* Send a send nodes response. */ 639/* Send a send nodes response. */
656/* because of BINARY compatibility, the Node_format MUST BE Node4_format, 640/* because of BINARY compatibility, the Node_format MUST BE Node4_format,
657 * IPv6 nodes are sent in a different message */ 641 * IPv6 nodes are sent in a different message
658static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 642 * encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH */
643static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
659{ 644{
660 /* Check if packet is going to be sent to ourself. */ 645 /* Check if packet is going to be sent to ourself. */
661 if (id_equal(public_key, dht->c->self_public_key)) 646 if (id_equal(public_key, dht->c->self_public_key))
662 return -1; 647 return -1;
663 648
664 size_t Node4_format_size = sizeof(Node4_format); 649 size_t Node4_format_size = sizeof(Node4_format);
665 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 650 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
666 + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 651 + Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
667 652
668 Node_format nodes_list[MAX_SENT_NODES]; 653 Node_format nodes_list[MAX_SENT_NODES];
669 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0); 654 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET, LAN_ip(ip_port.ip) == 0);
@@ -671,14 +656,12 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
671 if (num_nodes == 0) 656 if (num_nodes == 0)
672 return 0; 657 return 0;
673 658
674 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; 659 uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
675 uint8_t encrypt[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 660 uint8_t encrypt[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
676 uint8_t nonce[crypto_box_NONCEBYTES]; 661 uint8_t nonce[crypto_box_NONCEBYTES];
677 new_nonce(nonce); 662 new_nonce(nonce);
678 663
679 memcpy(plain, &ping_id, sizeof(ping_id)); 664 Node4_format *nodes4_list = (Node4_format *)(plain);
680
681 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id));
682 int i, num_nodes_ok = 0; 665 int i, num_nodes_ok = 0;
683 666
684 for (i = 0; i < num_nodes; i++) { 667 for (i = 0; i < num_nodes; i++) {
@@ -703,17 +686,16 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
703 num_nodes = num_nodes_ok; 686 num_nodes = num_nodes_ok;
704 } 687 }
705 688
689 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
706 int len = encrypt_data( public_key, 690 int len = encrypt_data( public_key,
707 dht->c->self_secret_key, 691 dht->c->self_secret_key,
708 nonce, 692 nonce,
709 plain, 693 plain,
710 sizeof(ping_id) + num_nodes * Node4_format_size, 694 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
711 encrypt ); 695 encrypt );
712 696
713 if (len == -1) 697 if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH +
714 return -1; 698 crypto_box_MACBYTES)
715
716 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING)
717 return -1; 699 return -1;
718 700
719 data[0] = NET_PACKET_SEND_NODES; 701 data[0] = NET_PACKET_SEND_NODES;
@@ -725,15 +707,15 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
725} 707}
726 708
727/* Send a send nodes response: message for IPv6 nodes */ 709/* Send a send nodes response: message for IPv6 nodes */
728static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint64_t ping_id) 710static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
729{ 711{
730 /* Check if packet is going to be sent to ourself. */ 712 /* Check if packet is going to be sent to ourself. */
731 if (id_equal(public_key, dht->c->self_public_key)) 713 if (id_equal(public_key, dht->c->self_public_key))
732 return -1; 714 return -1;
733 715
734 size_t Node_format_size = sizeof(Node_format); 716 size_t Node_format_size = sizeof(Node_format);
735 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(ping_id) 717 uint8_t data[1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES
736 + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 718 + Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
737 719
738 Node_format nodes_list[MAX_SENT_NODES]; 720 Node_format nodes_list[MAX_SENT_NODES];
739 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0); 721 int num_nodes = get_close_nodes(dht, client_id, nodes_list, AF_INET6, LAN_ip(ip_port.ip) == 0);
@@ -741,25 +723,21 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
741 if (num_nodes == 0) 723 if (num_nodes == 0)
742 return 0; 724 return 0;
743 725
744 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; 726 uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
745 uint8_t encrypt[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES + ENCRYPTION_PADDING]; 727 uint8_t encrypt[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES];
746 uint8_t nonce[crypto_box_NONCEBYTES]; 728 uint8_t nonce[crypto_box_NONCEBYTES];
747 new_nonce(nonce); 729 new_nonce(nonce);
748 730
749 memcpy(plain, &ping_id, sizeof(ping_id)); 731 memcpy(plain, nodes_list, num_nodes * Node_format_size);
750 memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * Node_format_size); 732 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
751
752 int len = encrypt_data( public_key, 733 int len = encrypt_data( public_key,
753 dht->c->self_secret_key, 734 dht->c->self_secret_key,
754 nonce, 735 nonce,
755 plain, 736 plain,
756 sizeof(ping_id) + num_nodes * Node_format_size, 737 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
757 encrypt ); 738 encrypt );
758 739
759 if (len == -1) 740 if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES)
760 return -1;
761
762 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING)
763 return -1; 741 return -1;
764 742
765 data[0] = NET_PACKET_SEND_NODES_IPV6; 743 data[0] = NET_PACKET_SEND_NODES_IPV6;
@@ -773,45 +751,74 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
773static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 751static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
774{ 752{
775 DHT *dht = object; 753 DHT *dht = object;
776 uint64_t ping_id;
777 754
778 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES 755 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH +
779 + sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING )) 756 crypto_box_MACBYTES ))
780 return 1; 757 return 1;
781 758
782 /* Check if packet is from ourself. */ 759 /* Check if packet is from ourself. */
783 if (id_equal(packet + 1, dht->c->self_public_key)) 760 if (id_equal(packet + 1, dht->c->self_public_key))
784 return 1; 761 return 1;
785 762
786 uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE]; 763 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
787 764
788 int len = decrypt_data( packet + 1, 765 int len = decrypt_data( packet + 1,
789 dht->c->self_secret_key, 766 dht->c->self_secret_key,
790 packet + 1 + CLIENT_ID_SIZE, 767 packet + 1 + CLIENT_ID_SIZE,
791 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 768 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
792 sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING, 769 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
793 plain ); 770 plain );
794 771
795 if (len != sizeof(ping_id) + CLIENT_ID_SIZE) 772 if (len != CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH)
796 return 1; 773 return 1;
797 774
798 memcpy(&ping_id, plain, sizeof(ping_id)); 775 sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE);
799 sendnodes(dht, source, packet + 1, plain + sizeof(ping_id), ping_id); 776 sendnodes_ipv6(dht, source, packet + 1, plain,
800 sendnodes_ipv6(dht, source, packet + 1, plain + sizeof(ping_id), 777 plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */
801 ping_id); /* TODO: prevent possible amplification attacks */
802 778
803 add_toping(dht->ping, packet + 1, source); 779 add_toping(dht->ping, packet + 1, source);
804 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ 780 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */
805 781
806 return 0; 782 return 0;
807} 783}
784/* return 0 if no
785 return 1 if yes
786 encrypted_data must be of size NODES_ENCRYPTED_MESSAGE_LENGTH*/
787static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_ip_port, uint8_t *encrypted_data,
788 Node_format *sendback_node)
789{
790 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH];
791
792 if (decrypt_data_symmetric(dht->secret_symmetric_key, encrypted_data, encrypted_data + crypto_secretbox_NONCEBYTES,
793 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES,
794 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2)
795 return 0;
796
797 uint64_t comp_time;
798 memcpy(&comp_time, plain_message, sizeof(uint64_t));
799 uint64_t temp_time = unix_time();
800
801 if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time)
802 return 0;
803
804 Node_format test;
805 memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format));
806
807 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0)
808 return 0;
809
810 memcpy(sendback_node, plain_message + sizeof(uint64_t) + sizeof(Node_format), sizeof(Node_format));
811 return 1;
812}
813
814/* Function is needed in following functions. */
815static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes);
808 816
809static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 817static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
810{ 818{
811 DHT *dht = object; 819 DHT *dht = object;
812 uint64_t ping_id;
813 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 820 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
814 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 821 cid_size += crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES;
815 822
816 size_t Node4_format_size = sizeof(Node4_format); 823 size_t Node4_format_size = sizeof(Node4_format);
817 824
@@ -821,24 +828,24 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
821 return 1; 828 return 1;
822 829
823 uint32_t num_nodes = (length - cid_size) / Node4_format_size; 830 uint32_t num_nodes = (length - cid_size) / Node4_format_size;
824 uint8_t plain[sizeof(ping_id) + Node4_format_size * MAX_SENT_NODES]; 831 uint8_t plain[Node4_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
825 832
826 int len = decrypt_data( 833 int len = decrypt_data(
827 packet + 1, 834 packet + 1,
828 dht->c->self_secret_key, 835 dht->c->self_secret_key,
829 packet + 1 + CLIENT_ID_SIZE, 836 packet + 1 + CLIENT_ID_SIZE,
830 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 837 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
831 sizeof(ping_id) + num_nodes * Node4_format_size + ENCRYPTION_PADDING, plain ); 838 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain );
832 839
833 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node4_format_size) 840 if ((unsigned int)len != num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH)
834 return 1; 841 return 1;
835 842
836 memcpy(&ping_id, plain, sizeof(ping_id)); 843 Node_format sendback_node;
837 844
838 if (!is_gettingnodes(dht, source, ping_id)) 845 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node))
839 return 1; 846 return 1;
840 847
841 Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); 848 Node4_format *nodes4_list = (Node4_format *)(plain);
842 Node_format nodes_list[MAX_SENT_NODES]; 849 Node_format nodes_list[MAX_SENT_NODES];
843 uint32_t i, num_nodes_ok = 0; 850 uint32_t i, num_nodes_ok = 0;
844 851
@@ -858,6 +865,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
858 num_nodes = num_nodes_ok; 865 num_nodes = num_nodes_ok;
859 } 866 }
860 867
868 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
861 addto_lists(dht, source, packet + 1); 869 addto_lists(dht, source, packet + 1);
862 870
863 for (i = 0; i < num_nodes; ++i) { 871 for (i = 0; i < num_nodes; ++i) {
@@ -871,9 +879,8 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
871static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length) 879static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet, uint32_t length)
872{ 880{
873 DHT *dht = object; 881 DHT *dht = object;
874 uint64_t ping_id;
875 uint32_t cid_size = 1 + CLIENT_ID_SIZE; 882 uint32_t cid_size = 1 + CLIENT_ID_SIZE;
876 cid_size += crypto_box_NONCEBYTES + sizeof(ping_id) + ENCRYPTION_PADDING; 883 cid_size += crypto_box_NONCEBYTES + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES;
877 884
878 size_t Node_format_size = sizeof(Node_format); 885 size_t Node_format_size = sizeof(Node_format);
879 886
@@ -883,27 +890,28 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
883 return 1; 890 return 1;
884 891
885 uint32_t num_nodes = (length - cid_size) / Node_format_size; 892 uint32_t num_nodes = (length - cid_size) / Node_format_size;
886 uint8_t plain[sizeof(ping_id) + Node_format_size * MAX_SENT_NODES]; 893 uint8_t plain[Node_format_size * MAX_SENT_NODES + NODES_ENCRYPTED_MESSAGE_LENGTH];
887 894
888 int len = decrypt_data( 895 int len = decrypt_data(
889 packet + 1, 896 packet + 1,
890 dht->c->self_secret_key, 897 dht->c->self_secret_key,
891 packet + 1 + CLIENT_ID_SIZE, 898 packet + 1 + CLIENT_ID_SIZE,
892 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 899 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
893 sizeof(ping_id) + num_nodes * Node_format_size + ENCRYPTION_PADDING, plain ); 900 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, plain );
894 901
895 if ((unsigned int)len != sizeof(ping_id) + num_nodes * Node_format_size) 902 if ((unsigned int)len != num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH)
896 return 1; 903 return 1;
897 904
898 memcpy(&ping_id, plain, sizeof(ping_id)); 905 Node_format sendback_node;
899 906
900 if (!is_gettingnodes(dht, source, ping_id)) 907 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node))
901 return 1; 908 return 1;
902 909
903 uint32_t i; 910 uint32_t i;
904 Node_format nodes_list[MAX_SENT_NODES]; 911 Node_format nodes_list[MAX_SENT_NODES];
905 memcpy(nodes_list, plain + sizeof(ping_id), num_nodes * sizeof(Node_format)); 912 memcpy(nodes_list, plain, num_nodes * sizeof(Node_format));
906 913
914 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
907 addto_lists(dht, source, packet + 1); 915 addto_lists(dht, source, packet + 1);
908 916
909 for (i = 0; i < num_nodes; ++i) { 917 for (i = 0; i < num_nodes; ++i) {
@@ -931,7 +939,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
931 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4) 939 for (a = 0, assoc = &list[i].assoc6; a < 2; a++, assoc = &list[i].assoc4)
932 if (ipport_isset(&(assoc->ip_port)) && 940 if (ipport_isset(&(assoc->ip_port)) &&
933 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 941 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
934 getnodes(dht, assoc->ip_port, list[i].client_id, client_id); 942 getnodes(dht, assoc->ip_port, list[i].client_id, client_id, NULL);
935 ++num; 943 ++num;
936 944
937 if (num >= max_num) 945 if (num >= max_num)
@@ -1064,7 +1072,7 @@ static void do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, uint8
1064 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) { 1072 if ((num_nodes != 0) && is_timeout(*lastgetnode, GET_NODE_INTERVAL)) {
1065 uint32_t rand_node = rand() % num_nodes; 1073 uint32_t rand_node = rand() % num_nodes;
1066 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id, 1074 getnodes(dht, assoc_list[rand_node]->ip_port, client_list[rand_node]->client_id,
1067 client_id); 1075 client_id, NULL);
1068 *lastgetnode = temp_time; 1076 *lastgetnode = temp_time;
1069 } 1077 }
1070} 1078}
@@ -1092,7 +1100,7 @@ static void do_Close(DHT *dht)
1092 1100
1093void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1101void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1094{ 1102{
1095 getnodes(dht, ip_port, public_key, dht->c->self_public_key); 1103 getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL);
1096} 1104}
1097int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 1105int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
1098 uint16_t port, uint8_t *public_key) 1106 uint16_t port, uint8_t *public_key)
@@ -1193,12 +1201,15 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num)
1193 1201
1194#ifdef FRIEND_IPLIST_PAD 1202#ifdef FRIEND_IPLIST_PAD
1195 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port)); 1203 memcpy(ip_portlist, ipv6s, num_ipv6s * sizeof(IP_Port));
1204
1196 if (num_ipv6s == MAX_FRIEND_CLIENTS) 1205 if (num_ipv6s == MAX_FRIEND_CLIENTS)
1197 return MAX_FRIEND_CLIENTS; 1206 return MAX_FRIEND_CLIENTS;
1198 1207
1199 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s; 1208 int num_ipv4s_used = MAX_FRIEND_CLIENTS - num_ipv6s;
1209
1200 if (num_ipv4s_used > num_ipv4s) 1210 if (num_ipv4s_used > num_ipv4s)
1201 num_ipv4s_used = num_ipv4s; 1211 num_ipv4s_used = num_ipv4s;
1212
1202 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port)); 1213 memcpy(&ip_portlist[num_ipv6s], ipv4s, num_ipv4s_used * sizeof(IP_Port));
1203 return num_ipv6s + num_ipv4s_used; 1214 return num_ipv6s + num_ipv4s_used;
1204 1215
@@ -1532,6 +1543,104 @@ static void do_NAT(DHT *dht)
1532/*----------------------------------------------------------------------------------*/ 1543/*----------------------------------------------------------------------------------*/
1533/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1544/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1534 1545
1546#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/
1547
1548#define CHECK_TYPE_GETNODE_REQ 0
1549#define CHECK_TYPE_GETNODE_RES 1
1550
1551static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length)
1552{
1553 if (length > HARDREQ_DATA_SIZE - 1)
1554 return -1;
1555
1556 uint8_t packet[MAX_DATA_SIZE];
1557 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1558 data[0] = type;
1559 memcpy(data + 1, contents, length);
1560 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1561 sizeof(data), CRYPTO_PACKET_HARDENING);
1562
1563 if (len == -1)
1564 return -1;
1565
1566 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1567}
1568
1569/* Send a get node hardening request */
1570static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id)
1571{
1572 uint8_t data[sizeof(Node_format) + CLIENT_ID_SIZE];
1573 memcpy(data, node_totest, sizeof(Node_format));
1574 memcpy(data + sizeof(Node_format), search_id, CLIENT_ID_SIZE);
1575 return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CLIENT_ID_SIZE);
1576}
1577
1578/* Send a get node hardening response */
1579static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes)
1580{
1581 if (!ip_isset(&sendto->ip_port.ip))
1582 return -1;
1583
1584 uint8_t packet[MAX_DATA_SIZE];
1585 uint8_t data[1 + num_nodes * sizeof(Node_format)];
1586 data[0] = CHECK_TYPE_GETNODE_RES;
1587 memcpy(data + 1, list, num_nodes * sizeof(Node_format));
1588 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1589 sizeof(data), CRYPTO_PACKET_HARDENING);
1590
1591 if (len == -1)
1592 return -1;
1593
1594 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1595}
1596
1597/* Handle a received hardening packet */
1598static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
1599{
1600 DHT *dht = object;
1601
1602 if (length < 2) {
1603 return 1;
1604 }
1605
1606 switch (packet[0]) {
1607 case CHECK_TYPE_GETNODE_REQ: {
1608 if (length != HARDREQ_DATA_SIZE)
1609 return 1;
1610
1611 Node_format node, tocheck_node;
1612 node.ip_port = source;
1613 memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE);
1614 memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
1615
1616 if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1)
1617 return 1;
1618
1619 return 0;
1620 }
1621
1622 case CHECK_TYPE_GETNODE_RES: {
1623 if ((length - 1) % sizeof(Node_format) != 0)
1624 return 1;
1625
1626 uint16_t num = (length - 1) / sizeof(Node_format);
1627
1628 if (num > MAX_SENT_NODES || num == 0)
1629 return 1;
1630
1631 Node_format nodes[num];
1632 memcpy(nodes, packet + 1, sizeof(Node_format)*num);
1633 /* If Nodes look good and the request checks out */
1634 //TODO
1635 return 0;/* success*/
1636 }
1637 }
1638
1639 return 1;
1640}
1641
1642/*----------------------------------------------------------------------------------*/
1643
1535DHT *new_DHT(Net_Crypto *c) 1644DHT *new_DHT(Net_Crypto *c)
1536{ 1645{
1537 /* init time */ 1646 /* init time */
@@ -1556,10 +1665,11 @@ DHT *new_DHT(Net_Crypto *c)
1556 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); 1665 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
1557 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); 1666 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
1558 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht); 1667 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
1559
1560 init_cryptopackets(dht); 1668 init_cryptopackets(dht);
1561 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 1669 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
1670 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
1562 1671
1672 new_symmetric_key(dht->secret_symmetric_key);
1563 return dht; 1673 return dht;
1564} 1674}
1565 1675
@@ -1579,82 +1689,11 @@ void kill_DHT(DHT *dht)
1579 free(dht); 1689 free(dht);
1580} 1690}
1581 1691
1582/* Get the size of the DHT (for saving). */
1583uint32_t DHT_size_old(DHT *dht)
1584{
1585 return sizeof(dht->close_clientlist) + sizeof(DHT_Friend) * dht->num_friends;
1586}
1587
1588/* Save the DHT in data where data is an array of size DHT_size(). */
1589void DHT_save_old(DHT *dht, uint8_t *data)
1590{
1591 memcpy(data, dht->close_clientlist, sizeof(dht->close_clientlist));
1592 memcpy(data + sizeof(dht->close_clientlist), dht->friends_list, sizeof(DHT_Friend) * dht->num_friends);
1593}
1594
1595/* Load the DHT from data of size size.
1596 *
1597 * return -1 if failure.
1598 * return 0 if success.
1599 */
1600int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size)
1601{
1602 size_t clientlist_oldsize = sizeof(Client_data_old) * LCLIENT_LIST;
1603
1604 if (size < clientlist_oldsize) {
1605#ifdef DEBUG
1606 fprintf(stderr, "DHT_load: Expected at least %u bytes, got %u.\n", sizeof(dht->close_clientlist), size);
1607#endif
1608 return -1;
1609 }
1610
1611 uint32_t friendlistsize = size - clientlist_oldsize;
1612
1613 if (friendlistsize % sizeof(DHT_Friend_old) != 0) {
1614#ifdef DEBUG
1615 fprintf(stderr, "DHT_load: Expected a multiple of %u, got %u.\n", sizeof(DHT_Friend), friendlistsize);
1616#endif
1617 return -1;
1618 }
1619
1620 uint32_t i, j;
1621 Client_data_old *client;
1622 uint16_t friends_num = friendlistsize / sizeof(DHT_Friend_old);
1623
1624 if (friends_num != 0) {
1625 DHT_Friend_old *tempfriends_list = (DHT_Friend_old *)(data + sizeof(dht->close_clientlist));
1626
1627 for (i = 0; i < friends_num; ++i) {
1628 DHT_addfriend(dht, tempfriends_list[i].client_id);
1629
1630 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1631 client = &tempfriends_list[i].client_list[j];
1632
1633 if (client->assoc.timestamp != 0)
1634 getnodes(dht, client->assoc.ip_port, client->client_id, tempfriends_list[i].client_id);
1635 }
1636 }
1637 }
1638
1639 Client_data_old *tempclose_clientlist = (Client_data_old *)data;
1640
1641 for (i = 0; i < LCLIENT_LIST; ++i) {
1642 if (tempclose_clientlist[i].assoc.timestamp != 0)
1643 DHT_bootstrap(dht, tempclose_clientlist[i].assoc.ip_port,
1644 tempclose_clientlist[i].client_id );
1645 }
1646
1647 return 0;
1648}
1649
1650
1651/* new DHT format for load/save, more robust and forward compatible */ 1692/* new DHT format for load/save, more robust and forward compatible */
1652 1693
1653#define DHT_STATE_COOKIE_GLOBAL 0x159000d 1694#define DHT_STATE_COOKIE_GLOBAL 0x159000d
1654 1695
1655#define DHT_STATE_COOKIE_TYPE 0x11ce 1696#define DHT_STATE_COOKIE_TYPE 0x11ce
1656#define DHT_STATE_TYPE_FRIENDS 1
1657#define DHT_STATE_TYPE_CLIENTS 2
1658#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3 1697#define DHT_STATE_TYPE_FRIENDS_ASSOC46 3
1659#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4 1698#define DHT_STATE_TYPE_CLIENTS_ASSOC46 4
1660 1699
@@ -1726,43 +1765,6 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1726 uint32_t num, i, j; 1765 uint32_t num, i, j;
1727 1766
1728 switch (type) { 1767 switch (type) {
1729 case DHT_STATE_TYPE_FRIENDS:
1730 if (length % sizeof(DHT_Friend_old) != 0)
1731 break;
1732
1733 { /* localize declarations */
1734 DHT_Friend_old *friend_list = (DHT_Friend_old *)data;
1735 num = length / sizeof(DHT_Friend_old);
1736
1737 for (i = 0; i < num; ++i) {
1738 DHT_addfriend(dht, friend_list[i].client_id);
1739
1740 for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) {
1741 Client_data_old *client = &friend_list[i].client_list[j];
1742
1743 if (client->assoc.timestamp != 0)
1744 getnodes(dht, client->assoc.ip_port, client->client_id, friend_list[i].client_id);
1745 }
1746 }
1747 } /* localize declarations */
1748
1749 break;
1750
1751 case DHT_STATE_TYPE_CLIENTS:
1752 if ((length % sizeof(Client_data_old)) != 0)
1753 break;
1754
1755 { /* localize declarations */
1756 num = length / sizeof(Client_data_old);
1757 Client_data_old *client_list = (Client_data_old *)data;
1758
1759 for (i = 0; i < num; ++i)
1760 if (client_list[i].assoc.timestamp != 0)
1761 DHT_bootstrap(dht, client_list[i].assoc.ip_port, client_list[i].client_id);
1762 } /* localize declarations */
1763
1764 break;
1765
1766 case DHT_STATE_TYPE_FRIENDS_ASSOC46: 1768 case DHT_STATE_TYPE_FRIENDS_ASSOC46:
1767 if (length % sizeof(DHT_Friend) != 0) 1769 if (length % sizeof(DHT_Friend) != 0)
1768 break; 1770 break;
@@ -1778,10 +1780,10 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1778 Client_data *client = &friend_list[i].client_list[j]; 1780 Client_data *client = &friend_list[i].client_list[j];
1779 1781
1780 if (client->assoc4.timestamp != 0) 1782 if (client->assoc4.timestamp != 0)
1781 getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id); 1783 getnodes(dht, client->assoc4.ip_port, client->client_id, friend_list[i].client_id, NULL);
1782 1784
1783 if (client->assoc6.timestamp != 0) 1785 if (client->assoc6.timestamp != 0)
1784 getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id); 1786 getnodes(dht, client->assoc6.ip_port, client->client_id, friend_list[i].client_id, NULL);
1785 } 1787 }
1786 } 1788 }
1787 } /* localize declarations */ 1789 } /* localize declarations */
@@ -1808,6 +1810,7 @@ static int dht_load_state_callback(void *outer, uint8_t *data, uint32_t length,
1808 break; 1810 break;
1809 1811
1810#ifdef DEBUG 1812#ifdef DEBUG
1813
1811 default: 1814 default:
1812 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n", 1815 fprintf(stderr, "Load state (DHT): contains unrecognized part (len %u, type %u)\n",
1813 length, type); 1816 length, type);
@@ -1835,7 +1838,7 @@ int DHT_load_new(DHT *dht, uint8_t *data, uint32_t length)
1835 length - cookie_len, DHT_STATE_COOKIE_TYPE); 1838 length - cookie_len, DHT_STATE_COOKIE_TYPE);
1836 } 1839 }
1837 1840
1838 return DHT_load_old(dht, data, length); 1841 return -1;
1839} 1842}
1840/* return 0 if we are not connected to the DHT. 1843/* return 0 if we are not connected to the DHT.
1841 * return 1 if we are. 1844 * return 1 if we are.
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 360773ff..ac02710f 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -35,11 +35,6 @@
35/* A list of the clients mathematically closest to ours. */ 35/* A list of the clients mathematically closest to ours. */
36#define LCLIENT_LIST 32 36#define LCLIENT_LIST 32
37 37
38/* The list of ip ports along with the ping_id of what we sent them and a timestamp. */
39#define LPING_ARRAY 256 // NOTE: Deprecated (doesn't do anything).
40
41#define LSEND_NODES_ARRAY LPING_ARRAY/2
42
43/* Maximum newly announced nodes to ping per TIME_TOPING seconds. */ 38/* Maximum newly announced nodes to ping per TIME_TOPING seconds. */
44#define MAX_TOPING 16 39#define MAX_TOPING 16
45 40
@@ -55,11 +50,6 @@ typedef struct {
55 50
56typedef struct { 51typedef struct {
57 uint8_t client_id[CLIENT_ID_SIZE]; 52 uint8_t client_id[CLIENT_ID_SIZE];
58 IPPTsPng assoc;
59} Client_data_old; /* required to load old state files */
60
61typedef struct {
62 uint8_t client_id[CLIENT_ID_SIZE];
63 IPPTsPng assoc4; 53 IPPTsPng assoc4;
64 IPPTsPng assoc6; 54 IPPTsPng assoc6;
65} Client_data; 55} Client_data;
@@ -77,15 +67,19 @@ typedef struct {
77} NAT; 67} NAT;
78 68
79typedef struct { 69typedef struct {
80 uint8_t client_id[CLIENT_ID_SIZE]; 70 /* Node routes request correctly (true (1) or false/didn't check (0)) */
81 Client_data_old client_list[MAX_FRIEND_CLIENTS]; 71 uint8_t routes_requests_ok;
82 72 /* Time which we last checked this.*/
83 /* Time at which the last get_nodes request was sent. */ 73 uint64_t routes_requests_timestamp;
84 uint64_t lastgetnode; 74 /* Node sends correct send_node (true (1) or false/didn't check (0)) */
85 75 uint8_t send_nodes_ok;
86 /* Symetric NAT hole punching stuff. */ 76 /* Time which we last checked this.*/
87 NAT nat; 77 uint64_t send_nodes_timestamp;
88} DHT_Friend_old; /* required to load old state files */ 78 /* Node can be used to test other nodes (true (1) or false/didn't check (0)) */
79 uint8_t testing_requests;
80 /* Time which we last checked this.*/
81 uint64_t testing_timestamp;
82} Hardening;
89 83
90typedef struct { 84typedef struct {
91 uint8_t client_id[CLIENT_ID_SIZE]; 85 uint8_t client_id[CLIENT_ID_SIZE];
@@ -94,6 +88,7 @@ typedef struct {
94 /* Time at which the last get_nodes request was sent. */ 88 /* Time at which the last get_nodes request was sent. */
95 uint64_t lastgetnode; 89 uint64_t lastgetnode;
96 90
91 Hardening hardening;
97 /* Symetric NAT hole punching stuff. */ 92 /* Symetric NAT hole punching stuff. */
98 NAT nat; 93 NAT nat;
99} DHT_Friend; 94} DHT_Friend;
@@ -111,11 +106,6 @@ typedef struct {
111 106
112/*----------------------------------------------------------------------------------*/ 107/*----------------------------------------------------------------------------------*/
113 108
114typedef struct {
115 IP_Port ip_port;
116 uint64_t id;
117 uint64_t timestamp;
118} pinged_t;
119 109
120typedef struct { 110typedef struct {
121 Net_Crypto *c; 111 Net_Crypto *c;
@@ -125,8 +115,10 @@ typedef struct {
125 uint16_t num_friends; 115 uint16_t num_friends;
126 uint64_t close_lastgetnodes; 116 uint64_t close_lastgetnodes;
127 117
128 pinged_t send_nodes[LSEND_NODES_ARRAY];
129 void *ping; 118 void *ping;
119
120 /* Note: this key should not be/is not used to transmit any sensitive materials */
121 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
130} DHT; 122} DHT;
131/*----------------------------------------------------------------------------------*/ 123/*----------------------------------------------------------------------------------*/
132 124
@@ -240,15 +232,6 @@ DHT *new_DHT(Net_Crypto *c);
240 232
241void kill_DHT(DHT *dht); 233void kill_DHT(DHT *dht);
242 234
243/* Load the DHT from data of size size.
244 * old/new: version of config file
245 *
246 * return -1 if failure.
247 * return 0 if success.
248 */
249int DHT_load_old(DHT *dht, uint8_t *data, uint32_t size);
250int DHT_load_new(DHT *dht, uint8_t *data, uint32_t size);
251
252/* return 0 if we are not connected to the DHT. 235/* return 0 if we are not connected to the DHT.
253 * return 1 if we are. 236 * return 1 if we are.
254 */ 237 */
diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c
index e291340d..04533a3b 100644
--- a/toxcore/Lossless_UDP.c
+++ b/toxcore/Lossless_UDP.c
@@ -455,8 +455,9 @@ uint32_t sendqueue_total(Lossless_UDP *ludp)
455{ 455{
456 uint32_t i, total = 0; 456 uint32_t i, total = 0;
457 457
458 for(i = 0; i < ludp->connections.len; i++) { 458 for (i = 0; i < ludp->connections.len; i++) {
459 Connection *connection = &tox_array_get(&ludp->connections, i, Connection); 459 Connection *connection = &tox_array_get(&ludp->connections, i, Connection);
460
460 if (connection->status != 0) 461 if (connection->status != 0)
461 total += connection->sendbuff_packetnum - connection->successful_sent; 462 total += connection->sendbuff_packetnum - connection->successful_sent;
462 } 463 }
diff --git a/toxcore/misc_tools.h b/toxcore/misc_tools.h
index 5fd0cb7a..4bf28ac7 100644
--- a/toxcore/misc_tools.h
+++ b/toxcore/misc_tools.h
@@ -89,7 +89,7 @@ int main()
89{ 89{
90 tox_list_t head; 90 tox_list_t head;
91 tox_list_new(&head); //initialize head 91 tox_list_new(&head); //initialize head
92 92
93 //input a new character, until user enters q or e 93 //input a new character, until user enters q or e
94 char c = '\0'; 94 char c = '\0';
95 while (c != 'q' && c != 'e') { 95 while (c != 'q' && c != 'e') {
@@ -98,16 +98,16 @@ int main()
98 tmp->c = c; 98 tmp->c = c;
99 tox_list_add(&head, &tmp->tox_lst); //add it to the list 99 tox_list_add(&head, &tmp->tox_lst); //add it to the list
100 } 100 }
101 101
102TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop. 102TOX_LIST_FOR_EACH() takes a struct tox_list and a name for a temporary pointer to use in the loop.
103 103
104TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t. 104TOX_LIST_GET_VALUE() uses magic to return an instance of a structure that contains tox_list_t.
105You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst), 105You have to give it a temporary tox_string_t, name of tox_list_t member inside our structure (tox_lst),
106and the type of structure to return. 106and the type of structure to return.
107 107
108 TOX_LIST_FOR_EACH(head, tmp) 108 TOX_LIST_FOR_EACH(head, tmp)
109 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); 109 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
110 110
111 TOX_LIST_FOR_EACH(head, tmp) { 111 TOX_LIST_FOR_EACH(head, tmp) {
112 if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') { 112 if (TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c == 'z') {
113 //If you delete tmp, you have to quit the loop, or it will go on infinitly. 113 //If you delete tmp, you have to quit the loop, or it will go on infinitly.
@@ -116,12 +116,12 @@ and the type of structure to return.
116 break; 116 break;
117 } 117 }
118 } 118 }
119 119
120 printf("\n"); 120 printf("\n");
121 TOX_LIST_FOR_EACH(head, tmp) 121 TOX_LIST_FOR_EACH(head, tmp)
122 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c); 122 printf("%c", TOX_LIST_GET_VALUE(*tmp, tox_lst, tox_string_t).c);
123 123
124 124
125 return 0; 125 return 0;
126} 126}
127*/ 127*/
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3c7c114e..d58f4c27 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -77,7 +77,7 @@ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
77 77
78 /* Unpad the encrypted message. */ 78 /* Unpad the encrypted message. */
79 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES); 79 memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
80 return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; 80 return length + crypto_box_MACBYTES;
81} 81}
82 82
83/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */ 83/* Fast decrypt. Depends on enc_ley from encrypt_precompute. */
@@ -104,7 +104,7 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
104 104
105 /* Unpad the plain message. */ 105 /* Unpad the plain message. */
106 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES); 106 memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
107 return length - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; 107 return length - crypto_box_MACBYTES;
108} 108}
109 109
110int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, 110int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
@@ -123,6 +123,39 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
123 return decrypt_data_fast(k, nonce, encrypted, length, plain); 123 return decrypt_data_fast(k, nonce, encrypted, length, plain);
124} 124}
125 125
126int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted)
127{
128 if (length + crypto_secretbox_MACBYTES > MAX_DATA_SIZE || length == 0)
129 return -1;
130
131 uint8_t temp_plain[MAX_DATA_SIZE + crypto_secretbox_ZEROBYTES] = {0};
132 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_secretbox_BOXZEROBYTES];
133
134 memcpy(temp_plain + crypto_secretbox_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
135
136 crypto_secretbox(temp_encrypted, temp_plain, length + crypto_secretbox_ZEROBYTES, nonce, secret_key);
137 /* Unpad the encrypted message. */
138 memcpy(encrypted, temp_encrypted + crypto_secretbox_BOXZEROBYTES, length + crypto_secretbox_MACBYTES);
139 return length + crypto_secretbox_MACBYTES;
140}
141
142int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain)
143{
144 if (length > MAX_DATA_SIZE || length <= crypto_secretbox_BOXZEROBYTES)
145 return -1;
146
147 uint8_t temp_plain[MAX_DATA_SIZE + crypto_secretbox_ZEROBYTES];
148 uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_secretbox_BOXZEROBYTES] = {0};
149
150 memcpy(temp_encrypted + crypto_secretbox_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
151
152 if (crypto_secretbox_open(temp_plain, temp_encrypted, length + crypto_secretbox_BOXZEROBYTES, nonce, secret_key) == -1)
153 return -1;
154
155 memcpy(plain, temp_plain + crypto_secretbox_ZEROBYTES, length - crypto_secretbox_MACBYTES);
156 return length - crypto_secretbox_MACBYTES;
157}
158
126/* Increment the given nonce by 1. */ 159/* Increment the given nonce by 1. */
127static void increment_nonce(uint8_t *nonce) 160static void increment_nonce(uint8_t *nonce)
128{ 161{
@@ -136,16 +169,29 @@ static void increment_nonce(uint8_t *nonce)
136 } 169 }
137} 170}
138 171
172#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES
173/*if they no longer equal each other, this function must be slit into two.*/
174#error random_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES.
175#endif
139/* Fill the given nonce with random bytes. */ 176/* Fill the given nonce with random bytes. */
140void random_nonce(uint8_t *nonce) 177void random_nonce(uint8_t *nonce)
141{ 178{
142 randombytes(nonce, crypto_box_NONCEBYTES); 179 randombytes(nonce, crypto_box_NONCEBYTES);
143} 180}
144 181
182/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */
183void new_symmetric_key(uint8_t *key)
184{
185 randombytes(key, crypto_secretbox_KEYBYTES);
186}
145 187
146static uint8_t base_nonce[crypto_box_NONCEBYTES]; 188static uint8_t base_nonce[crypto_box_NONCEBYTES];
147static uint8_t nonce_set = 0; 189static uint8_t nonce_set = 0;
148 190
191#if crypto_box_NONCEBYTES != crypto_secretbox_NONCEBYTES
192/*if they no longer equal each other, this function must be slit into two.*/
193#error new_nonce(): crypto_box_NONCEBYTES must equal crypto_secretbox_NONCEBYTES.
194#endif
149/* Gives a nonce guaranteed to be different from previous ones.*/ 195/* Gives a nonce guaranteed to be different from previous ones.*/
150void new_nonce(uint8_t *nonce) 196void new_nonce(uint8_t *nonce)
151{ 197{
@@ -247,7 +293,7 @@ int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uin
247int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key, 293int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
248 uint8_t *data, uint32_t length, uint8_t request_id) 294 uint8_t *data, uint32_t length, uint8_t request_id)
249{ 295{
250 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) 296 if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES)
251 return -1; 297 return -1;
252 298
253 uint8_t nonce[crypto_box_NONCEBYTES]; 299 uint8_t nonce[crypto_box_NONCEBYTES];
@@ -278,7 +324,7 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *
278int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data, 324int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
279 uint8_t *request_id, uint8_t *packet, uint16_t length) 325 uint8_t *request_id, uint8_t *packet, uint16_t length)
280{ 326{
281 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && 327 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
282 length <= MAX_DATA_SIZE) { 328 length <= MAX_DATA_SIZE) {
283 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { 329 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
284 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); 330 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
@@ -313,8 +359,8 @@ static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, ui
313 DHT *dht = object; 359 DHT *dht = object;
314 360
315 if (packet[0] == NET_PACKET_CRYPTO) { 361 if (packet[0] == NET_PACKET_CRYPTO) {
316 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || 362 if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES ||
317 length > MAX_DATA_SIZE + ENCRYPTION_PADDING) 363 length > MAX_DATA_SIZE + crypto_box_MACBYTES)
318 return 1; 364 return 1;
319 365
320 if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. 366 if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 0de66e98..38400ebc 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -27,6 +27,7 @@
27#include "Lossless_UDP.h" 27#include "Lossless_UDP.h"
28 28
29#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */ 29#define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
30#define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
30#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */ 31#define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
31#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2) 32#define CRYPTO_HANDSHAKE_TIMEOUT (CONNECTION_TIMEOUT * 2)
32 33
@@ -77,8 +78,6 @@ typedef struct {
77 78
78#include "DHT.h" 79#include "DHT.h"
79 80
80#define ENCRYPTION_PADDING (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
81
82/* return zero if the buffer contains only zeros. */ 81/* return zero if the buffer contains only zeros. */
83uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen); 82uint8_t crypto_iszero(uint8_t *buffer, uint32_t blen);
84 83
@@ -114,10 +113,28 @@ int encrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
114int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce, 113int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
115 uint8_t *encrypted, uint32_t length, uint8_t *plain); 114 uint8_t *encrypted, uint32_t length, uint8_t *plain);
116 115
116/* Encrypts plain of length length to encrypted of length + 16 using a
117 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
118 *
119 * return -1 if there was a problem.
120 * return length of encrypted data if everything was fine.
121 */
122int encrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted);
123
124/* Decrypts encrypted of length length to plain of length length - 16 using a
125 * secret key crypto_secretbox_KEYBYTES big and a 24 byte nonce.
126 *
127 * return -1 if there was a problem (decryption failed).
128 * return length of plain data if everything was fine.
129 */
130int decrypt_data_symmetric(uint8_t *secret_key, uint8_t *nonce, uint8_t *encrypted, uint32_t length, uint8_t *plain);
117 131
118/* Fill the given nonce with random bytes. */ 132/* Fill the given nonce with random bytes. */
119void random_nonce(uint8_t *nonce); 133void random_nonce(uint8_t *nonce);
120 134
135/* Fill a key crypto_secretbox_KEYBYTES big with random bytes */
136void new_symmetric_key(uint8_t *key);
137
121/*Gives a nonce guaranteed to be different from previous ones.*/ 138/*Gives a nonce guaranteed to be different from previous ones.*/
122void new_nonce(uint8_t *nonce); 139void new_nonce(uint8_t *nonce);
123 140
diff --git a/toxcore/network.c b/toxcore/network.c
index 0f96083c..d163c0eb 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -373,13 +373,15 @@ int networking_wait_execute(uint8_t *data, uint16_t len, uint16_t milliseconds)
373 /* returns -1 on error, 0 on timeout, the socket on activity */ 373 /* returns -1 on error, 0 on timeout, the socket on activity */
374 int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout); 374 int res = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
375#ifdef LOGGING 375#ifdef LOGGING
376
376 /* only dump if not timeout */ 377 /* only dump if not timeout */
377 if (res) { 378 if (res) {
378 sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno, 379 sprintf(logbuffer, "select(%d): %d (%d, %s) - %d %d %d\n", milliseconds, res, errno,
379 strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds), 380 strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
380 FD_ISSET(s->sock, &exceptfds)); 381 FD_ISSET(s->sock, &exceptfds));
381 loglog(logbuffer); 382 loglog(logbuffer);
382 } 383 }
384
383#endif 385#endif
384 386
385 if (FD_ISSET(s->sock, &writefds)) 387 if (FD_ISSET(s->sock, &writefds))
@@ -527,14 +529,14 @@ Networking_Core *new_networking(IP ip, uint16_t port)
527 } else 529 } else
528 return NULL; 530 return NULL;
529 531
530 if (ip.family == AF_INET6) 532 if (ip.family == AF_INET6) {
531 {
532 char ipv6only = 0; 533 char ipv6only = 0;
533 socklen_t optsize = sizeof(ipv6only); 534 socklen_t optsize = sizeof(ipv6only);
534#ifdef LOGGING 535#ifdef LOGGING
535 errno = 0; 536 errno = 0;
536#endif 537#endif
537 int res = getsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize); 538 int res = getsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, &ipv6only, &optsize);
539
538 if ((res == 0) && (ipv6only == 0)) { 540 if ((res == 0) && (ipv6only == 0)) {
539#ifdef LOGGING 541#ifdef LOGGING
540 loglog("Dual-stack socket: enabled per default.\n"); 542 loglog("Dual-stack socket: enabled per default.\n");
@@ -542,6 +544,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
542 } else { 544 } else {
543 ipv6only = 0; 545 ipv6only = 0;
544#ifdef LOGGING 546#ifdef LOGGING
547
545 if (res < 0) { 548 if (res < 0) {
546 sprintf(logbuffer, "Dual-stack socket: Failed to query default. (%d, %s)\n", 549 sprintf(logbuffer, "Dual-stack socket: Failed to query default. (%d, %s)\n",
547 errno, strerror(errno)); 550 errno, strerror(errno));
@@ -551,8 +554,9 @@ Networking_Core *new_networking(IP ip, uint16_t port)
551 errno = 0; 554 errno = 0;
552 res = 555 res =
553#endif 556#endif
554 setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); 557 setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only));
555#ifdef LOGGING 558#ifdef LOGGING
559
556 if (res < 0) { 560 if (res < 0) {
557 sprintf(logbuffer, 561 sprintf(logbuffer,
558 "Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n", 562 "Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses. (%u, %s)\n",
@@ -560,6 +564,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
560 loglog(logbuffer); 564 loglog(logbuffer);
561 } else 565 } else
562 loglog("Dual-stack socket: Enabled successfully.\n"); 566 loglog("Dual-stack socket: Enabled successfully.\n");
567
563#endif 568#endif
564 } 569 }
565 570
@@ -607,8 +612,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
607 *portptr = htons(port_to_try); 612 *portptr = htons(port_to_try);
608 int tries, res; 613 int tries, res;
609 614
610 for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) 615 for (tries = TOX_PORTRANGE_FROM; tries <= TOX_PORTRANGE_TO; tries++) {
611 {
612 res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); 616 res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
613 617
614 if (!res) { 618 if (!res) {
@@ -676,6 +680,7 @@ int ip_equal(IP *a, IP *b)
676 else if (a->family == AF_INET6) 680 else if (a->family == AF_INET6)
677#ifdef WIN32 681#ifdef WIN32
678 return IN6_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); 682 return IN6_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr);
683
679#else 684#else
680 return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr); 685 return IN6_ARE_ADDR_EQUAL(&a->ip6.in6_addr, &b->ip6.in6_addr);
681#endif 686#endif
diff --git a/toxcore/network.h b/toxcore/network.h
index 8b9b8b2f..bb851dcb 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -68,10 +68,15 @@ typedef int sock_t;
68#include <sodium.h> 68#include <sodium.h>
69#else 69#else
70#include <crypto_box.h> 70#include <crypto_box.h>
71#include <crypto_secretbox.h>
71#include <randombytes.h> 72#include <randombytes.h>
72#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 73#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
73#endif 74#endif
74 75
76#ifndef crypto_secretbox_MACBYTES
77#define crypto_secretbox_MACBYTES (crypto_secretbox_ZEROBYTES - crypto_secretbox_BOXZEROBYTES)
78#endif
79
75#ifndef IPV6_ADD_MEMBERSHIP 80#ifndef IPV6_ADD_MEMBERSHIP
76#ifdef IPV6_JOIN_GROUP 81#ifdef IPV6_JOIN_GROUP
77#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 82#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
diff --git a/toxcore/ping.c b/toxcore/ping.c
index c7b829b4..3f237836 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * This file is donated to the Tox Project. 4 * This file is donated to the Tox Project.
5 * Copyright 2013 plutooo 5 * Copyright 2013 plutooo
6 * 6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 * 8 *
9 * This file is part of Tox. 9 * This file is part of Tox.
@@ -20,7 +20,7 @@
20 * 20 *
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with Tox. If not, see <http://www.gnu.org/licenses/>. 22 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
23 * 23 *
24 */ 24 */
25 25
26#ifdef HAVE_CONFIG_H 26#ifdef HAVE_CONFIG_H
@@ -40,6 +40,12 @@
40#define TIME_TOPING 5 40#define TIME_TOPING 5
41 41
42typedef struct { 42typedef struct {
43 IP_Port ip_port;
44 uint64_t id;
45 uint64_t timestamp;
46} pinged_t;
47
48typedef struct {
43 Net_Crypto *c; 49 Net_Crypto *c;
44 50
45 pinged_t pings[PING_NUM_MAX]; 51 pinged_t pings[PING_NUM_MAX];
@@ -132,7 +138,7 @@ static bool is_pinging(PING *ping, IP_Port ipp, uint64_t ping_id) // O(n) TOD
132 return false; 138 return false;
133} 139}
134 140
135#define DHT_PING_SIZE (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(uint64_t) + ENCRYPTION_PADDING) 141#define DHT_PING_SIZE (1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + sizeof(uint64_t) + crypto_box_MACBYTES)
136 142
137int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id) 143int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
138{ 144{
@@ -157,7 +163,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
157 (uint8_t *) &ping_id, sizeof(ping_id), 163 (uint8_t *) &ping_id, sizeof(ping_id),
158 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 164 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
159 165
160 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 166 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
161 return 1; 167 return 1;
162 168
163 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 169 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk));
@@ -182,7 +188,7 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
182 (uint8_t *) &ping_id, sizeof(ping_id), 188 (uint8_t *) &ping_id, sizeof(ping_id),
183 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 189 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
184 190
185 if (rc != sizeof(ping_id) + ENCRYPTION_PADDING) 191 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
186 return 1; 192 return 1;
187 193
188 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 194 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk));
@@ -207,7 +213,7 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
207 ping->c->self_secret_key, 213 ping->c->self_secret_key,
208 packet + 1 + CLIENT_ID_SIZE, 214 packet + 1 + CLIENT_ID_SIZE,
209 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 215 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
210 sizeof(ping_id) + ENCRYPTION_PADDING, 216 sizeof(ping_id) + crypto_box_MACBYTES,
211 (uint8_t *) &ping_id); 217 (uint8_t *) &ping_id);
212 218
213 if (rc != sizeof(ping_id)) 219 if (rc != sizeof(ping_id))
@@ -239,7 +245,7 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
239 ping->c->self_secret_key, 245 ping->c->self_secret_key,
240 packet + 1 + CLIENT_ID_SIZE, 246 packet + 1 + CLIENT_ID_SIZE,
241 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 247 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
242 sizeof(ping_id) + ENCRYPTION_PADDING, 248 sizeof(ping_id) + crypto_box_MACBYTES,
243 (uint8_t *) &ping_id); 249 (uint8_t *) &ping_id);
244 250
245 if (rc != sizeof(ping_id)) 251 if (rc != sizeof(ping_id))
diff --git a/toxcore/ping.h b/toxcore/ping.h
index 32742401..c2437e1b 100644
--- a/toxcore/ping.h
+++ b/toxcore/ping.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * This file is donated to the Tox Project. 4 * This file is donated to the Tox Project.
5 * Copyright 2013 plutooo 5 * Copyright 2013 plutooo
6 * 6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 * 8 *
9 * This file is part of Tox. 9 * This file is part of Tox.
diff --git a/toxcore/util.c b/toxcore/util.c
index d3df64c1..fab9f660 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * This file is donated to the Tox Project. 4 * This file is donated to the Tox Project.
5 * Copyright 2013 plutooo 5 * Copyright 2013 plutooo
6 * 6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 * 8 *
9 * This file is part of Tox. 9 * This file is part of Tox.
diff --git a/toxcore/util.h b/toxcore/util.h
index f69f294b..20dcb2de 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * This file is donated to the Tox Project. 4 * This file is donated to the Tox Project.
5 * Copyright 2013 plutooo 5 * Copyright 2013 plutooo
6 * 6 *
7 * Copyright (C) 2013 Tox project All Rights Reserved. 7 * Copyright (C) 2013 Tox project All Rights Reserved.
8 * 8 *
9 * This file is part of Tox. 9 * This file is part of Tox.