diff options
-rw-r--r-- | auto_tests/onion_test.c | 16 | ||||
-rw-r--r-- | auto_tests/tox_test.c | 23 | ||||
-rw-r--r-- | docs/Prevent_Tracking.txt | 20 | ||||
-rw-r--r-- | docs/updates/Crypto.md | 2 | ||||
-rw-r--r-- | other/DHT_bootstrap.c | 12 | ||||
-rw-r--r-- | toxcore/DHT.c | 135 | ||||
-rw-r--r-- | toxcore/DHT.h | 8 | ||||
-rw-r--r-- | toxcore/LAN_discovery.c | 16 | ||||
-rw-r--r-- | toxcore/LAN_discovery.h | 2 | ||||
-rw-r--r-- | toxcore/Messenger.c | 66 | ||||
-rw-r--r-- | toxcore/Messenger.h | 7 | ||||
-rw-r--r-- | toxcore/friend_requests.c | 46 | ||||
-rw-r--r-- | toxcore/friend_requests.h | 6 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 4 | ||||
-rw-r--r-- | toxcore/onion.c | 3 | ||||
-rw-r--r-- | toxcore/onion_announce.c | 66 | ||||
-rw-r--r-- | toxcore/onion_announce.h | 16 | ||||
-rw-r--r-- | toxcore/onion_client.c | 254 | ||||
-rw-r--r-- | toxcore/onion_client.h | 31 | ||||
-rw-r--r-- | toxcore/ping.c | 40 | ||||
-rw-r--r-- | toxcore/ping.h | 2 | ||||
-rw-r--r-- | toxcore/util.c | 19 | ||||
-rw-r--r-- | toxcore/util.h | 2 |
23 files changed, 543 insertions, 253 deletions
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 17151398..4dae2136 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c | |||
@@ -73,15 +73,15 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t | |||
73 | { | 73 | { |
74 | Onion *onion = object; | 74 | Onion *onion = object; |
75 | 75 | ||
76 | if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_hash_sha256_BYTES + | 76 | if (length != (1 + crypto_box_NONCEBYTES + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + 1 + crypto_hash_sha256_BYTES + |
77 | crypto_box_MACBYTES)) | 77 | crypto_box_MACBYTES)) |
78 | return 1; | 78 | return 1; |
79 | 79 | ||
80 | uint8_t plain[crypto_hash_sha256_BYTES]; | 80 | uint8_t plain[1 + crypto_hash_sha256_BYTES]; |
81 | //print_client_id(packet, length); | 81 | //print_client_id(packet, length); |
82 | int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, | 82 | int len = decrypt_data(test_3_pub_key, onion->dht->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, |
83 | packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, | 83 | packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, |
84 | crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain); | 84 | 1 + crypto_hash_sha256_BYTES + crypto_box_MACBYTES, plain); |
85 | 85 | ||
86 | if (len == -1) | 86 | if (len == -1) |
87 | return 1; | 87 | return 1; |
@@ -90,7 +90,7 @@ static int handle_test_3(void *object, IP_Port source, uint8_t *packet, uint32_t | |||
90 | if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) | 90 | if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) |
91 | return 1; | 91 | return 1; |
92 | 92 | ||
93 | memcpy(test_3_ping_id, plain, crypto_hash_sha256_BYTES); | 93 | memcpy(test_3_ping_id, plain + 1, crypto_hash_sha256_BYTES); |
94 | //print_client_id(test_3_ping_id, sizeof(test_3_ping_id)); | 94 | //print_client_id(test_3_ping_id, sizeof(test_3_ping_id)); |
95 | handled_test_3 = 1; | 95 | handled_test_3 = 1; |
96 | return 0; | 96 | return 0; |
@@ -174,7 +174,7 @@ START_TEST(test_basic) | |||
174 | randombytes(sb_data, sizeof(sb_data)); | 174 | randombytes(sb_data, sizeof(sb_data)); |
175 | memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES); | 175 | memcpy(test_3_pub_key, nodes[3].client_id, crypto_box_PUBLICKEYBYTES); |
176 | ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, | 176 | ret = send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, |
177 | zeroes, onion1->dht->c->self_public_key, sb_data); | 177 | zeroes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data); |
178 | ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet."); | 178 | ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet."); |
179 | handled_test_3 = 0; | 179 | handled_test_3 = 0; |
180 | 180 | ||
@@ -188,7 +188,7 @@ START_TEST(test_basic) | |||
188 | onion2_a->entries[1].time = unix_time(); | 188 | onion2_a->entries[1].time = unix_time(); |
189 | networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); | 189 | networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1); |
190 | send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, | 190 | send_announce_request(onion1->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_secret_key, |
191 | test_3_ping_id, onion1->dht->c->self_public_key, sb_data); | 191 | test_3_ping_id, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, sb_data); |
192 | 192 | ||
193 | while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key, | 193 | while (memcmp(onion2_a->entries[ONION_ANNOUNCE_MAX_ENTRIES - 2].public_key, onion1->dht->c->self_public_key, |
194 | crypto_box_PUBLICKEYBYTES) != 0) { | 194 | crypto_box_PUBLICKEYBYTES) != 0) { |
@@ -202,8 +202,8 @@ START_TEST(test_basic) | |||
202 | ck_assert_msg((onion3 != NULL), "Onion failed initializing."); | 202 | ck_assert_msg((onion3 != NULL), "Onion failed initializing."); |
203 | 203 | ||
204 | new_nonce(nonce); | 204 | new_nonce(nonce); |
205 | ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, nonce, (uint8_t *)"Install gentoo", | 205 | ret = send_data_request(onion3->dht, nodes, onion1->dht->c->self_public_key, onion1->dht->c->self_public_key, |
206 | sizeof("Install gentoo")); | 206 | nonce, (uint8_t *)"Install gentoo", sizeof("Install gentoo")); |
207 | ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet."); | 207 | ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet."); |
208 | handled_test_4 = 0; | 208 | handled_test_4 = 0; |
209 | 209 | ||
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c index 0f54ed7e..06e8e257 100644 --- a/auto_tests/tox_test.c +++ b/auto_tests/tox_test.c | |||
@@ -23,8 +23,9 @@ void accept_friend_request(uint8_t *public_key, uint8_t *data, uint16_t length, | |||
23 | { | 23 | { |
24 | Tox *t = userdata; | 24 | Tox *t = userdata; |
25 | 25 | ||
26 | if (length == 7 && memcmp("Gentoo", data, 7) == 0) | 26 | if (length == 7 && memcmp("Gentoo", data, 7) == 0) { |
27 | tox_add_friend_norequest(t, public_key); | 27 | tox_add_friend_norequest(t, public_key); |
28 | } | ||
28 | } | 29 | } |
29 | uint32_t messages_received; | 30 | uint32_t messages_received; |
30 | 31 | ||
@@ -58,14 +59,22 @@ START_TEST(test_few_clients) | |||
58 | tox_callback_friend_request(tox2, accept_friend_request, tox2); | 59 | tox_callback_friend_request(tox2, accept_friend_request, tox2); |
59 | uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; | 60 | uint8_t address[TOX_FRIEND_ADDRESS_SIZE]; |
60 | tox_get_address(tox2, address); | 61 | tox_get_address(tox2, address); |
61 | int test = tox_add_friend(tox3, address, "Gentoo", 7); | 62 | int test = tox_add_friend(tox3, address, (uint8_t *)"Gentoo", 7); |
62 | ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); | 63 | ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); |
63 | 64 | ||
65 | uint8_t off = 1; | ||
66 | |||
64 | while (1) { | 67 | while (1) { |
65 | tox_do(tox1); | 68 | tox_do(tox1); |
66 | tox_do(tox2); | 69 | tox_do(tox2); |
67 | tox_do(tox3); | 70 | tox_do(tox3); |
68 | 71 | ||
72 | if (tox_isconnected(tox1) && tox_isconnected(tox2) && tox_isconnected(tox3) && off) { | ||
73 | printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); | ||
74 | off = 0; | ||
75 | } | ||
76 | |||
77 | |||
69 | if (tox_get_friend_connection_status(tox2, 0) == 1 && tox_get_friend_connection_status(tox3, 0) == 1) | 78 | if (tox_get_friend_connection_status(tox2, 0) == 1 && tox_get_friend_connection_status(tox3, 0) == 1) |
70 | break; | 79 | break; |
71 | 80 | ||
@@ -75,7 +84,7 @@ START_TEST(test_few_clients) | |||
75 | printf("tox clients connected\n"); | 84 | printf("tox clients connected\n"); |
76 | uint32_t to_compare = 974536; | 85 | uint32_t to_compare = 974536; |
77 | tox_callback_friend_message(tox3, print_message, &to_compare); | 86 | tox_callback_friend_message(tox3, print_message, &to_compare); |
78 | tox_send_message(tox2, 0, "Install Gentoo", sizeof("Install Gentoo")); | 87 | tox_send_message(tox2, 0, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo")); |
79 | 88 | ||
80 | while (1) { | 89 | while (1) { |
81 | messages_received = 0; | 90 | messages_received = 0; |
@@ -92,7 +101,7 @@ START_TEST(test_few_clients) | |||
92 | printf("tox clients messaging succeeded\n"); | 101 | printf("tox clients messaging succeeded\n"); |
93 | 102 | ||
94 | tox_callback_name_change(tox3, print_nickchange, &to_compare); | 103 | tox_callback_name_change(tox3, print_nickchange, &to_compare); |
95 | tox_set_name(tox2, "Gentoo", sizeof("Gentoo")); | 104 | tox_set_name(tox2, (uint8_t *)"Gentoo", sizeof("Gentoo")); |
96 | 105 | ||
97 | while (1) { | 106 | while (1) { |
98 | name_changes = 0; | 107 | name_changes = 0; |
@@ -113,8 +122,8 @@ START_TEST(test_few_clients) | |||
113 | } | 122 | } |
114 | END_TEST | 123 | END_TEST |
115 | 124 | ||
116 | #define NUM_TOXES 66 | 125 | #define NUM_TOXES 33 |
117 | #define NUM_FRIENDS 20 | 126 | #define NUM_FRIENDS 10 |
118 | 127 | ||
119 | START_TEST(test_many_clients) | 128 | START_TEST(test_many_clients) |
120 | { | 129 | { |
@@ -140,7 +149,7 @@ loop_top: | |||
140 | pairs[i].tox1 = rand() % NUM_TOXES; | 149 | pairs[i].tox1 = rand() % NUM_TOXES; |
141 | pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; | 150 | pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; |
142 | tox_get_address(toxes[pairs[i].tox1], address); | 151 | tox_get_address(toxes[pairs[i].tox1], address); |
143 | int test = tox_add_friend(toxes[pairs[i].tox2], address, "Gentoo", 7); | 152 | int test = tox_add_friend(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7); |
144 | 153 | ||
145 | if (test == TOX_FAERR_ALREADYSENT) { | 154 | if (test == TOX_FAERR_ALREADYSENT) { |
146 | goto loop_top; | 155 | goto loop_top; |
diff --git a/docs/Prevent_Tracking.txt b/docs/Prevent_Tracking.txt index 5f7aaf1e..07e8ae1e 100644 --- a/docs/Prevent_Tracking.txt +++ b/docs/Prevent_Tracking.txt | |||
@@ -97,7 +97,8 @@ Data sent to Node D: | |||
97 | 97 | ||
98 | announce request packet: | 98 | announce request packet: |
99 | [uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)] | 99 | [uint8_t packet id (131)][nonce][our real long term public key or a temporary one (see next)] |
100 | encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce:[[(32 bytes) ping_id][client id we are searching for][data to send back in response(fixed size)]] | 100 | encrypted (with our real long term private key if we want to announce ourselves, a temporary one if we are searching for friends) and the pub key of Node D and the nonce: |
101 | [[(32 bytes) ping_id][client id we are searching for][public key that we want those sending back data packets to use.][data to send back in response(fixed size)]] | ||
101 | 102 | ||
102 | (if the ping id is zero, respond with a announce response packet) | 103 | (if the ping id is zero, respond with a announce response packet) |
103 | (If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for, | 104 | (If the ping id matches the one the node sent in the announce response and the public key matches the one being searched for, |
@@ -105,7 +106,7 @@ add the part used to send data to our list (if the list is full make it replace | |||
105 | 106 | ||
106 | data to route request packet: | 107 | data to route request packet: |
107 | [uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key] | 108 | [uint8_t packet id (133)][public key of destination node][nonce][temporary just generated public key] |
108 | encrypted with that temporary private key and the nonce and the real public key of the destination node:[data] | 109 | encrypted with that temporary private key and the nonce and the public key from the announce response packet of the destination node:[data] |
109 | (if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node) | 110 | (if Node D contains the ret data for the node, it sends the stuff in this packet as a data to route response packet to the right node) |
110 | 111 | ||
111 | The data in the previous packet is in format: [real public key of sender] | 112 | The data in the previous packet is in format: [real public key of sender] |
@@ -114,12 +115,13 @@ encrypted with real private key of the sender, the nonce in the data packet and | |||
114 | Data sent to us: | 115 | Data sent to us: |
115 | announce response packet: | 116 | announce response packet: |
116 | [uint8_t packet id (132)][data to send back in response(fixed size)][nonce] | 117 | [uint8_t packet id (132)][data to send back in response(fixed size)][nonce] |
117 | encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]] | 118 | encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[uint8_t is_stored] |
118 | (if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node) | 119 | [(32 bytes) ping_id if is_stored is 0, public key that must be used to send data packets if is_stored is not 0][Node_Format * (maximum of 8)]] |
120 | (if the is_stored is not 0, it means the information to reach the client id we are searching for is stored on this node) | ||
119 | 121 | ||
120 | data to route response packet: | 122 | data to route response packet: |
121 | [uint8_t packet id (134)][nonce][temporary just generated public key] | 123 | [uint8_t packet id (134)][nonce][temporary just generated public key] |
122 | encrypted with that temporary private key and the nonce and the real public key of the destination node:[data] | 124 | encrypted with that temporary private key, the nonce and the public key from the announce response packet of the destination node:[data] |
123 | 125 | ||
124 | 126 | ||
125 | Onion packet (response): | 127 | Onion packet (response): |
@@ -145,3 +147,11 @@ encrypted with temp symmetric key of Node A: [IP_Port (of us)][data to send back | |||
145 | (sent from node A to us): | 147 | (sent from node A to us): |
146 | 148 | ||
147 | [data to send back] | 149 | [data to send back] |
150 | |||
151 | |||
152 | Data packets: | ||
153 | |||
154 | To tell our friend what our DHT public key is so that he can connect to us we send a data packet with id 156 and | ||
155 | the data being:[uint64_t (in network byte order) no_replay, the packet will only be accepted if this number is bigger than the last one recieved] | ||
156 | [our dht public key][Node_Format * (maximum of 8) nodes closest to us so that the friend can find us faster] | ||
157 | |||
diff --git a/docs/updates/Crypto.md b/docs/updates/Crypto.md index 6b489c3b..a6c701d3 100644 --- a/docs/updates/Crypto.md +++ b/docs/updates/Crypto.md | |||
@@ -20,7 +20,7 @@ case 1: Alice adds Bobs public key and bob waits for Alice to attempt to connect | |||
20 | case 2: Bob and Alice add their respective public keys to their friends list at the same time. | 20 | case 2: Bob and Alice add their respective public keys to their friends list at the same time. |
21 | 21 | ||
22 | case 1: | 22 | case 1: |
23 | Alice sends a crypto request packet to bob with the encrypted part containing the friends request like so: | 23 | Alice sends a onion data (see: Prevent_tracking.txt) packet to bob with the encrypted part containing the friends request like so: |
24 | ``` | 24 | ``` |
25 | [char with a value of 32][nospam number (4 bytes)][Message] | 25 | [char with a value of 32][nospam number (4 bytes)][Message] |
26 | ``` | 26 | ``` |
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 6561fe70..479e97a6 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c | |||
@@ -102,9 +102,19 @@ int main(int argc, char *argv[]) | |||
102 | ip_init(&ip, ipv6enabled); | 102 | ip_init(&ip, ipv6enabled); |
103 | 103 | ||
104 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); | 104 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); |
105 | Onion *onion = new_onion(dht); | ||
106 | Onion_Announce *onion_a = new_onion_announce(dht); | ||
107 | |||
108 | if (!(onion && onion_a)) { | ||
109 | printf("Something failed to initialize.\n"); | ||
110 | exit(1); | ||
111 | } | ||
105 | perror("Initialization"); | 112 | perror("Initialization"); |
106 | 113 | ||
107 | manage_keys(dht); | 114 | manage_keys(dht); |
115 | /* We want our DHT public key to be the same as our internal one since this is a bootstrap server */ | ||
116 | memcpy(dht->self_public_key, dht->c->self_public_key, crypto_box_PUBLICKEYBYTES); | ||
117 | memcpy(dht->self_secret_key, dht->c->self_secret_key, crypto_box_SECRETKEYBYTES); | ||
108 | printf("Public key: "); | 118 | printf("Public key: "); |
109 | uint32_t i; | 119 | uint32_t i; |
110 | 120 | ||
@@ -152,7 +162,7 @@ int main(int argc, char *argv[]) | |||
152 | do_DHT(dht); | 162 | do_DHT(dht); |
153 | 163 | ||
154 | if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) { | 164 | if (is_timeout(last_LANdiscovery, is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL)) { |
155 | send_LANdiscovery(htons(PORT), dht->c); | 165 | send_LANdiscovery(htons(PORT), dht); |
156 | last_LANdiscovery = unix_time(); | 166 | last_LANdiscovery = unix_time(); |
157 | } | 167 | } |
158 | 168 | ||
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 | |||
366 | int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, | 377 | int 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 | ||
736 | end: | 755 | end: |
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: | |||
754 | static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, Node_format *sendback_node) | 775 | static 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 | |||
818 | static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) | 839 | static 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 | ||
884 | void to_net_family(IP *ip) | 905 | void to_net_family(IP *ip) |
@@ -904,7 +925,7 @@ void to_host_family(IP *ip) | |||
904 | static int sendnodes_ipv6(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *client_id, uint8_t *encrypted_data) | 925 | static 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 | ||
950 | static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 971 | static 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 | /* | ||
1143 | static void get_bunchnodes(DHT *dht, Client_data *list, uint16_t length, uint16_t max_num, uint8_t *client_id) | 1165 | static 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 | */ | |
1163 | int DHT_addfriend(DHT *dht, uint8_t *client_id) | 1185 | int 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 | */ |
1344 | static void do_Close(DHT *dht) | 1368 | static 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 | ||
1375 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | 1399 | void 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 | } |
1388 | int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enabled, | 1413 | int 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 | } |
2247 | void kill_DHT(DHT *dht) | 2284 | void 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. */ |
60 | void to_net_family(IP *ip); | 63 | void to_net_family(IP *ip); |
61 | void to_host_family(IP *ip); | 64 | void to_host_family(IP *ip); |
@@ -139,6 +142,7 @@ typedef struct { | |||
139 | 142 | ||
140 | typedef struct { | 143 | typedef 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 | ||
223 | int send_LANdiscovery(uint16_t port, Net_Crypto *c) | 223 | int 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 | ||
256 | void LANdiscovery_init(DHT *dht) | 256 | void 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. */ |
42 | int send_LANdiscovery(uint16_t port, Net_Crypto *c); | 42 | int send_LANdiscovery(uint16_t port, DHT *dht); |
43 | 43 | ||
44 | /* Sets up packet handlers. */ | 44 | /* Sets up packet handlers. */ |
45 | void LANdiscovery_init(DHT *dht); | 45 | void 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 | ||
37 | void 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 | |||
58 | static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); | 37 | static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); |
59 | static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); | 38 | static 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) | |||
1513 | static void LANdiscovery(Messenger *m) | 1504 | static 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 | ||
131 | typedef struct { | 132 | typedef 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 | */ |
38 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length) | 38 | int 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 | ||
133 | static int friendreq_handlepacket(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, | 116 | static 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 | ||
159 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c) | 147 | void 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 | */ |
52 | int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8_t *data, uint32_t length); | 52 | int 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. */ |
54 | void set_nospam(Friend_Requests *fr, uint32_t num); | 54 | void set_nospam(Friend_Requests *fr, uint32_t num); |
55 | uint32_t get_nospam(Friend_Requests *fr); | 55 | uint32_t get_nospam(Friend_Requests *fr); |
@@ -67,7 +67,7 @@ void callback_friendrequest(Friend_Requests *fr, void (*function)(uint8_t *, uin | |||
67 | void set_filter_function(Friend_Requests *fr, int (*function)(uint8_t *, void *), void *userdata); | 67 | void 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. */ |
70 | void friendreq_init(Friend_Requests *fr, Net_Crypto *c); | 70 | void 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 | ||
364 | void kill_onion(Onion *onion) | 364 | void 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 | */ |
52 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, | 53 | int 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 | */ |
86 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, uint16_t length) | 91 | int 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 | */ |
173 | static int add_to_entries(Onion_Announce *onion_a, IP_Port ret_ip_port, uint8_t *public_key, uint8_t *ret) | 179 | static 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 | ||
205 | static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) | 213 | static 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 | ||
322 | void kill_onion_announce(Onion_Announce *onion_a) | 337 | void 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 | |||
39 | typedef struct { | 43 | typedef 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 | */ |
68 | int send_announce_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *secret_key, uint8_t *ping_id, | 74 | int 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 | */ |
83 | int send_data_request(DHT *dht, Node_format *nodes, uint8_t *public_key, uint8_t *nonce, uint8_t *data, | 91 | int 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 | ||
87 | Onion_Announce *new_onion_announce(DHT *dht); | 95 | Onion_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 | ||
33 | static 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 | ||
166 | static int client_add_to_list(Onion_Client *onion_c, uint32_t num, uint8_t *public_key, IP_Port ip_port, | 165 | static 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) |
338 | static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length) | 352 | static 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 | */ |
438 | static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num) | 465 | static 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 | |||
495 | static 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 | */ | ||
527 | static 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 | */ |
564 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port) | 672 | int 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 | */ | ||
695 | int 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 | ||
596 | static void do_friend(Onion_Client *onion_c, uint16_t friendnum) | 725 | static 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. */ |
635 | void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object) | 771 | void 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 | ||
644 | static void do_announce(Onion_Client *onion_c) | 780 | static 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 | ||
715 | void kill_onion_client(Onion_Client *onion_c) | 852 | void 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 | ||
35 | typedef struct { | 36 | typedef 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 | ||
44 | typedef struct { | 48 | typedef 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 | ||
57 | typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | 66 | typedef 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 | */ |
95 | int onion_delfriend(Onion_Client *onion_c, int friend_num); | 106 | int 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 | */ | ||
117 | int 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 | */ |
103 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); | 126 | int 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 | ||
49 | struct PING { | 49 | struct 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 | ||
174 | static int send_ping_response(PING *ping, IP_Port ipp, uint8_t *client_id, uint64_t ping_id) | 174 | static 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 | ||
199 | static int handle_ping_request(void *_dht, IP_Port source, uint8_t *packet, uint32_t length) | 199 | static 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 | ||
326 | PING *new_ping(DHT *dht, Net_Crypto *c) | 326 | PING *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 | ||
340 | void kill_ping(PING *ping) | 340 | void 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; | |||
39 | int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port); | 39 | int add_toping(PING *ping, uint8_t *client_id, IP_Port ip_port); |
40 | void do_toping(PING *ping); | 40 | void do_toping(PING *ping); |
41 | 41 | ||
42 | PING *new_ping(DHT *dht, Net_Crypto *c); | 42 | PING *new_ping(DHT *dht); |
43 | void kill_ping(PING *ping); | 43 | void kill_ping(PING *ping); |
44 | 44 | ||
45 | int send_ping_request(PING *ping, IP_Port ipp, uint8_t *client_id); | 45 | int 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 | ||
68 | void 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 */ |
70 | int load_state(load_state_callback_func load_state_callback, void *outer, | 89 | int 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); | |||
37 | bool id_equal(uint8_t *dest, uint8_t *src); | 37 | bool id_equal(uint8_t *dest, uint8_t *src); |
38 | uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */ | 38 | uint32_t id_copy(uint8_t *dest, uint8_t *src); /* return value is CLIENT_ID_SIZE */ |
39 | 39 | ||
40 | void 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 */ |
42 | typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); | 44 | typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len, uint16_t type); |