summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c4
-rw-r--r--toxcore/LAN_discovery.c37
-rw-r--r--toxcore/LAN_discovery.h3
-rw-r--r--toxcore/Messenger.c78
-rw-r--r--toxcore/Messenger.h9
-rw-r--r--toxcore/TCP_connection.c1
-rw-r--r--toxcore/TCP_server.h2
-rw-r--r--toxcore/crypto_core.h1
-rw-r--r--toxcore/friend_connection.c21
-rw-r--r--toxcore/friend_connection.h2
-rw-r--r--toxcore/list.c8
-rw-r--r--toxcore/list.h8
-rw-r--r--toxcore/net_crypto.c93
-rw-r--r--toxcore/net_crypto.h16
-rw-r--r--toxcore/network.c2
-rw-r--r--toxcore/onion.c4
-rw-r--r--toxcore/onion.h4
-rw-r--r--toxcore/onion_announce.h2
-rw-r--r--toxcore/onion_client.c15
-rw-r--r--toxcore/ping.c6
-rw-r--r--toxcore/tox.c132
-rw-r--r--toxcore/tox.h6
22 files changed, 294 insertions, 160 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 9ebe11cf..8cd8852c 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -145,7 +145,7 @@ void get_shared_key(Shared_Keys *shared_keys, uint8_t *shared_key, const uint8_t
145 */ 145 */
146void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *client_id) 146void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *client_id)
147{ 147{
148 return get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id); 148 get_shared_key(&dht->shared_keys_recv, shared_key, dht->self_secret_key, client_id);
149} 149}
150 150
151/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key 151/* Copy shared_key to encrypt/decrypt DHT packet from client_id into shared_key
@@ -153,7 +153,7 @@ void DHT_get_shared_key_recv(DHT *dht, uint8_t *shared_key, const uint8_t *clien
153 */ 153 */
154void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *client_id) 154void DHT_get_shared_key_sent(DHT *dht, uint8_t *shared_key, const uint8_t *client_id)
155{ 155{
156 return get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id); 156 get_shared_key(&dht->shared_keys_sent, shared_key, dht->self_secret_key, client_id);
157} 157}
158 158
159void to_net_family(IP *ip) 159void to_net_family(IP *ip)
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index dbce762e..5ab5b0e1 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -227,18 +227,43 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
227 return ip; 227 return ip;
228} 228}
229 229
230/* Is IP a local ip or not. */
231_Bool Local_ip(IP ip)
232{
233 if (ip.family == AF_INET) {
234 IP4 ip4 = ip.ip4;
235
236 /* Loopback. */
237 if (ip4.uint8[0] == 127)
238 return 1;
239 } else {
240 /* embedded IPv4-in-IPv6 */
241 if (IPV6_IPV4_IN_V6(ip.ip6)) {
242 IP ip4;
243 ip4.family = AF_INET;
244 ip4.ip4.uint32 = ip.ip6.uint32[3];
245 return Local_ip(ip4);
246 }
247
248 /* localhost in IPv6 (::1) */
249 if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1))
250 return 1;
251 }
252
253 return 0;
254}
255
230/* return 0 if ip is a LAN ip. 256/* return 0 if ip is a LAN ip.
231 * return -1 if it is not. 257 * return -1 if it is not.
232 */ 258 */
233int LAN_ip(IP ip) 259int LAN_ip(IP ip)
234{ 260{
261 if (Local_ip(ip))
262 return 0;
263
235 if (ip.family == AF_INET) { 264 if (ip.family == AF_INET) {
236 IP4 ip4 = ip.ip4; 265 IP4 ip4 = ip.ip4;
237 266
238 /* Loopback. */
239 if (ip4.uint8[0] == 127)
240 return 0;
241
242 /* 10.0.0.0 to 10.255.255.255 range. */ 267 /* 10.0.0.0 to 10.255.255.255 range. */
243 if (ip4.uint8[0] == 10) 268 if (ip4.uint8[0] == 10)
244 return 0; 269 return 0;
@@ -276,10 +301,6 @@ int LAN_ip(IP ip)
276 ip4.ip4.uint32 = ip.ip6.uint32[3]; 301 ip4.ip4.uint32 = ip.ip6.uint32[3];
277 return LAN_ip(ip4); 302 return LAN_ip(ip4);
278 } 303 }
279
280 /* localhost in IPv6 (::1) */
281 if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1))
282 return 0;
283 } 304 }
284 305
285 return -1; 306 return -1;
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 5243bd93..358bea2f 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -40,6 +40,9 @@ void LANdiscovery_init(DHT *dht);
40/* Clear packet handlers. */ 40/* Clear packet handlers. */
41void LANdiscovery_kill(DHT *dht); 41void LANdiscovery_kill(DHT *dht);
42 42
43/* Is IP a local ip or not. */
44_Bool Local_ip(IP ip);
45
43/* checks if a given IP isn't routable 46/* checks if a given IP isn't routable
44 * 47 *
45 * return 0 if ip is a LAN ip. 48 * return 0 if ip is a LAN ip.
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index a7e0a9fe..dc0e605a 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -52,24 +52,6 @@ static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber)
52 return 1; 52 return 1;
53} 53}
54 54
55static int add_online_friend(Messenger *m, int32_t friendnumber)
56{
57 if (friend_not_valid(m, friendnumber))
58 return -1;
59
60 ++m->numonline_friends;
61 return 0;
62}
63
64
65static int remove_online_friend(Messenger *m, int32_t friendnumber)
66{
67 if (friend_not_valid(m, friendnumber))
68 return -1;
69
70 --m->numonline_friends;
71 return 0;
72}
73/* Set the size of the friend list to numfriends. 55/* Set the size of the friend list to numfriends.
74 * 56 *
75 * return -1 if realloc fails. 57 * return -1 if realloc fails.
@@ -399,9 +381,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
399 if (friend_not_valid(m, friendnumber)) 381 if (friend_not_valid(m, friendnumber))
400 return -1; 382 return -1;
401 383
402 if (m->friendlist[friendnumber].status == FRIEND_ONLINE)
403 remove_online_friend(m, friendnumber);
404
405 clear_receipts(m, friendnumber); 384 clear_receipts(m, friendnumber);
406 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); 385 remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk);
407 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); 386 friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0);
@@ -884,10 +863,7 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
884 if (is_online != was_online) { 863 if (is_online != was_online) {
885 if (was_online) { 864 if (was_online) {
886 break_files(m, friendnumber); 865 break_files(m, friendnumber);
887 remove_online_friend(m, friendnumber);
888 clear_receipts(m, friendnumber); 866 clear_receipts(m, friendnumber);
889 } else {
890 add_online_friend(m, friendnumber);
891 } 867 }
892 868
893 m->friendlist[friendnumber].status = status; 869 m->friendlist[friendnumber].status = status;
@@ -1831,6 +1807,27 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
1831 return NULL; 1807 return NULL;
1832 } 1808 }
1833 1809
1810 if (options->tcp_server_port) {
1811 m->tcp_server = new_TCP_server(options->ipv6enabled, 1, &options->tcp_server_port, m->dht->self_public_key,
1812 m->dht->self_secret_key, m->onion);
1813
1814 if (m->tcp_server == NULL) {
1815 kill_friend_connections(m->fr_c);
1816 kill_onion(m->onion);
1817 kill_onion_announce(m->onion_a);
1818 kill_onion_client(m->onion_c);
1819 kill_DHT(m->dht);
1820 kill_net_crypto(m->net_crypto);
1821 kill_networking(m->net);
1822 free(m);
1823
1824 if (error)
1825 *error = MESSENGER_ERROR_TCP_SERVER;
1826
1827 return NULL;
1828 }
1829 }
1830
1834 m->options = *options; 1831 m->options = *options;
1835 friendreq_init(&(m->fr), m->fr_c); 1832 friendreq_init(&(m->fr), m->fr_c);
1836 set_nospam(&(m->fr), random_int()); 1833 set_nospam(&(m->fr), random_int());
@@ -1850,6 +1847,10 @@ void kill_messenger(Messenger *m)
1850 1847
1851 uint32_t i; 1848 uint32_t i;
1852 1849
1850 if (m->tcp_server) {
1851 kill_TCP_server(m->tcp_server);
1852 }
1853
1853 kill_friend_connections(m->fr_c); 1854 kill_friend_connections(m->fr_c);
1854 kill_onion(m->onion); 1855 kill_onion(m->onion);
1855 kill_onion_announce(m->onion_a); 1856 kill_onion_announce(m->onion_a);
@@ -2285,6 +2286,15 @@ void do_messenger(Messenger *m)
2285 for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { 2286 for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) {
2286 add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key); 2287 add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key);
2287 } 2288 }
2289
2290 if (m->tcp_server) {
2291 /* Add self tcp server. */
2292 IP_Port local_ip_port;
2293 local_ip_port.port = m->options.tcp_server_port;
2294 local_ip_port.ip.family = AF_INET;
2295 local_ip_port.ip.ip4.uint32 = INADDR_LOOPBACK;
2296 add_tcp_relay(m->net_crypto, local_ip_port, m->tcp_server->public_key);
2297 }
2288 } 2298 }
2289 2299
2290 unix_time_update(); 2300 unix_time_update();
@@ -2294,6 +2304,10 @@ void do_messenger(Messenger *m)
2294 do_DHT(m->dht); 2304 do_DHT(m->dht);
2295 } 2305 }
2296 2306
2307 if (m->tcp_server) {
2308 do_TCP_server(m->tcp_server);
2309 }
2310
2297 do_net_crypto(m->net_crypto); 2311 do_net_crypto(m->net_crypto);
2298 do_onion_client(m->onion_c); 2312 do_onion_client(m->onion_c);
2299 do_friend_connections(m->fr_c); 2313 do_friend_connections(m->fr_c);
@@ -2622,13 +2636,11 @@ static int messenger_load_state_callback(void *outer, const uint8_t *data, uint3
2622 case MESSENGER_STATE_TYPE_NOSPAMKEYS: 2636 case MESSENGER_STATE_TYPE_NOSPAMKEYS:
2623 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) { 2637 if (length == crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t)) {
2624 set_nospam(&(m->fr), *(uint32_t *)data); 2638 set_nospam(&(m->fr), *(uint32_t *)data);
2625 load_keys(m->net_crypto, &data[sizeof(uint32_t)]); 2639 load_secret_key(m->net_crypto, (&data[sizeof(uint32_t)]) + crypto_box_PUBLICKEYBYTES);
2626#ifdef ENABLE_ASSOC_DHT
2627 2640
2628 if (m->dht->assoc) 2641 if (memcmp((&data[sizeof(uint32_t)]), m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
2629 Assoc_self_client_id_changed(m->dht->assoc, m->net_crypto->self_public_key); 2642 return -1;
2630 2643 }
2631#endif
2632 } else 2644 } else
2633 return -1; /* critical */ 2645 return -1; /* critical */
2634 2646
@@ -2738,12 +2750,6 @@ uint32_t count_friendlist(const Messenger *m)
2738 return ret; 2750 return ret;
2739} 2751}
2740 2752
2741/* Return the number of online friends in the instance m. */
2742uint32_t get_num_online_friends(const Messenger *m)
2743{
2744 return m->numonline_friends;
2745}
2746
2747/* Copy a list of valid friend IDs into the array out_list. 2753/* Copy a list of valid friend IDs into the array out_list.
2748 * If out_list is NULL, returns 0. 2754 * If out_list is NULL, returns 0.
2749 * Otherwise, returns the number of elements copied. 2755 * Otherwise, returns the number of elements copied.
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 6943475f..26704dd1 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -27,7 +27,6 @@
27#define MESSENGER_H 27#define MESSENGER_H
28 28
29#include "friend_requests.h" 29#include "friend_requests.h"
30#include "LAN_discovery.h"
31#include "friend_connection.h" 30#include "friend_connection.h"
32 31
33#define MAX_NAME_LENGTH 128 32#define MAX_NAME_LENGTH 128
@@ -71,6 +70,7 @@ typedef struct {
71 uint8_t udp_disabled; 70 uint8_t udp_disabled;
72 TCP_Proxy_Info proxy_info; 71 TCP_Proxy_Info proxy_info;
73 uint16_t port_range[2]; 72 uint16_t port_range[2];
73 uint16_t tcp_server_port;
74} Messenger_Options; 74} Messenger_Options;
75 75
76 76
@@ -220,6 +220,7 @@ struct Messenger {
220 220
221 Friend_Connections *fr_c; 221 Friend_Connections *fr_c;
222 222
223 TCP_Server *tcp_server;
223 Friend_Requests fr; 224 Friend_Requests fr;
224 uint8_t name[MAX_NAME_LENGTH]; 225 uint8_t name[MAX_NAME_LENGTH];
225 uint16_t name_length; 226 uint16_t name_length;
@@ -232,8 +233,6 @@ struct Messenger {
232 Friend *friendlist; 233 Friend *friendlist;
233 uint32_t numfriends; 234 uint32_t numfriends;
234 235
235 uint32_t numonline_friends;
236
237#define NUM_SAVED_TCP_RELAYS 8 236#define NUM_SAVED_TCP_RELAYS 8
238 uint8_t has_added_relays; // If the first connection has occurred in do_messenger 237 uint8_t has_added_relays; // If the first connection has occurred in do_messenger
239 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config 238 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
@@ -730,6 +729,7 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const
730enum { 729enum {
731 MESSENGER_ERROR_NONE, 730 MESSENGER_ERROR_NONE,
732 MESSENGER_ERROR_PORT, 731 MESSENGER_ERROR_PORT,
732 MESSENGER_ERROR_TCP_SERVER,
733 MESSENGER_ERROR_OTHER 733 MESSENGER_ERROR_OTHER
734}; 734};
735 735
@@ -772,9 +772,6 @@ int messenger_load(Messenger *m, const uint8_t *data, uint32_t length);
772 * for copy_friendlist. */ 772 * for copy_friendlist. */
773uint32_t count_friendlist(const Messenger *m); 773uint32_t count_friendlist(const Messenger *m);
774 774
775/* Return the number of online friends in the instance m. */
776uint32_t get_num_online_friends(const Messenger *m);
777
778/* Copy a list of valid friend IDs into the array out_list. 775/* Copy a list of valid friend IDs into the array out_list.
779 * If out_list is NULL, returns 0. 776 * If out_list is NULL, returns 0.
780 * Otherwise, returns the number of elements copied. 777 * Otherwise, returns the number of elements copied.
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index fe39dc52..b0b26d20 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -249,7 +249,6 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
249 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 249 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
250 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 250 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
251 uint8_t status = con_to->connections[i].status; 251 uint8_t status = con_to->connections[i].status;
252 uint8_t connection_id = con_to->connections[i].connection_id;
253 252
254 if (tcp_con_num && status == TCP_CONNECTIONS_STATUS_REGISTERED) { 253 if (tcp_con_num && status == TCP_CONNECTIONS_STATUS_REGISTERED) {
255 tcp_con_num -= 1; 254 tcp_con_num -= 1;
diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h
index 727c4b4e..ba3e7308 100644
--- a/toxcore/TCP_server.h
+++ b/toxcore/TCP_server.h
@@ -85,7 +85,7 @@ typedef struct TCP_Priority_List TCP_Priority_List;
85struct TCP_Priority_List { 85struct TCP_Priority_List {
86 TCP_Priority_List *next; 86 TCP_Priority_List *next;
87 uint16_t size, sent; 87 uint16_t size, sent;
88 uint8_t data[0]; 88 uint8_t data[];
89}; 89};
90 90
91typedef struct TCP_Secure_Connection { 91typedef struct TCP_Secure_Connection {
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index d7306a8a..eefb1d90 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -35,6 +35,7 @@
35#include <crypto_hash_sha512.h> 35#include <crypto_hash_sha512.h>
36#include <crypto_verify_16.h> 36#include <crypto_verify_16.h>
37#include <crypto_verify_32.h> 37#include <crypto_verify_32.h>
38#include <crypto_scalarmult_curve25519.h>
38#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) 39#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39#endif 40#endif
40 41
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index c13ca949..1656def0 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -158,6 +158,15 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
158 if (!friend_con) 158 if (!friend_con)
159 return -1; 159 return -1;
160 160
161 /* Local ip and same pk means that they are hosting a TCP relay. */
162 if (Local_ip(ip_port.ip) && memcmp(friend_con->dht_temp_pk, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
163 if (friend_con->dht_ip_port.ip.family != 0) {
164 ip_port.ip = friend_con->dht_ip_port.ip;
165 } else {
166 friend_con->hosting_tcp_relay = 0;
167 }
168 }
169
161 unsigned int i; 170 unsigned int i;
162 171
163 uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; 172 uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
@@ -265,9 +274,14 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
265 friend_new_connection(fr_c, number); 274 friend_new_connection(fr_c, number);
266 } 275 }
267 276
268 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port); 277 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1);
269 friend_con->dht_ip_port = ip_port; 278 friend_con->dht_ip_port = ip_port;
270 friend_con->dht_ip_port_lastrecv = unix_time(); 279 friend_con->dht_ip_port_lastrecv = unix_time();
280
281 if (friend_con->hosting_tcp_relay) {
282 friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk);
283 friend_con->hosting_tcp_relay = 0;
284 }
271} 285}
272 286
273static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key) 287static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
@@ -317,6 +331,7 @@ static int handle_status(void *object, int number, uint8_t status)
317 331
318 friend_con->status = FRIENDCONN_STATUS_CONNECTING; 332 friend_con->status = FRIENDCONN_STATUS_CONNECTING;
319 friend_con->crypt_connection_id = -1; 333 friend_con->crypt_connection_id = -1;
334 friend_con->hosting_tcp_relay = 0;
320 } 335 }
321 336
322 if (call_cb) { 337 if (call_cb) {
@@ -458,7 +473,7 @@ static int handle_new_connections(void *object, New_Connection *n_c)
458 friend_con->crypt_connection_id = id; 473 friend_con->crypt_connection_id = id;
459 474
460 if (n_c->source.ip.family != AF_INET && n_c->source.ip.family != AF_INET6) { 475 if (n_c->source.ip.family != AF_INET && n_c->source.ip.family != AF_INET6) {
461 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); 476 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0);
462 } else { 477 } else {
463 friend_con->dht_ip_port = n_c->source; 478 friend_con->dht_ip_port = n_c->source;
464 friend_con->dht_ip_port_lastrecv = unix_time(); 479 friend_con->dht_ip_port_lastrecv = unix_time();
@@ -796,7 +811,7 @@ void do_friend_connections(Friend_Connections *fr_c)
796 811
797 if (friend_con->dht_lock) { 812 if (friend_con->dht_lock) {
798 if (friend_new_connection(fr_c, i) == 0) { 813 if (friend_new_connection(fr_c, i) == 0) {
799 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); 814 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0);
800 connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */ 815 connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */
801 } 816 }
802 } 817 }
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h
index baca4b76..32e947ac 100644
--- a/toxcore/friend_connection.h
+++ b/toxcore/friend_connection.h
@@ -96,6 +96,8 @@ typedef struct {
96 96
97 Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; 97 Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS];
98 uint16_t tcp_relay_counter; 98 uint16_t tcp_relay_counter;
99
100 _Bool hosting_tcp_relay;
99} Friend_Conn; 101} Friend_Conn;
100 102
101 103
diff --git a/toxcore/list.c b/toxcore/list.c
index 301e56f8..b97727f8 100644
--- a/toxcore/list.c
+++ b/toxcore/list.c
@@ -45,7 +45,7 @@
45 * < 0 : no match, returns index (return value is INDEX(index)) where 45 * < 0 : no match, returns index (return value is INDEX(index)) where
46 * the data should be inserted 46 * the data should be inserted
47 */ 47 */
48static int find(const BS_LIST *list, const void *data) 48static int find(const BS_LIST *list, const uint8_t *data)
49{ 49{
50 //should work well, but could be improved 50 //should work well, but could be improved
51 if (list->n == 0) { 51 if (list->n == 0) {
@@ -162,7 +162,7 @@ void bs_list_free(BS_LIST *list)
162 free(list->ids); 162 free(list->ids);
163} 163}
164 164
165int bs_list_find(const BS_LIST *list, const void *data) 165int bs_list_find(const BS_LIST *list, const uint8_t *data)
166{ 166{
167 int r = find(list, data); 167 int r = find(list, data);
168 168
@@ -174,7 +174,7 @@ int bs_list_find(const BS_LIST *list, const void *data)
174 return list->ids[r]; 174 return list->ids[r];
175} 175}
176 176
177int bs_list_add(BS_LIST *list, const void *data, int id) 177int bs_list_add(BS_LIST *list, const uint8_t *data, int id)
178{ 178{
179 //find where the new element should be inserted 179 //find where the new element should be inserted
180 //see: return value of find() 180 //see: return value of find()
@@ -214,7 +214,7 @@ int bs_list_add(BS_LIST *list, const void *data, int id)
214 return 1; 214 return 1;
215} 215}
216 216
217int bs_list_remove(BS_LIST *list, const void *data, int id) 217int bs_list_remove(BS_LIST *list, const uint8_t *data, int id)
218{ 218{
219 int i = find(list, data); 219 int i = find(list, data);
220 220
diff --git a/toxcore/list.h b/toxcore/list.h
index 03ac04dd..b04177e1 100644
--- a/toxcore/list.h
+++ b/toxcore/list.h
@@ -34,7 +34,7 @@ typedef struct {
34 uint32_t n; //number of elements 34 uint32_t n; //number of elements
35 uint32_t capacity; //number of elements memory is allocated for 35 uint32_t capacity; //number of elements memory is allocated for
36 uint32_t element_size; //size of the elements 36 uint32_t element_size; //size of the elements
37 void *data; //array of elements 37 uint8_t *data; //array of elements
38 int *ids; //array of element ids 38 int *ids; //array of element ids
39} BS_LIST; 39} BS_LIST;
40 40
@@ -56,7 +56,7 @@ void bs_list_free(BS_LIST *list);
56 * >= 0 : id associated with data 56 * >= 0 : id associated with data
57 * -1 : failure 57 * -1 : failure
58 */ 58 */
59int bs_list_find(const BS_LIST *list, const void *data); 59int bs_list_find(const BS_LIST *list, const uint8_t *data);
60 60
61/* Add an element with associated id to the list 61/* Add an element with associated id to the list
62 * 62 *
@@ -64,7 +64,7 @@ int bs_list_find(const BS_LIST *list, const void *data);
64 * 1 : success 64 * 1 : success
65 * 0 : failure (data already in list) 65 * 0 : failure (data already in list)
66 */ 66 */
67int bs_list_add(BS_LIST *list, const void *data, int id); 67int bs_list_add(BS_LIST *list, const uint8_t *data, int id);
68 68
69/* Remove element from the list 69/* Remove element from the list
70 * 70 *
@@ -72,7 +72,7 @@ int bs_list_add(BS_LIST *list, const void *data, int id);
72 * 1 : success 72 * 1 : success
73 * 0 : failure (element not found or id does not match) 73 * 0 : failure (element not found or id does not match)
74 */ 74 */
75int bs_list_remove(BS_LIST *list, const void *data, int id); 75int bs_list_remove(BS_LIST *list, const uint8_t *data, int id);
76 76
77/* Removes the memory overhead 77/* Removes the memory overhead
78 * 78 *
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 0ed855bb..6d4f6a9b 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -676,6 +676,8 @@ static int handle_request_packet(Packets_Array *send_array, const uint8_t *data,
676 uint32_t i, n = 1; 676 uint32_t i, n = 1;
677 uint32_t requested = 0; 677 uint32_t requested = 0;
678 678
679 uint64_t temp_time = current_time_monotonic();
680
679 for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) { 681 for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) {
680 if (length == 0) 682 if (length == 0)
681 break; 683 break;
@@ -684,7 +686,11 @@ static int handle_request_packet(Packets_Array *send_array, const uint8_t *data,
684 686
685 if (n == data[0]) { 687 if (n == data[0]) {
686 if (send_array->buffer[num]) { 688 if (send_array->buffer[num]) {
687 send_array->buffer[num]->sent = 0; 689 uint64_t sent_time = send_array->buffer[num]->sent_time;
690
691 if ((sent_time + DEFAULT_PING_CONNECTION) < temp_time) {
692 send_array->buffer[num]->sent_time = 0;
693 }
688 } 694 }
689 695
690 ++data; 696 ++data;
@@ -788,12 +794,12 @@ static int reset_max_speed_reached(Net_Crypto *c, int crypt_connection_id)
788 uint8_t send_failed = 0; 794 uint8_t send_failed = 0;
789 795
790 if (ret == 1) { 796 if (ret == 1) {
791 if (!dt->sent) { 797 if (!dt->sent_time) {
792 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, 798 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
793 dt->length) != 0) { 799 dt->length) != 0) {
794 send_failed = 1; 800 send_failed = 1;
795 } else { 801 } else {
796 dt->sent = 1; 802 dt->sent_time = current_time_monotonic();
797 } 803 }
798 } 804 }
799 } 805 }
@@ -831,7 +837,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
831 } 837 }
832 838
833 Packet_Data dt; 839 Packet_Data dt;
834 dt.sent = 0; 840 dt.sent_time = 0;
835 dt.length = length; 841 dt.length = length;
836 memcpy(dt.data, data, length); 842 memcpy(dt.data, data, length);
837 pthread_mutex_lock(&conn->mutex); 843 pthread_mutex_lock(&conn->mutex);
@@ -849,7 +855,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
849 Packet_Data *dt1 = NULL; 855 Packet_Data *dt1 = NULL;
850 856
851 if (get_data_pointer(&conn->send_array, &dt1, packet_num) == 1) 857 if (get_data_pointer(&conn->send_array, &dt1, packet_num) == 1)
852 dt1->sent = 1; 858 dt1->sent_time = current_time_monotonic();
853 } else { 859 } else {
854 conn->maximum_speed_reached = 1; 860 conn->maximum_speed_reached = 1;
855 LOGGER_ERROR("send_data_packet failed\n"); 861 LOGGER_ERROR("send_data_packet failed\n");
@@ -936,7 +942,7 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
936 * return -1 on failure. 942 * return -1 on failure.
937 * return number of packets sent on success. 943 * return number of packets sent on success.
938 */ 944 */
939static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) 945static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint32_t max_num)
940{ 946{
941 if (max_num == 0) 947 if (max_num == 0)
942 return -1; 948 return -1;
@@ -946,6 +952,7 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16
946 if (conn == 0) 952 if (conn == 0)
947 return -1; 953 return -1;
948 954
955 uint64_t temp_time = current_time_monotonic();
949 uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array); 956 uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array);
950 957
951 for (i = 0; i < array_size; ++i) { 958 for (i = 0; i < array_size; ++i) {
@@ -959,13 +966,13 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16
959 continue; 966 continue;
960 } 967 }
961 968
962 if (dt->sent) { 969 if (dt->sent_time) {
963 continue; 970 continue;
964 } 971 }
965 972
966 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, 973 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
967 dt->length) == 0) { 974 dt->length) == 0) {
968 dt->sent = 1; 975 dt->sent_time = temp_time;
969 ++num_sent; 976 ++num_sent;
970 } 977 }
971 978
@@ -1439,10 +1446,10 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1439 1446
1440 if (source.ip.family == AF_INET || source.ip.family == AF_INET6) { 1447 if (source.ip.family == AF_INET || source.ip.family == AF_INET6) {
1441 if (!ipport_equal(&source, &conn->ip_port)) { 1448 if (!ipport_equal(&source, &conn->ip_port)) {
1442 if (!bs_list_add(&c->ip_port_list, &source, crypt_connection_id)) 1449 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&source, crypt_connection_id))
1443 return -1; 1450 return -1;
1444 1451
1445 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 1452 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id);
1446 conn->ip_port = source; 1453 conn->ip_port = source;
1447 } 1454 }
1448 1455
@@ -1547,12 +1554,13 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1547 return -1; 1554 return -1;
1548 1555
1549 pthread_mutex_lock(&c->tcp_mutex); 1556 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); 1557 int 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); 1558 pthread_mutex_unlock(&c->tcp_mutex);
1552 1559
1553 if (conn->connection_number_tcp == -1) 1560 if (connection_number_tcp == -1)
1554 return -1; 1561 return -1;
1555 1562
1563 conn->connection_number_tcp = connection_number_tcp;
1556 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); 1564 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
1557 memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES); 1565 memcpy(conn->recv_nonce, n_c->recv_nonce, crypto_box_NONCEBYTES);
1558 memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES); 1566 memcpy(conn->peersessionpublic_key, n_c->peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
@@ -1600,12 +1608,13 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
1600 return -1; 1608 return -1;
1601 1609
1602 pthread_mutex_lock(&c->tcp_mutex); 1610 pthread_mutex_lock(&c->tcp_mutex);
1603 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id); 1611 int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
1604 pthread_mutex_unlock(&c->tcp_mutex); 1612 pthread_mutex_unlock(&c->tcp_mutex);
1605 1613
1606 if (conn->connection_number_tcp == -1) 1614 if (connection_number_tcp == -1)
1607 return -1; 1615 return -1;
1608 1616
1617 conn->connection_number_tcp = connection_number_tcp;
1609 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); 1618 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1610 random_nonce(conn->sent_nonce); 1619 random_nonce(conn->sent_nonce);
1611 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1620 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
@@ -1632,10 +1641,12 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
1632 1641
1633/* Set the direct ip of the crypto connection. 1642/* Set the direct ip of the crypto connection.
1634 * 1643 *
1644 * Connected is 0 if we are not sure we are connected to that person, 1 if we are sure.
1645 *
1635 * return -1 on failure. 1646 * return -1 on failure.
1636 * return 0 on success. 1647 * return 0 on success.
1637 */ 1648 */
1638int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port) 1649int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, _Bool connected)
1639{ 1650{
1640 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1651 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1641 1652
@@ -1656,10 +1667,16 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1656 return -1; 1667 return -1;
1657 } 1668 }
1658 1669
1659 if (bs_list_add(&c->ip_port_list, &ip_port, crypt_connection_id)) { 1670 if (bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
1660 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 1671 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id);
1661 conn->ip_port = ip_port; 1672 conn->ip_port = ip_port;
1662 conn->direct_lastrecv_time = 0; 1673
1674 if (connected) {
1675 conn->direct_lastrecv_time = unix_time();
1676 } else {
1677 conn->direct_lastrecv_time = 0;
1678 }
1679
1663 return 0; 1680 return 0;
1664 } 1681 }
1665 } 1682 }
@@ -1931,7 +1948,7 @@ int nc_dht_pk_callback(Net_Crypto *c, int crypt_connection_id, void (*function)(
1931 */ 1948 */
1932static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port) 1949static int crypto_id_ip_port(const Net_Crypto *c, IP_Port ip_port)
1933{ 1950{
1934 return bs_list_find(&c->ip_port_list, &ip_port); 1951 return bs_list_find(&c->ip_port_list, (uint8_t *)&ip_port);
1935} 1952}
1936 1953
1937#define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + crypto_box_MACBYTES) 1954#define CRYPTO_MIN_PACKET_SIZE (1 + sizeof(uint16_t) + crypto_box_MACBYTES)
@@ -1983,7 +2000,14 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
1983/* Ratio of recv queue size / recv packet rate (in seconds) times 2000/* Ratio of recv queue size / recv packet rate (in seconds) times
1984 * the number of ms between request packets to send at that ratio 2001 * the number of ms between request packets to send at that ratio
1985 */ 2002 */
1986#define REQUEST_PACKETS_COMPARE_CONSTANT (0.5 * 100.0) 2003#define REQUEST_PACKETS_COMPARE_CONSTANT (0.125 * 100.0)
2004
2005/* Multiplier for maximum allowed resends. */
2006#define PACKET_RESEND_MULTIPLIER 2
2007
2008/* Timeout for increasing speed after congestion event (in ms). */
2009#define CONGESTION_EVENT_TIMEOUT 4000
2010
1987static void send_crypto_packets(Net_Crypto *c) 2011static void send_crypto_packets(Net_Crypto *c)
1988{ 2012{
1989 uint32_t i; 2013 uint32_t i;
@@ -2061,7 +2085,11 @@ static void send_crypto_packets(Net_Crypto *c)
2061 double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) * 2085 double min_speed = 1000.0 * (((double)(total_sent)) / ((double)(CONGESTION_QUEUE_ARRAY_SIZE) *
2062 PACKET_COUNTER_AVERAGE_INTERVAL)); 2086 PACKET_COUNTER_AVERAGE_INTERVAL));
2063 2087
2064 conn->packet_send_rate = min_speed * 1.2; 2088 if (conn->last_congestion_event + CONGESTION_EVENT_TIMEOUT < temp_time) {
2089 conn->packet_send_rate = min_speed * 1.2;
2090 } else {
2091 conn->packet_send_rate = min_speed;
2092 }
2065 2093
2066 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) { 2094 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) {
2067 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 2095 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
@@ -2084,10 +2112,15 @@ static void send_crypto_packets(Net_Crypto *c)
2084 conn->last_packets_left_set = temp_time; 2112 conn->last_packets_left_set = temp_time;
2085 } 2113 }
2086 2114
2087 int ret = send_requested_packets(c, i, conn->packets_left); 2115 int ret = send_requested_packets(c, i, conn->packets_left * PACKET_RESEND_MULTIPLIER);
2088 2116
2089 if (ret != -1) { 2117 if (ret != -1) {
2090 conn->packets_left -= ret; 2118 if (ret < conn->packets_left) {
2119 conn->packets_left -= ret;
2120 } else {
2121 conn->last_congestion_event = temp_time;
2122 conn->packets_left = 0;
2123 }
2091 } 2124 }
2092 2125
2093 if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) { 2126 if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) {
@@ -2280,7 +2313,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2280 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); 2313 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
2281 pthread_mutex_unlock(&c->tcp_mutex); 2314 pthread_mutex_unlock(&c->tcp_mutex);
2282 2315
2283 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 2316 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id);
2284 clear_temp_packet(c, crypt_connection_id); 2317 clear_temp_packet(c, crypt_connection_id);
2285 clear_buffer(&conn->send_array); 2318 clear_buffer(&conn->send_array);
2286 clear_buffer(&conn->recv_array); 2319 clear_buffer(&conn->recv_array);
@@ -2326,6 +2359,8 @@ void new_keys(Net_Crypto *c)
2326 2359
2327/* Save the public and private keys to the keys array. 2360/* Save the public and private keys to the keys array.
2328 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 2361 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES.
2362 *
2363 * TODO: Save only secret key.
2329 */ 2364 */
2330void save_keys(const Net_Crypto *c, uint8_t *keys) 2365void save_keys(const Net_Crypto *c, uint8_t *keys)
2331{ 2366{
@@ -2333,13 +2368,13 @@ void save_keys(const Net_Crypto *c, uint8_t *keys)
2333 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES); 2368 memcpy(keys + crypto_box_PUBLICKEYBYTES, c->self_secret_key, crypto_box_SECRETKEYBYTES);
2334} 2369}
2335 2370
2336/* Load the public and private keys from the keys array. 2371/* Load the secret key.
2337 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 2372 * Length must be crypto_box_SECRETKEYBYTES.
2338 */ 2373 */
2339void load_keys(Net_Crypto *c, const uint8_t *keys) 2374void load_secret_key(Net_Crypto *c, const uint8_t *sk)
2340{ 2375{
2341 memcpy(c->self_public_key, keys, crypto_box_PUBLICKEYBYTES); 2376 memcpy(c->self_secret_key, sk, crypto_box_SECRETKEYBYTES);
2342 memcpy(c->self_secret_key, keys + crypto_box_PUBLICKEYBYTES, crypto_box_SECRETKEYBYTES); 2377 crypto_scalarmult_curve25519_base(c->self_public_key, c->self_secret_key);
2343} 2378}
2344 2379
2345/* Run this to (re)initialize net_crypto. 2380/* Run this to (re)initialize net_crypto.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 9eb5e2d3..56f43cc4 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -82,8 +82,11 @@
82 at the dT defined in net_crypto.c */ 82 at the dT defined in net_crypto.c */
83#define CONGESTION_QUEUE_ARRAY_SIZE 24 83#define CONGESTION_QUEUE_ARRAY_SIZE 24
84 84
85/* Connection ping in ms. TODO: calculate it per connection. */
86#define DEFAULT_PING_CONNECTION 50
87
85typedef struct { 88typedef struct {
86 _Bool sent; 89 uint64_t sent_time;
87 uint16_t length; 90 uint16_t length;
88 uint8_t data[MAX_CRYPTO_DATA_SIZE]; 91 uint8_t data[MAX_CRYPTO_DATA_SIZE];
89} Packet_Data; 92} Packet_Data;
@@ -146,6 +149,7 @@ typedef struct {
146 uint32_t last_sendqueue_size[CONGESTION_QUEUE_ARRAY_SIZE], last_sendqueue_counter; 149 uint32_t last_sendqueue_size[CONGESTION_QUEUE_ARRAY_SIZE], last_sendqueue_counter;
147 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; 150 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE];
148 uint32_t packets_sent; 151 uint32_t packets_sent;
152 uint64_t last_congestion_event;
149 153
150 /* TCP_connection connection_number */ 154 /* TCP_connection connection_number */
151 unsigned int connection_number_tcp; 155 unsigned int connection_number_tcp;
@@ -224,10 +228,12 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
224 228
225/* Set the direct ip of the crypto connection. 229/* Set the direct ip of the crypto connection.
226 * 230 *
231 * Connected is 0 if we are not sure we are connected to that person, 1 if we are sure.
232 *
227 * return -1 on failure. 233 * return -1 on failure.
228 * return 0 on success. 234 * return 0 on success.
229 */ 235 */
230int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port); 236int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port, _Bool connected);
231 237
232/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 238/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
233 * 239 *
@@ -378,10 +384,10 @@ void new_keys(Net_Crypto *c);
378 */ 384 */
379void save_keys(const Net_Crypto *c, uint8_t *keys); 385void save_keys(const Net_Crypto *c, uint8_t *keys);
380 386
381/* Load the public and private keys from the keys array. 387/* Load the secret key.
382 * Length must be crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES. 388 * Length must be crypto_box_SECRETKEYBYTES.
383 */ 389 */
384void load_keys(Net_Crypto *c, const uint8_t *keys); 390void load_secret_key(Net_Crypto *c, const uint8_t *sk);
385 391
386/* Create new instance of Net_Crypto. 392/* Create new instance of Net_Crypto.
387 * Sets all the global connection variables to their default values. 393 * Sets all the global connection variables to their default values.
diff --git a/toxcore/network.c b/toxcore/network.c
index e8787127..22ee4202 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -813,7 +813,7 @@ void ipport_copy(IP_Port *target, const IP_Port *source)
813 return; 813 return;
814 814
815 memcpy(target, source, sizeof(IP_Port)); 815 memcpy(target, source, sizeof(IP_Port));
816}; 816}
817 817
818/* ip_ntoa 818/* ip_ntoa
819 * converts ip into a string 819 * converts ip into a string
diff --git a/toxcore/onion.c b/toxcore/onion.c
index 48e4c769..cec178b9 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -104,7 +104,7 @@ static int ipport_unpack(IP_Port *target, const uint8_t *data, unsigned int data
104 104
105/* Create a new onion path. 105/* Create a new onion path.
106 * 106 *
107 * Create a new onion path out of nodes (nodes is a list of 3 nodes) 107 * Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
108 * 108 *
109 * new_path must be an empty memory location of atleast Onion_Path size. 109 * new_path must be an empty memory location of atleast Onion_Path size.
110 * 110 *
@@ -148,7 +148,7 @@ int create_onion_path(const DHT *dht, Onion_Path *new_path, const Node_format *n
148 */ 148 */
149int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_Path *path) 149int onion_path_to_nodes(Node_format *nodes, unsigned int num_nodes, const Onion_Path *path)
150{ 150{
151 if (num_nodes < 3) 151 if (num_nodes < ONION_PATH_LENGTH)
152 return -1; 152 return -1;
153 153
154 nodes[0].ip_port = path->ip_port1; 154 nodes[0].ip_port = path->ip_port1;
diff --git a/toxcore/onion.h b/toxcore/onion.h
index b05d2c8c..2b270ea9 100644
--- a/toxcore/onion.h
+++ b/toxcore/onion.h
@@ -53,6 +53,8 @@ typedef struct {
53#define ONION_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1)) 53#define ONION_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1))
54#define ONION_RESPONSE_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (1 + ONION_RETURN_3)) 54#define ONION_RESPONSE_MAX_DATA_SIZE (ONION_MAX_PACKET_SIZE - (1 + ONION_RETURN_3))
55 55
56#define ONION_PATH_LENGTH 3
57
56typedef struct { 58typedef struct {
57 uint8_t shared_key1[crypto_box_BEFORENMBYTES]; 59 uint8_t shared_key1[crypto_box_BEFORENMBYTES];
58 uint8_t shared_key2[crypto_box_BEFORENMBYTES]; 60 uint8_t shared_key2[crypto_box_BEFORENMBYTES];
@@ -76,7 +78,7 @@ typedef struct {
76 78
77/* Create a new onion path. 79/* Create a new onion path.
78 * 80 *
79 * Create a new onion path out of nodes (nodes is a list of 3 nodes) 81 * Create a new onion path out of nodes (nodes is a list of ONION_PATH_LENGTH nodes)
80 * 82 *
81 * new_path must be an empty memory location of atleast Onion_Path size. 83 * new_path must be an empty memory location of atleast Onion_Path size.
82 * 84 *
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h
index 36ffe767..0e041e50 100644
--- a/toxcore/onion_announce.h
+++ b/toxcore/onion_announce.h
@@ -25,7 +25,7 @@
25 25
26#include "onion.h" 26#include "onion.h"
27 27
28#define ONION_ANNOUNCE_MAX_ENTRIES 64 28#define ONION_ANNOUNCE_MAX_ENTRIES 96
29#define ONION_ANNOUNCE_TIMEOUT 300 29#define ONION_ANNOUNCE_TIMEOUT 300
30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES 30#define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES
31 31
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index ed328fb3..6575f632 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -190,7 +190,7 @@ static int is_path_used(const Onion_Client_Paths *onion_paths, const Node_format
190 continue; 190 continue;
191 } 191 }
192 192
193 if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[2].ip_port)) { 193 if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[ONION_PATH_LENGTH - 1].ip_port)) {
194 return i; 194 return i;
195 } 195 }
196 } 196 }
@@ -215,9 +215,9 @@ static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_pa
215 if ((onion_paths->last_path_success[pathnum] + ONION_PATH_TIMEOUT < onion_paths->last_path_used[pathnum] 215 if ((onion_paths->last_path_success[pathnum] + ONION_PATH_TIMEOUT < onion_paths->last_path_used[pathnum]
216 && onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES) 216 && onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES)
217 || is_timeout(onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME)) { 217 || is_timeout(onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME)) {
218 Node_format nodes[3]; 218 Node_format nodes[ONION_PATH_LENGTH];
219 219
220 if (random_nodes_path_onion(onion_c, nodes, 3) != 3) 220 if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH)
221 return -1; 221 return -1;
222 222
223 int n = is_path_used(onion_paths, nodes); 223 int n = is_path_used(onion_paths, nodes);
@@ -267,13 +267,12 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
267 onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = unix_time(); 267 onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = unix_time();
268 onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0; 268 onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0;
269 269
270 unsigned int path_len = 3; 270 Node_format nodes[ONION_PATH_LENGTH];
271 Node_format nodes[path_len];
272 271
273 if (onion_path_to_nodes(nodes, path_len, &onion_paths->paths[path_num % NUMBER_ONION_PATHS]) == 0) { 272 if (onion_path_to_nodes(nodes, ONION_PATH_LENGTH, &onion_paths->paths[path_num % NUMBER_ONION_PATHS]) == 0) {
274 unsigned int i; 273 unsigned int i;
275 274
276 for (i = 0; i < path_len; ++i) { 275 for (i = 0; i < ONION_PATH_LENGTH; ++i) {
277 onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].public_key); 276 onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].public_key);
278 } 277 }
279 } 278 }
@@ -1205,7 +1204,7 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c)
1205 unsigned int i; 1204 unsigned int i;
1206 1205
1207 for (i = 0; i < num_nodes; ++i) { 1206 for (i = 0; i < num_nodes; ++i) {
1208 onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); 1207 onion_add_bs_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
1209 } 1208 }
1210} 1209}
1211 1210
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 1c3564a3..2decca0a 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -304,16 +304,18 @@ void do_to_ping(PING *ping)
304 if (!ip_isset(&ping->to_ping[0].ip_port.ip)) 304 if (!ip_isset(&ping->to_ping[0].ip_port.ip))
305 return; 305 return;
306 306
307 ping->last_to_ping = unix_time();
308 uint32_t i; 307 uint32_t i;
309 308
310 for (i = 0; i < MAX_TO_PING; ++i) { 309 for (i = 0; i < MAX_TO_PING; ++i) {
311 if (!ip_isset(&ping->to_ping[i].ip_port.ip)) 310 if (!ip_isset(&ping->to_ping[i].ip_port.ip))
312 return; 311 break;
313 312
314 send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); 313 send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key);
315 ip_reset(&ping->to_ping[i].ip_port.ip); 314 ip_reset(&ping->to_ping[i].ip_port.ip);
316 } 315 }
316
317 if (i != 0)
318 ping->last_to_ping = unix_time();
317} 319}
318 320
319 321
diff --git a/toxcore/tox.c b/toxcore/tox.c
index 848f81c7..de615768 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -152,6 +152,7 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
152 m_options.udp_disabled = !options->udp_enabled; 152 m_options.udp_disabled = !options->udp_enabled;
153 m_options.port_range[0] = options->start_port; 153 m_options.port_range[0] = options->start_port;
154 m_options.port_range[1] = options->end_port; 154 m_options.port_range[1] = options->end_port;
155 m_options.tcp_server_port = options->tcp_port;
155 156
156 switch (options->proxy_type) { 157 switch (options->proxy_type) {
157 case TOX_PROXY_TYPE_HTTP: 158 case TOX_PROXY_TYPE_HTTP:
@@ -238,31 +239,6 @@ void tox_get_savedata(const Tox *tox, uint8_t *data)
238 } 239 }
239} 240}
240 241
241static int address_to_ip(Messenger *m, const char *address, IP_Port *ip_port, IP_Port *ip_port_v4)
242{
243 if (!addr_parse_ip(address, &ip_port->ip)) {
244 if (m->options.udp_disabled) { /* Disable DNS when udp is disabled. */
245 return -1;
246 }
247
248 IP *ip_extra = NULL;
249 ip_init(&ip_port->ip, m->options.ipv6enabled);
250
251 if (m->options.ipv6enabled && ip_port_v4) {
252 /* setup for getting BOTH: an IPv6 AND an IPv4 address */
253 ip_port->ip.family = AF_UNSPEC;
254 ip_reset(&ip_port_v4->ip);
255 ip_extra = &ip_port_v4->ip;
256 }
257
258 if (!addr_resolve(address, &ip_port->ip, ip_extra)) {
259 return -1;
260 }
261 }
262
263 return 0;
264}
265
266bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error) 242bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error)
267{ 243{
268 if (!address || !public_key) { 244 if (!address || !public_key) {
@@ -270,23 +246,53 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *
270 return 0; 246 return 0;
271 } 247 }
272 248
273 Messenger *m = tox; 249 if (port == 0) {
274 bool ret = tox_add_tcp_relay(tox, address, port, public_key, error); 250 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
251 return 0;
252 }
275 253
276 if (!ret) { 254 struct addrinfo *root, *info;
255
256 if (getaddrinfo(address, NULL, NULL, &root) != 0) {
257 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
277 return 0; 258 return 0;
278 } 259 }
279 260
280 if (m->options.udp_disabled) { 261 info = root;
281 return ret; 262
282 } else { /* DHT only works on UDP. */ 263 unsigned int count = 0;
283 if (DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key) == 0) { 264
284 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); 265 do {
285 return 0; 266 IP_Port ip_port;
267 ip_port.port = htons(port);
268 ip_port.ip.family = info->ai_family;
269
270 if (info->ai_socktype && info->ai_socktype != SOCK_DGRAM) {
271 continue;
272 }
273
274 if (info->ai_family == AF_INET) {
275 ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
276 } else if (info->ai_family == AF_INET6) {
277 ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
278 } else {
279 continue;
286 } 280 }
287 281
282 Messenger *m = tox;
283 onion_add_bs_path_node(m->onion_c, ip_port, public_key);
284 DHT_bootstrap(m->dht, ip_port, public_key);
285 ++count;
286 } while ((info = info->ai_next));
287
288 freeaddrinfo(root);
289
290 if (count) {
288 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); 291 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
289 return 1; 292 return 1;
293 } else {
294 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
295 return 0;
290 } 296 }
291} 297}
292 298
@@ -298,25 +304,53 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8
298 return 0; 304 return 0;
299 } 305 }
300 306
301 Messenger *m = tox;
302 IP_Port ip_port, ip_port_v4;
303
304 if (port == 0) { 307 if (port == 0) {
305 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT); 308 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT);
306 return 0; 309 return 0;
307 } 310 }
308 311
309 if (address_to_ip(m, address, &ip_port, &ip_port_v4) == -1) { 312 struct addrinfo *root, *info;
313
314 if (getaddrinfo(address, NULL, NULL, &root) != 0) {
310 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); 315 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
311 return 0; 316 return 0;
312 } 317 }
313 318
314 ip_port.port = htons(port); 319 info = root;
315 add_tcp_relay(m->net_crypto, ip_port, public_key);
316 onion_add_bs_path_node(m->onion_c, ip_port, public_key); //TODO: move this
317 320
318 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); 321 unsigned int count = 0;
319 return 1; 322
323 do {
324 IP_Port ip_port;
325 ip_port.port = htons(port);
326 ip_port.ip.family = info->ai_family;
327
328 if (info->ai_socktype && info->ai_socktype != SOCK_STREAM) {
329 continue;
330 }
331
332 if (info->ai_family == AF_INET) {
333 ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr;
334 } else if (info->ai_family == AF_INET6) {
335 ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr;
336 } else {
337 continue;
338 }
339
340 Messenger *m = tox;
341 add_tcp_relay(m->net_crypto, ip_port, public_key);
342 ++count;
343 } while ((info = info->ai_next));
344
345 freeaddrinfo(root);
346
347 if (count) {
348 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK);
349 return 1;
350 } else {
351 SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST);
352 return 0;
353 }
320} 354}
321 355
322TOX_CONNECTION tox_self_get_connection_status(const Tox *tox) 356TOX_CONNECTION tox_self_get_connection_status(const Tox *tox)
@@ -1205,9 +1239,15 @@ uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
1205 1239
1206uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error) 1240uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error)
1207{ 1241{
1208 /* TCP server not yet implemented in clients. */ 1242 const Messenger *m = tox;
1209 SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND); 1243
1210 return 0; 1244 if (m->tcp_server) {
1245 SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK);
1246 return m->options.tcp_server_port;
1247 } else {
1248 SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND);
1249 return 0;
1250 }
1211} 1251}
1212 1252
1213#include "tox_old_code.h" 1253#include "tox_old_code.h"
diff --git a/toxcore/tox.h b/toxcore/tox.h
index abd2f051..4afdf7c3 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -426,6 +426,12 @@ struct Tox_Options {
426 */ 426 */
427 uint16_t end_port; 427 uint16_t end_port;
428 428
429
430 /**
431 * The port to use for the TCP server. If 0, the tcp server is disabled.
432 */
433 uint16_t tcp_port;
434
429}; 435};
430 436
431 437