summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/Messenger.c17
-rw-r--r--toxcore/TCP_client.c1
-rw-r--r--toxcore/TCP_client.h1
-rw-r--r--toxcore/net_crypto.c35
-rw-r--r--toxcore/net_crypto.h8
-rw-r--r--toxcore/onion_client.c39
-rw-r--r--toxcore/onion_client.h15
-rw-r--r--toxcore/tox.c28
8 files changed, 139 insertions, 5 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 472c2ae4..f53a1d04 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. */
199static 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;
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 5abb7232..e1b460ab 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);
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 b47460bc..7cbac43b 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -1823,6 +1823,41 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key)
1823 return -1; 1823 return -1;
1824} 1824}
1825 1825
1826/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
1827 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
1828 *
1829 * return number of relays copied to tcp_relays on success.
1830 * return 0 on failure.
1831 */
1832unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
1833{
1834 if (num == 0)
1835 return 0;
1836
1837 uint32_t i;
1838 uint16_t copied = 0;
1839
1840 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1841 if (c->tcp_connections[i] != NULL) {
1842 memcpy(tcp_relays[copied].client_id, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
1843 tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
1844
1845 if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
1846 tcp_relays[copied].ip_port.ip.family = TCP_INET;
1847 } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
1848 tcp_relays[copied].ip_port.ip.family = TCP_INET6;
1849 }
1850
1851 ++copied;
1852
1853 if (copied == num)
1854 return copied;
1855 }
1856 }
1857
1858 return copied;
1859}
1860
1826/* Add a connected tcp connection to the tcp_connections array. 1861/* Add a connected tcp connection to the tcp_connections array.
1827 * 1862 *
1828 * return 0 if it was added. 1863 * return 0 if it was added.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 14b14229..25f8c2f7 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -267,6 +267,14 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
267 */ 267 */
268int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key); 268int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, uint8_t *public_key);
269 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 */
276unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
277
270/* Kill a crypto connection. 278/* Kill a crypto connection.
271 * 279 *
272 * return -1 on failure. 280 * return -1 on failure.
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 7fab76a7..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 */
822int 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.
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
107typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len); 111typedef 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 */
177int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port); 181int 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 */
191int 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. */
743static 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
742int tox_bootstrap_from_address(Tox *tox, const char *address, 767int 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.