summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-01-20 12:48:26 -0500
committerirungentoo <irungentoo@gmail.com>2014-01-20 12:48:26 -0500
commitaff6b112c00a9bed01c1e030ede91ef9bc7753d6 (patch)
treef42dc26ac5544797562746002cbe149270a468b0 /toxcore
parent66f0a7eaf0b538bc117715678c97358da605c023 (diff)
parent9aa94bfe1d86dc8e960a57b6eb0402be75ff77f1 (diff)
Merge branch 'onion'
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c135
-rw-r--r--toxcore/DHT.h8
-rw-r--r--toxcore/LAN_discovery.c16
-rw-r--r--toxcore/LAN_discovery.h2
-rw-r--r--toxcore/Messenger.c66
-rw-r--r--toxcore/Messenger.h7
-rw-r--r--toxcore/friend_requests.c46
-rw-r--r--toxcore/friend_requests.h6
-rw-r--r--toxcore/net_crypto.c4
-rw-r--r--toxcore/onion.c3
-rw-r--r--toxcore/onion_announce.c66
-rw-r--r--toxcore/onion_announce.h16
-rw-r--r--toxcore/onion_client.c254
-rw-r--r--toxcore/onion_client.h31
-rw-r--r--toxcore/ping.c40
-rw-r--r--toxcore/ping.h2
-rw-r--r--toxcore/util.c19
-rw-r--r--toxcore/util.h2
18 files changed, 492 insertions, 231 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 454047db..61ec5034 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -28,7 +28,11 @@
28#endif 28#endif
29 29
30#include "DHT.h" 30#include "DHT.h"
31
32#ifdef ENABLE_ASSOC_DHT
31#include "assoc.h" 33#include "assoc.h"
34#endif
35
32#include "ping.h" 36#include "ping.h"
33 37
34#include "network.h" 38#include "network.h"
@@ -285,7 +289,7 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
285 */ 289 */
286 sa_family_t ip_treat_as_family = client_ip->family; 290 sa_family_t ip_treat_as_family = client_ip->family;
287 291
288 if ((dht->c->lossless_udp->net->family == AF_INET6) && 292 if ((dht->net->family == AF_INET6) &&
289 (client_ip->family == AF_INET6)) { 293 (client_ip->family == AF_INET6)) {
290 /* socket is AF_INET6, address claims AF_INET6: 294 /* socket is AF_INET6, address claims AF_INET6:
291 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore, 295 * check for embedded IPv4-in-IPv6 (shouldn't happen anymore,
@@ -304,7 +308,8 @@ static void get_close_nodes_inner(DHT *dht, uint8_t *client_id, Node_format *nod
304 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN) 308 if (LAN_ip(ipptp->ip_port.ip) == 0 && !is_LAN)
305 continue; 309 continue;
306 310
307 if (want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK && !id_equal(client_id, client->client_id)) 311 if (LAN_ip(ipptp->ip_port.ip) != 0 && want_good && hardening_correct(&ipptp->hardening) != HARDENING_ALL_OK
312 && !id_equal(client_id, client->client_id))
308 continue; 313 continue;
309 314
310 if (num_nodes < MAX_SENT_NODES) { 315 if (num_nodes < MAX_SENT_NODES) {
@@ -355,10 +360,16 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
355 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 360 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
356 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good); 361 dht->close_clientlist, LCLIENT_LIST, &num_nodes, is_LAN, want_good);
357 362
363 /*TODO uncomment this when hardening is added to close friend clients
364 for (i = 0; i < dht->num_friends; ++i)
365 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
366 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
367 &num_nodes, is_LAN, want_good);
368 */
358 for (i = 0; i < dht->num_friends; ++i) 369 for (i = 0; i < dht->num_friends; ++i)
359 get_close_nodes_inner(dht, client_id, nodes_list, sa_family, 370 get_close_nodes_inner(dht, client_id, nodes_list, sa_family,
360 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS, 371 dht->friends_list[i].client_list, MAX_FRIEND_CLIENTS,
361 &num_nodes, is_LAN, want_good); 372 &num_nodes, is_LAN, 0);
362 373
363 return num_nodes; 374 return num_nodes;
364} 375}
@@ -366,9 +377,13 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n
366int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, 377int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN,
367 uint8_t want_good) 378 uint8_t want_good)
368{ 379{
380#ifdef ENABLE_ASSOC_DHT
381
369 if (!dht->assoc) 382 if (!dht->assoc)
383#endif
370 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); 384 return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good);
371 385
386#ifdef ENABLE_ASSOC_DHT
372 Client_data *result[MAX_SENT_NODES]; 387 Client_data *result[MAX_SENT_NODES];
373 388
374 Assoc_close_entries request; 389 Assoc_close_entries request;
@@ -420,6 +435,7 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa
420 } 435 }
421 436
422 return num_returned; 437 return num_returned;
438#endif
423} 439}
424 440
425/* Replace first bad (or empty) node with this one. 441/* Replace first bad (or empty) node with this one.
@@ -566,7 +582,7 @@ static int replace_good( Client_data *list,
566 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6)) 582 if ((ip_port.ip.family != AF_INET) && (ip_port.ip.family != AF_INET6))
567 return 1; 583 return 1;
568 584
569 sort_list(list, length, comp_client_id); 585 //sort_list(list, length, comp_client_id);
570 586
571 int8_t replace = -1; 587 int8_t replace = -1;
572 588
@@ -636,10 +652,10 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
636 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 652 if (!client_or_ip_port_in_list(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
637 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) { 653 if (replace_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port)) {
638 if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, 654 if (replace_possible_bad(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
639 dht->c->self_public_key)) { 655 dht->self_public_key)) {
640 /* If we can't replace bad nodes we try replacing good ones. */ 656 /* If we can't replace bad nodes we try replacing good ones. */
641 if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port, 657 if (!replace_good(dht->close_clientlist, LCLIENT_LIST, client_id, ip_port,
642 dht->c->self_public_key)) 658 dht->self_public_key))
643 used++; 659 used++;
644 } else 660 } else
645 used++; 661 used++;
@@ -669,6 +685,8 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
669 used++; 685 used++;
670 } 686 }
671 687
688#ifdef ENABLE_ASSOC_DHT
689
672 if (dht->assoc) { 690 if (dht->assoc) {
673 IPPTs ippts; 691 IPPTs ippts;
674 692
@@ -678,6 +696,7 @@ int addto_lists(DHT *dht, IP_Port ip_port, uint8_t *client_id)
678 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0); 696 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
679 } 697 }
680 698
699#endif
681 return used; 700 return used;
682} 701}
683 702
@@ -697,7 +716,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
697 ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3]; 716 ip_port.ip.ip4.uint32 = ip_port.ip.ip6.uint32[3];
698 } 717 }
699 718
700 if (id_equal(client_id, dht->c->self_public_key)) { 719 if (id_equal(client_id, dht->self_public_key)) {
701 for (i = 0; i < LCLIENT_LIST; ++i) { 720 for (i = 0; i < LCLIENT_LIST; ++i) {
702 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) { 721 if (id_equal(nodeclient_id, dht->close_clientlist[i].client_id)) {
703 if (ip_port.ip.family == AF_INET) { 722 if (ip_port.ip.family == AF_INET) {
@@ -734,6 +753,7 @@ static int returnedip_ports(DHT *dht, IP_Port ip_port, uint8_t *client_id, uint8
734 } 753 }
735 754
736end: 755end:
756#ifdef ENABLE_ASSOC_DHT
737 757
738 if (dht->assoc) { 758 if (dht->assoc) {
739 IPPTs ippts; 759 IPPTs ippts;
@@ -744,6 +764,7 @@ end:
744 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0); 764 Assoc_add_entry(dht->assoc, client_id, &ippts, NULL, used ? 1 : 0);
745 } 765 }
746 766
767#endif
747 return 0; 768 return 0;
748} 769}
749 770
@@ -754,7 +775,7 @@ end:
754static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node) 775static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node)
755{ 776{
756 /* Check if packet is going to be sent to ourself. */ 777 /* Check if packet is going to be sent to ourself. */
757 if (id_equal(public_key, dht->c->self_public_key)) 778 if (id_equal(public_key, dht->self_public_key))
758 return -1; 779 return -1;
759 780
760 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0}; 781 uint8_t plain_message[NODES_ENCRYPTED_MESSAGE_LENGTH] = {0};
@@ -794,7 +815,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
794 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH); 815 memcpy(plain + CLIENT_ID_SIZE, encrypted_message, NODES_ENCRYPTED_MESSAGE_LENGTH);
795 816
796 int len = encrypt_data( public_key, 817 int len = encrypt_data( public_key,
797 dht->c->self_secret_key, 818 dht->self_secret_key,
798 nonce, 819 nonce,
799 plain, 820 plain,
800 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH, 821 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -804,11 +825,11 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
804 return -1; 825 return -1;
805 826
806 data[0] = NET_PACKET_GET_NODES; 827 data[0] = NET_PACKET_GET_NODES;
807 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 828 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
808 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 829 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
809 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 830 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
810 831
811 return sendpacket(dht->c->lossless_udp->net, ip_port, data, sizeof(data)); 832 return sendpacket(dht->net, ip_port, data, sizeof(data));
812} 833}
813 834
814/* Send a send nodes response. */ 835/* Send a send nodes response. */
@@ -818,7 +839,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
818static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) 839static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
819{ 840{
820 /* Check if packet is going to be sent to ourself. */ 841 /* Check if packet is going to be sent to ourself. */
821 if (id_equal(public_key, dht->c->self_public_key)) 842 if (id_equal(public_key, dht->self_public_key))
822 return -1; 843 return -1;
823 844
824 size_t Node4_format_size = sizeof(Node4_format); 845 size_t Node4_format_size = sizeof(Node4_format);
@@ -863,7 +884,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
863 884
864 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); 885 memcpy(plain + num_nodes * Node4_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
865 int len = encrypt_data( public_key, 886 int len = encrypt_data( public_key,
866 dht->c->self_secret_key, 887 dht->self_secret_key,
867 nonce, 888 nonce,
868 plain, 889 plain,
869 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, 890 num_nodes * Node4_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -874,11 +895,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
874 return -1; 895 return -1;
875 896
876 data[0] = NET_PACKET_SEND_NODES; 897 data[0] = NET_PACKET_SEND_NODES;
877 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 898 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
878 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 899 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
879 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 900 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
880 901
881 return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 902 return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
882} 903}
883 904
884void to_net_family(IP *ip) 905void to_net_family(IP *ip)
@@ -904,7 +925,7 @@ void to_host_family(IP *ip)
904static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) 925static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data)
905{ 926{
906 /* Check if packet is going to be sent to ourself. */ 927 /* Check if packet is going to be sent to ourself. */
907 if (id_equal(public_key, dht->c->self_public_key)) 928 if (id_equal(public_key, dht->self_public_key))
908 return -1; 929 return -1;
909 930
910 size_t Node_format_size = sizeof(Node_format); 931 size_t Node_format_size = sizeof(Node_format);
@@ -930,7 +951,7 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
930 memcpy(plain, nodes_list, num_nodes * Node_format_size); 951 memcpy(plain, nodes_list, num_nodes * Node_format_size);
931 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH); 952 memcpy(plain + num_nodes * Node_format_size, encrypted_data, NODES_ENCRYPTED_MESSAGE_LENGTH);
932 int len = encrypt_data( public_key, 953 int len = encrypt_data( public_key,
933 dht->c->self_secret_key, 954 dht->self_secret_key,
934 nonce, 955 nonce,
935 plain, 956 plain,
936 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH, 957 num_nodes * Node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH,
@@ -940,11 +961,11 @@ static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_
940 return -1; 961 return -1;
941 962
942 data[0] = NET_PACKET_SEND_NODES_IPV6; 963 data[0] = NET_PACKET_SEND_NODES_IPV6;
943 memcpy(data + 1, dht->c->self_public_key, CLIENT_ID_SIZE); 964 memcpy(data + 1, dht->self_public_key, CLIENT_ID_SIZE);
944 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES); 965 memcpy(data + 1 + CLIENT_ID_SIZE, nonce, crypto_box_NONCEBYTES);
945 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len); 966 memcpy(data + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, encrypt, len);
946 967
947 return sendpacket(dht->c->lossless_udp->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len); 968 return sendpacket(dht->net, ip_port, data, 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + len);
948} 969}
949 970
950static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 971static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -956,13 +977,13 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
956 return 1; 977 return 1;
957 978
958 /* Check if packet is from ourself. */ 979 /* Check if packet is from ourself. */
959 if (id_equal(packet + 1, dht->c->self_public_key)) 980 if (id_equal(packet + 1, dht->self_public_key))
960 return 1; 981 return 1;
961 982
962 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH]; 983 uint8_t plain[CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH];
963 984
964 int len = decrypt_data( packet + 1, 985 int len = decrypt_data( packet + 1,
965 dht->c->self_secret_key, 986 dht->self_secret_key,
966 packet + 1 + CLIENT_ID_SIZE, 987 packet + 1 + CLIENT_ID_SIZE,
967 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 988 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
968 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 989 CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
@@ -1038,7 +1059,7 @@ static int handle_sendnodes_core(void *object, IP_Port source, uint8_t *packet,
1038 1059
1039 int len = decrypt_data( 1060 int len = decrypt_data(
1040 packet + 1, 1061 packet + 1,
1041 dht->c->self_secret_key, 1062 dht->self_secret_key,
1042 packet + 1 + CLIENT_ID_SIZE, 1063 packet + 1 + CLIENT_ID_SIZE,
1043 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 1064 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
1044 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES, 1065 num_nodes * node_format_size + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES,
@@ -1140,6 +1161,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
1140/* 1161/*
1141 * Send get nodes requests with client_id to max_num peers in list of length length 1162 * Send get nodes requests with client_id to max_num peers in list of length length
1142 */ 1163 */
1164/*
1143static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) 1165static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id)
1144{ 1166{
1145 uint32_t i, num = 0; 1167 uint32_t i, num = 0;
@@ -1159,7 +1181,7 @@ static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_
1159 } 1181 }
1160 } 1182 }
1161} 1183}
1162 1184*/
1163int DHT_addfriend(DHT *dht, uint8_t *client_id) 1185int DHT_addfriend(DHT *dht, uint8_t *client_id)
1164{ 1186{
1165 if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */ 1187 if (friend_number(dht, client_id) != -1) /* Is friend already in DHT? */
@@ -1177,6 +1199,7 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
1177 1199
1178 dht->friends_list[dht->num_friends].nat.NATping_id = random_64b(); 1200 dht->friends_list[dht->num_friends].nat.NATping_id = random_64b();
1179 ++dht->num_friends; 1201 ++dht->num_friends;
1202#ifdef ENABLE_ASSOC_DHT
1180 1203
1181 if (dht->assoc) { 1204 if (dht->assoc) {
1182 /* get up to MAX_FRIEND_CLIENTS connectable nodes */ 1205 /* get up to MAX_FRIEND_CLIENTS connectable nodes */
@@ -1206,8 +1229,9 @@ int DHT_addfriend(DHT *dht, uint8_t *client_id)
1206 } 1229 }
1207 } 1230 }
1208 1231
1209 /*TODO: make this better?*/ 1232#endif
1210 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id); 1233 /*this isn't really useful anymore.
1234 get_bunchnodes(dht, dht->close_clientlist, LCLIENT_LIST, MAX_FRIEND_CLIENTS, client_id);*/
1211 1235
1212 return 0; 1236 return 0;
1213} 1237}
@@ -1343,7 +1367,7 @@ static void do_DHT_friends(DHT *dht)
1343 */ 1367 */
1344static void do_Close(DHT *dht) 1368static void do_Close(DHT *dht)
1345{ 1369{
1346 uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->c->self_public_key, 1370 uint8_t not_killed = do_ping_and_sendnode_requests(dht, &dht->close_lastgetnodes, dht->self_public_key,
1347 dht->close_clientlist, LCLIENT_LIST); 1371 dht->close_clientlist, LCLIENT_LIST);
1348 1372
1349 if (!not_killed) { 1373 if (!not_killed) {
@@ -1374,16 +1398,17 @@ void DHT_getnodes(DHT *dht, IP_Port *from_ipp, uint8_t *from_id, uint8_t *which_
1374 1398
1375void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) 1399void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key)
1376{ 1400{
1377 /* 1401 /*#ifdef ENABLE_ASSOC_DHT
1378 if (dht->assoc) { 1402 if (dht->assoc) {
1379 IPPTs ippts; 1403 IPPTs ippts;
1380 ippts.ip_port = ip_port; 1404 ippts.ip_port = ip_port;
1381 ippts.timestamp = 0; 1405 ippts.timestamp = 0;
1382 1406
1383 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0); 1407 Assoc_add_entry(dht->assoc, public_key, &ippts, NULL, 0);
1384 }*/ 1408 }
1409 #endif*/
1385 1410
1386 getnodes(dht, ip_port, public_key, dht->c->self_public_key, NULL); 1411 getnodes(dht, ip_port, public_key, dht->self_public_key, NULL);
1387} 1412}
1388int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, 1413int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled,
1389 uint16_t port, uint8_t *public_key) 1414 uint16_t port, uint8_t *public_key)
@@ -1427,9 +1452,9 @@ int route_packet(DHT *dht, uint8_t *client_id, uint8_t *packet, uint32_t length)
1427 Client_data *client = &dht->close_clientlist[i]; 1452 Client_data *client = &dht->close_clientlist[i];
1428 1453
1429 if (ip_isset(&client->assoc6.ip_port.ip)) 1454 if (ip_isset(&client->assoc6.ip_port.ip))
1430 return sendpacket(dht->c->lossless_udp->net, client->assoc6.ip_port, packet, length); 1455 return sendpacket(dht->net, client->assoc6.ip_port, packet, length);
1431 else if (ip_isset(&client->assoc4.ip_port.ip)) 1456 else if (ip_isset(&client->assoc4.ip_port.ip))
1432 return sendpacket(dht->c->lossless_udp->net, client->assoc4.ip_port, packet, length); 1457 return sendpacket(dht->net, client->assoc4.ip_port, packet, length);
1433 else 1458 else
1434 break; 1459 break;
1435 } 1460 }
@@ -1552,7 +1577,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt
1552 /* If ip is not zero and node is good. */ 1577 /* If ip is not zero and node is good. */
1553 if (ip_isset(&assoc->ret_ip_port.ip) && 1578 if (ip_isset(&assoc->ret_ip_port.ip) &&
1554 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) { 1579 !is_timeout(assoc->ret_timestamp, BAD_NODE_TIMEOUT)) {
1555 int retval = sendpacket(dht->c->lossless_udp->net, assoc->ip_port, packet, length); 1580 int retval = sendpacket(dht->net, assoc->ip_port, packet, length);
1556 1581
1557 if ((unsigned int)retval == length) { 1582 if ((unsigned int)retval == length) {
1558 ++sent; 1583 ++sent;
@@ -1606,7 +1631,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint
1606 if (n < 1) 1631 if (n < 1)
1607 return 0; 1632 return 0;
1608 1633
1609 int retval = sendpacket(dht->c->lossless_udp->net, ip_list[rand() % n], packet, length); 1634 int retval = sendpacket(dht->net, ip_list[rand() % n], packet, length);
1610 1635
1611 if ((unsigned int)retval == length) 1636 if ((unsigned int)retval == length)
1612 return 1; 1637 return 1;
@@ -1647,7 +1672,7 @@ static int send_NATping(DHT *dht, uint8_t *public_key, uint64_t ping_id, uint8_t
1647 data[0] = type; 1672 data[0] = type;
1648 memcpy(data + 1, &ping_id, sizeof(uint64_t)); 1673 memcpy(data + 1, &ping_id, sizeof(uint64_t));
1649 /* 254 is NAT ping request packet id */ 1674 /* 254 is NAT ping request packet id */
1650 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, data, 1675 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, public_key, data,
1651 sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING); 1676 sizeof(uint64_t) + 1, CRYPTO_PACKET_NAT_PING);
1652 1677
1653 if (len == -1) 1678 if (len == -1)
@@ -1821,7 +1846,7 @@ static void do_NAT(DHT *dht)
1821/*----------------------------------------------------------------------------------*/ 1846/*----------------------------------------------------------------------------------*/
1822/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1847/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1823 1848
1824#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/ 1849#define HARDREQ_DATA_SIZE 384 /* Attempt to prevent amplification/other attacks*/
1825 1850
1826#define CHECK_TYPE_ROUTE_REQ 0 1851#define CHECK_TYPE_ROUTE_REQ 0
1827#define CHECK_TYPE_ROUTE_RES 1 1852#define CHECK_TYPE_ROUTE_RES 1
@@ -1839,13 +1864,13 @@ static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8
1839 uint8_t data[HARDREQ_DATA_SIZE] = {0}; 1864 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1840 data[0] = type; 1865 data[0] = type;
1841 memcpy(data + 1, contents, length); 1866 memcpy(data + 1, contents, length);
1842 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, 1867 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
1843 sizeof(data), CRYPTO_PACKET_HARDENING); 1868 sizeof(data), CRYPTO_PACKET_HARDENING);
1844 1869
1845 if (len == -1) 1870 if (len == -1)
1846 return -1; 1871 return -1;
1847 1872
1848 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); 1873 return sendpacket(dht->net, sendto->ip_port, packet, len);
1849} 1874}
1850 1875
1851/* Send a get node hardening request */ 1876/* Send a get node hardening request */
@@ -1869,13 +1894,13 @@ static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, uint8_t *qu
1869 data[0] = CHECK_TYPE_GETNODE_RES; 1894 data[0] = CHECK_TYPE_GETNODE_RES;
1870 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE); 1895 memcpy(data + 1, queried_client_id, CLIENT_ID_SIZE);
1871 memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format)); 1896 memcpy(data + 1 + CLIENT_ID_SIZE, list, num_nodes * sizeof(Node_format));
1872 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data, 1897 int len = create_request(dht->self_public_key, dht->self_secret_key, packet, sendto->client_id, data,
1873 sizeof(data), CRYPTO_PACKET_HARDENING); 1898 sizeof(data), CRYPTO_PACKET_HARDENING);
1874 1899
1875 if (len == -1) 1900 if (len == -1)
1876 return -1; 1901 return -1;
1877 1902
1878 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len); 1903 return sendpacket(dht->net, sendto->ip_port, packet, len);
1879} 1904}
1880 1905
1881/* TODO: improve */ 1906/* TODO: improve */
@@ -1906,7 +1931,7 @@ static uint32_t have_nodes_closelist(DHT *dht, Node_format *nodes, uint16_t num)
1906 uint32_t i; 1931 uint32_t i;
1907 1932
1908 for (i = 0; i < num; ++i) { 1933 for (i = 0; i < num; ++i) {
1909 if (id_equal(nodes[i].client_id, dht->c->self_public_key)) { 1934 if (id_equal(nodes[i].client_id, dht->self_public_key)) {
1910 ++counter; 1935 ++counter;
1911 continue; 1936 continue;
1912 } 1937 }
@@ -2116,7 +2141,7 @@ uint16_t random_nodes_path(DHT *dht, Node_format *nodes, uint16_t max_num)
2116 uint32_t i; 2141 uint32_t i;
2117 2142
2118 for (i = 0; i < max_num; ++i) { 2143 for (i = 0; i < max_num; ++i) {
2119 uint16_t rand_num = rand() % dht->num_friends + 1; 2144 uint16_t rand_num = rand() % (dht->num_friends + 1);
2120 2145
2121 if (rand_num == dht->num_friends) { 2146 if (rand_num == dht->num_friends) {
2122 list = dht->close_clientlist; 2147 list = dht->close_clientlist;
@@ -2173,7 +2198,7 @@ void do_hardening(DHT *dht)
2173 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE); 2198 memcpy(to_test.client_id, client_id, CLIENT_ID_SIZE);
2174 2199
2175 //TODO: The search id should maybe not be ours? 2200 //TODO: The search id should maybe not be ours?
2176 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->c->self_public_key) > 0) { 2201 if (send_hardening_getnode_req(dht, &rand_node, &to_test, dht->self_public_key) > 0) {
2177 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE); 2202 memcpy(cur_iptspng->hardening.send_nodes_pingedid, rand_node.client_id, CLIENT_ID_SIZE);
2178 cur_iptspng->hardening.send_nodes_timestamp = unix_time(); 2203 cur_iptspng->hardening.send_nodes_timestamp = unix_time();
2179 } 2204 }
@@ -2203,24 +2228,34 @@ DHT *new_DHT(Net_Crypto *c)
2203 if (dht == NULL) 2228 if (dht == NULL)
2204 return NULL; 2229 return NULL;
2205 2230
2206 dht->ping = new_ping(dht, c); 2231 dht->c = c;
2232 dht->net = c->lossless_udp->net;
2233 dht->ping = new_ping(dht);
2207 2234
2208 if (dht->ping == NULL) { 2235 if (dht->ping == NULL) {
2209 kill_DHT(dht); 2236 kill_DHT(dht);
2210 return NULL; 2237 return NULL;
2211 } 2238 }
2212 2239
2213 dht->c = c; 2240 networking_registerhandler(dht->net, NET_PACKET_GET_NODES, &handle_getnodes, dht);
2214 networking_registerhandler(c->lossless_udp->net, NET_PACKET_GET_NODES, &handle_getnodes, dht); 2241 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht);
2215 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES, &handle_sendnodes, dht); 2242 networking_registerhandler(dht->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
2216 networking_registerhandler(c->lossless_udp->net, NET_PACKET_SEND_NODES_IPV6, &handle_sendnodes_ipv6, dht);
2217 init_cryptopackets(dht); 2243 init_cryptopackets(dht);
2218 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht); 2244 cryptopacket_registerhandler(c, CRYPTO_PACKET_NAT_PING, &handle_NATping, dht);
2219 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht); 2245 cryptopacket_registerhandler(c, CRYPTO_PACKET_HARDENING, &handle_hardening, dht);
2220 2246
2221 new_symmetric_key(dht->secret_symmetric_key); 2247 new_symmetric_key(dht->secret_symmetric_key);
2222 crypto_box_keypair(dht->self_public_key, dht->self_secret_key); 2248 crypto_box_keypair(dht->self_public_key, dht->self_secret_key);
2223 dht->assoc = new_Assoc_default(dht->c->self_public_key); 2249#ifdef ENABLE_ASSOC_DHT
2250 dht->assoc = new_Assoc_default(dht->self_public_key);
2251#endif
2252 uint32_t i;
2253
2254 for (i = 0; i < DHT_FAKE_FRIEND_NUMBER; ++i) {
2255 uint8_t random_key_bytes[CLIENT_ID_SIZE];
2256 randombytes(random_key_bytes, sizeof(random_key_bytes));
2257 DHT_addfriend(dht, random_key_bytes);
2258 }
2224 2259
2225 return dht; 2260 return dht;
2226} 2261}
@@ -2238,15 +2273,19 @@ void do_DHT(DHT *dht)
2238 do_NAT(dht); 2273 do_NAT(dht);
2239 do_toping(dht->ping); 2274 do_toping(dht->ping);
2240 do_hardening(dht); 2275 do_hardening(dht);
2276#ifdef ENABLE_ASSOC_DHT
2241 2277
2242 if (dht->assoc) 2278 if (dht->assoc)
2243 do_Assoc(dht->assoc, dht); 2279 do_Assoc(dht->assoc, dht);
2244 2280
2281#endif
2245 dht->last_run = unix_time(); 2282 dht->last_run = unix_time();
2246} 2283}
2247void kill_DHT(DHT *dht) 2284void kill_DHT(DHT *dht)
2248{ 2285{
2286#ifdef ENABLE_ASSOC_DHT
2249 kill_Assoc(dht->assoc); 2287 kill_Assoc(dht->assoc);
2288#endif
2250 kill_ping(dht->ping); 2289 kill_ping(dht->ping);
2251 free(dht->friends_list); 2290 free(dht->friends_list);
2252 free(dht); 2291 free(dht);
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 5afc8ce8..eb889d5d 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -56,6 +56,9 @@
56#define TOX_AF_INET 2 56#define TOX_AF_INET 2
57#define TOX_AF_INET6 10 57#define TOX_AF_INET6 10
58 58
59/* The number of "fake" friends to add (for optimization purposes and so our paths for the onion part are more random) */
60#define DHT_FAKE_FRIEND_NUMBER 4
61
59/* Functions to transfer ips safely across wire. */ 62/* Functions to transfer ips safely across wire. */
60void to_net_family(IP *ip); 63void to_net_family(IP *ip);
61void to_host_family(IP *ip); 64void to_host_family(IP *ip);
@@ -139,6 +142,7 @@ typedef struct {
139 142
140typedef struct { 143typedef struct {
141 Net_Crypto *c; 144 Net_Crypto *c;
145 Networking_Core *net;
142 146
143 Client_data close_clientlist[LCLIENT_LIST]; 147 Client_data close_clientlist[LCLIENT_LIST];
144 uint64_t close_lastgetnodes; 148 uint64_t close_lastgetnodes;
@@ -153,9 +157,9 @@ typedef struct {
153 uint16_t num_friends; 157 uint16_t num_friends;
154 158
155 struct PING *ping; 159 struct PING *ping;
156 160#ifdef ENABLE_ASSOC_DHT
157 struct Assoc *assoc; 161 struct Assoc *assoc;
158 162#endif
159 uint64_t last_run; 163 uint64_t last_run;
160} DHT; 164} DHT;
161/*----------------------------------------------------------------------------------*/ 165/*----------------------------------------------------------------------------------*/
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index eadec9ec..bed14754 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -220,33 +220,33 @@ static int handle_LANdiscovery(void *object, IP_Port source, uint8_t *packet, ui
220} 220}
221 221
222 222
223int send_LANdiscovery(uint16_t port, Net_Crypto *c) 223int send_LANdiscovery(uint16_t port, DHT *dht)
224{ 224{
225 uint8_t data[crypto_box_PUBLICKEYBYTES + 1]; 225 uint8_t data[crypto_box_PUBLICKEYBYTES + 1];
226 data[0] = NET_PACKET_LAN_DISCOVERY; 226 data[0] = NET_PACKET_LAN_DISCOVERY;
227 id_copy(data + 1, c->self_public_key); 227 id_copy(data + 1, dht->self_public_key);
228 228
229#ifdef __linux 229#ifdef __linux
230 send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); 230 send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
231#endif 231#endif
232 int res = -1; 232 int res = -1;
233 IP_Port ip_port; 233 IP_Port ip_port;
234 ip_port.port = port; 234 ip_port.port = port;
235 235
236 /* IPv6 multicast */ 236 /* IPv6 multicast */
237 if (c->lossless_udp->net->family == AF_INET6) { 237 if (dht->net->family == AF_INET6) {
238 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6); 238 ip_port.ip = broadcast_ip(AF_INET6, AF_INET6);
239 239
240 if (ip_isset(&ip_port.ip)) 240 if (ip_isset(&ip_port.ip))
241 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0) 241 if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES) > 0)
242 res = 1; 242 res = 1;
243 } 243 }
244 244
245 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */ 245 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is AF_INET6 */
246 ip_port.ip = broadcast_ip(c->lossless_udp->net->family, AF_INET); 246 ip_port.ip = broadcast_ip(dht->net->family, AF_INET);
247 247
248 if (ip_isset(&ip_port.ip)) 248 if (ip_isset(&ip_port.ip))
249 if (sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES)) 249 if (sendpacket(dht->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES))
250 res = 1; 250 res = 1;
251 251
252 return res; 252 return res;
@@ -255,5 +255,5 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c)
255 255
256void LANdiscovery_init(DHT *dht) 256void LANdiscovery_init(DHT *dht)
257{ 257{
258 networking_registerhandler(dht->c->lossless_udp->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); 258 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
259} 259}
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 9d19114d..58bd2bee 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -39,7 +39,7 @@
39#define LAN_DISCOVERY_INTERVAL 60 39#define LAN_DISCOVERY_INTERVAL 60
40 40
41/* Send a LAN discovery pcaket to the broadcast address with port port. */ 41/* Send a LAN discovery pcaket to the broadcast address with port port. */
42int send_LANdiscovery(uint16_t port, Net_Crypto *c); 42int send_LANdiscovery(uint16_t port, DHT *dht);
43 43
44/* Sets up packet handlers. */ 44/* Sets up packet handlers. */
45void LANdiscovery_init(DHT *dht); 45void LANdiscovery_init(DHT *dht);
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index bb3a56f0..19246d7d 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -34,27 +34,6 @@
34#define MIN(a,b) (((a)<(b))?(a):(b)) 34#define MIN(a,b) (((a)<(b))?(a):(b))
35 35
36 36
37void host_to_net(uint8_t *num, uint16_t numbytes)
38{
39 union {
40 uint32_t i;
41 uint8_t c[4];
42 } a;
43 a.i = 1;
44
45 if (a.c[0] == 1) {
46 uint32_t i;
47 uint8_t buff[numbytes];
48
49 for (i = 0; i < numbytes; ++i) {
50 buff[i] = num[numbytes - i - 1];
51 }
52
53 memcpy(num, buff, numbytes);
54 }
55}
56#define net_to_host(x, y) host_to_net(x, y)
57
58static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); 37static void set_friend_status(Messenger *m, int friendnumber, uint8_t status);
59static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); 38static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length);
60 39
@@ -206,11 +185,16 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
206 185
207 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); 186 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
208 187
188 int onion_friendnum = onion_addfriend(m->onion_c, client_id);
189
190 if (onion_friendnum == -1)
191 return FAERR_UNKNOWN;
192
209 uint32_t i; 193 uint32_t i;
210 194
211 for (i = 0; i <= m->numfriends; ++i) { 195 for (i = 0; i <= m->numfriends; ++i) {
212 if (m->friendlist[i].status == NOFRIEND) { 196 if (m->friendlist[i].status == NOFRIEND) {
213 DHT_addfriend(m->dht, client_id); 197 m->friendlist[i].onion_friendnum = onion_friendnum;
214 m->friendlist[i].status = FRIEND_ADDED; 198 m->friendlist[i].status = FRIEND_ADDED;
215 m->friendlist[i].crypt_connection_id = -1; 199 m->friendlist[i].crypt_connection_id = -1;
216 m->friendlist[i].friendrequest_lastsent = 0; 200 m->friendlist[i].friendrequest_lastsent = 0;
@@ -249,11 +233,16 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
249 233
250 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend)); 234 memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));
251 235
236 int onion_friendnum = onion_addfriend(m->onion_c, client_id);
237
238 if (onion_friendnum == -1)
239 return FAERR_UNKNOWN;
240
252 uint32_t i; 241 uint32_t i;
253 242
254 for (i = 0; i <= m->numfriends; ++i) { 243 for (i = 0; i <= m->numfriends; ++i) {
255 if (m->friendlist[i].status == NOFRIEND) { 244 if (m->friendlist[i].status == NOFRIEND) {
256 DHT_addfriend(m->dht, client_id); 245 m->friendlist[i].onion_friendnum = onion_friendnum;
257 m->friendlist[i].status = FRIEND_CONFIRMED; 246 m->friendlist[i].status = FRIEND_CONFIRMED;
258 m->friendlist[i].crypt_connection_id = -1; 247 m->friendlist[i].crypt_connection_id = -1;
259 m->friendlist[i].friendrequest_lastsent = 0; 248 m->friendlist[i].friendrequest_lastsent = 0;
@@ -284,7 +273,7 @@ int m_delfriend(Messenger *m, int friendnumber)
284 if (friend_not_valid(m, friendnumber)) 273 if (friend_not_valid(m, friendnumber))
285 return -1; 274 return -1;
286 275
287 DHT_delfriend(m->dht, m->friendlist[friendnumber].client_id); 276 onion_delfriend(m->onion_c, m->friendlist[friendnumber].onion_friendnum);
288 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id); 277 crypto_kill(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id);
289 free(m->friendlist[friendnumber].statusmessage); 278 free(m->friendlist[friendnumber].statusmessage);
290 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); 279 memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend));
@@ -673,6 +662,8 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
673 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE; 662 const uint8_t was_online = m->friendlist[friendnumber].status == FRIEND_ONLINE;
674 const uint8_t is_online = status == FRIEND_ONLINE; 663 const uint8_t is_online = status == FRIEND_ONLINE;
675 664
665 onion_set_friend_online(m->onion_c, m->friendlist[friendnumber].onion_friendnum, is_online);
666
676 if (is_online != was_online) { 667 if (is_online != was_online) {
677 if (was_online) 668 if (was_online)
678 break_files(m, friendnumber); 669 break_files(m, friendnumber);
@@ -1513,7 +1504,7 @@ static int friend_already_added(uint8_t *client_id, void *data)
1513static void LANdiscovery(Messenger *m) 1504static void LANdiscovery(Messenger *m)
1514{ 1505{
1515 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { 1506 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
1516 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->net_crypto); 1507 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->dht);
1517 m->last_LANdiscovery = unix_time(); 1508 m->last_LANdiscovery = unix_time();
1518 } 1509 }
1519} 1510}
@@ -1552,9 +1543,24 @@ Messenger *new_messenger(uint8_t ipv6enabled)
1552 return NULL; 1543 return NULL;
1553 } 1544 }
1554 1545
1546 m->onion = new_onion(m->dht);
1547 m->onion_a = new_onion_announce(m->dht);
1548 m->onion_c = new_onion_client(m->dht);
1549
1550 if (!(m->onion && m->onion_a && m->onion_c)) {
1551 kill_onion(m->onion);
1552 kill_onion_announce(m->onion_a);
1553 kill_onion_client(m->onion_c);
1554 kill_DHT(m->dht);
1555 kill_net_crypto(m->net_crypto);
1556 kill_networking(m->net);
1557 free(m);
1558 return NULL;
1559 }
1560
1555 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online")); 1561 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
1556 1562
1557 friendreq_init(&(m->fr), m->net_crypto); 1563 friendreq_init(&(m->fr), m->onion_c);
1558 LANdiscovery_init(m->dht); 1564 LANdiscovery_init(m->dht);
1559 set_nospam(&(m->fr), random_int()); 1565 set_nospam(&(m->fr), random_int());
1560 set_filter_function(&(m->fr), &friend_already_added, m); 1566 set_filter_function(&(m->fr), &friend_already_added, m);
@@ -1610,7 +1616,7 @@ void do_friends(Messenger *m)
1610 1616
1611 for (i = 0; i < m->numfriends; ++i) { 1617 for (i = 0; i < m->numfriends; ++i) {
1612 if (m->friendlist[i].status == FRIEND_ADDED) { 1618 if (m->friendlist[i].status == FRIEND_ADDED) {
1613 int fr = send_friendrequest(m->dht, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, 1619 int fr = send_friendrequest(m->onion_c, m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam,
1614 m->friendlist[i].info, 1620 m->friendlist[i].info,
1615 m->friendlist[i].info_size); 1621 m->friendlist[i].info_size);
1616 1622
@@ -1630,7 +1636,7 @@ void do_friends(Messenger *m)
1630 } 1636 }
1631 1637
1632 IP_Port friendip; 1638 IP_Port friendip;
1633 int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip); 1639 int friendok = onion_getfriendip(m->onion_c, m->friendlist[i].onion_friendnum, &friendip);
1634 1640
1635 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { 1641 switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) {
1636 case CRYPTO_CONN_NO_CONNECTION: 1642 case CRYPTO_CONN_NO_CONNECTION:
@@ -1957,6 +1963,7 @@ void do_messenger(Messenger *m)
1957 1963
1958 do_DHT(m->dht); 1964 do_DHT(m->dht);
1959 do_net_crypto(m->net_crypto); 1965 do_net_crypto(m->net_crypto);
1966 do_onion_client(m->onion_c);
1960 do_friends(m); 1967 do_friends(m);
1961 do_inbound(m); 1968 do_inbound(m);
1962 do_allgroupchats(m); 1969 do_allgroupchats(m);
@@ -2188,9 +2195,12 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le
2188 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { 2195 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) {
2189 set_nospam(&(m->fr), *(uint32_t *)data); 2196 set_nospam(&(m->fr), *(uint32_t *)data);
2190 load_keys(m->net_crypto, &data[sizeof(uint32_t)]); 2197 load_keys(m->net_crypto, &data[sizeof(uint32_t)]);
2198#ifdef ENABLE_ASSOC_DHT
2191 2199
2192 if (m->dht->assoc) 2200 if (m->dht->assoc)
2193 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key); 2201 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key);
2202
2203#endif
2194 } else 2204 } else
2195 return -1; /* critical */ 2205 return -1; /* critical */
2196 2206
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 3cfd5065..e09b2f30 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -31,6 +31,7 @@
31#include "friend_requests.h" 31#include "friend_requests.h"
32#include "LAN_discovery.h" 32#include "LAN_discovery.h"
33#include "group_chats.h" 33#include "group_chats.h"
34#include "onion_client.h"
34 35
35#define MAX_NAME_LENGTH 128 36#define MAX_NAME_LENGTH 128
36#define MAX_STATUSMESSAGE_LENGTH 1007 37#define MAX_STATUSMESSAGE_LENGTH 1007
@@ -130,6 +131,7 @@ enum {
130 131
131typedef struct { 132typedef struct {
132 uint8_t client_id[CLIENT_ID_SIZE]; 133 uint8_t client_id[CLIENT_ID_SIZE];
134 uint32_t onion_friendnum;
133 int crypt_connection_id; 135 int crypt_connection_id;
134 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent. 136 uint64_t friendrequest_lastsent; // Time at which the last friend request was sent.
135 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts. 137 uint32_t friendrequest_timeout; // The timeout between successful friendrequest sending attempts.
@@ -160,6 +162,11 @@ typedef struct Messenger {
160 Networking_Core *net; 162 Networking_Core *net;
161 Net_Crypto *net_crypto; 163 Net_Crypto *net_crypto;
162 DHT *dht; 164 DHT *dht;
165
166 Onion *onion;
167 Onion_Announce *onion_a;
168 Onion_Client *onion_c;
169
163 Friend_Requests fr; 170 Friend_Requests fr;
164 uint8_t name[MAX_NAME_LENGTH]; 171 uint8_t name[MAX_NAME_LENGTH];
165 uint16_t name_length; 172 uint16_t name_length;
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c
index 589bd315..5c294c76 100644
--- a/toxcore/friend_requests.c
+++ b/toxcore/friend_requests.c
@@ -35,41 +35,24 @@
35 * return 0 if it sent the friend request directly to the friend. 35 * return 0 if it sent the friend request directly to the friend.
36 * return the number of peers it was routed through if it did not send it directly. 36 * return the number of peers it was routed through if it did not send it directly.
37 */ 37 */
38int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) 38int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length)
39{ 39{
40 if (length + sizeof(nospam_num) > MAX_DATA_SIZE) 40 if (length + sizeof(nospam_num) > MAX_DATA_SIZE)
41 return -1; 41 return -1;
42 42
43 uint8_t temp[MAX_DATA_SIZE]; 43 uint8_t temp[MAX_DATA_SIZE];
44 memcpy(temp, &nospam_num, sizeof(nospam_num)); 44 temp[0] = CRYPTO_PACKET_FRIEND_REQ;
45 memcpy(temp + sizeof(nospam_num), data, length); 45 memcpy(temp + 1, &nospam_num, sizeof(nospam_num));
46 uint8_t packet[MAX_DATA_SIZE]; 46 memcpy(temp + 1 + sizeof(nospam_num), data, length);
47 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, public_key, temp,
48 length + sizeof(nospam_num),
49 CRYPTO_PACKET_FRIEND_REQ);
50
51 if (len == -1)
52 return -1;
53
54 IP_Port ip_port;
55 int friendok = DHT_getfriendip(dht, public_key, &ip_port);
56
57 // not a friend
58 if (friendok == -1)
59 return -1;
60 47
61 // is a friend and we know how to reach him 48 int friend_num = onion_friend_num(onion_c, public_key);
62 if (friendok == 1) {
63 if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1)
64 return 0;
65 49
50 if (friend_num == -1)
66 return -1; 51 return -1;
67 }
68 52
69 // is a friend, we DON'T know how to reach him 53 int num = send_onion_data(onion_c, friend_num, temp, 1 + sizeof(nospam_num) + length);
70 int num = route_tofriend(dht, public_key, packet, len);
71 54
72 if (num == 0) 55 if (num <= 0)
73 return -1; 56 return -1;
74 57
75 return num; 58 return num;
@@ -130,9 +113,14 @@ static int request_received(Friend_Requests *fr, uint8_t *client_id)
130} 113}
131 114
132 115
133static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, 116static int friendreq_handlepacket(void *object, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
134 uint32_t length)
135{ 117{
118 if (length == 0)
119 return 1;
120
121 ++packet;
122 --length;
123
136 Friend_Requests *fr = object; 124 Friend_Requests *fr = object;
137 125
138 if (fr->handle_friendrequest_isset == 0) 126 if (fr->handle_friendrequest_isset == 0)
@@ -156,7 +144,7 @@ static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_
156 return 0; 144 return 0;
157} 145}
158 146
159void friendreq_init(Friend_Requests *fr, Net_Crypto *c) 147void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c)
160{ 148{
161 cryptopacket_registerhandler(c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr); 149 oniondata_registerhandler(onion_c, CRYPTO_PACKET_FRIEND_REQ, &friendreq_handlepacket, fr);
162} 150}
diff --git a/toxcore/friend_requests.h b/toxcore/friend_requests.h
index c655669d..732dc4a2 100644
--- a/toxcore/friend_requests.h
+++ b/toxcore/friend_requests.h
@@ -24,7 +24,7 @@
24#ifndef FRIEND_REQUESTS_H 24#ifndef FRIEND_REQUESTS_H
25#define FRIEND_REQUESTS_H 25#define FRIEND_REQUESTS_H
26 26
27#include "DHT.h" 27#include "onion_client.h"
28#include "net_crypto.h" 28#include "net_crypto.h"
29 29
30 30
@@ -49,7 +49,7 @@ typedef struct {
49/* Try to send a friendrequest to peer with public_key. 49/* Try to send a friendrequest to peer with public_key.
50 * data is the data in the request and length is the length. 50 * data is the data in the request and length is the length.
51 */ 51 */
52int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); 52int send_friendrequest(Onion_Client *onion_c, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length);
53/* Set and get the nospam variable used to prevent one type of friend request spam. */ 53/* Set and get the nospam variable used to prevent one type of friend request spam. */
54void set_nospam(Friend_Requests *fr, uint32_t num); 54void set_nospam(Friend_Requests *fr, uint32_t num);
55uint32_t get_nospam(Friend_Requests *fr); 55uint32_t get_nospam(Friend_Requests *fr);
@@ -67,7 +67,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uin
67void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata); 67void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata);
68 68
69/* Sets up friendreq packet handlers. */ 69/* Sets up friendreq packet handlers. */
70void friendreq_init(Friend_Requests *fr, Net_Crypto *c); 70void friendreq_init(Friend_Requests *fr, Onion_Client *onion_c);
71 71
72 72
73#endif 73#endif
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index a6c3ecd9..5c2691f3 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -365,11 +365,11 @@ static int cryptopacket_handle(void *object, IP_Port source, uint8_t *packet, ui
365 length > MAX_DATA_SIZE + crypto_box_MACBYTES) 365 length > MAX_DATA_SIZE + crypto_box_MACBYTES)
366 return 1; 366 return 1;
367 367
368 if (memcmp(packet + 1, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us. 368 if (memcmp(packet + 1, dht->self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { // Check if request is for us.
369 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 369 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
370 uint8_t data[MAX_DATA_SIZE]; 370 uint8_t data[MAX_DATA_SIZE];
371 uint8_t number; 371 uint8_t number;
372 int len = handle_request(dht->c->self_public_key, dht->c->self_secret_key, public_key, data, &number, packet, length); 372 int len = handle_request(dht->self_public_key, dht->self_secret_key, public_key, data, &number, packet, length);
373 373
374 if (len == -1 || len == 0) 374 if (len == -1 || len == 0)
375 return 1; 375 return 1;
diff --git a/toxcore/onion.c b/toxcore/onion.c
index 7ec6bb61..9819762d 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -363,6 +363,9 @@ Onion *new_onion(DHT *dht)
363 363
364void kill_onion(Onion *onion) 364void kill_onion(Onion *onion)
365{ 365{
366 if (onion == NULL)
367 return;
368
366 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL); 369 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_INITIAL, NULL, NULL);
367 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL); 370 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_1, NULL, NULL);
368 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL); 371 networking_registerhandler(onion->net, NET_PACKET_ONION_SEND_2, NULL, NULL);
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 92c9e940..8150974b 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -29,7 +29,7 @@
29 29
30#define PING_ID_TIMEOUT 20 30#define PING_ID_TIMEOUT 20
31 31
32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES) 32#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES)
33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3) 33#define ANNOUNCE_REQUEST_SIZE_RECV (ANNOUNCE_REQUEST_SIZE + ONION_RETURN_3)
34 34
35#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 35#define DATA_REQUEST_MIN_SIZE (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
@@ -43,6 +43,7 @@
43 * public_key and secret_key is the kepair which will be used to encrypt the request. 43 * public_key and secret_key is the kepair which will be used to encrypt the request.
44 * ping_id is the ping id that will be sent in the request. 44 * ping_id is the ping id that will be sent in the request.
45 * client_id is the client id of the node we are searching for. 45 * client_id is the client id of the node we are searching for.
46 * data_public_key is the public key we want others to encrypt their data packets with.
46 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to 47 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
47 * receive back in the response. 48 * receive back in the response.
48 * 49 *
@@ -50,12 +51,14 @@
50 * return 0 on success. 51 * return 0 on success.
51 */ 52 */
52int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 53int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
53 uint8_t *client_id, uint8_t *sendback_data) 54 uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data)
54{ 55{
55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 56 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
56 memcpy(plain, ping_id, ONION_PING_ID_SIZE); 57 memcpy(plain, ping_id, ONION_PING_ID_SIZE);
57 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES); 58 memcpy(plain + ONION_PING_ID_SIZE, client_id, crypto_box_PUBLICKEYBYTES);
58 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, sendback_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); 59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES);
60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, sendback_data,
61 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
59 uint8_t packet[ANNOUNCE_REQUEST_SIZE]; 62 uint8_t packet[ANNOUNCE_REQUEST_SIZE];
60 packet[0] = NET_PACKET_ANNOUNCE_REQUEST; 63 packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
61 new_nonce(packet + 1); 64 new_nonce(packet + 1);
@@ -78,12 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
78 * send the packet to that person in the form of a response) 81 * send the packet to that person in the form of a response)
79 * 82 *
80 * public_key is the real public key of the node which we want to send the data of length length to. 83 * public_key is the real public key of the node which we want to send the data of length length to.
84 * encrypt_public_key is the public key used to encrypt the data packet.
85 *
81 * nonce is the nonce to encrypt this packet with 86 * nonce is the nonce to encrypt this packet with
82 * 87 *
83 * return -1 on failure. 88 * return -1 on failure.
84 * return 0 on success. 89 * return 0 on success.
85 */ 90 */
86int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 91int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
92 uint8_t *data, uint16_t length)
87{ 93{
88 uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; 94 uint8_t packet[DATA_REQUEST_MIN_SIZE + length];
89 packet[0] = NET_PACKET_ONION_DATA_REQUEST; 95 packet[0] = NET_PACKET_ONION_DATA_REQUEST;
@@ -96,7 +102,7 @@ int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t
96 102
97 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); 103 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES);
98 104
99 int len = encrypt_data(public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, 105 int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES,
100 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 106 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
101 107
102 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) 108 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet))
@@ -167,10 +173,11 @@ static int cmp_entry(const void *a, const void *b)
167 173
168/* add entry to entries list 174/* add entry to entries list
169 * 175 *
170 * return 0 if failure 176 * return -1 if failure
171 * return 1 if added 177 * return position if added
172 */ 178 */
173static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret) 179static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *data_public_key,
180 uint8_t *ret)
174{ 181{
175 182
176 int pos = in_entries(onion_a, public_key); 183 int pos = in_entries(onion_a, public_key);
@@ -190,16 +197,17 @@ static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t
190 } 197 }
191 198
192 if (pos == -1) 199 if (pos == -1)
193 return 0; 200 return -1;
194 201
195 memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES); 202 memcpy(onion_a->entries[pos].public_key, public_key, crypto_box_PUBLICKEYBYTES);
196 onion_a->entries[pos].ret_ip_port = ret_ip_port; 203 onion_a->entries[pos].ret_ip_port = ret_ip_port;
197 memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3); 204 memcpy(onion_a->entries[pos].ret, ret, ONION_RETURN_3);
205 memcpy(onion_a->entries[pos].data_public_key, data_public_key, crypto_box_PUBLICKEYBYTES);
198 onion_a->entries[pos].time = unix_time(); 206 onion_a->entries[pos].time = unix_time();
199 207
200 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 208 memcpy(cmp_public_key, onion_a->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
201 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry); 209 qsort(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, sizeof(Onion_Announce_Entry), cmp_entry);
202 return 1; 210 return pos;
203} 211}
204 212
205static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) 213static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length)
@@ -209,10 +217,11 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
209 if (length != ANNOUNCE_REQUEST_SIZE_RECV) 217 if (length != ANNOUNCE_REQUEST_SIZE_RECV)
210 return 1; 218 return 1;
211 219
212 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 220 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
213 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1, 221 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1,
214 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 222 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
215 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_MACBYTES, plain); 223 ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH +
224 crypto_box_MACBYTES, plain);
216 225
217 if ((uint32_t)len != sizeof(plain)) 226 if ((uint32_t)len != sizeof(plain))
218 return 1; 227 return 1;
@@ -223,13 +232,14 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
223 uint8_t ping_id2[ONION_PING_ID_SIZE]; 232 uint8_t ping_id2[ONION_PING_ID_SIZE];
224 generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2); 233 generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, source, ping_id2);
225 234
226 int stored = 0; 235 int index = -1;
227 236
228 if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) { 237 if (memcmp(ping_id1, plain, ONION_PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, ONION_PING_ID_SIZE) == 0) {
229 stored = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES, 238 index = add_to_entries(onion_a, source, packet + 1 + crypto_box_NONCEBYTES,
230 packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3)); 239 plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES,
240 packet + (ANNOUNCE_REQUEST_SIZE_RECV - ONION_RETURN_3));
231 } else { 241 } else {
232 stored = (in_entries(onion_a, plain + ONION_PING_ID_SIZE) != -1); 242 index = in_entries(onion_a, plain + ONION_PING_ID_SIZE);
233 } 243 }
234 244
235 /*Respond with a announce response packet*/ 245 /*Respond with a announce response packet*/
@@ -245,24 +255,29 @@ static int handle_announce_request(void *object, IP_Port source, uint8_t *packet
245 uint8_t nonce[crypto_box_NONCEBYTES]; 255 uint8_t nonce[crypto_box_NONCEBYTES];
246 new_nonce(nonce); 256 new_nonce(nonce);
247 257
248 uint8_t pl[ONION_PING_ID_SIZE + sizeof(nodes_list)] = {0}; 258 uint8_t pl[1 + ONION_PING_ID_SIZE + sizeof(nodes_list)];
249 259
250 if (!stored) { 260 if (index == -1) {
251 memcpy(pl, ping_id2, ONION_PING_ID_SIZE); 261 pl[0] = 0;
262 memcpy(pl + 1, ping_id2, ONION_PING_ID_SIZE);
263 } else {
264 pl[0] = 1;
265 memcpy(pl + 1, onion_a->entries[index].data_public_key, crypto_box_PUBLICKEYBYTES);
252 } 266 }
253 267
254 memcpy(pl + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format)); 268 memcpy(pl + 1 + ONION_PING_ID_SIZE, nodes_list, num_nodes * sizeof(Node_format));
255 269
256 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE]; 270 uint8_t data[ONION_ANNOUNCE_RESPONSE_MAX_SIZE];
257 len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl, 271 len = encrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, nonce, pl,
258 ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format), 272 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format),
259 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES); 273 data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES);
260 274
261 if ((uint32_t)len != ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES) 275 if ((uint32_t)len != 1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format) + crypto_box_MACBYTES)
262 return 1; 276 return 1;
263 277
264 data[0] = NET_PACKET_ANNOUNCE_RESPONSE; 278 data[0] = NET_PACKET_ANNOUNCE_RESPONSE;
265 memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH); 279 memcpy(data + 1, plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES,
280 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH);
266 memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES); 281 memcpy(data + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, nonce, crypto_box_NONCEBYTES);
267 282
268 if (send_onion_response(onion_a->net, source, data, 283 if (send_onion_response(onion_a->net, source, data,
@@ -321,6 +336,9 @@ Onion_Announce *new_onion_announce(DHT *dht)
321 336
322void kill_onion_announce(Onion_Announce *onion_a) 337void kill_onion_announce(Onion_Announce *onion_a)
323{ 338{
339 if (onion_a == NULL)
340 return;
341
324 networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL); 342 networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL);
325 networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL); 343 networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL);
326 free(onion_a); 344 free(onion_a);
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index 01cd7243..27b25bd4 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -31,15 +31,20 @@
31 31
32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES) 32#define ONION_ANNOUNCE_SENDBACK_DATA_LENGTH (crypto_secretbox_NONCEBYTES + sizeof(uint32_t) + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES + sizeof(IP_Port) + crypto_secretbox_MACBYTES)
33 33
34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + ONION_PING_ID_SIZE + crypto_box_MACBYTES) 34#define ONION_ANNOUNCE_RESPONSE_MIN_SIZE (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES + 1 + ONION_PING_ID_SIZE + crypto_box_MACBYTES)
35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES) 35#define ONION_ANNOUNCE_RESPONSE_MAX_SIZE (ONION_ANNOUNCE_RESPONSE_MIN_SIZE + sizeof(Node_format)*MAX_SENT_NODES)
36 36
37#define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) 37#define ONION_DATA_RESPONSE_MIN_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
38 38
39#if ONION_PING_ID_SIZE != crypto_box_PUBLICKEYBYTES
40#error announce response packets assume that ONION_PING_ID_SIZE is equal to crypto_box_PUBLICKEYBYTES
41#endif
42
39typedef struct { 43typedef struct {
40 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 44 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
41 IP_Port ret_ip_port; 45 IP_Port ret_ip_port;
42 uint8_t ret[ONION_RETURN_3]; 46 uint8_t ret[ONION_RETURN_3];
47 uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
43 uint64_t time; 48 uint64_t time;
44} Onion_Announce_Entry; 49} Onion_Announce_Entry;
45 50
@@ -59,6 +64,7 @@ typedef struct {
59 * public_key and secret_key is the kepair which will be used to encrypt the request. 64 * public_key and secret_key is the kepair which will be used to encrypt the request.
60 * ping_id is the ping id that will be sent in the request. 65 * ping_id is the ping id that will be sent in the request.
61 * client_id is the client id of the node we are searching for. 66 * client_id is the client id of the node we are searching for.
67 * data_public_key is the public key we want others to encrypt their data packets with.
62 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to 68 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
63 * receive back in the response. 69 * receive back in the response.
64 * 70 *
@@ -66,7 +72,7 @@ typedef struct {
66 * return 0 on success. 72 * return 0 on success.
67 */ 73 */
68int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, 74int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id,
69 uint8_t *client_id, uint8_t *sendback_data); 75 uint8_t *client_id, uint8_t *data_public_key, uint8_t *sendback_data);
70 76
71/* Create and send an onion data request packet. 77/* Create and send an onion data request packet.
72 * 78 *
@@ -75,13 +81,15 @@ int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uin
75 * send the packet to that person in the form of a response) 81 * send the packet to that person in the form of a response)
76 * 82 *
77 * public_key is the real public key of the node which we want to send the data of length length to. 83 * public_key is the real public key of the node which we want to send the data of length length to.
84 * encrypt_public_key is the public key used to encrypt the data packet.
85 *
78 * nonce is the nonce to encrypt this packet with 86 * nonce is the nonce to encrypt this packet with
79 * 87 *
80 * return -1 on failure. 88 * return -1 on failure.
81 * return 0 on success. 89 * return 0 on success.
82 */ 90 */
83int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, 91int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *encrypt_public_key, uint8_t *nonce,
84 uint16_t length); 92 uint8_t *data, uint16_t length);
85 93
86 94
87Onion_Announce *new_onion_announce(DHT *dht); 95Onion_Announce *new_onion_announce(DHT *dht);
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 27823f0d..32928fd9 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -30,7 +30,6 @@
30 30
31#define ANNOUNCE_TIMEOUT 10 31#define ANNOUNCE_TIMEOUT 10
32 32
33static uint8_t zero_ping[ONION_PING_ID_SIZE];
34 33
35/* Creates a sendback for use in an announce request. 34/* Creates a sendback for use in an announce request.
36 * 35 *
@@ -107,7 +106,7 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
107 106
108 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 107 uint8_t sendback[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
109 108
110 if (new_sendback(onion_c, 0, dest_pubkey, dest, sendback) == -1) 109 if (new_sendback(onion_c, num, dest_pubkey, dest, sendback) == -1)
111 return -1; 110 return -1;
112 111
113 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0}; 112 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
@@ -126,11 +125,11 @@ static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_
126 if (num == 0) { 125 if (num == 0) {
127 return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key, 126 return send_announce_request(onion_c->dht, nodes, onion_c->dht->c->self_public_key,
128 onion_c->dht->c->self_secret_key, ping_id, 127 onion_c->dht->c->self_secret_key, ping_id,
129 onion_c->dht->c->self_public_key, sendback); 128 onion_c->dht->c->self_public_key, onion_c->temp_public_key, sendback);
130 } else { 129 } else {
131 return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key, 130 return send_announce_request(onion_c->dht, nodes, onion_c->friends_list[num - 1].temp_public_key,
132 onion_c->friends_list[num - 1].temp_secret_key, ping_id, 131 onion_c->friends_list[num - 1].temp_secret_key, ping_id,
133 onion_c->friends_list[num - 1].real_client_id, sendback); 132 onion_c->friends_list[num - 1].real_client_id, zero_ping_id, sendback);
134 } 133 }
135} 134}
136 135
@@ -164,7 +163,7 @@ static int cmp_entry(const void *a, const void *b)
164} 163}
165 164
166static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, 165static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port,
167 uint8_t *ping_id) 166 uint8_t is_stored, uint8_t *pingid_or_key)
168{ 167{
169 if (num > onion_c->num_friends) 168 if (num > onion_c->num_friends)
170 return -1; 169 return -1;
@@ -204,7 +203,14 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *publ
204 203
205 memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE); 204 memcpy(list_nodes[index].client_id, public_key, CLIENT_ID_SIZE);
206 list_nodes[index].ip_port = ip_port; 205 list_nodes[index].ip_port = ip_port;
207 memcpy(list_nodes[index].ping_id, ping_id, ONION_PING_ID_SIZE); 206
207 if (is_stored) {
208 memcpy(list_nodes[index].data_public_key, pingid_or_key, crypto_box_PUBLICKEYBYTES);
209 } else {
210 memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE);
211 }
212
213 list_nodes[index].is_stored = is_stored;
208 list_nodes[index].timestamp = unix_time(); 214 list_nodes[index].timestamp = unix_time();
209 list_nodes[index].last_pinged = 0; 215 list_nodes[index].last_pinged = 0;
210 return 0; 216 return 0;
@@ -230,7 +236,7 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
230 reference_id = onion_c->friends_list[num - 1].real_client_id; 236 reference_id = onion_c->friends_list[num - 1].real_client_id;
231 } 237 }
232 238
233 uint32_t i; 239 uint32_t i, j;
234 int lan_ips_accepted = (LAN_ip(source.ip) == 0); 240 int lan_ips_accepted = (LAN_ip(source.ip) == 0);
235 241
236 for (i = 0; i < num_nodes; ++i) { 242 for (i = 0; i < num_nodes; ++i) {
@@ -242,7 +248,15 @@ static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, Node_format *n
242 248
243 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT) 249 if (is_timeout(list_nodes[0].timestamp, ONION_NODE_TIMEOUT)
244 || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) { 250 || id_closest(reference_id, list_nodes[0].client_id, nodes[i].client_id) == 2) {
245 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL); 251 /* check if node is already in list. */
252 for (j = 0; j < MAX_ONION_CLIENTS; ++j) {
253 if (memcmp(list_nodes[j].client_id, nodes[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) {
254 break;
255 }
256 }
257
258 if (j == MAX_ONION_CLIENTS)
259 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].client_id, NULL);
246 } 260 }
247 } 261 }
248 262
@@ -268,7 +282,7 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
268 if (num > onion_c->num_friends) 282 if (num > onion_c->num_friends)
269 return 1; 283 return 1;
270 284
271 uint8_t plain[ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)]; 285 uint8_t plain[1 + ONION_PING_ID_SIZE + num_nodes * sizeof(Node_format)];
272 int len = -1; 286 int len = -1;
273 287
274 if (num == 0) { 288 if (num == 0) {
@@ -289,10 +303,10 @@ static int handle_announce_response(void *object, IP_Port source, uint8_t *packe
289 return 1; 303 return 1;
290 304
291 305
292 if (client_add_to_list(onion_c, num, public_key, ip_port, plain) == -1) 306 if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1) == -1)
293 return 1; 307 return 1;
294 308
295 if (client_ping_nodes(onion_c, num, (Node_format *)plain + ONION_PING_ID_SIZE, num_nodes, source) == -1) 309 if (client_ping_nodes(onion_c, num, (Node_format *)plain + 1 + ONION_PING_ID_SIZE, num_nodes, source) == -1)
296 return 1; 310 return 1;
297 311
298 return 0; 312 return 0;
@@ -311,7 +325,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
311 return 1; 325 return 1;
312 326
313 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE]; 327 uint8_t temp_plain[length - ONION_DATA_RESPONSE_MIN_SIZE];
314 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->dht->c->self_secret_key, packet + 1, 328 int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_c->temp_secret_key, packet + 1,
315 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, 329 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES,
316 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain); 330 length - (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES), temp_plain);
317 331
@@ -333,7 +347,7 @@ static int handle_data_response(void *object, IP_Port source, uint8_t *packet, u
333} 347}
334 348
335#define FAKEID_DATA_ID 156 349#define FAKEID_DATA_ID 156
336#define FAKEID_DATA_MIN_LENGTH (1 + crypto_box_PUBLICKEYBYTES) 350#define FAKEID_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES)
337#define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES) 351#define FAKEID_DATA_MAX_LENGTH (FAKEID_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES)
338static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length) 352static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length)
339{ 353{
@@ -353,19 +367,30 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
353 if (friend_num == -1) 367 if (friend_num == -1)
354 return 1; 368 return 1;
355 369
356 if (memcmp(data + 1, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) != 0) { 370 uint64_t no_replay;
371 net_to_host(data + 1, sizeof(no_replay));
372 memcpy(&no_replay, data + 1, sizeof(uint64_t));
373
374 if (no_replay <= onion_c->friends_list[friend_num].last_noreplay)
375 return 1;
376
377 onion_c->friends_list[friend_num].last_noreplay = no_replay;
378
379 if (memcmp(data + 1 + sizeof(uint64_t), onion_c->friends_list[friend_num].fake_client_id,
380 crypto_box_PUBLICKEYBYTES) != 0) {
357 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); 381 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
358 382
359 if (DHT_addfriend(onion_c->dht, data + 1) == 1) { 383 if (DHT_addfriend(onion_c->dht, data + 1 + sizeof(uint64_t)) == 1) {
360 return 1; 384 return 1;
361 } 385 }
362 386
363 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1, crypto_box_PUBLICKEYBYTES); 387 onion_c->friends_list[friend_num].is_fake_clientid = 1;
388 memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
364 } 389 }
365 390
366 uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format); 391 uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format);
367 Node_format nodes[num_nodes]; 392 Node_format nodes[num_nodes];
368 memcpy(nodes, data + 1 + crypto_box_PUBLICKEYBYTES, sizeof(nodes)); 393 memcpy(nodes, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
369 uint32_t i; 394 uint32_t i;
370 395
371 for (i = 0; i < num_nodes; ++i) { 396 for (i = 0; i < num_nodes; ++i) {
@@ -373,7 +398,6 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t
373 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); 398 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
374 } 399 }
375 400
376 //TODO replay protection
377 return 0; 401 return 0;
378} 402}
379/* Send data of length length to friendnum. 403/* Send data of length length to friendnum.
@@ -413,7 +437,7 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
413 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) 437 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
414 continue; 438 continue;
415 439
416 if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { 440 if (list_nodes[i].is_stored) {
417 Node_format nodes[4]; 441 Node_format nodes[4];
418 442
419 if (random_path(onion_c, nodes) == -1) 443 if (random_path(onion_c, nodes) == -1)
@@ -422,8 +446,8 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
422 memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES); 446 memcpy(nodes[3].client_id, list_nodes[i].client_id, crypto_box_PUBLICKEYBYTES);
423 nodes[3].ip_port = list_nodes[i].ip_port; 447 nodes[3].ip_port = list_nodes[i].ip_port;
424 448
425 if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id, nonce, packet, 449 if (send_data_request(onion_c->dht, nodes, onion_c->friends_list[friend_num].real_client_id,
426 sizeof(packet)) == 0) 450 list_nodes[i].data_public_key, nonce, packet, sizeof(packet)) == 0)
427 ++good; 451 ++good;
428 } 452 }
429 } 453 }
@@ -431,24 +455,104 @@ int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32
431 return good; 455 return good;
432} 456}
433 457
434/* Send the packets to tell our friends 458/* Try to send the fakeid via the DHT instead of onion
459 *
460 * Even if this function succeeds, the friend might not recieve any data.
461 *
435 * return the number of packets sent on success 462 * return the number of packets sent on success
436 * return -1 on failure. 463 * return -1 on failure.
437 */ 464 */
438static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num) 465static int send_dht_fakeid(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length)
466{
467 if ((uint32_t)friend_num >= onion_c->num_friends)
468 return -1;
469
470 if (!onion_c->friends_list[friend_num].is_fake_clientid)
471 return -1;
472
473 uint8_t nonce[crypto_box_NONCEBYTES];
474 new_nonce(nonce);
475
476 uint8_t temp[DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES + length];
477 memcpy(temp, onion_c->dht->c->self_public_key, crypto_box_PUBLICKEYBYTES);
478 memcpy(temp + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
479 int len = encrypt_data(onion_c->friends_list[friend_num].real_client_id, onion_c->dht->c->self_secret_key, nonce, data,
480 length, temp + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
481
482 if ((uint32_t)len + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES != sizeof(temp))
483 return -1;
484
485 uint8_t packet[MAX_DATA_SIZE];
486 len = create_request(onion_c->dht->self_public_key, onion_c->dht->self_secret_key, packet,
487 onion_c->friends_list[friend_num].fake_client_id, temp, sizeof(temp), FAKEID_DATA_ID);
488
489 if (len == -1)
490 return -1;
491
492 return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, packet, len);
493}
494
495static int handle_dht_fakeid(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
496{
497 Onion_Client *onion_c = object;
498
499 if (length < FAKEID_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
500 return 1;
501
502 if (length > FAKEID_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES)
503 return 1;
504
505 uint8_t plain[FAKEID_DATA_MAX_LENGTH];
506 int len = decrypt_data(packet, onion_c->dht->c->self_secret_key, packet + crypto_box_PUBLICKEYBYTES,
507 packet + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES,
508 length - (crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES), plain);
509
510 if ((uint32_t)len != length - (DATA_IN_RESPONSE_MIN_SIZE + crypto_box_NONCEBYTES))
511 return 1;
512
513 if (memcpy(source_pubkey, packet, crypto_box_PUBLICKEYBYTES) != 0)
514 return 1;
515
516 return handle_fakeid_announce(onion_c, packet, plain, len);
517}
518/* Send the packets to tell our friends what our DHT public key is.
519 *
520 * if onion_dht_both is 0, use only the onion to send the packet.
521 * if it is 1, use only the dht.
522 * if it is something else, use both.
523 *
524 * return the number of packets sent on success
525 * return -1 on failure.
526 */
527static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
439{ 528{
440 if (friend_num >= onion_c->num_friends) 529 if (friend_num >= onion_c->num_friends)
441 return -1; 530 return -1;
442 531
443 uint8_t data[FAKEID_DATA_MAX_LENGTH]; 532 uint8_t data[FAKEID_DATA_MAX_LENGTH];
444 data[0] = FAKEID_DATA_ID; 533 data[0] = FAKEID_DATA_ID;
445 memcpy(data + 1, onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); 534 uint64_t no_replay = unix_time();
535 host_to_net((uint8_t *)&no_replay, sizeof(no_replay));
536 memcpy(data + 1, &no_replay, sizeof(no_replay));
537 memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES);
446 Node_format nodes[MAX_SENT_NODES]; 538 Node_format nodes[MAX_SENT_NODES];
447 uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); 539 uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES);
448 memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes); 540 memcpy(data + FAKEID_DATA_MIN_LENGTH, nodes, sizeof(Node_format) * num_nodes);
449 return send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes); 541 int num1 = -1, num2 = -1;
450 //TODO: somehow make this function send our DHT client id directly to the other if we know theirs but they don't 542
451 //seem to know ours. 543 if (onion_dht_both != 1)
544 num1 = send_onion_data(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
545
546 if (onion_dht_both != 0)
547 num2 = send_dht_fakeid(onion_c, friend_num, data, FAKEID_DATA_MIN_LENGTH + sizeof(Node_format) * num_nodes);
548
549 if (num1 == -1)
550 return num2;
551
552 if (num2 == -1)
553 return num1;
554
555 return num1 + num2;
452} 556}
453 557
454/* Get the friend_num of a friend. 558/* Get the friend_num of a friend.
@@ -525,6 +629,7 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id)
525 629
526 onion_c->friends_list[index].status = 1; 630 onion_c->friends_list[index].status = 1;
527 memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES); 631 memcpy(onion_c->friends_list[index].real_client_id, client_id, crypto_box_PUBLICKEYBYTES);
632 crypto_box_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
528 return index; 633 return index;
529} 634}
530 635
@@ -538,7 +643,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
538 if ((uint32_t)friend_num >= onion_c->num_friends) 643 if ((uint32_t)friend_num >= onion_c->num_friends)
539 return -1; 644 return -1;
540 645
541 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id); 646 if (onion_c->friends_list[friend_num].is_fake_clientid)
647 DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
648
542 memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend)); 649 memset(&(onion_c->friends_list[friend_num]), 0, sizeof(Onion_Friend));
543 uint32_t i; 650 uint32_t i;
544 651
@@ -557,8 +664,9 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
557 664
558/* Get the ip of friend friendnum and put it in ip_port 665/* Get the ip of friend friendnum and put it in ip_port
559 * 666 *
560 * return -1 on failure 667 * return -1, -- if client_id does NOT refer to a friend
561 * return 0 on success 668 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
669 * return 1, ip if client_id refers to a friend and we found him
562 * 670 *
563 */ 671 */
564int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) 672int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
@@ -569,10 +677,31 @@ int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
569 if (onion_c->friends_list[friend_num].status == 0) 677 if (onion_c->friends_list[friend_num].status == 0)
570 return -1; 678 return -1;
571 679
572 if (DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port) == 1) 680 if (!onion_c->friends_list[friend_num].is_fake_clientid)
573 return 0; 681 return -1;
574 682
575 return -1; 683 return DHT_getfriendip(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id, ip_port);
684}
685
686/* Set if friend is online or not.
687 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
688 *
689 * is_online 1 means friend is online.
690 * is_online 0 means friend is offline
691 *
692 * return -1 on failure.
693 * return 0 on success.
694 */
695int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online)
696{
697 if ((uint32_t)friend_num >= onion_c->num_friends)
698 return -1;
699
700 onion_c->friends_list[friend_num].is_online = is_online;
701 /* Should we reset the no_replay when the other goes offline?
702 if (!is_online)
703 onion_c->friends_list[friend_num].last_noreplay = 0; */
704 return 0;
576} 705}
577 706
578/* Takes 3 random nodes that we know and puts them in nodes 707/* Takes 3 random nodes that we know and puts them in nodes
@@ -591,7 +720,7 @@ int random_path(Onion_Client *onion_c, Node_format *nodes)
591 return 0; 720 return 0;
592} 721}
593 722
594#define ANNOUNCE_FRIEND 30 723#define ANNOUNCE_FRIEND 120
595 724
596static void do_friend(Onion_Client *onion_c, uint16_t friendnum) 725static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
597{ 726{
@@ -604,32 +733,39 @@ static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
604 uint32_t i, count = 0; 733 uint32_t i, count = 0;
605 Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list; 734 Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list;
606 735
607 for (i = 0; i < MAX_ONION_CLIENTS; ++i) { 736 if (!onion_c->friends_list[friendnum].is_online) {
608 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT)) 737 for (i = 0; i < MAX_ONION_CLIENTS; ++i) {
609 continue; 738 if (is_timeout(list_nodes[i].timestamp, ONION_NODE_TIMEOUT))
739 continue;
610 740
611 ++count; 741 ++count;
612 742
613 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) { 743 if (is_timeout(list_nodes[i].last_pinged, ANNOUNCE_FRIEND)) {
614 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0) == 0) { 744 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port, list_nodes[i].client_id, 0) == 0) {
615 list_nodes[i].last_pinged = unix_time(); 745 list_nodes[i].last_pinged = unix_time();
746 }
616 } 747 }
617 } 748 }
618 }
619 749
620 if (count < MAX_ONION_CLIENTS / 2) { 750 if (count < MAX_ONION_CLIENTS / 2) {
621 Node_format nodes_list[MAX_SENT_NODES]; 751 Node_format nodes_list[MAX_SENT_NODES];
622 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[i].real_client_id, nodes_list, 752 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->friends_list[friendnum].real_client_id, nodes_list,
623 rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1); 753 rand() % 2 ? AF_INET : AF_INET6, 1, 0);
624 754
625 for (i = 0; i < num_nodes; ++i) 755 for (i = 0; i < num_nodes; ++i)
626 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0); 756 client_send_announce_request(onion_c, friendnum + 1, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
627 } 757 }
758
759
760 /* send packets to friend telling them our fake DHT id. */
761 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_onion_sent, ONION_FAKEID_INTERVAL))
762 if (send_fakeid_announce(onion_c, friendnum, 0) > 1)
763 onion_c->friends_list[friendnum].last_fakeid_onion_sent = unix_time();
628 764
629 /* send packets to friend telling them our fake DHT id. */ 765 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_dht_sent, DHT_FAKEID_INTERVAL))
630 if (is_timeout(onion_c->friends_list[friendnum].last_fakeid_sent, ONION_FAKEID_INTERVAL)) 766 if (send_fakeid_announce(onion_c, friendnum, 1) > 1)
631 if (send_fakeid_announce(onion_c, friendnum) > 3) 767 onion_c->friends_list[friendnum].last_fakeid_dht_sent = unix_time();
632 onion_c->friends_list[friendnum].last_fakeid_sent = unix_time(); 768 }
633} 769}
634/* Function to call when onion data packet with contents beginning with byte is received. */ 770/* Function to call when onion data packet with contents beginning with byte is received. */
635void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object) 771void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object)
@@ -639,7 +775,7 @@ void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_ha
639} 775}
640 776
641#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10 777#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 10
642#define ANNOUNCE_INTERVAL_ANNOUNCED 60 778#define ANNOUNCE_INTERVAL_ANNOUNCED 120
643 779
644static void do_announce(Onion_Client *onion_c) 780static void do_announce(Onion_Client *onion_c)
645{ 781{
@@ -653,7 +789,7 @@ static void do_announce(Onion_Client *onion_c)
653 ++count; 789 ++count;
654 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED; 790 uint32_t interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
655 791
656 if (memcmp(list_nodes[i].ping_id, zero_ping, ONION_PING_ID_SIZE) == 0) { 792 if (list_nodes[i].is_stored) {
657 interval = ANNOUNCE_INTERVAL_ANNOUNCED; 793 interval = ANNOUNCE_INTERVAL_ANNOUNCED;
658 } 794 }
659 795
@@ -668,7 +804,7 @@ static void do_announce(Onion_Client *onion_c)
668 if (count < MAX_ONION_CLIENTS / 2) { 804 if (count < MAX_ONION_CLIENTS / 2) {
669 Node_format nodes_list[MAX_SENT_NODES]; 805 Node_format nodes_list[MAX_SENT_NODES];
670 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list, 806 uint32_t num_nodes = get_close_nodes(onion_c->dht, onion_c->dht->c->self_public_key, nodes_list,
671 rand() % 2 ? AF_INET : AF_INET6, rand() % 2, 1); 807 rand() % 2 ? AF_INET : AF_INET6, 1, 0);
672 808
673 for (i = 0; i < num_nodes; ++i) 809 for (i = 0; i < num_nodes; ++i)
674 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0); 810 client_send_announce_request(onion_c, 0, nodes_list[i].ip_port, nodes_list[i].client_id, 0);
@@ -704,16 +840,20 @@ Onion_Client *new_onion_client(DHT *dht)
704 onion_c->dht = dht; 840 onion_c->dht = dht;
705 onion_c->net = dht->c->lossless_udp->net; 841 onion_c->net = dht->c->lossless_udp->net;
706 new_symmetric_key(onion_c->secret_symmetric_key); 842 new_symmetric_key(onion_c->secret_symmetric_key);
707 843 crypto_box_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
708 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c); 844 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
709 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 845 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
710 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c); 846 oniondata_registerhandler(onion_c, FAKEID_DATA_ID, &handle_fakeid_announce, onion_c);
847 cryptopacket_registerhandler(onion_c->dht->c, FAKEID_DATA_ID, &handle_dht_fakeid, onion_c);
711 848
712 return onion_c; 849 return onion_c;
713} 850}
714 851
715void kill_onion_client(Onion_Client *onion_c) 852void kill_onion_client(Onion_Client *onion_c)
716{ 853{
854 if (onion_c == NULL)
855 return;
856
717 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL); 857 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, NULL, NULL);
718 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 858 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
719 free(onion_c); 859 free(onion_c);
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index 181bc533..9491b0b7 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -27,15 +27,19 @@
27#include "onion_announce.h" 27#include "onion_announce.h"
28 28
29#define MAX_ONION_CLIENTS 8 29#define MAX_ONION_CLIENTS 8
30#define ONION_NODE_TIMEOUT 200 30#define ONION_NODE_TIMEOUT 240
31 31
32/* The interval in seconds at which to tell our friends where we are */ 32/* The interval in seconds at which to tell our friends where we are */
33#define ONION_FAKEID_INTERVAL 60 33#define ONION_FAKEID_INTERVAL 60
34#define DHT_FAKEID_INTERVAL 20
34 35
35typedef struct { 36typedef struct {
36 uint8_t client_id[CLIENT_ID_SIZE]; 37 uint8_t client_id[CLIENT_ID_SIZE];
37 IP_Port ip_port; 38 IP_Port ip_port;
38 uint8_t ping_id[ONION_PING_ID_SIZE]; 39 uint8_t ping_id[ONION_PING_ID_SIZE];
40 uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
41 uint8_t is_stored;
42
39 uint64_t timestamp; 43 uint64_t timestamp;
40 44
41 uint64_t last_pinged; 45 uint64_t last_pinged;
@@ -43,7 +47,9 @@ typedef struct {
43 47
44typedef struct { 48typedef struct {
45 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/ 49 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
50 uint8_t is_online; /* Set by the onion_set_friend_status function. */
46 51
52 uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
47 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES]; 53 uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
48 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES]; 54 uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
49 55
@@ -51,7 +57,10 @@ typedef struct {
51 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 57 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
52 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 58 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
53 59
54 uint64_t last_fakeid_sent; 60 uint64_t last_fakeid_onion_sent;
61 uint64_t last_fakeid_dht_sent;
62
63 uint64_t last_noreplay;
55} Onion_Friend; 64} Onion_Friend;
56 65
57typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); 66typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
@@ -67,6 +76,8 @@ typedef struct {
67 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES]; 76 uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
68 uint64_t last_run; 77 uint64_t last_run;
69 78
79 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
80 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
70 struct { 81 struct {
71 oniondata_handler_callback function; 82 oniondata_handler_callback function;
72 void *object; 83 void *object;
@@ -94,10 +105,22 @@ int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id);
94 */ 105 */
95int onion_delfriend(Onion_Client *onion_c, int friend_num); 106int onion_delfriend(Onion_Client *onion_c, int friend_num);
96 107
108/* Set if friend is online or not.
109 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
110 *
111 * is_online 1 means friend is online.
112 * is_online 0 means friend is offline
113 *
114 * return -1 on failure.
115 * return 0 on success.
116 */
117int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
118
97/* Get the ip of friend friendnum and put it in ip_port 119/* Get the ip of friend friendnum and put it in ip_port
98 * 120 *
99 * return -1 on failure 121 * return -1, -- if client_id does NOT refer to a friend
100 * return 0 on success 122 * return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
123 * return 1, ip if client_id refers to a friend and we found him
101 * 124 *
102 */ 125 */
103int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 126int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 6c368d0c..a37b531d 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -47,7 +47,7 @@ typedef struct {
47} pinged_t; 47} pinged_t;
48 48
49struct PING { 49struct PING {
50 Net_Crypto *c; 50 DHT *dht;
51 51
52 pinged_t pings[PING_NUM_MAX]; 52 pinged_t pings[PING_NUM_MAX];
53 size_t num_pings; 53 size_t num_pings;
@@ -148,19 +148,19 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
148 int rc; 148 int rc;
149 uint64_t ping_id; 149 uint64_t ping_id;
150 150
151 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->c->self_public_key)) 151 if (is_pinging(ping, ipp, 0) || id_equal(client_id, ping->dht->self_public_key))
152 return 1; 152 return 1;
153 153
154 // Generate random ping_id. 154 // Generate random ping_id.
155 ping_id = add_ping(ping, ipp); 155 ping_id = add_ping(ping, ipp);
156 156
157 pk[0] = NET_PACKET_PING_REQUEST; 157 pk[0] = NET_PACKET_PING_REQUEST;
158 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey 158 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
159 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 159 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
160 160
161 // Encrypt ping_id using recipient privkey 161 // Encrypt ping_id using recipient privkey
162 rc = encrypt_data(client_id, 162 rc = encrypt_data(client_id,
163 ping->c->self_secret_key, 163 ping->dht->self_secret_key,
164 pk + 1 + CLIENT_ID_SIZE, 164 pk + 1 + CLIENT_ID_SIZE,
165 (uint8_t *) &ping_id, sizeof(ping_id), 165 (uint8_t *) &ping_id, sizeof(ping_id),
166 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 166 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
@@ -168,7 +168,7 @@ int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id)
168 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 168 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
169 return 1; 169 return 1;
170 170
171 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 171 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
172} 172}
173 173
174static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id) 174static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id)
@@ -176,16 +176,16 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
176 uint8_t pk[DHT_PING_SIZE]; 176 uint8_t pk[DHT_PING_SIZE];
177 int rc; 177 int rc;
178 178
179 if (id_equal(client_id, ping->c->self_public_key)) 179 if (id_equal(client_id, ping->dht->self_public_key))
180 return 1; 180 return 1;
181 181
182 pk[0] = NET_PACKET_PING_RESPONSE; 182 pk[0] = NET_PACKET_PING_RESPONSE;
183 id_copy(pk + 1, ping->c->self_public_key); // Our pubkey 183 id_copy(pk + 1, ping->dht->self_public_key); // Our pubkey
184 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce 184 new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
185 185
186 // Encrypt ping_id using recipient privkey 186 // Encrypt ping_id using recipient privkey
187 rc = encrypt_data(client_id, 187 rc = encrypt_data(client_id,
188 ping->c->self_secret_key, 188 ping->dht->self_secret_key,
189 pk + 1 + CLIENT_ID_SIZE, 189 pk + 1 + CLIENT_ID_SIZE,
190 (uint8_t *) &ping_id, sizeof(ping_id), 190 (uint8_t *) &ping_id, sizeof(ping_id),
191 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES); 191 pk + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES);
@@ -193,7 +193,7 @@ static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint6
193 if (rc != sizeof(ping_id) + crypto_box_MACBYTES) 193 if (rc != sizeof(ping_id) + crypto_box_MACBYTES)
194 return 1; 194 return 1;
195 195
196 return sendpacket(ping->c->lossless_udp->net, ipp, pk, sizeof(pk)); 196 return sendpacket(ping->dht->net, ipp, pk, sizeof(pk));
197} 197}
198 198
199static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length) 199static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length)
@@ -207,12 +207,12 @@ static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint
207 207
208 PING *ping = dht->ping; 208 PING *ping = dht->ping;
209 209
210 if (id_equal(packet + 1, ping->c->self_public_key)) 210 if (id_equal(packet + 1, ping->dht->self_public_key))
211 return 1; 211 return 1;
212 212
213 // Decrypt ping_id 213 // Decrypt ping_id
214 rc = decrypt_data(packet + 1, 214 rc = decrypt_data(packet + 1,
215 ping->c->self_secret_key, 215 ping->dht->self_secret_key,
216 packet + 1 + CLIENT_ID_SIZE, 216 packet + 1 + CLIENT_ID_SIZE,
217 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 217 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
218 sizeof(ping_id) + crypto_box_MACBYTES, 218 sizeof(ping_id) + crypto_box_MACBYTES,
@@ -239,12 +239,12 @@ static int handle_ping_response(void *_dht, IP_Port source, uint8_t *packet, uin
239 239
240 PING *ping = dht->ping; 240 PING *ping = dht->ping;
241 241
242 if (id_equal(packet + 1, ping->c->self_public_key)) 242 if (id_equal(packet + 1, ping->dht->self_public_key))
243 return 1; 243 return 1;
244 244
245 // Decrypt ping_id 245 // Decrypt ping_id
246 rc = decrypt_data(packet + 1, 246 rc = decrypt_data(packet + 1,
247 ping->c->self_secret_key, 247 ping->dht->self_secret_key,
248 packet + 1 + CLIENT_ID_SIZE, 248 packet + 1 + CLIENT_ID_SIZE,
249 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES, 249 packet + 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES,
250 sizeof(ping_id) + crypto_box_MACBYTES, 250 sizeof(ping_id) + crypto_box_MACBYTES,
@@ -291,7 +291,7 @@ int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port)
291 } 291 }
292 292
293 for (i = 0; i < MAX_TOPING; ++i) { 293 for (i = 0; i < MAX_TOPING; ++i) {
294 if (id_closest(ping->c->self_public_key, ping->toping[i].client_id, client_id) == 2) { 294 if (id_closest(ping->dht->self_public_key, ping->toping[i].client_id, client_id) == 2) {
295 memcpy(ping->toping[i].client_id, client_id, CLIENT_ID_SIZE); 295 memcpy(ping->toping[i].client_id, client_id, CLIENT_ID_SIZE);
296 ipport_copy(&ping->toping[i].ip_port, &ip_port); 296 ipport_copy(&ping->toping[i].ip_port, &ip_port);
297 return 0; 297 return 0;
@@ -323,24 +323,24 @@ void do_toping(PING *ping)
323} 323}
324 324
325 325
326PING *new_ping(DHT *dht, Net_Crypto *c) 326PING *new_ping(DHT *dht)
327{ 327{
328 PING *ping = calloc(1, sizeof(PING)); 328 PING *ping = calloc(1, sizeof(PING));
329 329
330 if (ping == NULL) 330 if (ping == NULL)
331 return NULL; 331 return NULL;
332 332
333 ping->c = c; 333 ping->dht = dht;
334 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht); 334 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, &handle_ping_request, dht);
335 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht); 335 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, &handle_ping_response, dht);
336 336
337 return ping; 337 return ping;
338} 338}
339 339
340void kill_ping(PING *ping) 340void kill_ping(PING *ping)
341{ 341{
342 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_REQUEST, NULL, NULL); 342 networking_registerhandler(ping->dht->net, NET_PACKET_PING_REQUEST, NULL, NULL);
343 networking_registerhandler(ping->c->lossless_udp->net, NET_PACKET_PING_RESPONSE, NULL, NULL); 343 networking_registerhandler(ping->dht->net, NET_PACKET_PING_RESPONSE, NULL, NULL);
344 344
345 free(ping); 345 free(ping);
346} 346}
diff --git a/toxcore/ping.h b/toxcore/ping.h
index 00e1c697..a0008f3c 100644
--- a/toxcore/ping.h
+++ b/toxcore/ping.h
@@ -39,7 +39,7 @@ typedef struct PING PING;
39int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port); 39int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port);
40void do_toping(PING *ping); 40void do_toping(PING *ping);
41 41
42PING *new_ping(DHT *dht, Net_Crypto *c); 42PING *new_ping(DHT *dht);
43void kill_ping(PING *ping); 43void kill_ping(PING *ping);
44 44
45int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id); 45int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id);
diff --git a/toxcore/util.c b/toxcore/util.c
index 9af7262f..d56c446e 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -65,6 +65,25 @@ uint32_t id_copy(uint8_t *dest, uint8_t *src)
65 return CLIENT_ID_SIZE; 65 return CLIENT_ID_SIZE;
66} 66}
67 67
68void host_to_net(uint8_t *num, uint16_t numbytes)
69{
70 union {
71 uint32_t i;
72 uint8_t c[4];
73 } a;
74 a.i = 1;
75
76 if (a.c[0] == 1) {
77 uint32_t i;
78 uint8_t buff[numbytes];
79
80 for (i = 0; i < numbytes; ++i) {
81 buff[i] = num[numbytes - i - 1];
82 }
83
84 memcpy(num, buff, numbytes);
85 }
86}
68 87
69/* state load/save */ 88/* state load/save */
70int load_state(load_state_callback_func load_state_callback, void *outer, 89int load_state(load_state_callback_func load_state_callback, void *outer,
diff --git a/toxcore/util.h b/toxcore/util.h
index f05a9821..ae364d52 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -37,6 +37,8 @@ int is_timeout(uint64_t timestamp, uint64_t timeout);
37bool id_equal(uint8_t *dest, uint8_t *src); 37bool id_equal(uint8_t *dest, uint8_t *src);
38uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */ 38uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */
39 39
40void host_to_net(uint8_t *num, uint16_t numbytes);
41#define net_to_host(x, y) host_to_net(x, y)
40 42
41/* state load/save */ 43/* state load/save */
42typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); 44typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type);