diff options
-rw-r--r-- | toxcore/Messenger.c | 138 | ||||
-rw-r--r-- | toxcore/TCP_client.c | 9 | ||||
-rw-r--r-- | toxcore/TCP_client.h | 1 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 151 | ||||
-rw-r--r-- | toxcore/net_crypto.h | 28 | ||||
-rw-r--r-- | toxcore/onion_client.c | 40 | ||||
-rw-r--r-- | toxcore/onion_client.h | 15 | ||||
-rw-r--r-- | toxcore/tox.c | 28 |
8 files changed, 309 insertions, 101 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index b0d5a2e5..96005237 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -195,6 +195,21 @@ void getaddress(Messenger *m, uint8_t *address) | |||
195 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); | 195 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum)); |
196 | } | 196 | } |
197 | 197 | ||
198 | /* callback for recv TCP relay nodes. */ | ||
199 | static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key) | ||
200 | { | ||
201 | Messenger *m = object; | ||
202 | |||
203 | if (friend_not_valid(m, number)) | ||
204 | return -1; | ||
205 | |||
206 | if (m->friendlist[number].crypt_connection_id != -1) { | ||
207 | return add_tcp_relay_peer(m->net_crypto, m->friendlist[number].crypt_connection_id, ip_port, public_key); | ||
208 | } else { | ||
209 | return add_tcp_relay(m->net_crypto, ip_port, public_key); | ||
210 | } | ||
211 | } | ||
212 | |||
198 | /* | 213 | /* |
199 | * Add a friend. | 214 | * Add a friend. |
200 | * Set the data that will be sent along with friend request. | 215 | * Set the data that will be sent along with friend request. |
@@ -277,6 +292,7 @@ int32_t m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t leng | |||
277 | m->friendlist[i].message_id = 0; | 292 | m->friendlist[i].message_id = 0; |
278 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | 293 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ |
279 | memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); | 294 | memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t)); |
295 | recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); | ||
280 | 296 | ||
281 | if (m->numfriends == i) | 297 | if (m->numfriends == i) |
282 | ++m->numfriends; | 298 | ++m->numfriends; |
@@ -322,6 +338,7 @@ int32_t m_addfriend_norequest(Messenger *m, uint8_t *client_id) | |||
322 | m->friendlist[i].is_typing = 0; | 338 | m->friendlist[i].is_typing = 0; |
323 | m->friendlist[i].message_id = 0; | 339 | m->friendlist[i].message_id = 0; |
324 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ | 340 | m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ |
341 | recv_tcp_relay_handler(m->onion_c, onion_friendnum, &tcp_relay_node_callback, m, i); | ||
325 | 342 | ||
326 | if (m->numfriends == i) | 343 | if (m->numfriends == i) |
327 | ++m->numfriends; | 344 | ++m->numfriends; |
@@ -2203,17 +2220,15 @@ void do_friends(Messenger *m) | |||
2203 | } | 2220 | } |
2204 | 2221 | ||
2205 | if (m->friendlist[i].crypt_connection_id != -1) { | 2222 | if (m->friendlist[i].crypt_connection_id != -1) { |
2206 | uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; | 2223 | uint8_t dht_public_key1[crypto_box_PUBLICKEYBYTES]; |
2207 | uint64_t timestamp = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key); | 2224 | uint64_t timestamp1 = onion_getfriend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key1); |
2208 | 2225 | uint8_t dht_public_key2[crypto_box_PUBLICKEYBYTES]; | |
2209 | if (timestamp != 0) { | 2226 | uint64_t timestamp2 = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key2); |
2210 | set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key, timestamp); | 2227 | |
2211 | } | 2228 | if (timestamp1 > timestamp2) { |
2212 | 2229 | set_connection_dht_public_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key1, timestamp1); | |
2213 | timestamp = get_connection_dht_key(m->net_crypto, m->friendlist[i].crypt_connection_id, dht_public_key); | 2230 | } else if (timestamp1 < timestamp2) { |
2214 | 2231 | onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key2, timestamp2); | |
2215 | if (timestamp != 0) { | ||
2216 | onion_set_friend_DHT_pubkey(m->onion_c, m->friendlist[i].onion_friendnum, dht_public_key, timestamp); | ||
2217 | } | 2232 | } |
2218 | 2233 | ||
2219 | uint8_t direct_connected; | 2234 | uint8_t direct_connected; |
@@ -2462,9 +2477,10 @@ int wait_cleanup_messenger(Messenger *m, uint8_t *data) | |||
2462 | #define MESSENGER_STATE_TYPE_NAME 4 | 2477 | #define MESSENGER_STATE_TYPE_NAME 4 |
2463 | #define MESSENGER_STATE_TYPE_STATUSMESSAGE 5 | 2478 | #define MESSENGER_STATE_TYPE_STATUSMESSAGE 5 |
2464 | #define MESSENGER_STATE_TYPE_STATUS 6 | 2479 | #define MESSENGER_STATE_TYPE_STATUS 6 |
2480 | #define MESSENGER_STATE_TYPE_TCP_RELAY 10 | ||
2465 | 2481 | ||
2466 | #define SAVED_FRIEND_REQUEST_SIZE 1024 | 2482 | #define SAVED_FRIEND_REQUEST_SIZE 1024 |
2467 | 2483 | #define NUM_SAVED_TCP_RELAYS 8 | |
2468 | struct SAVED_FRIEND { | 2484 | struct SAVED_FRIEND { |
2469 | uint8_t status; | 2485 | uint8_t status; |
2470 | uint8_t client_id[CLIENT_ID_SIZE]; | 2486 | uint8_t client_id[CLIENT_ID_SIZE]; |
@@ -2599,6 +2615,7 @@ uint32_t messenger_size(Messenger *m) | |||
2599 | + sizesubhead + m->name_length // Own nickname. | 2615 | + sizesubhead + m->name_length // Own nickname. |
2600 | + sizesubhead + m->statusmessage_length // status message | 2616 | + sizesubhead + m->statusmessage_length // status message |
2601 | + sizesubhead + 1 // status | 2617 | + sizesubhead + 1 // status |
2618 | + sizesubhead + NUM_SAVED_TCP_RELAYS * sizeof(Node_format) //TCP relays | ||
2602 | ; | 2619 | ; |
2603 | } | 2620 | } |
2604 | 2621 | ||
@@ -2663,74 +2680,15 @@ void messenger_save(Messenger *m, uint8_t *data) | |||
2663 | data = z_state_save_subheader(data, len, type); | 2680 | data = z_state_save_subheader(data, len, type); |
2664 | *data = m->userstatus; | 2681 | *data = m->userstatus; |
2665 | data += len; | 2682 | data += len; |
2666 | } | ||
2667 | |||
2668 | static int messenger_load_state_callback_old(void *outer, uint8_t *data, uint32_t length, uint16_t type) | ||
2669 | { | ||
2670 | Messenger *m = outer; | ||
2671 | |||
2672 | switch (type) { | ||
2673 | case MESSENGER_STATE_TYPE_NOSPAMKEYS: | ||
2674 | if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { | ||
2675 | set_nospam(&(m->fr), *(uint32_t *)data); | ||
2676 | load_keys(m->net_crypto, &data[sizeof(uint32_t)]); | ||
2677 | #ifdef ENABLE_ASSOC_DHT | ||
2678 | |||
2679 | if (m->dht->assoc) | ||
2680 | Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key); | ||
2681 | |||
2682 | #endif | ||
2683 | } else | ||
2684 | return -1; /* critical */ | ||
2685 | |||
2686 | break; | ||
2687 | |||
2688 | case MESSENGER_STATE_TYPE_DHT: | ||
2689 | DHT_load(m->dht, data, length); | ||
2690 | break; | ||
2691 | |||
2692 | case MESSENGER_STATE_TYPE_FRIENDS: | ||
2693 | if (!(length % sizeof(Friend))) { | ||
2694 | uint16_t num = length / sizeof(Friend); | ||
2695 | Friend *friends = (Friend *)data; | ||
2696 | uint32_t i; | ||
2697 | |||
2698 | for (i = 0; i < num; ++i) { | ||
2699 | if (friends[i].status >= 3) { | ||
2700 | int fnum = m_addfriend_norequest(m, friends[i].client_id); | ||
2701 | setfriendname(m, fnum, friends[i].name, friends[i].name_length); | ||
2702 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ | ||
2703 | } else if (friends[i].status != 0) { | ||
2704 | /* TODO: This is not a good way to do this. */ | ||
2705 | uint8_t address[FRIEND_ADDRESS_SIZE]; | ||
2706 | id_copy(address, friends[i].client_id); | ||
2707 | memcpy(address + crypto_box_PUBLICKEYBYTES, &(friends[i].friendrequest_nospam), sizeof(uint32_t)); | ||
2708 | uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); | ||
2709 | memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum)); | ||
2710 | m_addfriend(m, address, friends[i].info, friends[i].info_size); | ||
2711 | } | ||
2712 | } | ||
2713 | } | ||
2714 | |||
2715 | break; | ||
2716 | 2683 | ||
2717 | case MESSENGER_STATE_TYPE_NAME: | 2684 | Node_format relays[NUM_SAVED_TCP_RELAYS]; |
2718 | if ((length > 0) && (length < MAX_NAME_LENGTH)) { | 2685 | len = sizeof(relays); |
2719 | setname(m, data, length); | 2686 | type = MESSENGER_STATE_TYPE_TCP_RELAY; |
2720 | } | 2687 | data = z_state_save_subheader(data, len, type); |
2721 | 2688 | memset(relays, 0, len); | |
2722 | break; | 2689 | copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); |
2723 | 2690 | memcpy(data, relays, len); | |
2724 | #ifdef DEBUG | 2691 | data += len; |
2725 | |||
2726 | default: | ||
2727 | fprintf(stderr, "Load state: contains unrecognized part (len %u, type %u)\n", | ||
2728 | length, type); | ||
2729 | break; | ||
2730 | #endif | ||
2731 | } | ||
2732 | |||
2733 | return 0; | ||
2734 | } | 2692 | } |
2735 | 2693 | ||
2736 | static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type) | 2694 | static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t length, uint16_t type) |
@@ -2781,6 +2739,22 @@ static int messenger_load_state_callback(void *outer, uint8_t *data, uint32_t le | |||
2781 | } | 2739 | } |
2782 | 2740 | ||
2783 | break; | 2741 | break; |
2742 | |||
2743 | case MESSENGER_STATE_TYPE_TCP_RELAY: { | ||
2744 | Node_format relays[NUM_SAVED_TCP_RELAYS]; | ||
2745 | |||
2746 | if (length != sizeof(relays)) { | ||
2747 | return -1; | ||
2748 | } | ||
2749 | |||
2750 | memcpy(relays, data, length); | ||
2751 | uint32_t i; | ||
2752 | |||
2753 | for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { | ||
2754 | add_tcp_relay(m->net_crypto, relays[i].ip_port, relays[i].client_id); | ||
2755 | } | ||
2756 | } | ||
2757 | break; | ||
2784 | #ifdef DEBUG | 2758 | #ifdef DEBUG |
2785 | 2759 | ||
2786 | default: | 2760 | default: |
@@ -2807,11 +2781,7 @@ int messenger_load(Messenger *m, uint8_t *data, uint32_t length) | |||
2807 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) | 2781 | if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL)) |
2808 | return load_state(messenger_load_state_callback, m, data + cookie_len, | 2782 | return load_state(messenger_load_state_callback, m, data + cookie_len, |
2809 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); | 2783 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); |
2810 | 2784 | else | |
2811 | else if (!data32[0] && (data32[1] == MESSENGER_STATE_COOKIE_GLOBAL_OLD)) | ||
2812 | return load_state(messenger_load_state_callback_old, m, data + cookie_len, | ||
2813 | length - cookie_len, MESSENGER_STATE_COOKIE_TYPE); | ||
2814 | else /* old state file */ | ||
2815 | return -1; | 2785 | return -1; |
2816 | } | 2786 | } |
2817 | 2787 | ||
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 9091900f..e4845852 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c | |||
@@ -372,6 +372,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, uint8_t *public_key, | |||
372 | temp->status = TCP_CLIENT_CONNECTING; | 372 | temp->status = TCP_CLIENT_CONNECTING; |
373 | temp->sock = sock; | 373 | temp->sock = sock; |
374 | memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES); | 374 | memcpy(temp->public_key, public_key, crypto_box_PUBLICKEYBYTES); |
375 | temp->ip_port = ip_port; | ||
375 | 376 | ||
376 | if (generate_handshake(temp, self_public_key, self_secret_key) == -1) { | 377 | if (generate_handshake(temp, self_public_key, self_secret_key) == -1) { |
377 | kill_sock(sock); | 378 | kill_sock(sock); |
@@ -403,7 +404,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_ | |||
403 | uint8_t con_id = data[1] - NUM_RESERVED_PORTS; | 404 | uint8_t con_id = data[1] - NUM_RESERVED_PORTS; |
404 | 405 | ||
405 | if (conn->connections[con_id].status != 0) | 406 | if (conn->connections[con_id].status != 0) |
406 | return -1; | 407 | return 0; |
407 | 408 | ||
408 | conn->connections[con_id].status = 1; | 409 | conn->connections[con_id].status = 1; |
409 | conn->connections[con_id].number = ~0; | 410 | conn->connections[con_id].number = ~0; |
@@ -445,6 +446,9 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, uint8_t *data, uint16_ | |||
445 | 446 | ||
446 | uint8_t con_id = data[1] - NUM_RESERVED_PORTS; | 447 | uint8_t con_id = data[1] - NUM_RESERVED_PORTS; |
447 | 448 | ||
449 | if (conn->connections[con_id].status == 0) | ||
450 | return 0; | ||
451 | |||
448 | if (conn->connections[con_id].status != 2) | 452 | if (conn->connections[con_id].status != 2) |
449 | return -1; | 453 | return -1; |
450 | 454 | ||
@@ -604,6 +608,9 @@ void do_TCP_connection(TCP_Client_Connection *TCP_connection) | |||
604 | */ | 608 | */ |
605 | void kill_TCP_connection(TCP_Client_Connection *TCP_connection) | 609 | void kill_TCP_connection(TCP_Client_Connection *TCP_connection) |
606 | { | 610 | { |
611 | if (TCP_connection == NULL) | ||
612 | return; | ||
613 | |||
607 | kill_sock(TCP_connection->sock); | 614 | kill_sock(TCP_connection->sock); |
608 | memset(TCP_connection, 0, sizeof(TCP_Client_Connection)); | 615 | memset(TCP_connection, 0, sizeof(TCP_Client_Connection)); |
609 | free(TCP_connection); | 616 | free(TCP_connection); |
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index 9583e15f..afb95392 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h | |||
@@ -40,6 +40,7 @@ typedef struct { | |||
40 | uint8_t status; | 40 | uint8_t status; |
41 | sock_t sock; | 41 | sock_t sock; |
42 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */ | 42 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* public key of the server */ |
43 | IP_Port ip_port; /* The ip and port of the server */ | ||
43 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */ | 44 | uint8_t recv_nonce[crypto_box_NONCEBYTES]; /* Nonce of received packets. */ |
44 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */ | 45 | uint8_t sent_nonce[crypto_box_NONCEBYTES]; /* Nonce of sent packets. */ |
45 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; | 46 | uint8_t shared_key[crypto_box_BEFORENMBYTES]; |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 1e3456c3..875c639f 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -406,6 +406,8 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, | |||
406 | if (conn == 0) | 406 | if (conn == 0) |
407 | return -1; | 407 | return -1; |
408 | 408 | ||
409 | int direct_send_attempt = 0; | ||
410 | |||
409 | //TODO: on bad networks, direct connections might not last indefinitely. | 411 | //TODO: on bad networks, direct connections might not last indefinitely. |
410 | if (conn->ip_port.ip.family != 0) { | 412 | if (conn->ip_port.ip.family != 0) { |
411 | uint8_t direct_connected = 0; | 413 | uint8_t direct_connected = 0; |
@@ -415,8 +417,10 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, | |||
415 | return 0; | 417 | return 0; |
416 | 418 | ||
417 | //TODO: a better way of sending packets directly to confirm the others ip. | 419 | //TODO: a better way of sending packets directly to confirm the others ip. |
418 | if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) | 420 | if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) { |
419 | sendpacket(c->dht->net, conn->ip_port, data, length); | 421 | if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) |
422 | direct_send_attempt = 1; | ||
423 | } | ||
420 | 424 | ||
421 | } | 425 | } |
422 | 426 | ||
@@ -424,12 +428,23 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data, | |||
424 | uint32_t i; | 428 | uint32_t i; |
425 | 429 | ||
426 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 430 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
427 | if (conn->status_tcp[i] == 2) {/* friend is connected to this relay. */ | 431 | if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ |
428 | if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) | 432 | if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) |
429 | return 0; | 433 | return 0; |
430 | } | 434 | } |
431 | } | 435 | } |
432 | 436 | ||
437 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
438 | if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) { | ||
439 | if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1) | ||
440 | return 0; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | if (direct_send_attempt) { | ||
445 | return 0; | ||
446 | } | ||
447 | |||
433 | return -1; | 448 | return -1; |
434 | } | 449 | } |
435 | 450 | ||
@@ -1461,9 +1476,9 @@ static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id) | |||
1461 | uint32_t i; | 1476 | uint32_t i; |
1462 | 1477 | ||
1463 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 1478 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
1464 | if (conn->status_tcp[i]) { | 1479 | if (conn->status_tcp[i] != STATUS_TCP_NULL) { |
1465 | send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]); | 1480 | send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]); |
1466 | conn->status_tcp[i] = 0; | 1481 | conn->status_tcp[i] = STATUS_TCP_NULL; |
1467 | conn->con_number_tcp[i] = 0; | 1482 | conn->con_number_tcp[i] = 0; |
1468 | } | 1483 | } |
1469 | } | 1484 | } |
@@ -1575,9 +1590,10 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) | |||
1575 | if (!ipport_equal(&ip_port, &conn->ip_port)) { | 1590 | if (!ipport_equal(&ip_port, &conn->ip_port)) { |
1576 | conn->ip_port = ip_port; | 1591 | conn->ip_port = ip_port; |
1577 | conn->direct_lastrecv_time = 0; | 1592 | conn->direct_lastrecv_time = 0; |
1593 | return 0; | ||
1578 | } | 1594 | } |
1579 | 1595 | ||
1580 | return 0; | 1596 | return -1; |
1581 | } | 1597 | } |
1582 | 1598 | ||
1583 | static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) | 1599 | static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *public_key) |
@@ -1605,8 +1621,17 @@ static int tcp_response_callback(void *object, uint8_t connection_id, uint8_t *p | |||
1605 | if (c->tcp_connections[location] != TCP_con) | 1621 | if (c->tcp_connections[location] != TCP_con) |
1606 | return -1; | 1622 | return -1; |
1607 | 1623 | ||
1608 | conn->status_tcp[location] = 1; | ||
1609 | conn->con_number_tcp[location] = connection_id; | 1624 | conn->con_number_tcp[location] = connection_id; |
1625 | uint32_t i; | ||
1626 | |||
1627 | for (i = 0; i < conn->num_tcp_relays; ++i) { | ||
1628 | if (memcmp(TCP_con->public_key, conn->tcp_relays[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1629 | conn->status_tcp[location] = STATUS_TCP_INVISIBLE; | ||
1630 | return 0; | ||
1631 | } | ||
1632 | } | ||
1633 | |||
1634 | conn->status_tcp[location] = STATUS_TCP_OFFLINE; | ||
1610 | return 0; | 1635 | return 0; |
1611 | } | 1636 | } |
1612 | 1637 | ||
@@ -1628,13 +1653,19 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection | |||
1628 | if (c->tcp_connections[location] != TCP_con) | 1653 | if (c->tcp_connections[location] != TCP_con) |
1629 | return -1; | 1654 | return -1; |
1630 | 1655 | ||
1631 | conn->status_tcp[location] = status; | 1656 | if (status == 1) { |
1657 | conn->status_tcp[location] = STATUS_TCP_OFFLINE; | ||
1658 | } else if (status == 2) { | ||
1659 | conn->status_tcp[location] = STATUS_TCP_ONLINE; | ||
1660 | } | ||
1661 | |||
1632 | conn->con_number_tcp[location] = connection_id; | 1662 | conn->con_number_tcp[location] = connection_id; |
1633 | return 0; | 1663 | return 0; |
1634 | } | 1664 | } |
1635 | 1665 | ||
1636 | static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) | 1666 | static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t *data, uint16_t length) |
1637 | { | 1667 | { |
1668 | |||
1638 | if (length == 0) | 1669 | if (length == 0) |
1639 | return -1; | 1670 | return -1; |
1640 | 1671 | ||
@@ -1729,6 +1760,59 @@ static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) | |||
1729 | return 0; | 1760 | return 0; |
1730 | } | 1761 | } |
1731 | 1762 | ||
1763 | /* Add a tcp relay, associating it to a crypt_connection_id. | ||
1764 | * | ||
1765 | * return 0 if it was added. | ||
1766 | * return -1 if it wasn't. | ||
1767 | */ | ||
1768 | int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key) | ||
1769 | { | ||
1770 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
1771 | |||
1772 | if (conn == 0) | ||
1773 | return -1; | ||
1774 | |||
1775 | if (ip_port.ip.family == TCP_INET) { | ||
1776 | ip_port.ip.family = AF_INET; | ||
1777 | } else if (ip_port.ip.family == TCP_INET6) { | ||
1778 | ip_port.ip.family = AF_INET6; | ||
1779 | } | ||
1780 | |||
1781 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
1782 | return -1; | ||
1783 | |||
1784 | uint32_t i; | ||
1785 | |||
1786 | for (i = 0; i < conn->num_tcp_relays; ++i) { | ||
1787 | if (memcmp(conn->tcp_relays[i].client_id, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1788 | conn->tcp_relays[i].ip_port = ip_port; | ||
1789 | return 0; | ||
1790 | } | ||
1791 | } | ||
1792 | |||
1793 | if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) { | ||
1794 | uint16_t index = rand() % MAX_TCP_RELAYS_PEER; | ||
1795 | conn->tcp_relays[index].ip_port = ip_port; | ||
1796 | memcpy(conn->tcp_relays[index].client_id, public_key, crypto_box_PUBLICKEYBYTES); | ||
1797 | } else { | ||
1798 | conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port; | ||
1799 | memcpy(conn->tcp_relays[conn->num_tcp_relays].client_id, public_key, crypto_box_PUBLICKEYBYTES); | ||
1800 | ++conn->num_tcp_relays; | ||
1801 | } | ||
1802 | |||
1803 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1804 | if (c->tcp_connections[i] == NULL) | ||
1805 | continue; | ||
1806 | |||
1807 | if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
1808 | if (conn->status_tcp[i] == STATUS_TCP_OFFLINE) | ||
1809 | conn->status_tcp[i] = STATUS_TCP_INVISIBLE; | ||
1810 | } | ||
1811 | } | ||
1812 | |||
1813 | return add_tcp_relay(c, ip_port, public_key); | ||
1814 | } | ||
1815 | |||
1732 | /* Add a tcp relay to the array. | 1816 | /* Add a tcp relay to the array. |
1733 | * | 1817 | * |
1734 | * return 0 if it was added. | 1818 | * return 0 if it was added. |
@@ -1736,6 +1820,15 @@ static int tcp_connection_check(Net_Crypto *c, uint8_t *public_key) | |||
1736 | */ | 1820 | */ |
1737 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) | 1821 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) |
1738 | { | 1822 | { |
1823 | if (ip_port.ip.family == TCP_INET) { | ||
1824 | ip_port.ip.family = AF_INET; | ||
1825 | } else if (ip_port.ip.family == TCP_INET6) { | ||
1826 | ip_port.ip.family = AF_INET6; | ||
1827 | } | ||
1828 | |||
1829 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
1830 | return -1; | ||
1831 | |||
1739 | if (tcp_connection_check(c, public_key) != 0) | 1832 | if (tcp_connection_check(c, public_key) != 0) |
1740 | return -1; | 1833 | return -1; |
1741 | 1834 | ||
@@ -1751,6 +1844,41 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key) | |||
1751 | return -1; | 1844 | return -1; |
1752 | } | 1845 | } |
1753 | 1846 | ||
1847 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. | ||
1848 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | ||
1849 | * | ||
1850 | * return number of relays copied to tcp_relays on success. | ||
1851 | * return 0 on failure. | ||
1852 | */ | ||
1853 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num) | ||
1854 | { | ||
1855 | if (num == 0) | ||
1856 | return 0; | ||
1857 | |||
1858 | uint32_t i; | ||
1859 | uint16_t copied = 0; | ||
1860 | |||
1861 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
1862 | if (c->tcp_connections[i] != NULL) { | ||
1863 | memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES); | ||
1864 | tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port; | ||
1865 | |||
1866 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { | ||
1867 | tcp_relays[copied].ip_port.ip.family = TCP_INET; | ||
1868 | } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) { | ||
1869 | tcp_relays[copied].ip_port.ip.family = TCP_INET6; | ||
1870 | } | ||
1871 | |||
1872 | ++copied; | ||
1873 | |||
1874 | if (copied == num) | ||
1875 | return copied; | ||
1876 | } | ||
1877 | } | ||
1878 | |||
1879 | return copied; | ||
1880 | } | ||
1881 | |||
1754 | /* Add a connected tcp connection to the tcp_connections array. | 1882 | /* Add a connected tcp connection to the tcp_connections array. |
1755 | * | 1883 | * |
1756 | * return 0 if it was added. | 1884 | * return 0 if it was added. |
@@ -1834,7 +1962,7 @@ static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number | |||
1834 | if (number >= MAX_TCP_CONNECTIONS) | 1962 | if (number >= MAX_TCP_CONNECTIONS) |
1835 | return; | 1963 | return; |
1836 | 1964 | ||
1837 | conn->status_tcp[number] = 0; | 1965 | conn->status_tcp[number] = STATUS_TCP_NULL; |
1838 | conn->con_number_tcp[number] = 0; | 1966 | conn->con_number_tcp[number] = 0; |
1839 | } | 1967 | } |
1840 | 1968 | ||
@@ -2255,6 +2383,11 @@ void kill_net_crypto(Net_Crypto *c) | |||
2255 | crypto_kill(c, i); | 2383 | crypto_kill(c, i); |
2256 | } | 2384 | } |
2257 | 2385 | ||
2386 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | ||
2387 | kill_TCP_connection(c->tcp_connections_new[i]); | ||
2388 | kill_TCP_connection(c->tcp_connections[i]); | ||
2389 | } | ||
2390 | |||
2258 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); | 2391 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); |
2259 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); | 2392 | networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); |
2260 | networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL); | 2393 | networking_registerhandler(c->dht->net, NET_PACKET_CRYPTO_HS, NULL, NULL); |
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index e41e7e1d..25f8c2f7 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h | |||
@@ -61,7 +61,13 @@ | |||
61 | 61 | ||
62 | #define CRYPTO_RESERVED_PACKETS 16 | 62 | #define CRYPTO_RESERVED_PACKETS 16 |
63 | 63 | ||
64 | #define MAX_TCP_CONNECTIONS 8 | 64 | #define MAX_TCP_CONNECTIONS 32 |
65 | #define MAX_TCP_RELAYS_PEER 4 | ||
66 | |||
67 | #define STATUS_TCP_NULL 0 | ||
68 | #define STATUS_TCP_OFFLINE 1 | ||
69 | #define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */ | ||
70 | #define STATUS_TCP_ONLINE 3 | ||
65 | 71 | ||
66 | typedef struct { | 72 | typedef struct { |
67 | uint64_t time; | 73 | uint64_t time; |
@@ -127,8 +133,11 @@ typedef struct { | |||
127 | 133 | ||
128 | uint8_t killed; /* set to 1 to kill the connection. */ | 134 | uint8_t killed; /* set to 1 to kill the connection. */ |
129 | 135 | ||
130 | uint8_t status_tcp[MAX_TCP_CONNECTIONS]; | 136 | uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */ |
131 | uint8_t con_number_tcp[MAX_TCP_CONNECTIONS]; | 137 | uint8_t con_number_tcp[MAX_TCP_CONNECTIONS]; |
138 | |||
139 | Node_format tcp_relays[MAX_TCP_RELAYS_PEER]; | ||
140 | uint16_t num_tcp_relays; | ||
132 | } Crypto_Connection; | 141 | } Crypto_Connection; |
133 | 142 | ||
134 | typedef struct { | 143 | typedef struct { |
@@ -244,6 +253,13 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) | |||
244 | */ | 253 | */ |
245 | int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); | 254 | int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); |
246 | 255 | ||
256 | /* Add a tcp relay, associating it to a crypt_connection_id. | ||
257 | * | ||
258 | * return 0 if it was added. | ||
259 | * return -1 if it wasn't. | ||
260 | */ | ||
261 | int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, uint8_t *public_key); | ||
262 | |||
247 | /* Add a tcp relay to the array. | 263 | /* Add a tcp relay to the array. |
248 | * | 264 | * |
249 | * return 0 if it was added. | 265 | * return 0 if it was added. |
@@ -251,6 +267,14 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, | |||
251 | */ | 267 | */ |
252 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key); | 268 | int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key); |
253 | 269 | ||
270 | /* Copy a maximum of num TCP relays we are connected to to tcp_relays. | ||
271 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | ||
272 | * | ||
273 | * return number of relays copied to tcp_relays on success. | ||
274 | * return 0 on failure. | ||
275 | */ | ||
276 | unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num); | ||
277 | |||
254 | /* Kill a crypto connection. | 278 | /* Kill a crypto connection. |
255 | * | 279 | * |
256 | * return -1 on failure. | 280 | * return -1 on failure. |
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index be4d12aa..03ffbaa7 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c | |||
@@ -505,7 +505,7 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t | |||
505 | if (len_nodes != 0) { | 505 | if (len_nodes != 0) { |
506 | Node_format nodes[MAX_SENT_NODES]; | 506 | Node_format nodes[MAX_SENT_NODES]; |
507 | int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, | 507 | int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, |
508 | len_nodes, 0); | 508 | len_nodes, 1); |
509 | 509 | ||
510 | if (num_nodes <= 0) | 510 | if (num_nodes <= 0) |
511 | return 1; | 511 | return 1; |
@@ -513,7 +513,17 @@ static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t | |||
513 | int i; | 513 | int i; |
514 | 514 | ||
515 | for (i = 0; i < num_nodes; ++i) { | 515 | for (i = 0; i < num_nodes; ++i) { |
516 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); | 516 | uint8_t family = nodes[i].ip_port.ip.family; |
517 | |||
518 | if (family == AF_INET || family == AF_INET6) { | ||
519 | DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); | ||
520 | } else if (family == TCP_INET || family == TCP_INET6) { | ||
521 | if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { | ||
522 | void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; | ||
523 | uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; | ||
524 | onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].client_id); | ||
525 | } | ||
526 | } | ||
517 | } | 527 | } |
518 | } | 528 | } |
519 | 529 | ||
@@ -664,8 +674,9 @@ static int send_fakeid_announce(Onion_Client *onion_c, uint16_t friend_num, uint | |||
664 | memcpy(data + 1, &no_replay, sizeof(no_replay)); | 674 | memcpy(data + 1, &no_replay, sizeof(no_replay)); |
665 | memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); | 675 | memcpy(data + 1 + sizeof(uint64_t), onion_c->dht->self_public_key, crypto_box_PUBLICKEYBYTES); |
666 | Node_format nodes[MAX_SENT_NODES]; | 676 | Node_format nodes[MAX_SENT_NODES]; |
667 | uint16_t num_nodes = closelist_nodes(onion_c->dht, nodes, MAX_SENT_NODES); | 677 | uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2)); |
668 | 678 | uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays); | |
679 | num_nodes += num_relays; | ||
669 | int nodes_len = 0; | 680 | int nodes_len = 0; |
670 | 681 | ||
671 | if (num_nodes != 0) { | 682 | if (num_nodes != 0) { |
@@ -800,6 +811,26 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num) | |||
800 | return friend_num; | 811 | return friend_num; |
801 | } | 812 | } |
802 | 813 | ||
814 | /* Set the function for this friend that will be callbacked with object and number | ||
815 | * when that friends gives us one of the TCP relays he is connected to. | ||
816 | * | ||
817 | * object and number will be passed as argument to this function. | ||
818 | * | ||
819 | * return -1 on failure. | ||
820 | * return 0 on success. | ||
821 | */ | ||
822 | int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, | ||
823 | uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number) | ||
824 | { | ||
825 | if ((uint32_t)friend_num >= onion_c->num_friends) | ||
826 | return -1; | ||
827 | |||
828 | onion_c->friends_list[friend_num].tcp_relay_node_callback = tcp_relay_node_callback; | ||
829 | onion_c->friends_list[friend_num].tcp_relay_node_callback_object = object; | ||
830 | onion_c->friends_list[friend_num].tcp_relay_node_callback_number = number; | ||
831 | return 0; | ||
832 | } | ||
833 | |||
803 | /* Set a friends DHT public key. | 834 | /* Set a friends DHT public key. |
804 | * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to | 835 | * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to |
805 | * the other peer. | 836 | * the other peer. |
@@ -830,6 +861,7 @@ int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, uint8_t * | |||
830 | return -1; | 861 | return -1; |
831 | } | 862 | } |
832 | 863 | ||
864 | onion_c->friends_list[friend_num].last_seen = unix_time(); | ||
833 | onion_c->friends_list[friend_num].is_fake_clientid = 1; | 865 | onion_c->friends_list[friend_num].is_fake_clientid = 1; |
834 | onion_c->friends_list[friend_num].fake_client_id_timestamp = timestamp; | 866 | onion_c->friends_list[friend_num].fake_client_id_timestamp = timestamp; |
835 | memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES); | 867 | memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES); |
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 029f5624..0d2e84a5 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h | |||
@@ -102,6 +102,10 @@ typedef struct { | |||
102 | 102 | ||
103 | Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; | 103 | Last_Pinged last_pinged[MAX_STORED_PINGED_NODES]; |
104 | uint8_t last_pinged_index; | 104 | uint8_t last_pinged_index; |
105 | |||
106 | int (*tcp_relay_node_callback)(void *object, uint32_t number, IP_Port ip_port, uint8_t *public_key); | ||
107 | void *tcp_relay_node_callback_object; | ||
108 | uint32_t tcp_relay_node_callback_number; | ||
105 | } Onion_Friend; | 109 | } Onion_Friend; |
106 | 110 | ||
107 | typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); | 111 | typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); |
@@ -176,6 +180,17 @@ int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_on | |||
176 | */ | 180 | */ |
177 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); | 181 | int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); |
178 | 182 | ||
183 | /* Set the function for this friend that will be callbacked with object and number | ||
184 | * when that friends gives us one of the TCP relays he is connected to. | ||
185 | * | ||
186 | * object and number will be passed as argument to this function. | ||
187 | * | ||
188 | * return -1 on failure. | ||
189 | * return 0 on success. | ||
190 | */ | ||
191 | int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num, int (*tcp_relay_node_callback)(void *object, | ||
192 | uint32_t number, IP_Port ip_port, uint8_t *public_key), void *object, uint32_t number); | ||
193 | |||
179 | /* Set a friends DHT public key. | 194 | /* Set a friends DHT public key. |
180 | * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to | 195 | * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to |
181 | * the other peer. | 196 | * the other peer. |
diff --git a/toxcore/tox.c b/toxcore/tox.c index d86f1a17..083582bb 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -739,12 +739,38 @@ uint64_t tox_file_data_remaining(Tox *tox, int32_t friendnumber, uint8_t filenum | |||
739 | 739 | ||
740 | /***************END OF FILE SENDING FUNCTIONS******************/ | 740 | /***************END OF FILE SENDING FUNCTIONS******************/ |
741 | 741 | ||
742 | /* TODO: expose this properly. */ | ||
743 | static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) | ||
744 | { | ||
745 | Messenger *m = tox; | ||
746 | IP_Port ip_port_v64; | ||
747 | IP *ip_extra = NULL; | ||
748 | IP_Port ip_port_v4; | ||
749 | ip_init(&ip_port_v64.ip, ipv6enabled); | ||
750 | |||
751 | if (ipv6enabled) { | ||
752 | /* setup for getting BOTH: an IPv6 AND an IPv4 address */ | ||
753 | ip_port_v64.ip.family = AF_UNSPEC; | ||
754 | ip_reset(&ip_port_v4.ip); | ||
755 | ip_extra = &ip_port_v4.ip; | ||
756 | } | ||
757 | |||
758 | if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) { | ||
759 | ip_port_v64.port = port; | ||
760 | add_tcp_relay(m->net_crypto, ip_port_v64, public_key); | ||
761 | return 1; | ||
762 | } else { | ||
763 | return 0; | ||
764 | } | ||
765 | } | ||
766 | |||
742 | int tox_bootstrap_from_address(Tox *tox, const char *address, | 767 | int tox_bootstrap_from_address(Tox *tox, const char *address, |
743 | uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) | 768 | uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) |
744 | { | 769 | { |
745 | Messenger *m = tox; | 770 | Messenger *m = tox; |
771 | tox_add_tcp_relay(tox, address, ipv6enabled, port, public_key); | ||
746 | return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); | 772 | return DHT_bootstrap_from_address(m->dht, address, ipv6enabled, port, public_key); |
747 | }; | 773 | } |
748 | 774 | ||
749 | /* return 0 if we are not connected to the DHT. | 775 | /* return 0 if we are not connected to the DHT. |
750 | * return 1 if we are. | 776 | * return 1 if we are. |