diff options
-rw-r--r-- | toxcore/Messenger.c | 64 | ||||
-rw-r--r-- | toxcore/Messenger.h | 13 | ||||
-rw-r--r-- | toxcore/TCP_client.c | 2 | ||||
-rw-r--r-- | toxcore/TCP_client.h | 4 | ||||
-rw-r--r-- | toxcore/TCP_connection.c | 480 | ||||
-rw-r--r-- | toxcore/TCP_connection.h | 57 | ||||
-rw-r--r-- | toxcore/crypto_core.c | 22 | ||||
-rw-r--r-- | toxcore/crypto_core.h | 4 | ||||
-rw-r--r-- | toxcore/friend_connection.c | 179 | ||||
-rw-r--r-- | toxcore/friend_connection.h | 22 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 875 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 66 | ||||
-rw-r--r-- | toxcore/onion.c | 4 | ||||
-rw-r--r-- | toxcore/onion_client.c | 15 | ||||
-rw-r--r-- | toxcore/onion_client.h | 2 | ||||
-rw-r--r-- | toxcore/tox.h | 6 |
16 files changed, 925 insertions, 890 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index fefc3b17..fd17ab98 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -433,14 +433,19 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber) | |||
433 | return -1; | 433 | return -1; |
434 | 434 | ||
435 | if (m->friendlist[friendnumber].status == FRIEND_ONLINE) { | 435 | if (m->friendlist[friendnumber].status == FRIEND_ONLINE) { |
436 | uint8_t direct_connected = 0; | 436 | _Bool direct_connected = 0; |
437 | unsigned int num_online_relays = 0; | ||
437 | crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, | 438 | crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, |
438 | m->friendlist[friendnumber].friendcon_id), &direct_connected); | 439 | m->friendlist[friendnumber].friendcon_id), &direct_connected, &num_online_relays); |
439 | 440 | ||
440 | if (direct_connected) { | 441 | if (direct_connected) { |
441 | return CONNECTION_UDP; | 442 | return CONNECTION_UDP; |
442 | } else { | 443 | } else { |
443 | return CONNECTION_TCP; | 444 | if (num_online_relays) { |
445 | return CONNECTION_TCP; | ||
446 | } else { | ||
447 | return CONNECTION_UNKNOWN; | ||
448 | } | ||
444 | } | 449 | } |
445 | } else { | 450 | } else { |
446 | return CONNECTION_NONE; | 451 | return CONNECTION_NONE; |
@@ -493,10 +498,6 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con | |||
493 | 498 | ||
494 | uint32_t msg_id = ++m->friendlist[friendnumber].message_id; | 499 | uint32_t msg_id = ++m->friendlist[friendnumber].message_id; |
495 | 500 | ||
496 | if (msg_id == 0) { | ||
497 | msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error | ||
498 | } | ||
499 | |||
500 | add_receipt(m, friendnumber, packet_num, msg_id); | 501 | add_receipt(m, friendnumber, packet_num, msg_id); |
501 | 502 | ||
502 | if (message_id) | 503 | if (message_id) |
@@ -753,25 +754,6 @@ static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t | |||
753 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); | 754 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); |
754 | } | 755 | } |
755 | 756 | ||
756 | static int send_relays(const Messenger *m, int32_t friendnumber) | ||
757 | { | ||
758 | Node_format nodes[MAX_SHARED_RELAYS]; | ||
759 | uint8_t data[1024]; | ||
760 | int n, length; | ||
761 | |||
762 | n = copy_connected_tcp_relays(m->net_crypto, nodes, MAX_SHARED_RELAYS); | ||
763 | length = pack_nodes(data, sizeof(data), nodes, n); | ||
764 | |||
765 | int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_SHARE_RELAYS, data, length, 0); | ||
766 | |||
767 | if (ret == 1) | ||
768 | m->friendlist[friendnumber].share_relays_lastsent = unix_time(); | ||
769 | |||
770 | return ret; | ||
771 | } | ||
772 | |||
773 | |||
774 | |||
775 | static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length) | 757 | static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length) |
776 | { | 758 | { |
777 | if (friend_not_valid(m, friendnumber)) | 759 | if (friend_not_valid(m, friendnumber)) |
@@ -874,6 +856,14 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber) | |||
874 | if (ret == -1) | 856 | if (ret == -1) |
875 | return; | 857 | return; |
876 | 858 | ||
859 | if (ret == CONNECTION_UNKNOWN) { | ||
860 | if (last_connection_udp_tcp == CONNECTION_UDP) { | ||
861 | return; | ||
862 | } else { | ||
863 | ret = CONNECTION_TCP; | ||
864 | } | ||
865 | } | ||
866 | |||
877 | if (last_connection_udp_tcp != ret) { | 867 | if (last_connection_udp_tcp != ret) { |
878 | if (m->friend_connectionstatuschange) | 868 | if (m->friend_connectionstatuschange) |
879 | m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata); | 869 | m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata); |
@@ -1350,7 +1340,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin | |||
1350 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) | 1340 | if (m->friendlist[friendnumber].status != FRIEND_ONLINE) |
1351 | return -2; | 1341 | return -2; |
1352 | 1342 | ||
1353 | if (filenumber > MAX_CONCURRENT_FILE_PIPES) | 1343 | if (filenumber >= MAX_CONCURRENT_FILE_PIPES) |
1354 | return -3; | 1344 | return -3; |
1355 | 1345 | ||
1356 | struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber]; | 1346 | struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber]; |
@@ -2178,22 +2168,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) | |||
2178 | break; | 2168 | break; |
2179 | } | 2169 | } |
2180 | 2170 | ||
2181 | case PACKET_ID_SHARE_RELAYS: { | ||
2182 | Node_format nodes[MAX_SHARED_RELAYS]; | ||
2183 | int n; | ||
2184 | |||
2185 | if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data, data_length, 1)) == -1) | ||
2186 | break; | ||
2187 | |||
2188 | int i; | ||
2189 | |||
2190 | for (i = 0; i < n; i++) { | ||
2191 | add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].public_key); | ||
2192 | } | ||
2193 | |||
2194 | break; | ||
2195 | } | ||
2196 | |||
2197 | default: { | 2171 | default: { |
2198 | handle_custom_lossless_packet(object, i, temp, len); | 2172 | handle_custom_lossless_packet(object, i, temp, len); |
2199 | break; | 2173 | break; |
@@ -2251,10 +2225,6 @@ void do_friends(Messenger *m) | |||
2251 | m->friendlist[i].user_istyping_sent = 1; | 2225 | m->friendlist[i].user_istyping_sent = 1; |
2252 | } | 2226 | } |
2253 | 2227 | ||
2254 | if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) { | ||
2255 | send_relays(m, i); | ||
2256 | } | ||
2257 | |||
2258 | check_friend_tcp_udp(m, i); | 2228 | check_friend_tcp_udp(m, i); |
2259 | do_receipts(m, i); | 2229 | do_receipts(m, i); |
2260 | do_reqchunk_filecb(m, i); | 2230 | do_reqchunk_filecb(m, i); |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 63fb2820..5221e639 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -42,8 +42,7 @@ enum { | |||
42 | MESSAGE_ACTION | 42 | MESSAGE_ACTION |
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* NOTE: Packet ids below 20 must never be used. */ | 45 | /* NOTE: Packet ids below 24 must never be used. */ |
46 | #define PACKET_ID_SHARE_RELAYS 23 | ||
47 | #define PACKET_ID_ONLINE 24 | 46 | #define PACKET_ID_ONLINE 24 |
48 | #define PACKET_ID_OFFLINE 25 | 47 | #define PACKET_ID_OFFLINE 25 |
49 | #define PACKET_ID_NICKNAME 48 | 48 | #define PACKET_ID_NICKNAME 48 |
@@ -62,9 +61,6 @@ enum { | |||
62 | #define PACKET_ID_MESSAGE_GROUPCHAT 99 | 61 | #define PACKET_ID_MESSAGE_GROUPCHAT 99 |
63 | #define PACKET_ID_LOSSY_GROUPCHAT 199 | 62 | #define PACKET_ID_LOSSY_GROUPCHAT 199 |
64 | 63 | ||
65 | /* Max number of tcp relays sent to friends */ | ||
66 | #define MAX_SHARED_RELAYS 16 | ||
67 | |||
68 | /* All packets starting with a byte in this range can be used for anything. */ | 64 | /* All packets starting with a byte in this range can be used for anything. */ |
69 | #define PACKET_ID_LOSSLESS_RANGE_START 160 | 65 | #define PACKET_ID_LOSSLESS_RANGE_START 160 |
70 | #define PACKET_ID_LOSSLESS_RANGE_SIZE 32 | 66 | #define PACKET_ID_LOSSLESS_RANGE_SIZE 32 |
@@ -110,13 +106,11 @@ enum { | |||
110 | /* Default start timeout in seconds between friend requests. */ | 106 | /* Default start timeout in seconds between friend requests. */ |
111 | #define FRIENDREQUEST_TIMEOUT 5; | 107 | #define FRIENDREQUEST_TIMEOUT 5; |
112 | 108 | ||
113 | /* Interval between the sending of tcp relay information */ | ||
114 | #define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60) | ||
115 | |||
116 | enum { | 109 | enum { |
117 | CONNECTION_NONE, | 110 | CONNECTION_NONE, |
118 | CONNECTION_TCP, | 111 | CONNECTION_TCP, |
119 | CONNECTION_UDP | 112 | CONNECTION_UDP, |
113 | CONNECTION_UNKNOWN | ||
120 | }; | 114 | }; |
121 | 115 | ||
122 | /* USERSTATUS - | 116 | /* USERSTATUS - |
@@ -199,7 +193,6 @@ typedef struct { | |||
199 | uint32_t message_id; // a semi-unique id used in read receipts. | 193 | uint32_t message_id; // a semi-unique id used in read receipts. |
200 | uint32_t friendrequest_nospam; // The nospam number used in the friend request. | 194 | uint32_t friendrequest_nospam; // The nospam number used in the friend request. |
201 | uint64_t last_seen_time; | 195 | uint64_t last_seen_time; |
202 | uint64_t share_relays_lastsent; | ||
203 | uint8_t last_connection_udp_tcp; | 196 | uint8_t last_connection_udp_tcp; |
204 | struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; | 197 | struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; |
205 | unsigned int num_sending_files; | 198 | unsigned int num_sending_files; |
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index d89b157c..1bd11a1d 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c | |||
@@ -87,7 +87,7 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con | |||
87 | const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, | 87 | const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, |
88 | ip, port, three); | 88 | ip, port, three); |
89 | 89 | ||
90 | if (written < 0) { | 90 | if (written < 0 || MAX_PACKET_SIZE < written) { |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index d4d18a4b..722430e0 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h | |||
@@ -78,10 +78,6 @@ typedef struct { | |||
78 | uint64_t ping_response_id; | 78 | uint64_t ping_response_id; |
79 | uint64_t ping_request_id; | 79 | uint64_t ping_request_id; |
80 | 80 | ||
81 | //TODO: remove | ||
82 | void *net_crypto_pointer; | ||
83 | uint32_t net_crypto_location; | ||
84 | |||
85 | struct { | 81 | struct { |
86 | uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ | 82 | uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ |
87 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 83 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index e11e1318..fe39dc52 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #include "TCP_connection.h" | 28 | #include "TCP_connection.h" |
29 | #include "util.h" | ||
29 | 30 | ||
30 | /* Set the size of the array to num. | 31 | /* Set the size of the array to num. |
31 | * | 32 | * |
@@ -212,6 +213,8 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
212 | unsigned int i; | 213 | unsigned int i; |
213 | int ret = -1; | 214 | int ret = -1; |
214 | 215 | ||
216 | _Bool limit_reached = 0; | ||
217 | |||
215 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | 218 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { |
216 | uint32_t tcp_con_num = con_to->connections[i].tcp_connection; | 219 | uint32_t tcp_con_num = con_to->connections[i].tcp_connection; |
217 | uint8_t status = con_to->connections[i].status; | 220 | uint8_t status = con_to->connections[i].status; |
@@ -227,6 +230,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
227 | 230 | ||
228 | ret = send_data(tcp_con->connection, connection_id, packet, length); | 231 | ret = send_data(tcp_con->connection, connection_id, packet, length); |
229 | 232 | ||
233 | if (ret == 0) { | ||
234 | limit_reached = 1; | ||
235 | } | ||
236 | |||
230 | if (ret == 1) { | 237 | if (ret == 1) { |
231 | break; | 238 | break; |
232 | } | 239 | } |
@@ -235,7 +242,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
235 | 242 | ||
236 | if (ret == 1) { | 243 | if (ret == 1) { |
237 | return 0; | 244 | return 0; |
238 | } else { | 245 | } else if (!limit_reached) { |
246 | ret = 0; | ||
247 | |||
248 | /* Send oob packets to all relays tied to the connection. */ | ||
239 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | 249 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { |
240 | uint32_t tcp_con_num = con_to->connections[i].tcp_connection; | 250 | uint32_t tcp_con_num = con_to->connections[i].tcp_connection; |
241 | uint8_t status = con_to->connections[i].status; | 251 | uint8_t status = con_to->connections[i].status; |
@@ -249,19 +259,19 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
249 | continue; | 259 | continue; |
250 | } | 260 | } |
251 | 261 | ||
252 | ret = send_oob_packet(tcp_con->connection, con_to->public_key, packet, length); | 262 | if (send_oob_packet(tcp_con->connection, con_to->public_key, packet, length) == 1) { |
253 | 263 | ret += 1; | |
254 | if (ret == 1) { | ||
255 | break; | ||
256 | } | 264 | } |
257 | } | 265 | } |
258 | } | 266 | } |
259 | 267 | ||
260 | if (ret == 1) { | 268 | if (ret >= 1) { |
261 | return 0; | 269 | return 0; |
262 | } else { | 270 | } else { |
263 | return -1; | 271 | return -1; |
264 | } | 272 | } |
273 | } else { | ||
274 | return -1; | ||
265 | } | 275 | } |
266 | } | 276 | } |
267 | 277 | ||
@@ -273,13 +283,15 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
273 | * return TCP connection number on success. | 283 | * return TCP connection number on success. |
274 | * return -1 on failure. | 284 | * return -1 on failure. |
275 | */ | 285 | */ |
276 | int get_random_tcp_conn_number(TCP_Connections *tcp_c) | 286 | int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c) |
277 | { | 287 | { |
278 | unsigned int i, r = rand(); | 288 | unsigned int i, r = rand(); |
279 | 289 | ||
280 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { | 290 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { |
281 | if (tcp_c->tcp_connections[(i + r) % tcp_c->tcp_connections_length].status == TCP_CONN_CONNECTED) { | 291 | unsigned int index = ((i + r) % tcp_c->tcp_connections_length); |
282 | return ((i + r) % tcp_c->tcp_connections_length); | 292 | |
293 | if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) { | ||
294 | return index; | ||
283 | } | 295 | } |
284 | } | 296 | } |
285 | 297 | ||
@@ -321,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num | |||
321 | if (!tcp_con) | 333 | if (!tcp_con) |
322 | return -1; | 334 | return -1; |
323 | 335 | ||
336 | if (tcp_con->status != TCP_CONN_CONNECTED) | ||
337 | return -1; | ||
338 | |||
324 | int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); | 339 | int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); |
325 | 340 | ||
326 | if (ret == 1) | 341 | if (ret == 1) |
@@ -392,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela | |||
392 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | 407 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); |
393 | 408 | ||
394 | if (tcp_con) { | 409 | if (tcp_con) { |
395 | if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { | 410 | if (tcp_con->status == TCP_CONN_SLEEPING) { |
396 | return i; | 411 | if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { |
412 | return i; | ||
413 | } | ||
414 | } else { | ||
415 | if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { | ||
416 | return i; | ||
417 | } | ||
397 | } | 418 | } |
398 | } | 419 | } |
399 | } | 420 | } |
@@ -451,14 +472,86 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number) | |||
451 | send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id); | 472 | send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id); |
452 | } | 473 | } |
453 | 474 | ||
454 | --tcp_con->lock_count; | 475 | if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) { |
476 | --tcp_con->lock_count; | ||
477 | |||
478 | if (con_to->status == TCP_CONN_SLEEPING) { | ||
479 | --tcp_con->sleep_count; | ||
480 | } | ||
481 | } | ||
455 | } | 482 | } |
456 | } | 483 | } |
457 | 484 | ||
458 | return wipe_connection(tcp_c, connections_number); | 485 | return wipe_connection(tcp_c, connections_number); |
459 | } | 486 | } |
460 | 487 | ||
461 | static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number) | 488 | /* Set connection status. |
489 | * | ||
490 | * status of 1 means we are using the connection. | ||
491 | * status of 0 means we are not using it. | ||
492 | * | ||
493 | * Unused tcp connections will be disconnected from but kept in case they are needed. | ||
494 | * | ||
495 | * return 0 on success. | ||
496 | * return -1 on failure. | ||
497 | */ | ||
498 | int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status) | ||
499 | { | ||
500 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | ||
501 | |||
502 | if (!con_to) | ||
503 | return -1; | ||
504 | |||
505 | if (status) { | ||
506 | /* Conection is unsleeping. */ | ||
507 | if (con_to->status != TCP_CONN_SLEEPING) | ||
508 | return -1; | ||
509 | |||
510 | unsigned int i; | ||
511 | |||
512 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | ||
513 | if (con_to->connections[i].tcp_connection) { | ||
514 | unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1; | ||
515 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
516 | |||
517 | if (!tcp_con) | ||
518 | continue; | ||
519 | |||
520 | if (tcp_con->status == TCP_CONN_SLEEPING) { | ||
521 | tcp_con->unsleep = 1; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | con_to->status = TCP_CONN_VALID; | ||
527 | return 0; | ||
528 | } else { | ||
529 | /* Conection is going to sleep. */ | ||
530 | if (con_to->status != TCP_CONN_VALID) | ||
531 | return -1; | ||
532 | |||
533 | unsigned int i; | ||
534 | |||
535 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | ||
536 | if (con_to->connections[i].tcp_connection) { | ||
537 | unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1; | ||
538 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
539 | |||
540 | if (!tcp_con) | ||
541 | continue; | ||
542 | |||
543 | if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) { | ||
544 | ++tcp_con->sleep_count; | ||
545 | } | ||
546 | } | ||
547 | } | ||
548 | |||
549 | con_to->status = TCP_CONN_SLEEPING; | ||
550 | return 0; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number) | ||
462 | { | 555 | { |
463 | unsigned int i; | 556 | unsigned int i; |
464 | 557 | ||
@@ -474,7 +567,7 @@ static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connectio | |||
474 | /* return index on success. | 567 | /* return index on success. |
475 | * return -1 on failure. | 568 | * return -1 on failure. |
476 | */ | 569 | */ |
477 | static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connections_number) | 570 | static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number) |
478 | { | 571 | { |
479 | unsigned int i; | 572 | unsigned int i; |
480 | 573 | ||
@@ -496,7 +589,7 @@ static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connect | |||
496 | /* return index on success. | 589 | /* return index on success. |
497 | * return -1 on failure. | 590 | * return -1 on failure. |
498 | */ | 591 | */ |
499 | static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connections_number) | 592 | static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number) |
500 | { | 593 | { |
501 | unsigned int i; | 594 | unsigned int i; |
502 | 595 | ||
@@ -512,16 +605,39 @@ static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connec | |||
512 | return -1; | 605 | return -1; |
513 | } | 606 | } |
514 | 607 | ||
608 | /* return number of online connections on success. | ||
609 | * return -1 on failure. | ||
610 | */ | ||
611 | static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to) | ||
612 | { | ||
613 | unsigned int i, count = 0; | ||
614 | |||
615 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | ||
616 | if (con_to->connections[i].tcp_connection) { | ||
617 | if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) { | ||
618 | ++count; | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | |||
623 | return count; | ||
624 | } | ||
625 | |||
515 | /* return index on success. | 626 | /* return index on success. |
516 | * return -1 on failure. | 627 | * return -1 on failure. |
517 | */ | 628 | */ |
518 | static int set_tcp_connection_status(TCP_Connection_to *con_to, int tcp_connections_number, unsigned int status, | 629 | static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp_connections_number, |
519 | uint8_t connection_id) | 630 | unsigned int status, uint8_t connection_id) |
520 | { | 631 | { |
521 | unsigned int i; | 632 | unsigned int i; |
522 | 633 | ||
523 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { | 634 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { |
524 | if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) { | 635 | if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) { |
636 | |||
637 | if (con_to->connections[i].status == status) { | ||
638 | return -1; | ||
639 | } | ||
640 | |||
525 | con_to->connections[i].status = status; | 641 | con_to->connections[i].status = status; |
526 | con_to->connections[i].connection_id = connection_id; | 642 | con_to->connections[i].connection_id = connection_id; |
527 | return i; | 643 | return i; |
@@ -553,11 +669,130 @@ static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections | |||
553 | } | 669 | } |
554 | } | 670 | } |
555 | 671 | ||
672 | if (tcp_con->onion) { | ||
673 | --tcp_c->onion_num_conns; | ||
674 | } | ||
675 | |||
556 | kill_TCP_connection(tcp_con->connection); | 676 | kill_TCP_connection(tcp_con->connection); |
557 | 677 | ||
558 | return wipe_tcp_connection(tcp_c, tcp_connections_number); | 678 | return wipe_tcp_connection(tcp_c, tcp_connections_number); |
559 | } | 679 | } |
560 | 680 | ||
681 | static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number) | ||
682 | { | ||
683 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
684 | |||
685 | if (!tcp_con) | ||
686 | return -1; | ||
687 | |||
688 | if (tcp_con->status == TCP_CONN_SLEEPING) | ||
689 | return -1; | ||
690 | |||
691 | IP_Port ip_port = tcp_con->connection->ip_port; | ||
692 | uint8_t relay_pk[crypto_box_PUBLICKEYBYTES]; | ||
693 | memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); | ||
694 | kill_TCP_connection(tcp_con->connection); | ||
695 | tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->dht->self_public_key, tcp_c->dht->self_secret_key, | ||
696 | &tcp_c->proxy_info); | ||
697 | |||
698 | if (!tcp_con->connection) { | ||
699 | kill_tcp_relay_connection(tcp_c, tcp_connections_number); | ||
700 | return -1; | ||
701 | } | ||
702 | |||
703 | unsigned int i; | ||
704 | |||
705 | for (i = 0; i < tcp_c->connections_length; ++i) { | ||
706 | TCP_Connection_to *con_to = get_connection(tcp_c, i); | ||
707 | |||
708 | if (con_to) { | ||
709 | set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0); | ||
710 | } | ||
711 | } | ||
712 | |||
713 | if (tcp_con->onion) { | ||
714 | --tcp_c->onion_num_conns; | ||
715 | tcp_con->onion = 0; | ||
716 | } | ||
717 | |||
718 | tcp_con->lock_count = 0; | ||
719 | tcp_con->sleep_count = 0; | ||
720 | tcp_con->connected_time = 0; | ||
721 | tcp_con->status = TCP_CONN_VALID; | ||
722 | tcp_con->unsleep = 0; | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number) | ||
728 | { | ||
729 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
730 | |||
731 | if (!tcp_con) | ||
732 | return -1; | ||
733 | |||
734 | if (tcp_con->status != TCP_CONN_CONNECTED) | ||
735 | return -1; | ||
736 | |||
737 | if (tcp_con->lock_count != tcp_con->sleep_count) | ||
738 | return -1; | ||
739 | |||
740 | tcp_con->ip_port = tcp_con->connection->ip_port; | ||
741 | memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); | ||
742 | |||
743 | kill_TCP_connection(tcp_con->connection); | ||
744 | tcp_con->connection = NULL; | ||
745 | |||
746 | unsigned int i; | ||
747 | |||
748 | for (i = 0; i < tcp_c->connections_length; ++i) { | ||
749 | TCP_Connection_to *con_to = get_connection(tcp_c, i); | ||
750 | |||
751 | if (con_to) { | ||
752 | set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0); | ||
753 | } | ||
754 | } | ||
755 | |||
756 | if (tcp_con->onion) { | ||
757 | --tcp_c->onion_num_conns; | ||
758 | tcp_con->onion = 0; | ||
759 | } | ||
760 | |||
761 | tcp_con->lock_count = 0; | ||
762 | tcp_con->sleep_count = 0; | ||
763 | tcp_con->connected_time = 0; | ||
764 | tcp_con->status = TCP_CONN_SLEEPING; | ||
765 | tcp_con->unsleep = 0; | ||
766 | |||
767 | return 0; | ||
768 | } | ||
769 | |||
770 | static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number) | ||
771 | { | ||
772 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
773 | |||
774 | if (!tcp_con) | ||
775 | return -1; | ||
776 | |||
777 | if (tcp_con->status != TCP_CONN_SLEEPING) | ||
778 | return -1; | ||
779 | |||
780 | tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->dht->self_public_key, | ||
781 | tcp_c->dht->self_secret_key, &tcp_c->proxy_info); | ||
782 | |||
783 | if (!tcp_con->connection) { | ||
784 | kill_tcp_relay_connection(tcp_c, tcp_connections_number); | ||
785 | return -1; | ||
786 | } | ||
787 | |||
788 | tcp_con->lock_count = 0; | ||
789 | tcp_con->sleep_count = 0; | ||
790 | tcp_con->connected_time = 0; | ||
791 | tcp_con->status = TCP_CONN_VALID; | ||
792 | tcp_con->unsleep = 0; | ||
793 | return 0; | ||
794 | } | ||
795 | |||
561 | /* Send a TCP routing request. | 796 | /* Send a TCP routing request. |
562 | * | 797 | * |
563 | * return 0 on success. | 798 | * return 0 on success. |
@@ -570,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec | |||
570 | if (!tcp_con) | 805 | if (!tcp_con) |
571 | return -1; | 806 | return -1; |
572 | 807 | ||
808 | if (tcp_con->status == TCP_CONN_SLEEPING) | ||
809 | return -1; | ||
810 | |||
573 | if (send_routing_request(tcp_con->connection, public_key) != 1) | 811 | if (send_routing_request(tcp_con->connection, public_key) != 1) |
574 | return -1; | 812 | return -1; |
575 | 813 | ||
@@ -592,8 +830,6 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint | |||
592 | if (connections_number == -1) | 830 | if (connections_number == -1) |
593 | return -1; | 831 | return -1; |
594 | 832 | ||
595 | set_tcp_connection_number(tcp_con->connection, connection_id, connections_number); | ||
596 | |||
597 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | 833 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); |
598 | 834 | ||
599 | if (con_to == NULL) | 835 | if (con_to == NULL) |
@@ -602,6 +838,8 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint | |||
602 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) | 838 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) |
603 | return -1; | 839 | return -1; |
604 | 840 | ||
841 | set_tcp_connection_number(tcp_con->connection, connection_id, connections_number); | ||
842 | |||
605 | return 0; | 843 | return 0; |
606 | } | 844 | } |
607 | 845 | ||
@@ -621,10 +859,20 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection | |||
621 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) | 859 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) |
622 | return -1; | 860 | return -1; |
623 | 861 | ||
862 | --tcp_con->lock_count; | ||
863 | |||
864 | if (con_to->status == TCP_CONN_SLEEPING) { | ||
865 | --tcp_con->sleep_count; | ||
866 | } | ||
624 | } else if (status == 2) { | 867 | } else if (status == 2) { |
625 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1) | 868 | if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1) |
626 | return -1; | 869 | return -1; |
627 | 870 | ||
871 | ++tcp_con->lock_count; | ||
872 | |||
873 | if (con_to->status == TCP_CONN_SLEEPING) { | ||
874 | ++tcp_con->sleep_count; | ||
875 | } | ||
628 | } | 876 | } |
629 | 877 | ||
630 | return 0; | 878 | return 0; |
@@ -673,11 +921,13 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8 | |||
673 | /* TODO: optimize */ | 921 | /* TODO: optimize */ |
674 | int connections_number = find_tcp_connection_to(tcp_c, public_key); | 922 | int connections_number = find_tcp_connection_to(tcp_c, public_key); |
675 | 923 | ||
676 | if (connections_number == -1) { | 924 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); |
925 | |||
926 | if (con_to && tcp_connection_in_conn(con_to, tcp_connections_number)) { | ||
927 | return tcp_data_callback(object, connections_number, 0, data, length); | ||
928 | } else { | ||
677 | if (tcp_c->tcp_oob_callback) | 929 | if (tcp_c->tcp_oob_callback) |
678 | tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); | 930 | tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); |
679 | } else { | ||
680 | return tcp_data_callback(object, connections_number, 0, data, length); | ||
681 | } | 931 | } |
682 | 932 | ||
683 | return 0; | 933 | return 0; |
@@ -725,20 +975,35 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe | |||
725 | if (!tcp_con) | 975 | if (!tcp_con) |
726 | return -1; | 976 | return -1; |
727 | 977 | ||
728 | unsigned int i; | 978 | unsigned int i, sent = 0; |
729 | 979 | ||
730 | for (i = 0; i < tcp_c->connections_length; ++i) { | 980 | for (i = 0; i < tcp_c->connections_length; ++i) { |
731 | TCP_Connection_to *con_to = get_connection(tcp_c, i); | 981 | TCP_Connection_to *con_to = get_connection(tcp_c, i); |
732 | 982 | ||
733 | if (con_to) { | 983 | if (con_to) { |
734 | if (tcp_connection_in_conn(con_to, tcp_connections_number)) { | 984 | if (tcp_connection_in_conn(con_to, tcp_connections_number)) { |
735 | send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); | 985 | if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) { |
986 | ++sent; | ||
987 | } | ||
736 | } | 988 | } |
737 | } | 989 | } |
738 | } | 990 | } |
739 | 991 | ||
740 | tcp_relay_set_callbacks(tcp_c, tcp_connections_number); | 992 | tcp_relay_set_callbacks(tcp_c, tcp_connections_number); |
741 | tcp_con->status = TCP_CONN_CONNECTED; | 993 | tcp_con->status = TCP_CONN_CONNECTED; |
994 | |||
995 | /* If this connection isn't used by any connection, we don't need to wait for them to come online. */ | ||
996 | if (sent) { | ||
997 | tcp_con->connected_time = unix_time(); | ||
998 | } else { | ||
999 | tcp_con->connected_time = 0; | ||
1000 | } | ||
1001 | |||
1002 | if (tcp_c->onion_status && tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) { | ||
1003 | tcp_con->onion = 1; | ||
1004 | ++tcp_c->onion_num_conns; | ||
1005 | } | ||
1006 | |||
742 | return 0; | 1007 | return 0; |
743 | } | 1008 | } |
744 | 1009 | ||
@@ -807,13 +1072,17 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb | |||
807 | if (!tcp_con) | 1072 | if (!tcp_con) |
808 | return -1; | 1073 | return -1; |
809 | 1074 | ||
1075 | if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) { | ||
1076 | tcp_con->unsleep = 1; | ||
1077 | } | ||
1078 | |||
810 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) | 1079 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) |
811 | return -1; | 1080 | return -1; |
812 | 1081 | ||
813 | ++tcp_con->lock_count; | ||
814 | |||
815 | if (tcp_con->status == TCP_CONN_CONNECTED) { | 1082 | if (tcp_con->status == TCP_CONN_CONNECTED) { |
816 | send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); | 1083 | if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) { |
1084 | tcp_con->connected_time = unix_time(); | ||
1085 | } | ||
817 | } | 1086 | } |
818 | 1087 | ||
819 | return 0; | 1088 | return 0; |
@@ -836,22 +1105,38 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_ | |||
836 | if (tcp_connections_number != -1) { | 1105 | if (tcp_connections_number != -1) { |
837 | return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); | 1106 | return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); |
838 | } else { | 1107 | } else { |
839 | int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); | 1108 | if (online_tcp_connection_from_conn(con_to) >= RECOMMENDED_FRIEND_TCP_CONNECTIONS) { |
840 | |||
841 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) { | ||
842 | return -1; | 1109 | return -1; |
843 | } | 1110 | } |
844 | 1111 | ||
1112 | int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); | ||
1113 | |||
845 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | 1114 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); |
846 | 1115 | ||
847 | if (!tcp_con) | 1116 | if (!tcp_con) |
848 | return -1; | 1117 | return -1; |
849 | 1118 | ||
850 | ++tcp_con->lock_count; | 1119 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) { |
1120 | return -1; | ||
1121 | } | ||
1122 | |||
851 | return 0; | 1123 | return 0; |
852 | } | 1124 | } |
853 | } | 1125 | } |
854 | 1126 | ||
1127 | /* return number of online tcp relays tied to the connection on success. | ||
1128 | * return 0 on failure. | ||
1129 | */ | ||
1130 | unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number) | ||
1131 | { | ||
1132 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | ||
1133 | |||
1134 | if (!con_to) | ||
1135 | return 0; | ||
1136 | |||
1137 | return online_tcp_connection_from_conn(con_to); | ||
1138 | } | ||
1139 | |||
855 | /* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. | 1140 | /* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. |
856 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | 1141 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. |
857 | * | 1142 | * |
@@ -860,10 +1145,10 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_ | |||
860 | */ | 1145 | */ |
861 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) | 1146 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) |
862 | { | 1147 | { |
863 | unsigned int i, copied = 0; | 1148 | unsigned int i, copied = 0, r = rand(); |
864 | 1149 | ||
865 | for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { | 1150 | for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { |
866 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | 1151 | TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length); |
867 | 1152 | ||
868 | if (!tcp_con) { | 1153 | if (!tcp_con) { |
869 | continue; | 1154 | continue; |
@@ -886,7 +1171,74 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_ | |||
886 | return copied; | 1171 | return copied; |
887 | } | 1172 | } |
888 | 1173 | ||
889 | TCP_Connections *new_tcp_connections(DHT *dht) | 1174 | /* Set if we want TCP_connection to allocate some connection for onion use. |
1175 | * | ||
1176 | * If status is 1, allocate some connections. if status is 0, don't. | ||
1177 | * | ||
1178 | * return 0 on success. | ||
1179 | * return -1 on failure. | ||
1180 | */ | ||
1181 | int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status) | ||
1182 | { | ||
1183 | if (tcp_c->onion_status == status) | ||
1184 | return -1; | ||
1185 | |||
1186 | if (status) { | ||
1187 | unsigned int i; | ||
1188 | |||
1189 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { | ||
1190 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | ||
1191 | |||
1192 | if (tcp_con) { | ||
1193 | if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion) { | ||
1194 | ++tcp_c->onion_num_conns; | ||
1195 | tcp_con->onion = 1; | ||
1196 | } | ||
1197 | } | ||
1198 | |||
1199 | if (tcp_c->onion_num_conns >= NUM_ONION_TCP_CONNECTIONS) | ||
1200 | break; | ||
1201 | } | ||
1202 | |||
1203 | if (tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) { | ||
1204 | unsigned int wakeup = NUM_ONION_TCP_CONNECTIONS - tcp_c->onion_num_conns; | ||
1205 | |||
1206 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { | ||
1207 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | ||
1208 | |||
1209 | if (tcp_con) { | ||
1210 | if (tcp_con->status == TCP_CONN_SLEEPING) { | ||
1211 | tcp_con->unsleep = 1; | ||
1212 | } | ||
1213 | } | ||
1214 | |||
1215 | if (!wakeup) | ||
1216 | break; | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | tcp_c->onion_status = 1; | ||
1221 | } else { | ||
1222 | unsigned int i; | ||
1223 | |||
1224 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { | ||
1225 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | ||
1226 | |||
1227 | if (tcp_con) { | ||
1228 | if (tcp_con->onion) { | ||
1229 | --tcp_c->onion_num_conns; | ||
1230 | tcp_con->onion = 0; | ||
1231 | } | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1235 | tcp_c->onion_status = 0; | ||
1236 | } | ||
1237 | |||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info) | ||
890 | { | 1242 | { |
891 | if (dht == NULL) | 1243 | if (dht == NULL) |
892 | return NULL; | 1244 | return NULL; |
@@ -897,6 +1249,8 @@ TCP_Connections *new_tcp_connections(DHT *dht) | |||
897 | return NULL; | 1249 | return NULL; |
898 | 1250 | ||
899 | temp->dht = dht; | 1251 | temp->dht = dht; |
1252 | temp->proxy_info = *proxy_info; | ||
1253 | |||
900 | return temp; | 1254 | return temp; |
901 | } | 1255 | } |
902 | 1256 | ||
@@ -908,18 +1262,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c) | |||
908 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | 1262 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); |
909 | 1263 | ||
910 | if (tcp_con) { | 1264 | if (tcp_con) { |
911 | do_TCP_connection(tcp_con->connection); | 1265 | if (tcp_con->status != TCP_CONN_SLEEPING) { |
1266 | do_TCP_connection(tcp_con->connection); | ||
912 | 1267 | ||
913 | /* callbacks can change TCP connection address. */ | 1268 | /* callbacks can change TCP connection address. */ |
914 | tcp_con = get_tcp_connection(tcp_c, i); | 1269 | tcp_con = get_tcp_connection(tcp_c, i); |
915 | 1270 | ||
916 | if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { | 1271 | if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { |
917 | kill_tcp_relay_connection(tcp_c, i); | 1272 | if (tcp_con->status == TCP_CONN_CONNECTED) { |
918 | continue; | 1273 | reconnect_tcp_relay_connection(tcp_c, i); |
1274 | } else { | ||
1275 | kill_tcp_relay_connection(tcp_c, i); | ||
1276 | } | ||
1277 | |||
1278 | continue; | ||
1279 | } | ||
1280 | |||
1281 | if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { | ||
1282 | tcp_relay_on_online(tcp_c, i); | ||
1283 | } | ||
1284 | |||
1285 | if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count | ||
1286 | && tcp_con->lock_count == tcp_con->sleep_count | ||
1287 | && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) { | ||
1288 | sleep_tcp_relay_connection(tcp_c, i); | ||
1289 | } | ||
919 | } | 1290 | } |
920 | 1291 | ||
921 | if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { | 1292 | if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) { |
922 | tcp_relay_on_online(tcp_c, i); | 1293 | unsleep_tcp_relay_connection(tcp_c, i); |
923 | } | 1294 | } |
924 | } | 1295 | } |
925 | } | 1296 | } |
@@ -927,27 +1298,42 @@ static void do_tcp_conns(TCP_Connections *tcp_c) | |||
927 | 1298 | ||
928 | static void kill_nonused_tcp(TCP_Connections *tcp_c) | 1299 | static void kill_nonused_tcp(TCP_Connections *tcp_c) |
929 | { | 1300 | { |
930 | unsigned int i, num_online = 0; | 1301 | if (tcp_c->tcp_connections_length == 0) |
1302 | return; | ||
1303 | |||
1304 | unsigned int i, num_online = 0, num_kill = 0, to_kill[tcp_c->tcp_connections_length]; | ||
931 | 1305 | ||
932 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { | 1306 | for (i = 0; i < tcp_c->tcp_connections_length; ++i) { |
933 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | 1307 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); |
934 | 1308 | ||
935 | if (tcp_con) { | 1309 | if (tcp_con) { |
936 | if (tcp_con->status == TCP_CONN_CONNECTED) { | 1310 | if (tcp_con->status == TCP_CONN_CONNECTED) { |
937 | if (!tcp_con->lock_count && num_online >= MAX_FRIEND_TCP_CONNECTIONS) { | 1311 | if (!tcp_con->onion && !tcp_con->lock_count && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) { |
938 | kill_tcp_relay_connection(tcp_c, i); | 1312 | to_kill[num_kill] = i; |
939 | continue; | 1313 | ++num_kill; |
940 | } | 1314 | } |
941 | 1315 | ||
942 | ++num_online; | 1316 | ++num_online; |
943 | } | 1317 | } |
944 | } | 1318 | } |
945 | } | 1319 | } |
1320 | |||
1321 | if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) { | ||
1322 | return; | ||
1323 | } else { | ||
1324 | unsigned int n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS; | ||
1325 | |||
1326 | if (n < num_kill) | ||
1327 | num_kill = n; | ||
1328 | } | ||
1329 | |||
1330 | for (i = 0; i < num_kill; ++i) { | ||
1331 | kill_tcp_relay_connection(tcp_c, to_kill[i]); | ||
1332 | } | ||
946 | } | 1333 | } |
947 | 1334 | ||
948 | void do_tcp_connections(TCP_Connections *tcp_c) | 1335 | void do_tcp_connections(TCP_Connections *tcp_c) |
949 | { | 1336 | { |
950 | //TODO reconnect to TCP relays if disconnects happen. | ||
951 | do_tcp_conns(tcp_c); | 1337 | do_tcp_conns(tcp_c); |
952 | kill_nonused_tcp(tcp_c); | 1338 | kill_nonused_tcp(tcp_c); |
953 | } | 1339 | } |
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 2c86304f..29fbdee0 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h | |||
@@ -28,14 +28,28 @@ | |||
28 | 28 | ||
29 | #define TCP_CONN_NONE 0 | 29 | #define TCP_CONN_NONE 0 |
30 | #define TCP_CONN_VALID 1 | 30 | #define TCP_CONN_VALID 1 |
31 | |||
32 | /* NOTE: only used by TCP_con */ | ||
31 | #define TCP_CONN_CONNECTED 2 | 33 | #define TCP_CONN_CONNECTED 2 |
32 | 34 | ||
35 | /* Connection is not connected but can be quickly reconnected in case it is needed. */ | ||
36 | #define TCP_CONN_SLEEPING 3 | ||
37 | |||
33 | #define TCP_CONNECTIONS_STATUS_NONE 0 | 38 | #define TCP_CONNECTIONS_STATUS_NONE 0 |
34 | #define TCP_CONNECTIONS_STATUS_REGISTERED 1 | 39 | #define TCP_CONNECTIONS_STATUS_REGISTERED 1 |
35 | #define TCP_CONNECTIONS_STATUS_ONLINE 2 | 40 | #define TCP_CONNECTIONS_STATUS_ONLINE 2 |
36 | 41 | ||
37 | #define MAX_FRIEND_TCP_CONNECTIONS 4 | 42 | #define MAX_FRIEND_TCP_CONNECTIONS 6 |
43 | |||
44 | /* Time until connection to friend gets killed (if it doesn't get locked withing that time) */ | ||
45 | #define TCP_CONNECTION_ANNOUNCE_TIMEOUT (TCP_CONNECTION_TIMEOUT) | ||
38 | 46 | ||
47 | /* The amount of recommended connections for each friend | ||
48 | NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2) */ | ||
49 | #define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2) | ||
50 | |||
51 | /* Number of TCP connections used for onion purposes. */ | ||
52 | #define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS | ||
39 | 53 | ||
40 | typedef struct { | 54 | typedef struct { |
41 | uint8_t status; | 55 | uint8_t status; |
@@ -53,7 +67,15 @@ typedef struct { | |||
53 | typedef struct { | 67 | typedef struct { |
54 | uint8_t status; | 68 | uint8_t status; |
55 | TCP_Client_Connection *connection; | 69 | TCP_Client_Connection *connection; |
70 | uint64_t connected_time; | ||
56 | uint32_t lock_count; | 71 | uint32_t lock_count; |
72 | uint32_t sleep_count; | ||
73 | _Bool onion; | ||
74 | |||
75 | /* Only used when connection is sleeping. */ | ||
76 | IP_Port ip_port; | ||
77 | uint8_t relay_pk[crypto_box_PUBLICKEYBYTES]; | ||
78 | _Bool unsleep; /* set to 1 to unsleep connection. */ | ||
57 | } TCP_con; | 79 | } TCP_con; |
58 | 80 | ||
59 | typedef struct { | 81 | typedef struct { |
@@ -76,6 +98,9 @@ typedef struct { | |||
76 | void *tcp_onion_callback_object; | 98 | void *tcp_onion_callback_object; |
77 | 99 | ||
78 | TCP_Proxy_Info proxy_info; | 100 | TCP_Proxy_Info proxy_info; |
101 | |||
102 | _Bool onion_status; | ||
103 | uint16_t onion_num_conns; | ||
79 | } TCP_Connections; | 104 | } TCP_Connections; |
80 | 105 | ||
81 | /* Send a packet to the TCP connection. | 106 | /* Send a packet to the TCP connection. |
@@ -93,7 +118,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c | |||
93 | * return TCP connection number on success. | 118 | * return TCP connection number on success. |
94 | * return -1 on failure. | 119 | * return -1 on failure. |
95 | */ | 120 | */ |
96 | int get_random_tcp_conn_number(TCP_Connections *tcp_c); | 121 | int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c); |
97 | 122 | ||
98 | /* Send an onion packet via the TCP relay corresponding to tcp_connections_number. | 123 | /* Send an onion packet via the TCP relay corresponding to tcp_connections_number. |
99 | * | 124 | * |
@@ -103,6 +128,15 @@ int get_random_tcp_conn_number(TCP_Connections *tcp_c); | |||
103 | int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, | 128 | int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, |
104 | uint16_t length); | 129 | uint16_t length); |
105 | 130 | ||
131 | /* Set if we want TCP_connection to allocate some connection for onion use. | ||
132 | * | ||
133 | * If status is 1, allocate some connections. if status is 0, don't. | ||
134 | * | ||
135 | * return 0 on success. | ||
136 | * return -1 on failure. | ||
137 | */ | ||
138 | int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status); | ||
139 | |||
106 | /* Send an oob packet via the TCP relay corresponding to tcp_connections_number. | 140 | /* Send an oob packet via the TCP relay corresponding to tcp_connections_number. |
107 | * | 141 | * |
108 | * return 0 on success. | 142 | * return 0 on success. |
@@ -140,6 +174,23 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int | |||
140 | */ | 174 | */ |
141 | int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); | 175 | int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); |
142 | 176 | ||
177 | /* Set connection status. | ||
178 | * | ||
179 | * status of 1 means we are using the connection. | ||
180 | * status of 0 means we are not using it. | ||
181 | * | ||
182 | * Unused tcp connections will be disconnected from but kept in case they are needed. | ||
183 | * | ||
184 | * return 0 on success. | ||
185 | * return -1 on failure. | ||
186 | */ | ||
187 | int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status); | ||
188 | |||
189 | /* return number of online tcp relays tied to the connection on success. | ||
190 | * return 0 on failure. | ||
191 | */ | ||
192 | unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number); | ||
193 | |||
143 | /* Add a TCP relay tied to a connection. | 194 | /* Add a TCP relay tied to a connection. |
144 | * | 195 | * |
145 | * NOTE: This can only be used during the tcp_oob_callback. | 196 | * NOTE: This can only be used during the tcp_oob_callback. |
@@ -172,7 +223,7 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t | |||
172 | */ | 223 | */ |
173 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); | 224 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); |
174 | 225 | ||
175 | TCP_Connections *new_tcp_connections(DHT *dht); | 226 | TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info); |
176 | void do_tcp_connections(TCP_Connections *tcp_c); | 227 | void do_tcp_connections(TCP_Connections *tcp_c); |
177 | void kill_tcp_connections(TCP_Connections *tcp_c); | 228 | void kill_tcp_connections(TCP_Connections *tcp_c); |
178 | 229 | ||
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index a364084a..418edcad 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c | |||
@@ -29,26 +29,16 @@ | |||
29 | 29 | ||
30 | #include "crypto_core.h" | 30 | #include "crypto_core.h" |
31 | 31 | ||
32 | #if crypto_box_PUBLICKEYBYTES != 32 | ||
33 | #error crypto_box_PUBLICKEYBYTES is required to be 32 bytes for public_key_cmp to work, | ||
34 | #endif | ||
32 | 35 | ||
33 | /* Use this instead of memcmp; not vulnerable to timing attacks. | 36 | /* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks. |
34 | returns 0 if both mem locations of length are equal, | 37 | returns 0 if both mem locations of length are equal, |
35 | return -1 if they are not. */ | 38 | return -1 if they are not. */ |
36 | int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length) | 39 | int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2) |
37 | { | 40 | { |
38 | if (length == 16) { | 41 | return crypto_verify_32(pk1, pk2); |
39 | return crypto_verify_16(mem1, mem2); | ||
40 | } else if (length == 32) { | ||
41 | return crypto_verify_32(mem1, mem2); | ||
42 | } | ||
43 | |||
44 | unsigned int check = 0; | ||
45 | size_t i; | ||
46 | |||
47 | for (i = 0; i < length; ++i) { | ||
48 | check |= mem1[i] ^ mem2[i]; | ||
49 | } | ||
50 | |||
51 | return (1 & ((check - 1) >> 8)) - 1; | ||
52 | } | 42 | } |
53 | 43 | ||
54 | /* return a random number. | 44 | /* return a random number. |
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h index decc7fb9..d7306a8a 100644 --- a/toxcore/crypto_core.h +++ b/toxcore/crypto_core.h | |||
@@ -40,10 +40,10 @@ | |||
40 | 40 | ||
41 | #define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) | 41 | #define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) |
42 | 42 | ||
43 | /* Use this instead of memcmp; not vulnerable to timing attacks. | 43 | /* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks. |
44 | returns 0 if both mem locations of length are equal, | 44 | returns 0 if both mem locations of length are equal, |
45 | return -1 if they are not. */ | 45 | return -1 if they are not. */ |
46 | int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length); | 46 | int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2); |
47 | 47 | ||
48 | /* return a random number. | 48 | /* return a random number. |
49 | * | 49 | * |
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index 074021da..892048ad 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c | |||
@@ -146,6 +146,95 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk) | |||
146 | return -1; | 146 | return -1; |
147 | } | 147 | } |
148 | 148 | ||
149 | /* Add a TCP relay associated to the friend. | ||
150 | * | ||
151 | * return -1 on failure. | ||
152 | * return 0 on success. | ||
153 | */ | ||
154 | int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key) | ||
155 | { | ||
156 | Friend_Conn *friend_con = get_conn(fr_c, friendcon_id); | ||
157 | |||
158 | if (!friend_con) | ||
159 | return -1; | ||
160 | |||
161 | unsigned int i; | ||
162 | |||
163 | uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; | ||
164 | |||
165 | for (i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) { | ||
166 | if (friend_con->tcp_relays[i].ip_port.ip.family != 0 | ||
167 | && memcmp(friend_con->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
168 | memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format)); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | friend_con->tcp_relays[index].ip_port = ip_port; | ||
173 | memcpy(friend_con->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES); | ||
174 | ++friend_con->tcp_relay_counter; | ||
175 | |||
176 | return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key); | ||
177 | } | ||
178 | |||
179 | /* Connect to number saved relays for friend. */ | ||
180 | static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_id, unsigned int number) | ||
181 | { | ||
182 | Friend_Conn *friend_con = get_conn(fr_c, friendcon_id); | ||
183 | |||
184 | if (!friend_con) | ||
185 | return; | ||
186 | |||
187 | unsigned int i; | ||
188 | |||
189 | for (i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) { | ||
190 | uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS; | ||
191 | |||
192 | if (friend_con->tcp_relays[index].ip_port.ip.family) { | ||
193 | if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port, | ||
194 | friend_con->tcp_relays[index].public_key) == 0) { | ||
195 | --number; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id) | ||
202 | { | ||
203 | Friend_Conn *friend_con = get_conn(fr_c, friendcon_id); | ||
204 | |||
205 | if (!friend_con) | ||
206 | return 0; | ||
207 | |||
208 | Node_format nodes[MAX_SHARED_RELAYS]; | ||
209 | uint8_t data[1024]; | ||
210 | int n, length; | ||
211 | |||
212 | n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS); | ||
213 | |||
214 | unsigned int i; | ||
215 | |||
216 | for (i = 0; i < n; ++i) { | ||
217 | /* Associated the relays being sent with this connection. | ||
218 | On receiving the peer will do the same which will establish the connection. */ | ||
219 | friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key); | ||
220 | } | ||
221 | |||
222 | length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n); | ||
223 | |||
224 | if (length <= 0) | ||
225 | return 0; | ||
226 | |||
227 | data[0] = PACKET_ID_SHARE_RELAYS; | ||
228 | ++length; | ||
229 | |||
230 | if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) { | ||
231 | friend_con->share_relays_lastsent = unix_time(); | ||
232 | return 1; | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
149 | /* callback for recv TCP relay nodes. */ | 238 | /* callback for recv TCP relay nodes. */ |
150 | static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) | 239 | static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) |
151 | { | 240 | { |
@@ -156,7 +245,7 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por | |||
156 | return -1; | 245 | return -1; |
157 | 246 | ||
158 | if (friend_con->crypt_connection_id != -1) { | 247 | if (friend_con->crypt_connection_id != -1) { |
159 | return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key); | 248 | return friend_add_tcp_relay(fr_c, number, ip_port, public_key); |
160 | } else { | 249 | } else { |
161 | return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); | 250 | return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); |
162 | } | 251 | } |
@@ -181,19 +270,14 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port) | |||
181 | friend_con->dht_ip_port_lastrecv = unix_time(); | 270 | friend_con->dht_ip_port_lastrecv = unix_time(); |
182 | } | 271 | } |
183 | 272 | ||
184 | /* Callback for dht public key changes. */ | 273 | static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key) |
185 | static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key) | ||
186 | { | 274 | { |
187 | Friend_Connections *fr_c = object; | 275 | Friend_Conn *friend_con = get_conn(fr_c, friendcon_id); |
188 | Friend_Conn *friend_con = get_conn(fr_c, number); | ||
189 | 276 | ||
190 | if (!friend_con) | 277 | if (!friend_con) |
191 | return; | 278 | return; |
192 | 279 | ||
193 | friend_con->dht_ping_lastrecv = unix_time(); | 280 | friend_con->dht_pk_lastrecv = unix_time(); |
194 | |||
195 | if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
196 | return; | ||
197 | 281 | ||
198 | if (friend_con->dht_lock) { | 282 | if (friend_con->dht_lock) { |
199 | if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { | 283 | if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { |
@@ -204,16 +288,32 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub | |||
204 | friend_con->dht_lock = 0; | 288 | friend_con->dht_lock = 0; |
205 | } | 289 | } |
206 | 290 | ||
207 | DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, object, number, &friend_con->dht_lock); | 291 | DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock); |
292 | memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
293 | } | ||
208 | 294 | ||
209 | if (friend_con->crypt_connection_id == -1) { | 295 | /* Callback for dht public key changes. */ |
210 | friend_new_connection(fr_c, number); | 296 | static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key) |
297 | { | ||
298 | Friend_Connections *fr_c = object; | ||
299 | Friend_Conn *friend_con = get_conn(fr_c, number); | ||
300 | |||
301 | if (!friend_con) | ||
302 | return; | ||
303 | |||
304 | if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
305 | return; | ||
306 | |||
307 | change_dht_pk(fr_c, number, dht_public_key); | ||
308 | |||
309 | /* if pk changed, create a new connection.*/ | ||
310 | if (friend_con->crypt_connection_id != -1) { | ||
311 | crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); | ||
312 | friend_con->crypt_connection_id = -1; | ||
211 | } | 313 | } |
212 | 314 | ||
213 | set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, dht_public_key); | 315 | friend_new_connection(fr_c, number); |
214 | onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key); | 316 | onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key); |
215 | |||
216 | memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
217 | } | 317 | } |
218 | 318 | ||
219 | static int handle_status(void *object, int number, uint8_t status) | 319 | static int handle_status(void *object, int number, uint8_t status) |
@@ -230,11 +330,12 @@ static int handle_status(void *object, int number, uint8_t status) | |||
230 | call_cb = 1; | 330 | call_cb = 1; |
231 | friend_con->status = FRIENDCONN_STATUS_CONNECTED; | 331 | friend_con->status = FRIENDCONN_STATUS_CONNECTED; |
232 | friend_con->ping_lastrecv = unix_time(); | 332 | friend_con->ping_lastrecv = unix_time(); |
333 | friend_con->share_relays_lastsent = 0; | ||
233 | onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); | 334 | onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); |
234 | } else { /* Went offline. */ | 335 | } else { /* Went offline. */ |
235 | if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { | 336 | if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { |
236 | call_cb = 1; | 337 | call_cb = 1; |
237 | friend_con->dht_ping_lastrecv = unix_time(); | 338 | friend_con->dht_pk_lastrecv = unix_time(); |
238 | onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); | 339 | onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); |
239 | } | 340 | } |
240 | 341 | ||
@@ -263,18 +364,30 @@ static int handle_packet(void *object, int number, uint8_t *data, uint16_t lengt | |||
263 | Friend_Connections *fr_c = object; | 364 | Friend_Connections *fr_c = object; |
264 | Friend_Conn *friend_con = get_conn(fr_c, number); | 365 | Friend_Conn *friend_con = get_conn(fr_c, number); |
265 | 366 | ||
367 | if (!friend_con) | ||
368 | return -1; | ||
369 | |||
266 | if (data[0] == PACKET_ID_FRIEND_REQUESTS) { | 370 | if (data[0] == PACKET_ID_FRIEND_REQUESTS) { |
267 | if (fr_c->fr_request_callback) | 371 | if (fr_c->fr_request_callback) |
268 | fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); | 372 | fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); |
269 | 373 | ||
270 | return 0; | 374 | return 0; |
271 | } | 375 | } else if (data[0] == PACKET_ID_ALIVE) { |
376 | friend_con->ping_lastrecv = unix_time(); | ||
377 | return 0; | ||
378 | } else if (data[0] == PACKET_ID_SHARE_RELAYS) { | ||
379 | Node_format nodes[MAX_SHARED_RELAYS]; | ||
380 | int n; | ||
272 | 381 | ||
273 | if (!friend_con) | 382 | if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1) |
274 | return -1; | 383 | return -1; |
384 | |||
385 | int j; | ||
386 | |||
387 | for (j = 0; j < n; j++) { | ||
388 | friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); | ||
389 | } | ||
275 | 390 | ||
276 | if (data[0] == PACKET_ID_ALIVE) { | ||
277 | friend_con->ping_lastrecv = unix_time(); | ||
278 | return 0; | 391 | return 0; |
279 | } | 392 | } |
280 | 393 | ||
@@ -333,6 +446,11 @@ static int handle_new_connections(void *object, New_Connection *n_c) | |||
333 | return -1; | 446 | return -1; |
334 | 447 | ||
335 | int id = accept_crypto_connection(fr_c->net_crypto, n_c); | 448 | int id = accept_crypto_connection(fr_c->net_crypto, n_c); |
449 | |||
450 | if (id == -1) { | ||
451 | return -1; | ||
452 | } | ||
453 | |||
336 | connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id); | 454 | connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id); |
337 | connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id); | 455 | connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id); |
338 | connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); | 456 | connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); |
@@ -345,7 +463,9 @@ static int handle_new_connections(void *object, New_Connection *n_c) | |||
345 | friend_con->dht_ip_port_lastrecv = unix_time(); | 463 | friend_con->dht_ip_port_lastrecv = unix_time(); |
346 | } | 464 | } |
347 | 465 | ||
348 | dht_pk_callback(fr_c, friendcon_id, n_c->dht_public_key); | 466 | if (memcmp(friend_con->dht_temp_pk, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES) != 0) { |
467 | change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key); | ||
468 | } | ||
349 | 469 | ||
350 | nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); | 470 | nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); |
351 | return 0; | 471 | return 0; |
@@ -365,7 +485,12 @@ static int friend_new_connection(Friend_Connections *fr_c, int friendcon_id) | |||
365 | return -1; | 485 | return -1; |
366 | } | 486 | } |
367 | 487 | ||
368 | int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key); | 488 | /* If dht_temp_pk does not contains a pk. */ |
489 | if (!friend_con->dht_lock) { | ||
490 | return -1; | ||
491 | } | ||
492 | |||
493 | int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key, friend_con->dht_temp_pk); | ||
369 | 494 | ||
370 | if (id == -1) | 495 | if (id == -1) |
371 | return -1; | 496 | return -1; |
@@ -647,7 +772,7 @@ void do_friend_connections(Friend_Connections *fr_c) | |||
647 | 772 | ||
648 | if (friend_con) { | 773 | if (friend_con) { |
649 | if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { | 774 | if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { |
650 | if (friend_con->dht_ping_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { | 775 | if (friend_con->dht_pk_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { |
651 | if (friend_con->dht_lock) { | 776 | if (friend_con->dht_lock) { |
652 | DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); | 777 | DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); |
653 | friend_con->dht_lock = 0; | 778 | friend_con->dht_lock = 0; |
@@ -660,8 +785,8 @@ void do_friend_connections(Friend_Connections *fr_c) | |||
660 | 785 | ||
661 | if (friend_con->dht_lock) { | 786 | if (friend_con->dht_lock) { |
662 | if (friend_new_connection(fr_c, i) == 0) { | 787 | if (friend_new_connection(fr_c, i) == 0) { |
663 | set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_temp_pk); | ||
664 | set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); | 788 | set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); |
789 | connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */ | ||
665 | } | 790 | } |
666 | } | 791 | } |
667 | 792 | ||
@@ -670,6 +795,10 @@ void do_friend_connections(Friend_Connections *fr_c) | |||
670 | send_ping(fr_c, i); | 795 | send_ping(fr_c, i); |
671 | } | 796 | } |
672 | 797 | ||
798 | if (friend_con->share_relays_lastsent + SHARE_RELAYS_INTERVAL < temp_time) { | ||
799 | send_relays(fr_c, i); | ||
800 | } | ||
801 | |||
673 | if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { | 802 | if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { |
674 | /* If we stopped receiving ping packets, kill it. */ | 803 | /* If we stopped receiving ping packets, kill it. */ |
675 | crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); | 804 | crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); |
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index b814eb0c..60b62646 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #define GROUPCHAT_CALLBACK_INDEX 1 | 36 | #define GROUPCHAT_CALLBACK_INDEX 1 |
37 | 37 | ||
38 | #define PACKET_ID_ALIVE 16 | 38 | #define PACKET_ID_ALIVE 16 |
39 | #define PACKET_ID_SHARE_RELAYS 17 | ||
39 | #define PACKET_ID_FRIEND_REQUESTS 18 | 40 | #define PACKET_ID_FRIEND_REQUESTS 18 |
40 | 41 | ||
41 | /* Interval between the sending of ping packets. */ | 42 | /* Interval between the sending of ping packets. */ |
@@ -47,6 +48,14 @@ | |||
47 | /* Time before friend is removed from the DHT after last hearing about him. */ | 48 | /* Time before friend is removed from the DHT after last hearing about him. */ |
48 | #define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT | 49 | #define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT |
49 | 50 | ||
51 | #define FRIEND_MAX_STORED_TCP_RELAYS (MAX_FRIEND_TCP_CONNECTIONS * 4) | ||
52 | |||
53 | /* Max number of tcp relays sent to friends */ | ||
54 | #define MAX_SHARED_RELAYS (RECOMMENDED_FRIEND_TCP_CONNECTIONS) | ||
55 | |||
56 | /* Interval between the sending of tcp relay information */ | ||
57 | #define SHARE_RELAYS_INTERVAL (5 * 60) | ||
58 | |||
50 | 59 | ||
51 | enum { | 60 | enum { |
52 | FRIENDCONN_STATUS_NONE, | 61 | FRIENDCONN_STATUS_NONE, |
@@ -61,12 +70,13 @@ typedef struct { | |||
61 | uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; | 70 | uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; |
62 | uint16_t dht_lock; | 71 | uint16_t dht_lock; |
63 | IP_Port dht_ip_port; | 72 | IP_Port dht_ip_port; |
64 | uint64_t dht_ping_lastrecv, dht_ip_port_lastrecv; | 73 | uint64_t dht_pk_lastrecv, dht_ip_port_lastrecv; |
65 | 74 | ||
66 | int onion_friendnum; | 75 | int onion_friendnum; |
67 | int crypt_connection_id; | 76 | int crypt_connection_id; |
68 | 77 | ||
69 | uint64_t ping_lastrecv, ping_lastsent; | 78 | uint64_t ping_lastrecv, ping_lastsent; |
79 | uint64_t share_relays_lastsent; | ||
70 | 80 | ||
71 | struct { | 81 | struct { |
72 | int (*status_callback)(void *object, int id, uint8_t status); | 82 | int (*status_callback)(void *object, int id, uint8_t status); |
@@ -83,6 +93,9 @@ typedef struct { | |||
83 | } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; | 93 | } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; |
84 | 94 | ||
85 | uint16_t lock_count; | 95 | uint16_t lock_count; |
96 | |||
97 | Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; | ||
98 | uint16_t tcp_relay_counter; | ||
86 | } Friend_Conn; | 99 | } Friend_Conn; |
87 | 100 | ||
88 | 101 | ||
@@ -127,6 +140,13 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Con | |||
127 | */ | 140 | */ |
128 | void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk); | 141 | void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk); |
129 | 142 | ||
143 | /* Add a TCP relay associated to the friend. | ||
144 | * | ||
145 | * return -1 on failure. | ||
146 | * return 0 on success. | ||
147 | */ | ||
148 | int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key); | ||
149 | |||
130 | /* Set the callbacks for the friend connection. | 150 | /* Set the callbacks for the friend connection. |
131 | * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. | 151 | * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. |
132 | * | 152 | * |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3e596a5f..ab0fb03a 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -35,7 +35,16 @@ | |||
35 | 35 | ||
36 | static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) | 36 | static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) |
37 | { | 37 | { |
38 | return (uint32_t)crypt_connection_id >= c->crypto_connections_length; | 38 | if ((uint32_t)crypt_connection_id >= c->crypto_connections_length) |
39 | return 1; | ||
40 | |||
41 | if (c->crypto_connections == NULL) | ||
42 | return 1; | ||
43 | |||
44 | if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION) | ||
45 | return 1; | ||
46 | |||
47 | return 0; | ||
39 | } | 48 | } |
40 | 49 | ||
41 | /* cookie timeout in seconds */ | 50 | /* cookie timeout in seconds */ |
@@ -206,8 +215,7 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t | |||
206 | 215 | ||
207 | /* Handle the cookie request packet (for TCP) | 216 | /* Handle the cookie request packet (for TCP) |
208 | */ | 217 | */ |
209 | static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, | 218 | static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length) |
210 | const uint8_t *packet, uint16_t length) | ||
211 | { | 219 | { |
212 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; | 220 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
213 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | 221 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
@@ -221,15 +229,13 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection | |||
221 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) | 229 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) |
222 | return -1; | 230 | return -1; |
223 | 231 | ||
224 | if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1) | 232 | int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data)); |
225 | return -1; | 233 | return ret; |
226 | |||
227 | return 0; | ||
228 | } | 234 | } |
229 | 235 | ||
230 | /* Handle the cookie request packet (for TCP oob packets) | 236 | /* Handle the cookie request packet (for TCP oob packets) |
231 | */ | 237 | */ |
232 | static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, | 238 | static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number, |
233 | const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) | 239 | const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) |
234 | { | 240 | { |
235 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; | 241 | uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; |
@@ -247,10 +253,8 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connect | |||
247 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) | 253 | if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) |
248 | return -1; | 254 | return -1; |
249 | 255 | ||
250 | if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1) | 256 | int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data)); |
251 | return -1; | 257 | return ret; |
252 | |||
253 | return 0; | ||
254 | } | 258 | } |
255 | 259 | ||
256 | /* Handle a cookie response packet of length encrypted with shared_key. | 260 | /* Handle a cookie response packet of length encrypted with shared_key. |
@@ -346,7 +350,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t | |||
346 | return -1; | 350 | return -1; |
347 | 351 | ||
348 | if (expected_real_pk) | 352 | if (expected_real_pk) |
349 | if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) | 353 | if (public_key_cmp(cookie_plain, expected_real_pk) != 0) |
350 | return -1; | 354 | return -1; |
351 | 355 | ||
352 | uint8_t cookie_hash[crypto_hash_sha512_BYTES]; | 356 | uint8_t cookie_hash[crypto_hash_sha512_BYTES]; |
@@ -400,12 +404,17 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t | |||
400 | 404 | ||
401 | //TODO: on bad networks, direct connections might not last indefinitely. | 405 | //TODO: on bad networks, direct connections might not last indefinitely. |
402 | if (conn->ip_port.ip.family != 0) { | 406 | if (conn->ip_port.ip.family != 0) { |
403 | uint8_t direct_connected = 0; | 407 | _Bool direct_connected = 0; |
404 | crypto_connection_status(c, crypt_connection_id, &direct_connected); | 408 | crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL); |
405 | 409 | ||
406 | if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { | 410 | if (direct_connected) { |
407 | pthread_mutex_unlock(&conn->mutex); | 411 | if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { |
408 | return 0; | 412 | pthread_mutex_unlock(&conn->mutex); |
413 | return 0; | ||
414 | } else { | ||
415 | pthread_mutex_unlock(&conn->mutex); | ||
416 | return -1; | ||
417 | } | ||
409 | } | 418 | } |
410 | 419 | ||
411 | //TODO: a better way of sending packets directly to confirm the others ip. | 420 | //TODO: a better way of sending packets directly to confirm the others ip. |
@@ -413,61 +422,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t | |||
413 | if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) | 422 | if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) |
414 | direct_send_attempt = 1; | 423 | direct_send_attempt = 1; |
415 | } | 424 | } |
416 | |||
417 | } | 425 | } |
418 | 426 | ||
419 | pthread_mutex_unlock(&conn->mutex); | 427 | pthread_mutex_unlock(&conn->mutex); |
428 | pthread_mutex_lock(&c->tcp_mutex); | ||
429 | int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length); | ||
430 | pthread_mutex_unlock(&c->tcp_mutex); | ||
420 | 431 | ||
421 | //TODO: detect and kill bad relays. | 432 | if (ret == 0 || direct_send_attempt) { |
422 | uint32_t i; | ||
423 | |||
424 | unsigned int r; | ||
425 | |||
426 | if (!conn->last_relay_sentto) { | ||
427 | r = rand(); | ||
428 | } else { | ||
429 | r = conn->last_relay_sentto - 1; | ||
430 | } | ||
431 | |||
432 | if (conn->num_tcp_online) { | ||
433 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
434 | pthread_mutex_lock(&c->tcp_mutex); | ||
435 | |||
436 | unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS; | ||
437 | int ret = 0; | ||
438 | |||
439 | if (conn->status_tcp[tcp_index] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ | ||
440 | ret = send_data(c->tcp_connections[tcp_index], conn->con_number_tcp[tcp_index], data, length); | ||
441 | } | ||
442 | |||
443 | pthread_mutex_unlock(&c->tcp_mutex); | ||
444 | |||
445 | if (ret == 1) { | ||
446 | conn->last_relay_sentto = tcp_index + 1; | ||
447 | return 0; | ||
448 | } | ||
449 | } | ||
450 | } | ||
451 | |||
452 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
453 | pthread_mutex_lock(&c->tcp_mutex); | ||
454 | |||
455 | unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS; | ||
456 | int ret = 0; | ||
457 | |||
458 | if (conn->status_tcp[tcp_index] == STATUS_TCP_INVISIBLE) { | ||
459 | ret = send_oob_packet(c->tcp_connections[tcp_index], conn->dht_public_key, data, length); | ||
460 | } | ||
461 | |||
462 | pthread_mutex_unlock(&c->tcp_mutex); | ||
463 | |||
464 | if (ret == 1) { | ||
465 | conn->last_relay_sentto = tcp_index + 1; | ||
466 | return 0; | ||
467 | } | ||
468 | } | ||
469 | |||
470 | if (direct_send_attempt) { | ||
471 | return 0; | 433 | return 0; |
472 | } | 434 | } |
473 | 435 | ||
@@ -1136,13 +1098,26 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id) | |||
1136 | &kill_packet, sizeof(kill_packet)); | 1098 | &kill_packet, sizeof(kill_packet)); |
1137 | } | 1099 | } |
1138 | 1100 | ||
1101 | static void connection_kill(Net_Crypto *c, int crypt_connection_id) | ||
1102 | { | ||
1103 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1104 | |||
1105 | if (conn == 0) | ||
1106 | return; | ||
1107 | |||
1108 | if (conn->connection_status_callback) { | ||
1109 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0); | ||
1110 | } | ||
1111 | |||
1112 | crypto_kill(c, crypt_connection_id); | ||
1113 | } | ||
1114 | |||
1139 | /* Handle a received data packet. | 1115 | /* Handle a received data packet. |
1140 | * | 1116 | * |
1141 | * return -1 on failure. | 1117 | * return -1 on failure. |
1142 | * return 0 on success. | 1118 | * return 0 on success. |
1143 | */ | 1119 | */ |
1144 | static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, | 1120 | static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length) |
1145 | uint16_t length) | ||
1146 | { | 1121 | { |
1147 | if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) | 1122 | if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) |
1148 | return -1; | 1123 | return -1; |
@@ -1179,7 +1154,7 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i | |||
1179 | } | 1154 | } |
1180 | 1155 | ||
1181 | if (real_data[0] == PACKET_ID_KILL) { | 1156 | if (real_data[0] == PACKET_ID_KILL) { |
1182 | conn->killed = 1; | 1157 | connection_kill(c, crypt_connection_id); |
1183 | return 0; | 1158 | return 0; |
1184 | } | 1159 | } |
1185 | 1160 | ||
@@ -1294,19 +1269,19 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons | |||
1294 | packet, length, conn->public_key) != 0) | 1269 | packet, length, conn->public_key) != 0) |
1295 | return -1; | 1270 | return -1; |
1296 | 1271 | ||
1297 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | 1272 | if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) { |
1298 | 1273 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | |
1299 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { | ||
1300 | if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) | ||
1301 | return -1; | ||
1302 | } | ||
1303 | 1274 | ||
1304 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | 1275 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { |
1305 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | 1276 | if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0) |
1306 | set_connection_dht_public_key(c, crypt_connection_id, dht_public_key); | 1277 | return -1; |
1278 | } | ||
1307 | 1279 | ||
1308 | if (conn->dht_pk_callback) | 1280 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; |
1309 | conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key); | 1281 | } else { |
1282 | if (conn->dht_pk_callback) | ||
1283 | conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key); | ||
1284 | } | ||
1310 | 1285 | ||
1311 | } else { | 1286 | } else { |
1312 | return -1; | 1287 | return -1; |
@@ -1448,31 +1423,12 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key) | |||
1448 | return -1; | 1423 | return -1; |
1449 | } | 1424 | } |
1450 | 1425 | ||
1451 | /* Get crypto connection id from public key of peer. | ||
1452 | * | ||
1453 | * return -1 if there are no connections like we are looking for. | ||
1454 | * return id if it found it. | ||
1455 | */ | ||
1456 | static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key) | ||
1457 | { | ||
1458 | uint32_t i; | ||
1459 | |||
1460 | for (i = 0; i < c->crypto_connections_length; ++i) { | ||
1461 | if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set) | ||
1462 | if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1463 | return i; | ||
1464 | } | ||
1465 | |||
1466 | return -1; | ||
1467 | } | ||
1468 | |||
1469 | /* Add a source to the crypto connection. | 1426 | /* Add a source to the crypto connection. |
1470 | * This is to be used only when we have received a packet from that source. | 1427 | * This is to be used only when we have received a packet from that source. |
1471 | * | 1428 | * |
1472 | * return -1 on failure. | 1429 | * return -1 on failure. |
1473 | * return positive number on success. | 1430 | * return positive number on success. |
1474 | * 0 if source was a direct UDP connection. | 1431 | * 0 if source was a direct UDP connection. |
1475 | * TODO | ||
1476 | */ | 1432 | */ |
1477 | static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) | 1433 | static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) |
1478 | { | 1434 | { |
@@ -1490,8 +1446,11 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, | |||
1490 | conn->ip_port = source; | 1446 | conn->ip_port = source; |
1491 | } | 1447 | } |
1492 | 1448 | ||
1493 | conn->direct_lastrecv_time = current_time_monotonic(); | 1449 | conn->direct_lastrecv_time = unix_time(); |
1494 | return 0; | 1450 | return 0; |
1451 | } else if (source.ip.family == TCP_FAMILY) { | ||
1452 | if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0) | ||
1453 | return 1; | ||
1495 | } | 1454 | } |
1496 | 1455 | ||
1497 | return -1; | 1456 | return -1; |
@@ -1537,30 +1496,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const | |||
1537 | int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); | 1496 | int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); |
1538 | 1497 | ||
1539 | if (crypt_connection_id != -1) { | 1498 | if (crypt_connection_id != -1) { |
1540 | int ret = -1; | ||
1541 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 1499 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
1542 | 1500 | ||
1543 | if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { | 1501 | if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) { |
1544 | memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); | 1502 | connection_kill(c, crypt_connection_id); |
1545 | memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); | 1503 | } else { |
1546 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | 1504 | int ret = -1; |
1547 | |||
1548 | crypto_connection_add_source(c, crypt_connection_id, source); | ||
1549 | 1505 | ||
1550 | if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { | 1506 | if (conn && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { |
1551 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | 1507 | memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); |
1552 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | 1508 | memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); |
1553 | set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key); | 1509 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); |
1554 | 1510 | ||
1555 | if (conn->dht_pk_callback) | 1511 | crypto_connection_add_source(c, crypt_connection_id, source); |
1556 | conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, n_c.dht_public_key); | ||
1557 | 1512 | ||
1558 | ret = 0; | 1513 | if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { |
1514 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
1515 | ret = 0; | ||
1516 | } | ||
1559 | } | 1517 | } |
1560 | } | ||
1561 | 1518 | ||
1562 | free(n_c.cookie); | 1519 | free(n_c.cookie); |
1563 | return ret; | 1520 | return ret; |
1521 | } | ||
1564 | } | 1522 | } |
1565 | 1523 | ||
1566 | int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); | 1524 | int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); |
@@ -1583,9 +1541,16 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1583 | if (crypt_connection_id == -1) | 1541 | if (crypt_connection_id == -1) |
1584 | return -1; | 1542 | return -1; |
1585 | 1543 | ||
1586 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 1544 | Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; |
1587 | 1545 | ||
1588 | if (conn == 0) | 1546 | if (n_c->cookie_length != COOKIE_LENGTH) |
1547 | return -1; | ||
1548 | |||
1549 | pthread_mutex_lock(&c->tcp_mutex); | ||
1550 | conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id); | ||
1551 | pthread_mutex_unlock(&c->tcp_mutex); | ||
1552 | |||
1553 | if (conn->connection_number_tcp == -1) | ||
1589 | return -1; | 1554 | return -1; |
1590 | 1555 | ||
1591 | memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); | 1556 | memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); |
@@ -1594,16 +1559,17 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1594 | random_nonce(conn->sent_nonce); | 1559 | random_nonce(conn->sent_nonce); |
1595 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); | 1560 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); |
1596 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); | 1561 | encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); |
1562 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | ||
1597 | 1563 | ||
1598 | if (n_c->cookie_length != COOKIE_LENGTH) | 1564 | if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) { |
1599 | return -1; | 1565 | pthread_mutex_lock(&c->tcp_mutex); |
1600 | 1566 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); | |
1601 | if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) | 1567 | pthread_mutex_unlock(&c->tcp_mutex); |
1568 | conn->status = CRYPTO_CONN_NO_CONNECTION; | ||
1602 | return -1; | 1569 | return -1; |
1570 | } | ||
1603 | 1571 | ||
1604 | conn->status = CRYPTO_CONN_NOT_CONFIRMED; | 1572 | memcpy(conn->dht_public_key, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES); |
1605 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | ||
1606 | set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key); | ||
1607 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 1573 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
1608 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; | 1574 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; |
1609 | crypto_connection_add_source(c, crypt_connection_id, n_c->source); | 1575 | crypto_connection_add_source(c, crypt_connection_id, n_c->source); |
@@ -1616,7 +1582,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1616 | * return -1 on failure. | 1582 | * return -1 on failure. |
1617 | * return connection id on success. | 1583 | * return connection id on success. |
1618 | */ | 1584 | */ |
1619 | int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) | 1585 | int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key) |
1620 | { | 1586 | { |
1621 | int crypt_connection_id = getcryptconnection_id(c, real_public_key); | 1587 | int crypt_connection_id = getcryptconnection_id(c, real_public_key); |
1622 | 1588 | ||
@@ -1628,149 +1594,40 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) | |||
1628 | if (crypt_connection_id == -1) | 1594 | if (crypt_connection_id == -1) |
1629 | return -1; | 1595 | return -1; |
1630 | 1596 | ||
1631 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 1597 | Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id]; |
1632 | 1598 | ||
1633 | if (conn == 0) | 1599 | if (conn == 0) |
1634 | return -1; | 1600 | return -1; |
1635 | 1601 | ||
1602 | pthread_mutex_lock(&c->tcp_mutex); | ||
1603 | conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); | ||
1604 | pthread_mutex_unlock(&c->tcp_mutex); | ||
1605 | |||
1606 | if (conn->connection_number_tcp == -1) | ||
1607 | return -1; | ||
1608 | |||
1636 | memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); | 1609 | memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); |
1637 | random_nonce(conn->sent_nonce); | 1610 | random_nonce(conn->sent_nonce); |
1638 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); | 1611 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); |
1639 | conn->status = CRYPTO_CONN_COOKIE_REQUESTING; | 1612 | conn->status = CRYPTO_CONN_COOKIE_REQUESTING; |
1640 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 1613 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
1641 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; | 1614 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; |
1642 | return crypt_connection_id; | 1615 | memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); |
1643 | } | ||
1644 | |||
1645 | /* Set the status for the TCP connection for conn in location to status. | ||
1646 | */ | ||
1647 | static void set_conn_tcp_status(Crypto_Connection *conn, unsigned int location, unsigned int status) | ||
1648 | { | ||
1649 | if (conn->status_tcp[location] == status) { | ||
1650 | return; | ||
1651 | } | ||
1652 | |||
1653 | if (conn->status_tcp[location] == STATUS_TCP_ONLINE) { | ||
1654 | --conn->num_tcp_online; | ||
1655 | } | ||
1656 | |||
1657 | if (status == STATUS_TCP_ONLINE) { | ||
1658 | ++conn->num_tcp_online; | ||
1659 | } | ||
1660 | |||
1661 | conn->status_tcp[location] = status; | ||
1662 | } | ||
1663 | |||
1664 | /* Disconnect peer from all associated TCP connections. | ||
1665 | * | ||
1666 | * return -1 on failure. | ||
1667 | * return 0 on success. | ||
1668 | */ | ||
1669 | static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | ||
1670 | { | ||
1671 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1672 | |||
1673 | if (conn == 0) | ||
1674 | return -1; | ||
1675 | |||
1676 | uint32_t i; | ||
1677 | |||
1678 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1679 | if (conn->status_tcp[i] != STATUS_TCP_NULL) { | ||
1680 | pthread_mutex_lock(&c->tcp_mutex); | ||
1681 | send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]); | ||
1682 | set_conn_tcp_status(conn, i, STATUS_TCP_NULL); | ||
1683 | conn->con_number_tcp[i] = 0; | ||
1684 | pthread_mutex_unlock(&c->tcp_mutex); | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | return 0; | ||
1689 | } | ||
1690 | |||
1691 | /* Connect peer to all associated TCP connections. | ||
1692 | * | ||
1693 | * return -1 on failure. | ||
1694 | * return 0 on success. | ||
1695 | */ | ||
1696 | static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | ||
1697 | { | ||
1698 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1699 | |||
1700 | if (conn == 0) | ||
1701 | return -1; | ||
1702 | 1616 | ||
1703 | uint32_t i; | 1617 | conn->cookie_request_number = random_64b(); |
1704 | 1618 | uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; | |
1705 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1706 | if (c->tcp_connections[i] == NULL) | ||
1707 | continue; | ||
1708 | 1619 | ||
1620 | if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, | ||
1621 | conn->shared_key) != sizeof(cookie_request) | ||
1622 | || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) { | ||
1709 | pthread_mutex_lock(&c->tcp_mutex); | 1623 | pthread_mutex_lock(&c->tcp_mutex); |
1710 | //TODO check function return? | 1624 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); |
1711 | send_routing_request(c->tcp_connections[i], conn->dht_public_key); | ||
1712 | pthread_mutex_unlock(&c->tcp_mutex); | 1625 | pthread_mutex_unlock(&c->tcp_mutex); |
1713 | } | 1626 | conn->status = CRYPTO_CONN_NO_CONNECTION; |
1714 | |||
1715 | return 0; | ||
1716 | } | ||
1717 | |||
1718 | /* Copy friends DHT public key into dht_key. | ||
1719 | * | ||
1720 | * return 0 on failure (no key copied). | ||
1721 | * return 1 on success (key copied). | ||
1722 | */ | ||
1723 | unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key) | ||
1724 | { | ||
1725 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1726 | |||
1727 | if (conn == 0) | ||
1728 | return 0; | ||
1729 | |||
1730 | if (conn->dht_public_key_set == 0) | ||
1731 | return 0; | ||
1732 | |||
1733 | memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES); | ||
1734 | return 1; | ||
1735 | } | ||
1736 | |||
1737 | |||
1738 | /* Set the DHT public key of the crypto connection. | ||
1739 | * | ||
1740 | * return -1 on failure. | ||
1741 | * return 0 on success. | ||
1742 | */ | ||
1743 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key) | ||
1744 | { | ||
1745 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1746 | |||
1747 | if (conn == 0) | ||
1748 | return -1; | 1627 | return -1; |
1749 | |||
1750 | if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1751 | return -1; | ||
1752 | |||
1753 | if (conn->dht_public_key_set == 1) { | ||
1754 | disconnect_peer_tcp(c, crypt_connection_id); | ||
1755 | } | 1628 | } |
1756 | 1629 | ||
1757 | memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); | 1630 | return crypt_connection_id; |
1758 | conn->dht_public_key_set = 1; | ||
1759 | |||
1760 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) { | ||
1761 | conn->cookie_request_number = random_64b(); | ||
1762 | uint8_t cookie_request[COOKIE_REQUEST_LENGTH]; | ||
1763 | |||
1764 | if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number, | ||
1765 | conn->shared_key) != sizeof(cookie_request)) | ||
1766 | return -1; | ||
1767 | |||
1768 | if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) | ||
1769 | return -1; | ||
1770 | }//TODO | ||
1771 | |||
1772 | connect_peer_tcp(c, crypt_connection_id); | ||
1773 | return 0; | ||
1774 | } | 1631 | } |
1775 | 1632 | ||
1776 | /* Set the direct ip of the crypto connection. | 1633 | /* Set the direct ip of the crypto connection. |
@@ -1789,7 +1646,7 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) | |||
1789 | return -1; | 1646 | return -1; |
1790 | 1647 | ||
1791 | if (!ipport_equal(&ip_port, &conn->ip_port)) { | 1648 | if (!ipport_equal(&ip_port, &conn->ip_port)) { |
1792 | if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) { | 1649 | if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) { |
1793 | if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port) | 1650 | if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port) |
1794 | return -1; | 1651 | return -1; |
1795 | } | 1652 | } |
@@ -1805,93 +1662,25 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) | |||
1805 | return -1; | 1662 | return -1; |
1806 | } | 1663 | } |
1807 | 1664 | ||
1808 | static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key) | ||
1809 | { | ||
1810 | TCP_Client_Connection *TCP_con = object; | ||
1811 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1812 | |||
1813 | int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key); | ||
1814 | |||
1815 | if (crypt_connection_id == -1) | ||
1816 | return -1; | ||
1817 | |||
1818 | set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id); | ||
1819 | 1665 | ||
1820 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 1666 | static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length) |
1821 | |||
1822 | if (conn == 0) | ||
1823 | return -1; | ||
1824 | |||
1825 | uint32_t location = TCP_con->net_crypto_location; | ||
1826 | |||
1827 | if (location >= MAX_TCP_CONNECTIONS) | ||
1828 | return -1; | ||
1829 | |||
1830 | if (c->tcp_connections[location] != TCP_con) | ||
1831 | return -1; | ||
1832 | |||
1833 | conn->con_number_tcp[location] = connection_id; | ||
1834 | uint32_t i; | ||
1835 | |||
1836 | for (i = 0; i < conn->num_tcp_relays; ++i) { | ||
1837 | if (memcmp(TCP_con->public_key, conn->tcp_relays[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1838 | set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE); | ||
1839 | return 0; | ||
1840 | } | ||
1841 | } | ||
1842 | |||
1843 | set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE); | ||
1844 | return 0; | ||
1845 | } | ||
1846 | |||
1847 | static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status) | ||
1848 | { | 1667 | { |
1849 | TCP_Client_Connection *TCP_con = object; | 1668 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) |
1850 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1851 | |||
1852 | Crypto_Connection *conn = get_crypto_connection(c, number); | ||
1853 | |||
1854 | if (conn == 0) | ||
1855 | return -1; | ||
1856 | |||
1857 | uint32_t location = TCP_con->net_crypto_location; | ||
1858 | |||
1859 | if (location >= MAX_TCP_CONNECTIONS) | ||
1860 | return -1; | ||
1861 | |||
1862 | if (c->tcp_connections[location] != TCP_con) | ||
1863 | return -1; | 1669 | return -1; |
1864 | 1670 | ||
1865 | if (status == 1) { | 1671 | Net_Crypto *c = object; |
1866 | set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE); | ||
1867 | } else if (status == 2) { | ||
1868 | set_conn_tcp_status(conn, location, STATUS_TCP_ONLINE); | ||
1869 | } | ||
1870 | |||
1871 | conn->con_number_tcp[location] = connection_id; | ||
1872 | return 0; | ||
1873 | } | ||
1874 | 1672 | ||
1875 | static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length) | 1673 | Crypto_Connection *conn = get_crypto_connection(c, id); |
1876 | { | ||
1877 | 1674 | ||
1878 | if (length == 0) | 1675 | if (conn == 0) |
1879 | return -1; | 1676 | return -1; |
1880 | 1677 | ||
1881 | TCP_Client_Connection *TCP_con = object; | ||
1882 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1883 | |||
1884 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { | 1678 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { |
1885 | return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length); | 1679 | return tcp_handle_cookie_request(c, conn->connection_number_tcp, data, length); |
1886 | } | 1680 | } |
1887 | 1681 | ||
1888 | Crypto_Connection *conn = get_crypto_connection(c, number); | ||
1889 | |||
1890 | if (conn == 0) | ||
1891 | return -1; | ||
1892 | |||
1893 | pthread_mutex_unlock(&c->tcp_mutex); | 1682 | pthread_mutex_unlock(&c->tcp_mutex); |
1894 | int ret = handle_packet_connection(c, number, data, length); | 1683 | int ret = handle_packet_connection(c, id, data, length); |
1895 | pthread_mutex_lock(&c->tcp_mutex); | 1684 | pthread_mutex_lock(&c->tcp_mutex); |
1896 | 1685 | ||
1897 | if (ret != 0) | 1686 | if (ret != 0) |
@@ -1901,92 +1690,29 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i | |||
1901 | return 0; | 1690 | return 0; |
1902 | } | 1691 | } |
1903 | 1692 | ||
1904 | static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length) | 1693 | static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, |
1694 | const uint8_t *data, uint16_t length) | ||
1905 | { | 1695 | { |
1906 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) | 1696 | if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) |
1907 | return -1; | 1697 | return -1; |
1908 | 1698 | ||
1909 | TCP_Client_Connection *TCP_con = object; | 1699 | Net_Crypto *c = object; |
1910 | Net_Crypto *c = TCP_con->net_crypto_pointer; | ||
1911 | uint32_t location = TCP_con->net_crypto_location; | ||
1912 | 1700 | ||
1913 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { | 1701 | if (data[0] == NET_PACKET_COOKIE_REQUEST) { |
1914 | return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length); | 1702 | return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length); |
1915 | } | 1703 | } else if (data[0] == NET_PACKET_CRYPTO_HS) { |
1916 | |||
1917 | int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key); | ||
1918 | |||
1919 | if (crypt_connection_id == -1) { | ||
1920 | IP_Port source; | 1704 | IP_Port source; |
1921 | source.port = 0; | 1705 | source.port = 0; |
1922 | source.ip.family = TCP_FAMILY; | 1706 | source.ip.family = TCP_FAMILY; |
1923 | source.ip.ip6.uint32[0] = location; | 1707 | source.ip.ip6.uint32[0] = tcp_connections_number; |
1924 | |||
1925 | if (data[0] != NET_PACKET_CRYPTO_HS) { | ||
1926 | LOGGER_DEBUG("tcp snhappen %u\n", data[0]); | ||
1927 | return -1; | ||
1928 | } | ||
1929 | 1708 | ||
1930 | if (handle_new_connection_handshake(c, source, data, length) != 0) | 1709 | if (handle_new_connection_handshake(c, source, data, length) != 0) |
1931 | return -1; | 1710 | return -1; |
1932 | 1711 | ||
1933 | return 0; | 1712 | return 0; |
1934 | } | 1713 | } else { |
1935 | |||
1936 | pthread_mutex_unlock(&c->tcp_mutex); | ||
1937 | int ret = handle_packet_connection(c, crypt_connection_id, data, length); | ||
1938 | pthread_mutex_lock(&c->tcp_mutex); | ||
1939 | |||
1940 | if (ret != 0) | ||
1941 | return -1; | 1714 | return -1; |
1942 | |||
1943 | return 0; | ||
1944 | } | ||
1945 | |||
1946 | static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length) | ||
1947 | { | ||
1948 | Net_Crypto *c = object; | ||
1949 | |||
1950 | if (c->tcp_onion_callback) | ||
1951 | return c->tcp_onion_callback(c->tcp_onion_callback_object, data, length); | ||
1952 | |||
1953 | return 1; | ||
1954 | } | ||
1955 | |||
1956 | |||
1957 | /* Check if tcp connection to public key can be created. | ||
1958 | * | ||
1959 | * return -1 if it can't. | ||
1960 | * return 0 if it can. | ||
1961 | */ | ||
1962 | static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key) | ||
1963 | { | ||
1964 | uint32_t i; | ||
1965 | |||
1966 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1967 | if (c->tcp_connections_new[i] == NULL) | ||
1968 | continue; | ||
1969 | |||
1970 | if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1971 | return -1; | ||
1972 | } | ||
1973 | |||
1974 | uint32_t num = 0; | ||
1975 | |||
1976 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1977 | if (c->tcp_connections[i] == NULL) | ||
1978 | continue; | ||
1979 | |||
1980 | if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) | ||
1981 | return -1; | ||
1982 | |||
1983 | ++num; | ||
1984 | } | 1715 | } |
1985 | |||
1986 | if (num == MAX_TCP_CONNECTIONS) | ||
1987 | return -1; | ||
1988 | |||
1989 | return 0; | ||
1990 | } | 1716 | } |
1991 | 1717 | ||
1992 | /* Add a tcp relay, associating it to a crypt_connection_id. | 1718 | /* Add a tcp relay, associating it to a crypt_connection_id. |
@@ -2001,45 +1727,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, | |||
2001 | if (conn == 0) | 1727 | if (conn == 0) |
2002 | return -1; | 1728 | return -1; |
2003 | 1729 | ||
2004 | if (ip_port.ip.family == TCP_INET) { | 1730 | pthread_mutex_lock(&c->tcp_mutex); |
2005 | ip_port.ip.family = AF_INET; | 1731 | int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key); |
2006 | } else if (ip_port.ip.family == TCP_INET6) { | 1732 | pthread_mutex_unlock(&c->tcp_mutex); |
2007 | ip_port.ip.family = AF_INET6; | 1733 | return ret; |
2008 | } | ||
2009 | |||
2010 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
2011 | return -1; | ||
2012 | |||
2013 | uint32_t i; | ||
2014 | |||
2015 | for (i = 0; i < conn->num_tcp_relays; ++i) { | ||
2016 | if (memcmp(conn->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
2017 | conn->tcp_relays[i].ip_port = ip_port; | ||
2018 | return 0; | ||
2019 | } | ||
2020 | } | ||
2021 | |||
2022 | if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { | ||
2023 | uint16_t index = rand() % MAX_TCP_RELAYS_PEER; | ||
2024 | conn->tcp_relays[index].ip_port = ip_port; | ||
2025 | memcpy(conn->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES); | ||
2026 | } else { | ||
2027 | conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; | ||
2028 | memcpy(conn->tcp_relays[conn->num_tcp_relays].public_key, public_key, crypto_box_PUBLICKEYBYTES); | ||
2029 | ++conn->num_tcp_relays; | ||
2030 | } | ||
2031 | |||
2032 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2033 | if (c->tcp_connections[i] == NULL) | ||
2034 | continue; | ||
2035 | |||
2036 | if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
2037 | if (conn->status_tcp[i] == STATUS_TCP_OFFLINE) | ||
2038 | set_conn_tcp_status(conn, i, STATUS_TCP_INVISIBLE); | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | return add_tcp_relay(c, ip_port, public_key); | ||
2043 | } | 1734 | } |
2044 | 1735 | ||
2045 | /* Add a tcp relay to the array. | 1736 | /* Add a tcp relay to the array. |
@@ -2049,30 +1740,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, | |||
2049 | */ | 1740 | */ |
2050 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) | 1741 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) |
2051 | { | 1742 | { |
2052 | if (ip_port.ip.family == TCP_INET) { | 1743 | pthread_mutex_lock(&c->tcp_mutex); |
2053 | ip_port.ip.family = AF_INET; | 1744 | int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key); |
2054 | } else if (ip_port.ip.family == TCP_INET6) { | 1745 | pthread_mutex_unlock(&c->tcp_mutex); |
2055 | ip_port.ip.family = AF_INET6; | 1746 | return ret; |
2056 | } | ||
2057 | |||
2058 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
2059 | return -1; | ||
2060 | |||
2061 | if (tcp_connection_check(c, public_key) != 0) | ||
2062 | return -1; | ||
2063 | |||
2064 | uint32_t i; | ||
2065 | |||
2066 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2067 | if (c->tcp_connections_new[i] == NULL) { | ||
2068 | c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key, | ||
2069 | &c->proxy_info); | ||
2070 | |||
2071 | return 0; | ||
2072 | } | ||
2073 | } | ||
2074 | |||
2075 | return -1; | ||
2076 | } | 1747 | } |
2077 | 1748 | ||
2078 | /* Return a random TCP connection number for use in send_tcp_onion_request. | 1749 | /* Return a random TCP connection number for use in send_tcp_onion_request. |
@@ -2085,47 +1756,25 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) | |||
2085 | */ | 1756 | */ |
2086 | int get_random_tcp_con_number(Net_Crypto *c) | 1757 | int get_random_tcp_con_number(Net_Crypto *c) |
2087 | { | 1758 | { |
2088 | unsigned int i, r = rand(); | 1759 | pthread_mutex_lock(&c->tcp_mutex); |
2089 | 1760 | int ret = get_random_tcp_onion_conn_number(c->tcp_c); | |
2090 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 1761 | pthread_mutex_unlock(&c->tcp_mutex); |
2091 | if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) { | ||
2092 | return (i + r) % MAX_TCP_CONNECTIONS; | ||
2093 | } | ||
2094 | } | ||
2095 | 1762 | ||
2096 | return -1; | 1763 | return ret; |
2097 | } | 1764 | } |
2098 | 1765 | ||
2099 | /* Send an onion packet via the TCP relay corresponding to TCP_conn_number. | 1766 | /* Send an onion packet via the TCP relay corresponding to tcp_connections_number. |
2100 | * | 1767 | * |
2101 | * return 0 on success. | 1768 | * return 0 on success. |
2102 | * return -1 on failure. | 1769 | * return -1 on failure. |
2103 | */ | 1770 | */ |
2104 | int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) | 1771 | int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length) |
2105 | { | 1772 | { |
2106 | if (TCP_conn_number > MAX_TCP_CONNECTIONS) { | 1773 | pthread_mutex_lock(&c->tcp_mutex); |
2107 | return -1; | 1774 | int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length); |
2108 | } | 1775 | pthread_mutex_unlock(&c->tcp_mutex); |
2109 | |||
2110 | if (c->tcp_connections[TCP_conn_number]) { | ||
2111 | pthread_mutex_lock(&c->tcp_mutex); | ||
2112 | int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length); | ||
2113 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2114 | |||
2115 | if (ret == 1) | ||
2116 | return 0; | ||
2117 | } | ||
2118 | |||
2119 | return -1; | ||
2120 | } | ||
2121 | 1776 | ||
2122 | /* Set the function to be called when an onion response packet is received by one of the TCP connections. | 1777 | return ret; |
2123 | */ | ||
2124 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, | ||
2125 | uint16_t length), void *object) | ||
2126 | { | ||
2127 | c->tcp_onion_callback = tcp_onion_callback; | ||
2128 | c->tcp_onion_callback_object = object; | ||
2129 | } | 1778 | } |
2130 | 1779 | ||
2131 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. | 1780 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. |
@@ -2134,173 +1783,47 @@ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *o | |||
2134 | * return number of relays copied to tcp_relays on success. | 1783 | * return number of relays copied to tcp_relays on success. |
2135 | * return 0 on failure. | 1784 | * return 0 on failure. |
2136 | */ | 1785 | */ |
2137 | unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num) | 1786 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) |
2138 | { | 1787 | { |
2139 | if (num == 0) | 1788 | if (num == 0) |
2140 | return 0; | 1789 | return 0; |
2141 | 1790 | ||
2142 | uint32_t i; | 1791 | pthread_mutex_lock(&c->tcp_mutex); |
2143 | uint16_t copied = 0; | 1792 | unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num); |
2144 | 1793 | pthread_mutex_unlock(&c->tcp_mutex); | |
2145 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2146 | if (c->tcp_connections[i] != NULL) { | ||
2147 | memcpy(tcp_relays[copied].public_key, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES); | ||
2148 | tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port; | ||
2149 | |||
2150 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { | ||
2151 | tcp_relays[copied].ip_port.ip.family = TCP_INET; | ||
2152 | } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) { | ||
2153 | tcp_relays[copied].ip_port.ip.family = TCP_INET6; | ||
2154 | } | ||
2155 | |||
2156 | ++copied; | ||
2157 | |||
2158 | if (copied == num) | ||
2159 | return copied; | ||
2160 | } | ||
2161 | } | ||
2162 | 1794 | ||
2163 | return copied; | 1795 | return ret; |
2164 | } | 1796 | } |
2165 | 1797 | ||
2166 | /* Add a connected tcp connection to the tcp_connections array. | 1798 | static void do_tcp(Net_Crypto *c) |
2167 | * | ||
2168 | * return 0 if it was added. | ||
2169 | * return -1 if it wasn't. | ||
2170 | */ | ||
2171 | static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con) | ||
2172 | { | 1799 | { |
2173 | uint32_t i; | 1800 | pthread_mutex_lock(&c->tcp_mutex); |
2174 | 1801 | do_tcp_connections(c->tcp_c); | |
2175 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 1802 | pthread_mutex_unlock(&c->tcp_mutex); |
2176 | if (c->tcp_connections[i] == NULL) | ||
2177 | break; | ||
2178 | } | ||
2179 | |||
2180 | if (i == MAX_TCP_CONNECTIONS) | ||
2181 | return -1; | ||
2182 | 1803 | ||
2183 | uint32_t tcp_num = i; | 1804 | uint32_t i; |
2184 | 1805 | ||
2185 | for (i = 0; i < c->crypto_connections_length; ++i) { | 1806 | for (i = 0; i < c->crypto_connections_length; ++i) { |
2186 | Crypto_Connection *conn = get_crypto_connection(c, i); | 1807 | Crypto_Connection *conn = get_crypto_connection(c, i); |
2187 | 1808 | ||
2188 | if (conn == 0) | 1809 | if (conn == 0) |
2189 | return -1; | 1810 | return; |
2190 | |||
2191 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) | ||
2192 | continue; | ||
2193 | |||
2194 | if (conn->status == CRYPTO_CONN_TIMED_OUT) | ||
2195 | continue; | ||
2196 | |||
2197 | if (conn->dht_public_key_set) | ||
2198 | if (send_routing_request(tcp_con, conn->dht_public_key) != 1) | ||
2199 | return -1; | ||
2200 | |||
2201 | } | ||
2202 | |||
2203 | tcp_con->net_crypto_pointer = c; | ||
2204 | tcp_con->net_crypto_location = tcp_num; | ||
2205 | routing_response_handler(tcp_con, tcp_response_callback, tcp_con); | ||
2206 | routing_status_handler(tcp_con, tcp_status_callback, tcp_con); | ||
2207 | routing_data_handler(tcp_con, tcp_data_callback, tcp_con); | ||
2208 | oob_data_handler(tcp_con, tcp_oob_callback, tcp_con); | ||
2209 | onion_response_handler(tcp_con, tcp_onion_callback, c); | ||
2210 | c->tcp_connections[tcp_num] = tcp_con; | ||
2211 | return 0; | ||
2212 | } | ||
2213 | |||
2214 | static void do_tcp(Net_Crypto *c) | ||
2215 | { | ||
2216 | uint32_t i; | ||
2217 | |||
2218 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2219 | if (c->tcp_connections_new[i] == NULL) | ||
2220 | continue; | ||
2221 | |||
2222 | pthread_mutex_lock(&c->tcp_mutex); | ||
2223 | do_TCP_connection(c->tcp_connections_new[i]); | ||
2224 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2225 | 1811 | ||
2226 | if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) { | 1812 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { |
2227 | pthread_mutex_lock(&c->tcp_mutex); | 1813 | _Bool direct_connected = 0; |
2228 | int ret = add_tcp_connected(c, c->tcp_connections_new[i]); | 1814 | crypto_connection_status(c, i, &direct_connected, NULL); |
2229 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2230 | 1815 | ||
2231 | if (ret == 0) { | 1816 | if (direct_connected) { |
2232 | c->tcp_connections_new[i] = NULL; | 1817 | pthread_mutex_lock(&c->tcp_mutex); |
1818 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0); | ||
1819 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2233 | } else { | 1820 | } else { |
2234 | kill_TCP_connection(c->tcp_connections_new[i]); | 1821 | pthread_mutex_lock(&c->tcp_mutex); |
2235 | c->tcp_connections_new[i] = NULL; | 1822 | set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1); |
1823 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2236 | } | 1824 | } |
2237 | } | 1825 | } |
2238 | } | 1826 | } |
2239 | |||
2240 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2241 | if (c->tcp_connections[i] == NULL) | ||
2242 | continue; | ||
2243 | |||
2244 | pthread_mutex_lock(&c->tcp_mutex); | ||
2245 | do_TCP_connection(c->tcp_connections[i]); | ||
2246 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2247 | } | ||
2248 | } | ||
2249 | |||
2250 | static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number) | ||
2251 | { | ||
2252 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) | ||
2253 | return; | ||
2254 | |||
2255 | if (number >= MAX_TCP_CONNECTIONS) | ||
2256 | return; | ||
2257 | |||
2258 | set_conn_tcp_status(conn, number, STATUS_TCP_NULL); | ||
2259 | conn->con_number_tcp[number] = 0; | ||
2260 | } | ||
2261 | |||
2262 | static void clear_disconnected_tcp(Net_Crypto *c) | ||
2263 | { | ||
2264 | uint32_t i, j; | ||
2265 | |||
2266 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2267 | if (c->tcp_connections_new[i] == NULL) | ||
2268 | continue; | ||
2269 | |||
2270 | if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED) | ||
2271 | continue; | ||
2272 | |||
2273 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
2274 | c->tcp_connections_new[i] = NULL; | ||
2275 | } | ||
2276 | |||
2277 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2278 | if (c->tcp_connections[i] == NULL) | ||
2279 | continue; | ||
2280 | |||
2281 | TCP_Client_Connection *tcp_con = c->tcp_connections[i]; | ||
2282 | |||
2283 | if (tcp_con->status != TCP_CLIENT_DISCONNECTED) | ||
2284 | continue; | ||
2285 | |||
2286 | /* Try reconnecting to relay on disconnect. */ | ||
2287 | add_tcp_relay(c, tcp_con->ip_port, tcp_con->public_key); | ||
2288 | |||
2289 | pthread_mutex_lock(&c->tcp_mutex); | ||
2290 | c->tcp_connections[i] = NULL; | ||
2291 | kill_TCP_connection(tcp_con); | ||
2292 | |||
2293 | for (j = 0; j < c->crypto_connections_length; ++j) { | ||
2294 | Crypto_Connection *conn = get_crypto_connection(c, j); | ||
2295 | |||
2296 | if (conn == 0) | ||
2297 | continue; | ||
2298 | |||
2299 | clear_disconnected_tcp_peer(conn, i); | ||
2300 | } | ||
2301 | |||
2302 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2303 | } | ||
2304 | } | 1827 | } |
2305 | 1828 | ||
2306 | /* Set function to be called when connection with crypt_connection_id goes connects/disconnects. | 1829 | /* Set function to be called when connection with crypt_connection_id goes connects/disconnects. |
@@ -2372,8 +1895,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, | |||
2372 | } | 1895 | } |
2373 | 1896 | ||
2374 | 1897 | ||
2375 | /* Set the function for this friend that will be callbacked with object and number | 1898 | /* Set the function for this friend that will be callbacked with object and number if |
2376 | * when that friend gives us his DHT temporary public key. | 1899 | * the friend sends us a different dht public key than we have associated to him. |
1900 | * | ||
1901 | * If this function is called, the connection should be recreated with the new public key. | ||
2377 | * | 1902 | * |
2378 | * object and number will be passed as argument to this function. | 1903 | * object and number will be passed as argument to this function. |
2379 | * | 1904 | * |
@@ -2441,7 +1966,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet | |||
2441 | return -1; | 1966 | return -1; |
2442 | 1967 | ||
2443 | pthread_mutex_lock(&conn->mutex); | 1968 | pthread_mutex_lock(&conn->mutex); |
2444 | conn->direct_lastrecv_time = current_time_monotonic(); | 1969 | conn->direct_lastrecv_time = unix_time(); |
2445 | pthread_mutex_unlock(&conn->mutex); | 1970 | pthread_mutex_unlock(&conn->mutex); |
2446 | return 0; | 1971 | return 0; |
2447 | } | 1972 | } |
@@ -2746,7 +2271,10 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) | |||
2746 | if (conn->status == CRYPTO_CONN_ESTABLISHED) | 2271 | if (conn->status == CRYPTO_CONN_ESTABLISHED) |
2747 | send_kill_packet(c, crypt_connection_id); | 2272 | send_kill_packet(c, crypt_connection_id); |
2748 | 2273 | ||
2749 | disconnect_peer_tcp(c, crypt_connection_id); | 2274 | pthread_mutex_lock(&c->tcp_mutex); |
2275 | kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); | ||
2276 | pthread_mutex_unlock(&c->tcp_mutex); | ||
2277 | |||
2750 | bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); | 2278 | bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); |
2751 | clear_temp_packet(c, crypt_connection_id); | 2279 | clear_temp_packet(c, crypt_connection_id); |
2752 | clear_buffer(&conn->send_array); | 2280 | clear_buffer(&conn->send_array); |
@@ -2762,18 +2290,26 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) | |||
2762 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. | 2290 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. |
2763 | * | 2291 | * |
2764 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. | 2292 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. |
2293 | * sets online_tcp_relays to the number of connected tcp relays this connection has. | ||
2765 | */ | 2294 | */ |
2766 | unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) | 2295 | unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected, |
2296 | unsigned int *online_tcp_relays) | ||
2767 | { | 2297 | { |
2768 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | 2298 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); |
2769 | 2299 | ||
2770 | if (conn == 0) | 2300 | if (conn == 0) |
2771 | return CRYPTO_CONN_NO_CONNECTION; | 2301 | return CRYPTO_CONN_NO_CONNECTION; |
2772 | 2302 | ||
2773 | *direct_connected = 0; | 2303 | if (direct_connected) { |
2304 | *direct_connected = 0; | ||
2774 | 2305 | ||
2775 | if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) | 2306 | if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) |
2776 | *direct_connected = 1; | 2307 | *direct_connected = 1; |
2308 | } | ||
2309 | |||
2310 | if (online_tcp_relays) { | ||
2311 | *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp); | ||
2312 | } | ||
2777 | 2313 | ||
2778 | return conn->status; | 2314 | return conn->status; |
2779 | } | 2315 | } |
@@ -2816,8 +2352,19 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info) | |||
2816 | if (temp == NULL) | 2352 | if (temp == NULL) |
2817 | return NULL; | 2353 | return NULL; |
2818 | 2354 | ||
2355 | temp->tcp_c = new_tcp_connections(dht, proxy_info); | ||
2356 | |||
2357 | if (temp->tcp_c == NULL) { | ||
2358 | free(temp); | ||
2359 | return NULL; | ||
2360 | } | ||
2361 | |||
2362 | set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp); | ||
2363 | set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp); | ||
2364 | |||
2819 | if (create_recursive_mutex(&temp->tcp_mutex) != 0 || | 2365 | if (create_recursive_mutex(&temp->tcp_mutex) != 0 || |
2820 | pthread_mutex_init(&temp->connections_mutex, NULL) != 0) { | 2366 | pthread_mutex_init(&temp->connections_mutex, NULL) != 0) { |
2367 | kill_tcp_connections(temp->tcp_c); | ||
2821 | free(temp); | 2368 | free(temp); |
2822 | return NULL; | 2369 | return NULL; |
2823 | } | 2370 | } |
@@ -2836,8 +2383,6 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info) | |||
2836 | 2383 | ||
2837 | bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); | 2384 | bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); |
2838 | 2385 | ||
2839 | temp->proxy_info = *proxy_info; | ||
2840 | |||
2841 | return temp; | 2386 | return temp; |
2842 | } | 2387 | } |
2843 | 2388 | ||
@@ -2852,7 +2397,7 @@ static void kill_timedout(Net_Crypto *c) | |||
2852 | if (conn == 0) | 2397 | if (conn == 0) |
2853 | return; | 2398 | return; |
2854 | 2399 | ||
2855 | if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT) | 2400 | if (conn->status == CRYPTO_CONN_NO_CONNECTION) |
2856 | continue; | 2401 | continue; |
2857 | 2402 | ||
2858 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT | 2403 | if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT |
@@ -2860,19 +2405,8 @@ static void kill_timedout(Net_Crypto *c) | |||
2860 | if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) | 2405 | if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) |
2861 | continue; | 2406 | continue; |
2862 | 2407 | ||
2863 | conn->killed = 1; | 2408 | connection_kill(c, i); |
2864 | |||
2865 | } | ||
2866 | |||
2867 | if (conn->killed) { | ||
2868 | if (conn->connection_status_callback) { | ||
2869 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0); | ||
2870 | crypto_kill(c, i); | ||
2871 | continue; | ||
2872 | } | ||
2873 | 2409 | ||
2874 | conn->status = CRYPTO_CONN_TIMED_OUT; | ||
2875 | continue; | ||
2876 | } | 2410 | } |
2877 | 2411 | ||
2878 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { | 2412 | if (conn->status == CRYPTO_CONN_ESTABLISHED) { |
@@ -2894,7 +2428,6 @@ void do_net_crypto(Net_Crypto *c) | |||
2894 | unix_time_update(); | 2428 | unix_time_update(); |
2895 | kill_timedout(c); | 2429 | kill_timedout(c); |
2896 | do_tcp(c); | 2430 | do_tcp(c); |
2897 | clear_disconnected_tcp(c); | ||
2898 | send_crypto_packets(c); | 2431 | send_crypto_packets(c); |
2899 | } | 2432 | } |
2900 | 2433 | ||
@@ -2906,14 +2439,10 @@ void kill_net_crypto(Net_Crypto *c) | |||
2906 | crypto_kill(c, i); | 2439 | crypto_kill(c, i); |
2907 | } | 2440 | } |
2908 | 2441 | ||
2909 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2910 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
2911 | kill_TCP_connection(c->tcp_connections[i]); | ||
2912 | } | ||
2913 | |||
2914 | pthread_mutex_destroy(&c->tcp_mutex); | 2442 | pthread_mutex_destroy(&c->tcp_mutex); |
2915 | pthread_mutex_destroy(&c->connections_mutex); | 2443 | pthread_mutex_destroy(&c->connections_mutex); |
2916 | 2444 | ||
2445 | kill_tcp_connections(c->tcp_c); | ||
2917 | bs_list_free(&c->ip_port_list); | 2446 | bs_list_free(&c->ip_port_list); |
2918 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); | 2447 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); |
2919 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); | 2448 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); |
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index fab72cb3..9eb5e2d3 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #include "DHT.h" | 27 | #include "DHT.h" |
28 | #include "LAN_discovery.h" | 28 | #include "LAN_discovery.h" |
29 | #include "TCP_client.h" | 29 | #include "TCP_connection.h" |
30 | #include <pthread.h> | 30 | #include <pthread.h> |
31 | 31 | ||
32 | #define CRYPTO_CONN_NO_CONNECTION 0 | 32 | #define CRYPTO_CONN_NO_CONNECTION 0 |
@@ -34,7 +34,6 @@ | |||
34 | #define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets | 34 | #define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets |
35 | #define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other | 35 | #define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other |
36 | #define CRYPTO_CONN_ESTABLISHED 4 | 36 | #define CRYPTO_CONN_ESTABLISHED 4 |
37 | #define CRYPTO_CONN_TIMED_OUT 5 | ||
38 | 37 | ||
39 | /* Maximum size of receiving and sending packet buffers. */ | 38 | /* Maximum size of receiving and sending packet buffers. */ |
40 | #define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */ | 39 | #define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */ |
@@ -61,7 +60,7 @@ | |||
61 | #define MAX_NUM_SENDPACKET_TRIES 8 | 60 | #define MAX_NUM_SENDPACKET_TRIES 8 |
62 | 61 | ||
63 | /* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ | 62 | /* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ |
64 | #define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 2) | 63 | #define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000) |
65 | 64 | ||
66 | #define PACKET_ID_PADDING 0 /* Denotes padding */ | 65 | #define PACKET_ID_PADDING 0 /* Denotes padding */ |
67 | #define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ | 66 | #define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ |
@@ -73,11 +72,6 @@ | |||
73 | #define MAX_TCP_CONNECTIONS 64 | 72 | #define MAX_TCP_CONNECTIONS 64 |
74 | #define MAX_TCP_RELAYS_PEER 4 | 73 | #define MAX_TCP_RELAYS_PEER 4 |
75 | 74 | ||
76 | #define STATUS_TCP_NULL 0 | ||
77 | #define STATUS_TCP_OFFLINE 1 | ||
78 | #define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */ | ||
79 | #define STATUS_TCP_ONLINE 3 | ||
80 | |||
81 | /* All packets starting with a byte in this range are considered lossy packets. */ | 75 | /* All packets starting with a byte in this range are considered lossy packets. */ |
82 | #define PACKET_ID_LOSSY_RANGE_START 192 | 76 | #define PACKET_ID_LOSSY_RANGE_START 192 |
83 | #define PACKET_ID_LOSSY_RANGE_SIZE 63 | 77 | #define PACKET_ID_LOSSY_RANGE_SIZE 63 |
@@ -112,11 +106,9 @@ typedef struct { | |||
112 | * 2 if we are sending handshake packets | 106 | * 2 if we are sending handshake packets |
113 | * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), | 107 | * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), |
114 | * 4 if the connection is established. | 108 | * 4 if the connection is established. |
115 | * 5 if the connection is timed out. | ||
116 | */ | 109 | */ |
117 | uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ | 110 | uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ |
118 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ | 111 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ |
119 | uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */ | ||
120 | 112 | ||
121 | uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ | 113 | uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ |
122 | uint16_t temp_packet_length; | 114 | uint16_t temp_packet_length; |
@@ -155,15 +147,8 @@ typedef struct { | |||
155 | long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; | 147 | long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; |
156 | uint32_t packets_sent; | 148 | uint32_t packets_sent; |
157 | 149 | ||
158 | uint8_t killed; /* set to 1 to kill the connection. */ | 150 | /* TCP_connection connection_number */ |
159 | 151 | unsigned int connection_number_tcp; | |
160 | uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */ | ||
161 | uint8_t con_number_tcp[MAX_TCP_CONNECTIONS]; | ||
162 | unsigned int last_relay_sentto; | ||
163 | unsigned int num_tcp_online; | ||
164 | |||
165 | Node_format tcp_relays[MAX_TCP_RELAYS_PEER]; | ||
166 | uint16_t num_tcp_relays; | ||
167 | 152 | ||
168 | uint8_t maximum_speed_reached; | 153 | uint8_t maximum_speed_reached; |
169 | 154 | ||
@@ -186,10 +171,9 @@ typedef struct { | |||
186 | 171 | ||
187 | typedef struct { | 172 | typedef struct { |
188 | DHT *dht; | 173 | DHT *dht; |
174 | TCP_Connections *tcp_c; | ||
189 | 175 | ||
190 | Crypto_Connection *crypto_connections; | 176 | Crypto_Connection *crypto_connections; |
191 | TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS]; | ||
192 | TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS]; | ||
193 | pthread_mutex_t tcp_mutex; | 177 | pthread_mutex_t tcp_mutex; |
194 | 178 | ||
195 | pthread_mutex_t connections_mutex; | 179 | pthread_mutex_t connections_mutex; |
@@ -211,11 +195,6 @@ typedef struct { | |||
211 | uint32_t current_sleep_time; | 195 | uint32_t current_sleep_time; |
212 | 196 | ||
213 | BS_LIST ip_port_list; | 197 | BS_LIST ip_port_list; |
214 | |||
215 | int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length); | ||
216 | void *tcp_onion_callback_object; | ||
217 | |||
218 | TCP_Proxy_Info proxy_info; | ||
219 | } Net_Crypto; | 198 | } Net_Crypto; |
220 | 199 | ||
221 | 200 | ||
@@ -241,21 +220,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c); | |||
241 | * return -1 on failure. | 220 | * return -1 on failure. |
242 | * return connection id on success. | 221 | * return connection id on success. |
243 | */ | 222 | */ |
244 | int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key); | 223 | int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key); |
245 | |||
246 | /* Copy friends DHT public key into dht_key. | ||
247 | * | ||
248 | * return 0 on failure (no key copied). | ||
249 | * return 1 on success (key copied). | ||
250 | */ | ||
251 | unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key); | ||
252 | |||
253 | /* Set the DHT public key of the crypto connection. | ||
254 | * | ||
255 | * return -1 on failure. | ||
256 | * return 0 on success. | ||
257 | */ | ||
258 | int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key); | ||
259 | 224 | ||
260 | /* Set the direct ip of the crypto connection. | 225 | /* Set the direct ip of the crypto connection. |
261 | * | 226 | * |
@@ -301,8 +266,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id, | |||
301 | int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, | 266 | int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, |
302 | int id); | 267 | int id); |
303 | 268 | ||
304 | /* Set the function for this friend that will be callbacked with object and number | 269 | /* Set the function for this friend that will be callbacked with object and number if |
305 | * when that friend gives us his DHT temporary public key. | 270 | * the friend sends us a different dht public key than we have associated to him. |
271 | * | ||
272 | * If this function is called, the connection should be recreated with the new public key. | ||
306 | * | 273 | * |
307 | * object and number will be passed as argument to this function. | 274 | * object and number will be passed as argument to this function. |
308 | * | 275 | * |
@@ -364,11 +331,6 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, | |||
364 | */ | 331 | */ |
365 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); | 332 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); |
366 | 333 | ||
367 | /* Set the function to be called when an onion response packet is received by one of the TCP connections. | ||
368 | */ | ||
369 | void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data, | ||
370 | uint16_t length), void *object); | ||
371 | |||
372 | /* Return a random TCP connection number for use in send_tcp_onion_request. | 334 | /* Return a random TCP connection number for use in send_tcp_onion_request. |
373 | * | 335 | * |
374 | * return TCP connection number on success. | 336 | * return TCP connection number on success. |
@@ -389,7 +351,7 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const ui | |||
389 | * return number of relays copied to tcp_relays on success. | 351 | * return number of relays copied to tcp_relays on success. |
390 | * return 0 on failure. | 352 | * return 0 on failure. |
391 | */ | 353 | */ |
392 | unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num); | 354 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num); |
393 | 355 | ||
394 | /* Kill a crypto connection. | 356 | /* Kill a crypto connection. |
395 | * | 357 | * |
@@ -398,13 +360,13 @@ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_rel | |||
398 | */ | 360 | */ |
399 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); | 361 | int crypto_kill(Net_Crypto *c, int crypt_connection_id); |
400 | 362 | ||
401 | |||
402 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. | 363 | /* return one of CRYPTO_CONN_* values indicating the state of the connection. |
403 | * | 364 | * |
404 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. | 365 | * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. |
366 | * sets online_tcp_relays to the number of connected tcp relays this connection has. | ||
405 | */ | 367 | */ |
406 | unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); | 368 | unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected, |
407 | 369 | unsigned int *online_tcp_relays); | |
408 | 370 | ||
409 | /* Generate our public and private keys. | 371 | /* Generate our public and private keys. |
410 | * Only call this function the first time the program starts. | 372 | * Only call this function the first time the program starts. |
diff --git a/toxcore/onion.c b/toxcore/onion.c index c6093f0c..48e4c769 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c | |||
@@ -35,8 +35,8 @@ | |||
35 | #define SEND_2 ONION_SEND_2 | 35 | #define SEND_2 ONION_SEND_2 |
36 | #define SEND_1 ONION_SEND_1 | 36 | #define SEND_1 ONION_SEND_1 |
37 | 37 | ||
38 | /* Change symmetric keys every hour to make paths expire eventually. */ | 38 | /* Change symmetric keys every 2 hours to make paths expire eventually. */ |
39 | #define KEY_REFRESH_INTERVAL (60 * 60) | 39 | #define KEY_REFRESH_INTERVAL (2 * 60 * 60) |
40 | static void change_symmetric_key(Onion *onion) | 40 | static void change_symmetric_key(Onion *onion) |
41 | { | 41 | { |
42 | if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) { | 42 | if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) { |
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index a9fc1643..ed328fb3 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c | |||
@@ -1425,7 +1425,6 @@ void do_onion_client(Onion_Client *onion_c) | |||
1425 | ++onion_c->onion_connected; | 1425 | ++onion_c->onion_connected; |
1426 | } | 1426 | } |
1427 | 1427 | ||
1428 | onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht); | ||
1429 | } else { | 1428 | } else { |
1430 | populate_path_nodes_tcp(onion_c); | 1429 | populate_path_nodes_tcp(onion_c); |
1431 | 1430 | ||
@@ -1434,12 +1433,22 @@ void do_onion_client(Onion_Client *onion_c) | |||
1434 | } | 1433 | } |
1435 | } | 1434 | } |
1436 | 1435 | ||
1436 | onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht); | ||
1437 | |||
1438 | if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) { | ||
1439 | set_tcp_onion_status(onion_c->c->tcp_c, !onion_c->UDP_connected); | ||
1440 | } | ||
1441 | |||
1437 | if (onion_connection_status(onion_c)) { | 1442 | if (onion_connection_status(onion_c)) { |
1438 | for (i = 0; i < onion_c->num_friends; ++i) { | 1443 | for (i = 0; i < onion_c->num_friends; ++i) { |
1439 | do_friend(onion_c, i); | 1444 | do_friend(onion_c, i); |
1440 | } | 1445 | } |
1441 | } | 1446 | } |
1442 | 1447 | ||
1448 | if (onion_c->last_run == 0) { | ||
1449 | onion_c->first_run = unix_time(); | ||
1450 | } | ||
1451 | |||
1443 | onion_c->last_run = unix_time(); | 1452 | onion_c->last_run = unix_time(); |
1444 | } | 1453 | } |
1445 | 1454 | ||
@@ -1467,7 +1476,7 @@ Onion_Client *new_onion_client(Net_Crypto *c) | |||
1467 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); | 1476 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); |
1468 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); | 1477 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); |
1469 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); | 1478 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); |
1470 | tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); | 1479 | set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, &handle_tcp_onion, onion_c); |
1471 | 1480 | ||
1472 | return onion_c; | 1481 | return onion_c; |
1473 | } | 1482 | } |
@@ -1483,7 +1492,7 @@ void kill_onion_client(Onion_Client *onion_c) | |||
1483 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); | 1492 | networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); |
1484 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); | 1493 | oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); |
1485 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); | 1494 | cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); |
1486 | tcp_onion_response_handler(onion_c->c, NULL, NULL); | 1495 | set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL); |
1487 | memset(onion_c, 0, sizeof(Onion_Client)); | 1496 | memset(onion_c, 0, sizeof(Onion_Client)); |
1488 | free(onion_c); | 1497 | free(onion_c); |
1489 | } | 1498 | } |
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index e10a86c5..ad28ac51 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h | |||
@@ -136,7 +136,7 @@ typedef struct { | |||
136 | Onion_Client_Paths onion_paths_friends; | 136 | Onion_Client_Paths onion_paths_friends; |
137 | 137 | ||
138 | uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; | 138 | uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; |
139 | uint64_t last_run; | 139 | uint64_t last_run, first_run; |
140 | 140 | ||
141 | uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; | 141 | uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; |
142 | uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; | 142 | uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; |
diff --git a/toxcore/tox.h b/toxcore/tox.h index 8e368851..d490eb91 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -368,7 +368,7 @@ struct Tox_Options { | |||
368 | * exceed 255 characters, and be in a NUL-terminated C string format | 368 | * exceed 255 characters, and be in a NUL-terminated C string format |
369 | * (255 chars + 1 NUL byte). | 369 | * (255 chars + 1 NUL byte). |
370 | * | 370 | * |
371 | * This member is ignored (it can be NULL) if proxy_enabled is false. | 371 | * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE. |
372 | */ | 372 | */ |
373 | const char *proxy_host; | 373 | const char *proxy_host; |
374 | 374 | ||
@@ -376,7 +376,7 @@ struct Tox_Options { | |||
376 | * The port to use to connect to the proxy server. | 376 | * The port to use to connect to the proxy server. |
377 | * | 377 | * |
378 | * Ports must be in the range (1, 65535). The value is ignored if | 378 | * Ports must be in the range (1, 65535). The value is ignored if |
379 | * proxy_enabled is false. | 379 | * proxy_type is TOX_PROXY_TYPE_NONE. |
380 | */ | 380 | */ |
381 | uint16_t proxy_port; | 381 | uint16_t proxy_port; |
382 | 382 | ||
@@ -1628,7 +1628,7 @@ typedef enum TOX_ERR_FILE_SEND { | |||
1628 | * a file name, not a path with directory names. | 1628 | * a file name, not a path with directory names. |
1629 | * | 1629 | * |
1630 | * If a non-zero file size is provided, this can be used by both sides to | 1630 | * If a non-zero file size is provided, this can be used by both sides to |
1631 | * determine the sending progress. File size can be set to zero for streaming | 1631 | * determine the sending progress. File size can be set to UINT64_MAX for streaming |
1632 | * data of unknown size. | 1632 | * data of unknown size. |
1633 | * | 1633 | * |
1634 | * File transmission occurs in chunks, which are requested through the | 1634 | * File transmission occurs in chunks, which are requested through the |