summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/LAN_discovery.c5
-rw-r--r--toxcore/LAN_discovery.h3
-rw-r--r--toxcore/Messenger.c75
-rw-r--r--toxcore/Messenger.h15
-rw-r--r--toxcore/TCP_client.c2
-rw-r--r--toxcore/TCP_client.h4
-rw-r--r--toxcore/TCP_connection.c480
-rw-r--r--toxcore/TCP_connection.h57
-rw-r--r--toxcore/crypto_core.c22
-rw-r--r--toxcore/crypto_core.h4
-rw-r--r--toxcore/friend_connection.c199
-rw-r--r--toxcore/friend_connection.h24
-rw-r--r--toxcore/net_crypto.c882
-rw-r--r--toxcore/net_crypto.h66
-rw-r--r--toxcore/onion.c4
-rw-r--r--toxcore/onion_client.c15
-rw-r--r--toxcore/onion_client.h2
-rw-r--r--toxcore/tox.h742
18 files changed, 1440 insertions, 1161 deletions
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index bc020d87..dbce762e 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -336,3 +336,8 @@ void LANdiscovery_init(DHT *dht)
336{ 336{
337 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht); 337 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, &handle_LANdiscovery, dht);
338} 338}
339
340void LANdiscovery_kill(DHT *dht)
341{
342 networking_registerhandler(dht->net, NET_PACKET_LAN_DISCOVERY, NULL, NULL);
343}
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h
index 5dffc3ad..5243bd93 100644
--- a/toxcore/LAN_discovery.h
+++ b/toxcore/LAN_discovery.h
@@ -37,6 +37,9 @@ int send_LANdiscovery(uint16_t port, DHT *dht);
37/* Sets up packet handlers. */ 37/* Sets up packet handlers. */
38void LANdiscovery_init(DHT *dht); 38void LANdiscovery_init(DHT *dht);
39 39
40/* Clear packet handlers. */
41void LANdiscovery_kill(DHT *dht);
42
40/* checks if a given IP isn't routable 43/* checks if a given IP isn't routable
41 * 44 *
42 * return 0 if ip is a LAN ip. 45 * return 0 if ip is a LAN ip.
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index fefc3b17..a7e0a9fe 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -433,14 +433,19 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
433 return -1; 433 return -1;
434 434
435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) { 435 if (m->friendlist[friendnumber].status == FRIEND_ONLINE) {
436 uint8_t direct_connected = 0; 436 _Bool direct_connected = 0;
437 unsigned int num_online_relays = 0;
437 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c, 438 crypto_connection_status(m->net_crypto, friend_connection_crypt_connection_id(m->fr_c,
438 m->friendlist[friendnumber].friendcon_id), &direct_connected); 439 m->friendlist[friendnumber].friendcon_id), &direct_connected, &num_online_relays);
439 440
440 if (direct_connected) { 441 if (direct_connected) {
441 return CONNECTION_UDP; 442 return CONNECTION_UDP;
442 } else { 443 } else {
443 return CONNECTION_TCP; 444 if (num_online_relays) {
445 return CONNECTION_TCP;
446 } else {
447 return CONNECTION_UNKNOWN;
448 }
444 } 449 }
445 } else { 450 } else {
446 return CONNECTION_NONE; 451 return CONNECTION_NONE;
@@ -493,10 +498,6 @@ int m_send_message_generic(Messenger *m, int32_t friendnumber, uint8_t type, con
493 498
494 uint32_t msg_id = ++m->friendlist[friendnumber].message_id; 499 uint32_t msg_id = ++m->friendlist[friendnumber].message_id;
495 500
496 if (msg_id == 0) {
497 msg_id = ++m->friendlist[friendnumber].message_id; // Otherwise, false error
498 }
499
500 add_receipt(m, friendnumber, packet_num, msg_id); 501 add_receipt(m, friendnumber, packet_num, msg_id);
501 502
502 if (message_id) 503 if (message_id)
@@ -753,25 +754,6 @@ static int send_user_istyping(const Messenger *m, int32_t friendnumber, uint8_t
753 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0); 754 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing), 0);
754} 755}
755 756
756static int send_relays(const Messenger *m, int32_t friendnumber)
757{
758 Node_format nodes[MAX_SHARED_RELAYS];
759 uint8_t data[1024];
760 int n, length;
761
762 n = copy_connected_tcp_relays(m->net_crypto, nodes, MAX_SHARED_RELAYS);
763 length = pack_nodes(data, sizeof(data), nodes, n);
764
765 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_SHARE_RELAYS, data, length, 0);
766
767 if (ret == 1)
768 m->friendlist[friendnumber].share_relays_lastsent = unix_time();
769
770 return ret;
771}
772
773
774
775static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length) 757static int set_friend_statusmessage(const Messenger *m, int32_t friendnumber, const uint8_t *status, uint16_t length)
776{ 758{
777 if (friend_not_valid(m, friendnumber)) 759 if (friend_not_valid(m, friendnumber))
@@ -874,6 +856,14 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber)
874 if (ret == -1) 856 if (ret == -1)
875 return; 857 return;
876 858
859 if (ret == CONNECTION_UNKNOWN) {
860 if (last_connection_udp_tcp == CONNECTION_UDP) {
861 return;
862 } else {
863 ret = CONNECTION_TCP;
864 }
865 }
866
877 if (last_connection_udp_tcp != ret) { 867 if (last_connection_udp_tcp != ret) {
878 if (m->friend_connectionstatuschange) 868 if (m->friend_connectionstatuschange)
879 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata); 869 m->friend_connectionstatuschange(m, friendnumber, ret, m->friend_connectionstatuschange_userdata);
@@ -1350,7 +1340,7 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
1350 if (m->friendlist[friendnumber].status != FRIEND_ONLINE) 1340 if (m->friendlist[friendnumber].status != FRIEND_ONLINE)
1351 return -2; 1341 return -2;
1352 1342
1353 if (filenumber > MAX_CONCURRENT_FILE_PIPES) 1343 if (filenumber >= MAX_CONCURRENT_FILE_PIPES)
1354 return -3; 1344 return -3;
1355 1345
1356 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber]; 1346 struct File_Transfers *ft = &m->friendlist[friendnumber].file_sending[filenumber];
@@ -1775,15 +1765,6 @@ static int friend_already_added(const uint8_t *real_pk, void *data)
1775 return -1; 1765 return -1;
1776} 1766}
1777 1767
1778/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
1779static void LANdiscovery(Messenger *m)
1780{
1781 if (m->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
1782 send_LANdiscovery(htons(TOX_PORT_DEFAULT), m->dht);
1783 m->last_LANdiscovery = unix_time();
1784 }
1785}
1786
1787/* Run this at startup. */ 1768/* Run this at startup. */
1788Messenger *new_messenger(Messenger_Options *options, unsigned int *error) 1769Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
1789{ 1770{
@@ -1852,7 +1833,6 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
1852 1833
1853 m->options = *options; 1834 m->options = *options;
1854 friendreq_init(&(m->fr), m->fr_c); 1835 friendreq_init(&(m->fr), m->fr_c);
1855 LANdiscovery_init(m->dht);
1856 set_nospam(&(m->fr), random_int()); 1836 set_nospam(&(m->fr), random_int());
1857 set_filter_function(&(m->fr), &friend_already_added, m); 1837 set_filter_function(&(m->fr), &friend_already_added, m);
1858 1838
@@ -2178,22 +2158,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
2178 break; 2158 break;
2179 } 2159 }
2180 2160
2181 case PACKET_ID_SHARE_RELAYS: {
2182 Node_format nodes[MAX_SHARED_RELAYS];
2183 int n;
2184
2185 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data, data_length, 1)) == -1)
2186 break;
2187
2188 int i;
2189
2190 for (i = 0; i < n; i++) {
2191 add_tcp_relay(m->net_crypto, nodes[i].ip_port, nodes[i].public_key);
2192 }
2193
2194 break;
2195 }
2196
2197 default: { 2161 default: {
2198 handle_custom_lossless_packet(object, i, temp, len); 2162 handle_custom_lossless_packet(object, i, temp, len);
2199 break; 2163 break;
@@ -2251,10 +2215,6 @@ void do_friends(Messenger *m)
2251 m->friendlist[i].user_istyping_sent = 1; 2215 m->friendlist[i].user_istyping_sent = 1;
2252 } 2216 }
2253 2217
2254 if (m->friendlist[i].share_relays_lastsent + FRIEND_SHARE_RELAYS_INTERVAL < temp_time) {
2255 send_relays(m, i);
2256 }
2257
2258 check_friend_tcp_udp(m, i); 2218 check_friend_tcp_udp(m, i);
2259 do_receipts(m, i); 2219 do_receipts(m, i);
2260 do_reqchunk_filecb(m, i); 2220 do_reqchunk_filecb(m, i);
@@ -2338,7 +2298,6 @@ void do_messenger(Messenger *m)
2338 do_onion_client(m->onion_c); 2298 do_onion_client(m->onion_c);
2339 do_friend_connections(m->fr_c); 2299 do_friend_connections(m->fr_c);
2340 do_friends(m); 2300 do_friends(m);
2341 LANdiscovery(m);
2342 connection_status_cb(m); 2301 connection_status_cb(m);
2343 2302
2344#ifdef LOGGING 2303#ifdef LOGGING
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 63fb2820..6943475f 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -42,8 +42,7 @@ enum {
42 MESSAGE_ACTION 42 MESSAGE_ACTION
43}; 43};
44 44
45/* NOTE: Packet ids below 20 must never be used. */ 45/* NOTE: Packet ids below 24 must never be used. */
46#define PACKET_ID_SHARE_RELAYS 23
47#define PACKET_ID_ONLINE 24 46#define PACKET_ID_ONLINE 24
48#define PACKET_ID_OFFLINE 25 47#define PACKET_ID_OFFLINE 25
49#define PACKET_ID_NICKNAME 48 48#define PACKET_ID_NICKNAME 48
@@ -62,9 +61,6 @@ enum {
62#define PACKET_ID_MESSAGE_GROUPCHAT 99 61#define PACKET_ID_MESSAGE_GROUPCHAT 99
63#define PACKET_ID_LOSSY_GROUPCHAT 199 62#define PACKET_ID_LOSSY_GROUPCHAT 199
64 63
65/* Max number of tcp relays sent to friends */
66#define MAX_SHARED_RELAYS 16
67
68/* All packets starting with a byte in this range can be used for anything. */ 64/* All packets starting with a byte in this range can be used for anything. */
69#define PACKET_ID_LOSSLESS_RANGE_START 160 65#define PACKET_ID_LOSSLESS_RANGE_START 160
70#define PACKET_ID_LOSSLESS_RANGE_SIZE 32 66#define PACKET_ID_LOSSLESS_RANGE_SIZE 32
@@ -110,13 +106,11 @@ enum {
110/* Default start timeout in seconds between friend requests. */ 106/* Default start timeout in seconds between friend requests. */
111#define FRIENDREQUEST_TIMEOUT 5; 107#define FRIENDREQUEST_TIMEOUT 5;
112 108
113/* Interval between the sending of tcp relay information */
114#define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60)
115
116enum { 109enum {
117 CONNECTION_NONE, 110 CONNECTION_NONE,
118 CONNECTION_TCP, 111 CONNECTION_TCP,
119 CONNECTION_UDP 112 CONNECTION_UDP,
113 CONNECTION_UNKNOWN
120}; 114};
121 115
122/* USERSTATUS - 116/* USERSTATUS -
@@ -199,7 +193,6 @@ typedef struct {
199 uint32_t message_id; // a semi-unique id used in read receipts. 193 uint32_t message_id; // a semi-unique id used in read receipts.
200 uint32_t friendrequest_nospam; // The nospam number used in the friend request. 194 uint32_t friendrequest_nospam; // The nospam number used in the friend request.
201 uint64_t last_seen_time; 195 uint64_t last_seen_time;
202 uint64_t share_relays_lastsent;
203 uint8_t last_connection_udp_tcp; 196 uint8_t last_connection_udp_tcp;
204 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; 197 struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES];
205 unsigned int num_sending_files; 198 unsigned int num_sending_files;
@@ -241,8 +234,6 @@ struct Messenger {
241 234
242 uint32_t numonline_friends; 235 uint32_t numonline_friends;
243 236
244 uint64_t last_LANdiscovery;
245
246#define NUM_SAVED_TCP_RELAYS 8 237#define NUM_SAVED_TCP_RELAYS 8
247 uint8_t has_added_relays; // If the first connection has occurred in do_messenger 238 uint8_t has_added_relays; // If the first connection has occurred in do_messenger
248 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config 239 Node_format loaded_relays[NUM_SAVED_TCP_RELAYS]; // Relays loaded from config
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index d89b157c..1bd11a1d 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -87,7 +87,7 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con
87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, 87 const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two,
88 ip, port, three); 88 ip, port, three);
89 89
90 if (written < 0) { 90 if (written < 0 || MAX_PACKET_SIZE < written) {
91 return 0; 91 return 0;
92 } 92 }
93 93
diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h
index d4d18a4b..722430e0 100644
--- a/toxcore/TCP_client.h
+++ b/toxcore/TCP_client.h
@@ -78,10 +78,6 @@ typedef struct {
78 uint64_t ping_response_id; 78 uint64_t ping_response_id;
79 uint64_t ping_request_id; 79 uint64_t ping_request_id;
80 80
81 //TODO: remove
82 void *net_crypto_pointer;
83 uint32_t net_crypto_location;
84
85 struct { 81 struct {
86 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ 82 uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
87 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 83 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index e11e1318..fe39dc52 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -26,6 +26,7 @@
26#endif 26#endif
27 27
28#include "TCP_connection.h" 28#include "TCP_connection.h"
29#include "util.h"
29 30
30/* Set the size of the array to num. 31/* Set the size of the array to num.
31 * 32 *
@@ -212,6 +213,8 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
212 unsigned int i; 213 unsigned int i;
213 int ret = -1; 214 int ret = -1;
214 215
216 _Bool limit_reached = 0;
217
215 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 218 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
216 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 219 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
217 uint8_t status = con_to->connections[i].status; 220 uint8_t status = con_to->connections[i].status;
@@ -227,6 +230,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
227 230
228 ret = send_data(tcp_con->connection, connection_id, packet, length); 231 ret = send_data(tcp_con->connection, connection_id, packet, length);
229 232
233 if (ret == 0) {
234 limit_reached = 1;
235 }
236
230 if (ret == 1) { 237 if (ret == 1) {
231 break; 238 break;
232 } 239 }
@@ -235,7 +242,10 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
235 242
236 if (ret == 1) { 243 if (ret == 1) {
237 return 0; 244 return 0;
238 } else { 245 } else if (!limit_reached) {
246 ret = 0;
247
248 /* Send oob packets to all relays tied to the connection. */
239 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 249 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
240 uint32_t tcp_con_num = con_to->connections[i].tcp_connection; 250 uint32_t tcp_con_num = con_to->connections[i].tcp_connection;
241 uint8_t status = con_to->connections[i].status; 251 uint8_t status = con_to->connections[i].status;
@@ -249,19 +259,19 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
249 continue; 259 continue;
250 } 260 }
251 261
252 ret = send_oob_packet(tcp_con->connection, con_to->public_key, packet, length); 262 if (send_oob_packet(tcp_con->connection, con_to->public_key, packet, length) == 1) {
253 263 ret += 1;
254 if (ret == 1) {
255 break;
256 } 264 }
257 } 265 }
258 } 266 }
259 267
260 if (ret == 1) { 268 if (ret >= 1) {
261 return 0; 269 return 0;
262 } else { 270 } else {
263 return -1; 271 return -1;
264 } 272 }
273 } else {
274 return -1;
265 } 275 }
266} 276}
267 277
@@ -273,13 +283,15 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
273 * return TCP connection number on success. 283 * return TCP connection number on success.
274 * return -1 on failure. 284 * return -1 on failure.
275 */ 285 */
276int get_random_tcp_conn_number(TCP_Connections *tcp_c) 286int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c)
277{ 287{
278 unsigned int i, r = rand(); 288 unsigned int i, r = rand();
279 289
280 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 290 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
281 if (tcp_c->tcp_connections[(i + r) % tcp_c->tcp_connections_length].status == TCP_CONN_CONNECTED) { 291 unsigned int index = ((i + r) % tcp_c->tcp_connections_length);
282 return ((i + r) % tcp_c->tcp_connections_length); 292
293 if (tcp_c->tcp_connections[index].onion && tcp_c->tcp_connections[index].status == TCP_CONN_CONNECTED) {
294 return index;
283 } 295 }
284 } 296 }
285 297
@@ -321,6 +333,9 @@ int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_num
321 if (!tcp_con) 333 if (!tcp_con)
322 return -1; 334 return -1;
323 335
336 if (tcp_con->status != TCP_CONN_CONNECTED)
337 return -1;
338
324 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); 339 int ret = send_oob_packet(tcp_con->connection, public_key, packet, length);
325 340
326 if (ret == 1) 341 if (ret == 1)
@@ -392,8 +407,14 @@ static int find_tcp_connection_relay(TCP_Connections *tcp_c, const uint8_t *rela
392 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 407 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
393 408
394 if (tcp_con) { 409 if (tcp_con) {
395 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) { 410 if (tcp_con->status == TCP_CONN_SLEEPING) {
396 return i; 411 if (memcmp(tcp_con->relay_pk, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
412 return i;
413 }
414 } else {
415 if (memcmp(tcp_con->connection->public_key, relay_pk, crypto_box_PUBLICKEYBYTES) == 0) {
416 return i;
417 }
397 } 418 }
398 } 419 }
399 } 420 }
@@ -451,14 +472,86 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number)
451 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id); 472 send_disconnect_request(tcp_con->connection, con_to->connections[i].connection_id);
452 } 473 }
453 474
454 --tcp_con->lock_count; 475 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
476 --tcp_con->lock_count;
477
478 if (con_to->status == TCP_CONN_SLEEPING) {
479 --tcp_con->sleep_count;
480 }
481 }
455 } 482 }
456 } 483 }
457 484
458 return wipe_connection(tcp_c, connections_number); 485 return wipe_connection(tcp_c, connections_number);
459} 486}
460 487
461static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connections_number) 488/* Set connection status.
489 *
490 * status of 1 means we are using the connection.
491 * status of 0 means we are not using it.
492 *
493 * Unused tcp connections will be disconnected from but kept in case they are needed.
494 *
495 * return 0 on success.
496 * return -1 on failure.
497 */
498int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status)
499{
500 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
501
502 if (!con_to)
503 return -1;
504
505 if (status) {
506 /* Conection is unsleeping. */
507 if (con_to->status != TCP_CONN_SLEEPING)
508 return -1;
509
510 unsigned int i;
511
512 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
513 if (con_to->connections[i].tcp_connection) {
514 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
515 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
516
517 if (!tcp_con)
518 continue;
519
520 if (tcp_con->status == TCP_CONN_SLEEPING) {
521 tcp_con->unsleep = 1;
522 }
523 }
524 }
525
526 con_to->status = TCP_CONN_VALID;
527 return 0;
528 } else {
529 /* Conection is going to sleep. */
530 if (con_to->status != TCP_CONN_VALID)
531 return -1;
532
533 unsigned int i;
534
535 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
536 if (con_to->connections[i].tcp_connection) {
537 unsigned int tcp_connections_number = con_to->connections[i].tcp_connection - 1;
538 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
539
540 if (!tcp_con)
541 continue;
542
543 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
544 ++tcp_con->sleep_count;
545 }
546 }
547 }
548
549 con_to->status = TCP_CONN_SLEEPING;
550 return 0;
551 }
552}
553
554static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
462{ 555{
463 unsigned int i; 556 unsigned int i;
464 557
@@ -474,7 +567,7 @@ static _Bool tcp_connection_in_conn(TCP_Connection_to *con_to, int tcp_connectio
474/* return index on success. 567/* return index on success.
475 * return -1 on failure. 568 * return -1 on failure.
476 */ 569 */
477static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connections_number) 570static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
478{ 571{
479 unsigned int i; 572 unsigned int i;
480 573
@@ -496,7 +589,7 @@ static int add_tcp_connection_to_conn(TCP_Connection_to *con_to, int tcp_connect
496/* return index on success. 589/* return index on success.
497 * return -1 on failure. 590 * return -1 on failure.
498 */ 591 */
499static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connections_number) 592static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, unsigned int tcp_connections_number)
500{ 593{
501 unsigned int i; 594 unsigned int i;
502 595
@@ -512,16 +605,39 @@ static int rm_tcp_connection_from_conn(TCP_Connection_to *con_to, int tcp_connec
512 return -1; 605 return -1;
513} 606}
514 607
608/* return number of online connections on success.
609 * return -1 on failure.
610 */
611static unsigned int online_tcp_connection_from_conn(TCP_Connection_to *con_to)
612{
613 unsigned int i, count = 0;
614
615 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
616 if (con_to->connections[i].tcp_connection) {
617 if (con_to->connections[i].status == TCP_CONNECTIONS_STATUS_ONLINE) {
618 ++count;
619 }
620 }
621 }
622
623 return count;
624}
625
515/* return index on success. 626/* return index on success.
516 * return -1 on failure. 627 * return -1 on failure.
517 */ 628 */
518static int set_tcp_connection_status(TCP_Connection_to *con_to, int tcp_connections_number, unsigned int status, 629static int set_tcp_connection_status(TCP_Connection_to *con_to, unsigned int tcp_connections_number,
519 uint8_t connection_id) 630 unsigned int status, uint8_t connection_id)
520{ 631{
521 unsigned int i; 632 unsigned int i;
522 633
523 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { 634 for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) {
524 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) { 635 if (con_to->connections[i].tcp_connection == (tcp_connections_number + 1)) {
636
637 if (con_to->connections[i].status == status) {
638 return -1;
639 }
640
525 con_to->connections[i].status = status; 641 con_to->connections[i].status = status;
526 con_to->connections[i].connection_id = connection_id; 642 con_to->connections[i].connection_id = connection_id;
527 return i; 643 return i;
@@ -553,11 +669,130 @@ static int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections
553 } 669 }
554 } 670 }
555 671
672 if (tcp_con->onion) {
673 --tcp_c->onion_num_conns;
674 }
675
556 kill_TCP_connection(tcp_con->connection); 676 kill_TCP_connection(tcp_con->connection);
557 677
558 return wipe_tcp_connection(tcp_c, tcp_connections_number); 678 return wipe_tcp_connection(tcp_c, tcp_connections_number);
559} 679}
560 680
681static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
682{
683 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
684
685 if (!tcp_con)
686 return -1;
687
688 if (tcp_con->status == TCP_CONN_SLEEPING)
689 return -1;
690
691 IP_Port ip_port = tcp_con->connection->ip_port;
692 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
693 memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
694 kill_TCP_connection(tcp_con->connection);
695 tcp_con->connection = new_TCP_connection(ip_port, relay_pk, tcp_c->dht->self_public_key, tcp_c->dht->self_secret_key,
696 &tcp_c->proxy_info);
697
698 if (!tcp_con->connection) {
699 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
700 return -1;
701 }
702
703 unsigned int i;
704
705 for (i = 0; i < tcp_c->connections_length; ++i) {
706 TCP_Connection_to *con_to = get_connection(tcp_c, i);
707
708 if (con_to) {
709 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
710 }
711 }
712
713 if (tcp_con->onion) {
714 --tcp_c->onion_num_conns;
715 tcp_con->onion = 0;
716 }
717
718 tcp_con->lock_count = 0;
719 tcp_con->sleep_count = 0;
720 tcp_con->connected_time = 0;
721 tcp_con->status = TCP_CONN_VALID;
722 tcp_con->unsleep = 0;
723
724 return 0;
725}
726
727static int sleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
728{
729 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
730
731 if (!tcp_con)
732 return -1;
733
734 if (tcp_con->status != TCP_CONN_CONNECTED)
735 return -1;
736
737 if (tcp_con->lock_count != tcp_con->sleep_count)
738 return -1;
739
740 tcp_con->ip_port = tcp_con->connection->ip_port;
741 memcpy(tcp_con->relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES);
742
743 kill_TCP_connection(tcp_con->connection);
744 tcp_con->connection = NULL;
745
746 unsigned int i;
747
748 for (i = 0; i < tcp_c->connections_length; ++i) {
749 TCP_Connection_to *con_to = get_connection(tcp_c, i);
750
751 if (con_to) {
752 set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_NONE, 0);
753 }
754 }
755
756 if (tcp_con->onion) {
757 --tcp_c->onion_num_conns;
758 tcp_con->onion = 0;
759 }
760
761 tcp_con->lock_count = 0;
762 tcp_con->sleep_count = 0;
763 tcp_con->connected_time = 0;
764 tcp_con->status = TCP_CONN_SLEEPING;
765 tcp_con->unsleep = 0;
766
767 return 0;
768}
769
770static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number)
771{
772 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
773
774 if (!tcp_con)
775 return -1;
776
777 if (tcp_con->status != TCP_CONN_SLEEPING)
778 return -1;
779
780 tcp_con->connection = new_TCP_connection(tcp_con->ip_port, tcp_con->relay_pk, tcp_c->dht->self_public_key,
781 tcp_c->dht->self_secret_key, &tcp_c->proxy_info);
782
783 if (!tcp_con->connection) {
784 kill_tcp_relay_connection(tcp_c, tcp_connections_number);
785 return -1;
786 }
787
788 tcp_con->lock_count = 0;
789 tcp_con->sleep_count = 0;
790 tcp_con->connected_time = 0;
791 tcp_con->status = TCP_CONN_VALID;
792 tcp_con->unsleep = 0;
793 return 0;
794}
795
561/* Send a TCP routing request. 796/* Send a TCP routing request.
562 * 797 *
563 * return 0 on success. 798 * return 0 on success.
@@ -570,6 +805,9 @@ static int send_tcp_relay_routing_request(TCP_Connections *tcp_c, int tcp_connec
570 if (!tcp_con) 805 if (!tcp_con)
571 return -1; 806 return -1;
572 807
808 if (tcp_con->status == TCP_CONN_SLEEPING)
809 return -1;
810
573 if (send_routing_request(tcp_con->connection, public_key) != 1) 811 if (send_routing_request(tcp_con->connection, public_key) != 1)
574 return -1; 812 return -1;
575 813
@@ -592,8 +830,6 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
592 if (connections_number == -1) 830 if (connections_number == -1)
593 return -1; 831 return -1;
594 832
595 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
596
597 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); 833 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
598 834
599 if (con_to == NULL) 835 if (con_to == NULL)
@@ -602,6 +838,8 @@ static int tcp_response_callback(void *object, uint8_t connection_id, const uint
602 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 838 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
603 return -1; 839 return -1;
604 840
841 set_tcp_connection_number(tcp_con->connection, connection_id, connections_number);
842
605 return 0; 843 return 0;
606} 844}
607 845
@@ -621,10 +859,20 @@ static int tcp_status_callback(void *object, uint32_t number, uint8_t connection
621 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1) 859 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_REGISTERED, connection_id) == -1)
622 return -1; 860 return -1;
623 861
862 --tcp_con->lock_count;
863
864 if (con_to->status == TCP_CONN_SLEEPING) {
865 --tcp_con->sleep_count;
866 }
624 } else if (status == 2) { 867 } else if (status == 2) {
625 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1) 868 if (set_tcp_connection_status(con_to, tcp_connections_number, TCP_CONNECTIONS_STATUS_ONLINE, connection_id) == -1)
626 return -1; 869 return -1;
627 870
871 ++tcp_con->lock_count;
872
873 if (con_to->status == TCP_CONN_SLEEPING) {
874 ++tcp_con->sleep_count;
875 }
628 } 876 }
629 877
630 return 0; 878 return 0;
@@ -673,11 +921,13 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8
673 /* TODO: optimize */ 921 /* TODO: optimize */
674 int connections_number = find_tcp_connection_to(tcp_c, public_key); 922 int connections_number = find_tcp_connection_to(tcp_c, public_key);
675 923
676 if (connections_number == -1) { 924 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
925
926 if (con_to && tcp_connection_in_conn(con_to, tcp_connections_number)) {
927 return tcp_data_callback(object, connections_number, 0, data, length);
928 } else {
677 if (tcp_c->tcp_oob_callback) 929 if (tcp_c->tcp_oob_callback)
678 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); 930 tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length);
679 } else {
680 return tcp_data_callback(object, connections_number, 0, data, length);
681 } 931 }
682 932
683 return 0; 933 return 0;
@@ -725,20 +975,35 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
725 if (!tcp_con) 975 if (!tcp_con)
726 return -1; 976 return -1;
727 977
728 unsigned int i; 978 unsigned int i, sent = 0;
729 979
730 for (i = 0; i < tcp_c->connections_length; ++i) { 980 for (i = 0; i < tcp_c->connections_length; ++i) {
731 TCP_Connection_to *con_to = get_connection(tcp_c, i); 981 TCP_Connection_to *con_to = get_connection(tcp_c, i);
732 982
733 if (con_to) { 983 if (con_to) {
734 if (tcp_connection_in_conn(con_to, tcp_connections_number)) { 984 if (tcp_connection_in_conn(con_to, tcp_connections_number)) {
735 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 985 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
986 ++sent;
987 }
736 } 988 }
737 } 989 }
738 } 990 }
739 991
740 tcp_relay_set_callbacks(tcp_c, tcp_connections_number); 992 tcp_relay_set_callbacks(tcp_c, tcp_connections_number);
741 tcp_con->status = TCP_CONN_CONNECTED; 993 tcp_con->status = TCP_CONN_CONNECTED;
994
995 /* If this connection isn't used by any connection, we don't need to wait for them to come online. */
996 if (sent) {
997 tcp_con->connected_time = unix_time();
998 } else {
999 tcp_con->connected_time = 0;
1000 }
1001
1002 if (tcp_c->onion_status && tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1003 tcp_con->onion = 1;
1004 ++tcp_c->onion_num_conns;
1005 }
1006
742 return 0; 1007 return 0;
743} 1008}
744 1009
@@ -807,13 +1072,17 @@ int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_numb
807 if (!tcp_con) 1072 if (!tcp_con)
808 return -1; 1073 return -1;
809 1074
1075 if (con_to->status != TCP_CONN_SLEEPING && tcp_con->status == TCP_CONN_SLEEPING) {
1076 tcp_con->unsleep = 1;
1077 }
1078
810 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) 1079 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1)
811 return -1; 1080 return -1;
812 1081
813 ++tcp_con->lock_count;
814
815 if (tcp_con->status == TCP_CONN_CONNECTED) { 1082 if (tcp_con->status == TCP_CONN_CONNECTED) {
816 send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); 1083 if (send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key) == 0) {
1084 tcp_con->connected_time = unix_time();
1085 }
817 } 1086 }
818 1087
819 return 0; 1088 return 0;
@@ -836,22 +1105,38 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
836 if (tcp_connections_number != -1) { 1105 if (tcp_connections_number != -1) {
837 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); 1106 return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number);
838 } else { 1107 } else {
839 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); 1108 if (online_tcp_connection_from_conn(con_to) >= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
840
841 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
842 return -1; 1109 return -1;
843 } 1110 }
844 1111
1112 int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk);
1113
845 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); 1114 TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number);
846 1115
847 if (!tcp_con) 1116 if (!tcp_con)
848 return -1; 1117 return -1;
849 1118
850 ++tcp_con->lock_count; 1119 if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) {
1120 return -1;
1121 }
1122
851 return 0; 1123 return 0;
852 } 1124 }
853} 1125}
854 1126
1127/* return number of online tcp relays tied to the connection on success.
1128 * return 0 on failure.
1129 */
1130unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number)
1131{
1132 TCP_Connection_to *con_to = get_connection(tcp_c, connections_number);
1133
1134 if (!con_to)
1135 return 0;
1136
1137 return online_tcp_connection_from_conn(con_to);
1138}
1139
855/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. 1140/* Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
856 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. 1141 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
857 * 1142 *
@@ -860,10 +1145,10 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_
860 */ 1145 */
861unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) 1146unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num)
862{ 1147{
863 unsigned int i, copied = 0; 1148 unsigned int i, copied = 0, r = rand();
864 1149
865 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { 1150 for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) {
866 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1151 TCP_con *tcp_con = get_tcp_connection(tcp_c, (i + r) % tcp_c->tcp_connections_length);
867 1152
868 if (!tcp_con) { 1153 if (!tcp_con) {
869 continue; 1154 continue;
@@ -886,7 +1171,74 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_
886 return copied; 1171 return copied;
887} 1172}
888 1173
889TCP_Connections *new_tcp_connections(DHT *dht) 1174/* Set if we want TCP_connection to allocate some connection for onion use.
1175 *
1176 * If status is 1, allocate some connections. if status is 0, don't.
1177 *
1178 * return 0 on success.
1179 * return -1 on failure.
1180 */
1181int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status)
1182{
1183 if (tcp_c->onion_status == status)
1184 return -1;
1185
1186 if (status) {
1187 unsigned int i;
1188
1189 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1190 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1191
1192 if (tcp_con) {
1193 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion) {
1194 ++tcp_c->onion_num_conns;
1195 tcp_con->onion = 1;
1196 }
1197 }
1198
1199 if (tcp_c->onion_num_conns >= NUM_ONION_TCP_CONNECTIONS)
1200 break;
1201 }
1202
1203 if (tcp_c->onion_num_conns < NUM_ONION_TCP_CONNECTIONS) {
1204 unsigned int wakeup = NUM_ONION_TCP_CONNECTIONS - tcp_c->onion_num_conns;
1205
1206 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1207 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1208
1209 if (tcp_con) {
1210 if (tcp_con->status == TCP_CONN_SLEEPING) {
1211 tcp_con->unsleep = 1;
1212 }
1213 }
1214
1215 if (!wakeup)
1216 break;
1217 }
1218 }
1219
1220 tcp_c->onion_status = 1;
1221 } else {
1222 unsigned int i;
1223
1224 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
1225 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
1226
1227 if (tcp_con) {
1228 if (tcp_con->onion) {
1229 --tcp_c->onion_num_conns;
1230 tcp_con->onion = 0;
1231 }
1232 }
1233 }
1234
1235 tcp_c->onion_status = 0;
1236 }
1237
1238 return 0;
1239}
1240
1241TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info)
890{ 1242{
891 if (dht == NULL) 1243 if (dht == NULL)
892 return NULL; 1244 return NULL;
@@ -897,6 +1249,8 @@ TCP_Connections *new_tcp_connections(DHT *dht)
897 return NULL; 1249 return NULL;
898 1250
899 temp->dht = dht; 1251 temp->dht = dht;
1252 temp->proxy_info = *proxy_info;
1253
900 return temp; 1254 return temp;
901} 1255}
902 1256
@@ -908,18 +1262,35 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
908 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1262 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
909 1263
910 if (tcp_con) { 1264 if (tcp_con) {
911 do_TCP_connection(tcp_con->connection); 1265 if (tcp_con->status != TCP_CONN_SLEEPING) {
1266 do_TCP_connection(tcp_con->connection);
912 1267
913 /* callbacks can change TCP connection address. */ 1268 /* callbacks can change TCP connection address. */
914 tcp_con = get_tcp_connection(tcp_c, i); 1269 tcp_con = get_tcp_connection(tcp_c, i);
915 1270
916 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { 1271 if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) {
917 kill_tcp_relay_connection(tcp_c, i); 1272 if (tcp_con->status == TCP_CONN_CONNECTED) {
918 continue; 1273 reconnect_tcp_relay_connection(tcp_c, i);
1274 } else {
1275 kill_tcp_relay_connection(tcp_c, i);
1276 }
1277
1278 continue;
1279 }
1280
1281 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) {
1282 tcp_relay_on_online(tcp_c, i);
1283 }
1284
1285 if (tcp_con->status == TCP_CONN_CONNECTED && !tcp_con->onion && tcp_con->lock_count
1286 && tcp_con->lock_count == tcp_con->sleep_count
1287 && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
1288 sleep_tcp_relay_connection(tcp_c, i);
1289 }
919 } 1290 }
920 1291
921 if (tcp_con->status == TCP_CONN_VALID && tcp_con->connection->status == TCP_CLIENT_CONFIRMED) { 1292 if (tcp_con->status == TCP_CONN_SLEEPING && tcp_con->unsleep) {
922 tcp_relay_on_online(tcp_c, i); 1293 unsleep_tcp_relay_connection(tcp_c, i);
923 } 1294 }
924 } 1295 }
925 } 1296 }
@@ -927,27 +1298,42 @@ static void do_tcp_conns(TCP_Connections *tcp_c)
927 1298
928static void kill_nonused_tcp(TCP_Connections *tcp_c) 1299static void kill_nonused_tcp(TCP_Connections *tcp_c)
929{ 1300{
930 unsigned int i, num_online = 0; 1301 if (tcp_c->tcp_connections_length == 0)
1302 return;
1303
1304 unsigned int i, num_online = 0, num_kill = 0, to_kill[tcp_c->tcp_connections_length];
931 1305
932 for (i = 0; i < tcp_c->tcp_connections_length; ++i) { 1306 for (i = 0; i < tcp_c->tcp_connections_length; ++i) {
933 TCP_con *tcp_con = get_tcp_connection(tcp_c, i); 1307 TCP_con *tcp_con = get_tcp_connection(tcp_c, i);
934 1308
935 if (tcp_con) { 1309 if (tcp_con) {
936 if (tcp_con->status == TCP_CONN_CONNECTED) { 1310 if (tcp_con->status == TCP_CONN_CONNECTED) {
937 if (!tcp_con->lock_count && num_online >= MAX_FRIEND_TCP_CONNECTIONS) { 1311 if (!tcp_con->onion && !tcp_con->lock_count && is_timeout(tcp_con->connected_time, TCP_CONNECTION_ANNOUNCE_TIMEOUT)) {
938 kill_tcp_relay_connection(tcp_c, i); 1312 to_kill[num_kill] = i;
939 continue; 1313 ++num_kill;
940 } 1314 }
941 1315
942 ++num_online; 1316 ++num_online;
943 } 1317 }
944 } 1318 }
945 } 1319 }
1320
1321 if (num_online <= RECOMMENDED_FRIEND_TCP_CONNECTIONS) {
1322 return;
1323 } else {
1324 unsigned int n = num_online - RECOMMENDED_FRIEND_TCP_CONNECTIONS;
1325
1326 if (n < num_kill)
1327 num_kill = n;
1328 }
1329
1330 for (i = 0; i < num_kill; ++i) {
1331 kill_tcp_relay_connection(tcp_c, to_kill[i]);
1332 }
946} 1333}
947 1334
948void do_tcp_connections(TCP_Connections *tcp_c) 1335void do_tcp_connections(TCP_Connections *tcp_c)
949{ 1336{
950 //TODO reconnect to TCP relays if disconnects happen.
951 do_tcp_conns(tcp_c); 1337 do_tcp_conns(tcp_c);
952 kill_nonused_tcp(tcp_c); 1338 kill_nonused_tcp(tcp_c);
953} 1339}
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h
index 2c86304f..29fbdee0 100644
--- a/toxcore/TCP_connection.h
+++ b/toxcore/TCP_connection.h
@@ -28,14 +28,28 @@
28 28
29#define TCP_CONN_NONE 0 29#define TCP_CONN_NONE 0
30#define TCP_CONN_VALID 1 30#define TCP_CONN_VALID 1
31
32/* NOTE: only used by TCP_con */
31#define TCP_CONN_CONNECTED 2 33#define TCP_CONN_CONNECTED 2
32 34
35/* Connection is not connected but can be quickly reconnected in case it is needed. */
36#define TCP_CONN_SLEEPING 3
37
33#define TCP_CONNECTIONS_STATUS_NONE 0 38#define TCP_CONNECTIONS_STATUS_NONE 0
34#define TCP_CONNECTIONS_STATUS_REGISTERED 1 39#define TCP_CONNECTIONS_STATUS_REGISTERED 1
35#define TCP_CONNECTIONS_STATUS_ONLINE 2 40#define TCP_CONNECTIONS_STATUS_ONLINE 2
36 41
37#define MAX_FRIEND_TCP_CONNECTIONS 4 42#define MAX_FRIEND_TCP_CONNECTIONS 6
43
44/* Time until connection to friend gets killed (if it doesn't get locked withing that time) */
45#define TCP_CONNECTION_ANNOUNCE_TIMEOUT (TCP_CONNECTION_TIMEOUT)
38 46
47/* The amount of recommended connections for each friend
48 NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2) */
49#define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2)
50
51/* Number of TCP connections used for onion purposes. */
52#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
39 53
40typedef struct { 54typedef struct {
41 uint8_t status; 55 uint8_t status;
@@ -53,7 +67,15 @@ typedef struct {
53typedef struct { 67typedef struct {
54 uint8_t status; 68 uint8_t status;
55 TCP_Client_Connection *connection; 69 TCP_Client_Connection *connection;
70 uint64_t connected_time;
56 uint32_t lock_count; 71 uint32_t lock_count;
72 uint32_t sleep_count;
73 _Bool onion;
74
75 /* Only used when connection is sleeping. */
76 IP_Port ip_port;
77 uint8_t relay_pk[crypto_box_PUBLICKEYBYTES];
78 _Bool unsleep; /* set to 1 to unsleep connection. */
57} TCP_con; 79} TCP_con;
58 80
59typedef struct { 81typedef struct {
@@ -76,6 +98,9 @@ typedef struct {
76 void *tcp_onion_callback_object; 98 void *tcp_onion_callback_object;
77 99
78 TCP_Proxy_Info proxy_info; 100 TCP_Proxy_Info proxy_info;
101
102 _Bool onion_status;
103 uint16_t onion_num_conns;
79} TCP_Connections; 104} TCP_Connections;
80 105
81/* Send a packet to the TCP connection. 106/* Send a packet to the TCP connection.
@@ -93,7 +118,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, c
93 * return TCP connection number on success. 118 * return TCP connection number on success.
94 * return -1 on failure. 119 * return -1 on failure.
95 */ 120 */
96int get_random_tcp_conn_number(TCP_Connections *tcp_c); 121int get_random_tcp_onion_conn_number(TCP_Connections *tcp_c);
97 122
98/* Send an onion packet via the TCP relay corresponding to tcp_connections_number. 123/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
99 * 124 *
@@ -103,6 +128,15 @@ int get_random_tcp_conn_number(TCP_Connections *tcp_c);
103int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, 128int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data,
104 uint16_t length); 129 uint16_t length);
105 130
131/* Set if we want TCP_connection to allocate some connection for onion use.
132 *
133 * If status is 1, allocate some connections. if status is 0, don't.
134 *
135 * return 0 on success.
136 * return -1 on failure.
137 */
138int set_tcp_onion_status(TCP_Connections *tcp_c, _Bool status);
139
106/* Send an oob packet via the TCP relay corresponding to tcp_connections_number. 140/* Send an oob packet via the TCP relay corresponding to tcp_connections_number.
107 * 141 *
108 * return 0 on success. 142 * return 0 on success.
@@ -140,6 +174,23 @@ int new_tcp_connection_to(TCP_Connections *tcp_c, const uint8_t *public_key, int
140 */ 174 */
141int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); 175int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number);
142 176
177/* Set connection status.
178 *
179 * status of 1 means we are using the connection.
180 * status of 0 means we are not using it.
181 *
182 * Unused tcp connections will be disconnected from but kept in case they are needed.
183 *
184 * return 0 on success.
185 * return -1 on failure.
186 */
187int set_tcp_connection_to_status(TCP_Connections *tcp_c, int connections_number, _Bool status);
188
189/* return number of online tcp relays tied to the connection on success.
190 * return 0 on failure.
191 */
192unsigned int tcp_connection_to_online_tcp_relays(TCP_Connections *tcp_c, int connections_number);
193
143/* Add a TCP relay tied to a connection. 194/* Add a TCP relay tied to a connection.
144 * 195 *
145 * NOTE: This can only be used during the tcp_oob_callback. 196 * NOTE: This can only be used during the tcp_oob_callback.
@@ -172,7 +223,7 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t
172 */ 223 */
173unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); 224unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num);
174 225
175TCP_Connections *new_tcp_connections(DHT *dht); 226TCP_Connections *new_tcp_connections(DHT *dht, TCP_Proxy_Info *proxy_info);
176void do_tcp_connections(TCP_Connections *tcp_c); 227void do_tcp_connections(TCP_Connections *tcp_c);
177void kill_tcp_connections(TCP_Connections *tcp_c); 228void kill_tcp_connections(TCP_Connections *tcp_c);
178 229
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index a364084a..418edcad 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -29,26 +29,16 @@
29 29
30#include "crypto_core.h" 30#include "crypto_core.h"
31 31
32#if crypto_box_PUBLICKEYBYTES != 32
33#error crypto_box_PUBLICKEYBYTES is required to be 32 bytes for public_key_cmp to work,
34#endif
32 35
33/* Use this instead of memcmp; not vulnerable to timing attacks. 36/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
34 returns 0 if both mem locations of length are equal, 37 returns 0 if both mem locations of length are equal,
35 return -1 if they are not. */ 38 return -1 if they are not. */
36int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length) 39int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2)
37{ 40{
38 if (length == 16) { 41 return crypto_verify_32(pk1, pk2);
39 return crypto_verify_16(mem1, mem2);
40 } else if (length == 32) {
41 return crypto_verify_32(mem1, mem2);
42 }
43
44 unsigned int check = 0;
45 size_t i;
46
47 for (i = 0; i < length; ++i) {
48 check |= mem1[i] ^ mem2[i];
49 }
50
51 return (1 & ((check - 1) >> 8)) - 1;
52} 42}
53 43
54/* return a random number. 44/* return a random number.
diff --git a/toxcore/crypto_core.h b/toxcore/crypto_core.h
index decc7fb9..d7306a8a 100644
--- a/toxcore/crypto_core.h
+++ b/toxcore/crypto_core.h
@@ -40,10 +40,10 @@
40 40
41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES) 41#define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES)
42 42
43/* Use this instead of memcmp; not vulnerable to timing attacks. 43/* compare 2 public keys of length crypto_box_PUBLICKEYBYTES, not vulnerable to timing attacks.
44 returns 0 if both mem locations of length are equal, 44 returns 0 if both mem locations of length are equal,
45 return -1 if they are not. */ 45 return -1 if they are not. */
46int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length); 46int public_key_cmp(const uint8_t *pk1, const uint8_t *pk2);
47 47
48/* return a random number. 48/* return a random number.
49 * 49 *
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index 074021da..c13ca949 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -146,6 +146,95 @@ int getfriend_conn_id_pk(Friend_Connections *fr_c, const uint8_t *real_pk)
146 return -1; 146 return -1;
147} 147}
148 148
149/* Add a TCP relay associated to the friend.
150 *
151 * return -1 on failure.
152 * return 0 on success.
153 */
154int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key)
155{
156 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
157
158 if (!friend_con)
159 return -1;
160
161 unsigned int i;
162
163 uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
164
165 for (i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) {
166 if (friend_con->tcp_relays[i].ip_port.ip.family != 0
167 && memcmp(friend_con->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
168 memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format));
169 }
170 }
171
172 friend_con->tcp_relays[index].ip_port = ip_port;
173 memcpy(friend_con->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
174 ++friend_con->tcp_relay_counter;
175
176 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key);
177}
178
179/* Connect to number saved relays for friend. */
180static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_id, unsigned int number)
181{
182 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
183
184 if (!friend_con)
185 return;
186
187 unsigned int i;
188
189 for (i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) {
190 uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS;
191
192 if (friend_con->tcp_relays[index].ip_port.ip.family) {
193 if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port,
194 friend_con->tcp_relays[index].public_key) == 0) {
195 --number;
196 }
197 }
198 }
199}
200
201static unsigned int send_relays(Friend_Connections *fr_c, int friendcon_id)
202{
203 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
204
205 if (!friend_con)
206 return 0;
207
208 Node_format nodes[MAX_SHARED_RELAYS];
209 uint8_t data[1024];
210 int n, length;
211
212 n = copy_connected_tcp_relays(fr_c->net_crypto, nodes, MAX_SHARED_RELAYS);
213
214 unsigned int i;
215
216 for (i = 0; i < n; ++i) {
217 /* Associated the relays being sent with this connection.
218 On receiving the peer will do the same which will establish the connection. */
219 friend_add_tcp_relay(fr_c, friendcon_id, nodes[i].ip_port, nodes[i].public_key);
220 }
221
222 length = pack_nodes(data + 1, sizeof(data) - 1, nodes, n);
223
224 if (length <= 0)
225 return 0;
226
227 data[0] = PACKET_ID_SHARE_RELAYS;
228 ++length;
229
230 if (write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, data, length, 0) != -1) {
231 friend_con->share_relays_lastsent = unix_time();
232 return 1;
233 }
234
235 return 0;
236}
237
149/* callback for recv TCP relay nodes. */ 238/* callback for recv TCP relay nodes. */
150static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key) 239static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_port, const uint8_t *public_key)
151{ 240{
@@ -156,7 +245,7 @@ static int tcp_relay_node_callback(void *object, uint32_t number, IP_Port ip_por
156 return -1; 245 return -1;
157 246
158 if (friend_con->crypt_connection_id != -1) { 247 if (friend_con->crypt_connection_id != -1) {
159 return add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, public_key); 248 return friend_add_tcp_relay(fr_c, number, ip_port, public_key);
160 } else { 249 } else {
161 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key); 250 return add_tcp_relay(fr_c->net_crypto, ip_port, public_key);
162 } 251 }
@@ -181,19 +270,14 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port)
181 friend_con->dht_ip_port_lastrecv = unix_time(); 270 friend_con->dht_ip_port_lastrecv = unix_time();
182} 271}
183 272
184/* Callback for dht public key changes. */ 273static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
185static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
186{ 274{
187 Friend_Connections *fr_c = object; 275 Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);
188 Friend_Conn *friend_con = get_conn(fr_c, number);
189 276
190 if (!friend_con) 277 if (!friend_con)
191 return; 278 return;
192 279
193 friend_con->dht_ping_lastrecv = unix_time(); 280 friend_con->dht_pk_lastrecv = unix_time();
194
195 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
196 return;
197 281
198 if (friend_con->dht_lock) { 282 if (friend_con->dht_lock) {
199 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) { 283 if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
@@ -204,15 +288,7 @@ static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_pub
204 friend_con->dht_lock = 0; 288 friend_con->dht_lock = 0;
205 } 289 }
206 290
207 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, object, number, &friend_con->dht_lock); 291 DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock);
208
209 if (friend_con->crypt_connection_id == -1) {
210 friend_new_connection(fr_c, number);
211 }
212
213 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, dht_public_key);
214 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
215
216 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES); 292 memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
217} 293}
218 294
@@ -230,11 +306,12 @@ static int handle_status(void *object, int number, uint8_t status)
230 call_cb = 1; 306 call_cb = 1;
231 friend_con->status = FRIENDCONN_STATUS_CONNECTED; 307 friend_con->status = FRIENDCONN_STATUS_CONNECTED;
232 friend_con->ping_lastrecv = unix_time(); 308 friend_con->ping_lastrecv = unix_time();
309 friend_con->share_relays_lastsent = 0;
233 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 310 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
234 } else { /* Went offline. */ 311 } else { /* Went offline. */
235 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) { 312 if (friend_con->status != FRIENDCONN_STATUS_CONNECTING) {
236 call_cb = 1; 313 call_cb = 1;
237 friend_con->dht_ping_lastrecv = unix_time(); 314 friend_con->dht_pk_lastrecv = unix_time();
238 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status); 315 onion_set_friend_online(fr_c->onion_c, friend_con->onion_friendnum, status);
239 } 316 }
240 317
@@ -255,6 +332,31 @@ static int handle_status(void *object, int number, uint8_t status)
255 return 0; 332 return 0;
256} 333}
257 334
335/* Callback for dht public key changes. */
336static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
337{
338 Friend_Connections *fr_c = object;
339 Friend_Conn *friend_con = get_conn(fr_c, number);
340
341 if (!friend_con)
342 return;
343
344 if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
345 return;
346
347 change_dht_pk(fr_c, number, dht_public_key);
348
349 /* if pk changed, create a new connection.*/
350 if (friend_con->crypt_connection_id != -1) {
351 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
352 friend_con->crypt_connection_id = -1;
353 handle_status(object, number, 0); /* Going offline. */
354 }
355
356 friend_new_connection(fr_c, number);
357 onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);
358}
359
258static int handle_packet(void *object, int number, uint8_t *data, uint16_t length) 360static int handle_packet(void *object, int number, uint8_t *data, uint16_t length)
259{ 361{
260 if (length == 0) 362 if (length == 0)
@@ -263,18 +365,30 @@ static int handle_packet(void *object, int number, uint8_t *data, uint16_t lengt
263 Friend_Connections *fr_c = object; 365 Friend_Connections *fr_c = object;
264 Friend_Conn *friend_con = get_conn(fr_c, number); 366 Friend_Conn *friend_con = get_conn(fr_c, number);
265 367
368 if (!friend_con)
369 return -1;
370
266 if (data[0] == PACKET_ID_FRIEND_REQUESTS) { 371 if (data[0] == PACKET_ID_FRIEND_REQUESTS) {
267 if (fr_c->fr_request_callback) 372 if (fr_c->fr_request_callback)
268 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); 373 fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length);
269 374
270 return 0; 375 return 0;
271 } 376 } else if (data[0] == PACKET_ID_ALIVE) {
377 friend_con->ping_lastrecv = unix_time();
378 return 0;
379 } else if (data[0] == PACKET_ID_SHARE_RELAYS) {
380 Node_format nodes[MAX_SHARED_RELAYS];
381 int n;
272 382
273 if (!friend_con) 383 if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1)
274 return -1; 384 return -1;
385
386 int j;
387
388 for (j = 0; j < n; j++) {
389 friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key);
390 }
275 391
276 if (data[0] == PACKET_ID_ALIVE) {
277 friend_con->ping_lastrecv = unix_time();
278 return 0; 392 return 0;
279 } 393 }
280 394
@@ -333,6 +447,11 @@ static int handle_new_connections(void *object, New_Connection *n_c)
333 return -1; 447 return -1;
334 448
335 int id = accept_crypto_connection(fr_c->net_crypto, n_c); 449 int id = accept_crypto_connection(fr_c->net_crypto, n_c);
450
451 if (id == -1) {
452 return -1;
453 }
454
336 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id); 455 connection_status_handler(fr_c->net_crypto, id, &handle_status, fr_c, friendcon_id);
337 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id); 456 connection_data_handler(fr_c->net_crypto, id, &handle_packet, fr_c, friendcon_id);
338 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); 457 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id);
@@ -345,7 +464,9 @@ static int handle_new_connections(void *object, New_Connection *n_c)
345 friend_con->dht_ip_port_lastrecv = unix_time(); 464 friend_con->dht_ip_port_lastrecv = unix_time();
346 } 465 }
347 466
348 dht_pk_callback(fr_c, friendcon_id, n_c->dht_public_key); 467 if (memcmp(friend_con->dht_temp_pk, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES) != 0) {
468 change_dht_pk(fr_c, friendcon_id, n_c->dht_public_key);
469 }
349 470
350 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id); 471 nc_dht_pk_callback(fr_c->net_crypto, id, &dht_pk_callback, fr_c, friendcon_id);
351 return 0; 472 return 0;
@@ -365,7 +486,12 @@ static int friend_new_connection(Friend_Connections *fr_c, int friendcon_id)
365 return -1; 486 return -1;
366 } 487 }
367 488
368 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key); 489 /* If dht_temp_pk does not contains a pk. */
490 if (!friend_con->dht_lock) {
491 return -1;
492 }
493
494 int id = new_crypto_connection(fr_c->net_crypto, friend_con->real_public_key, friend_con->dht_temp_pk);
369 495
370 if (id == -1) 496 if (id == -1)
371 return -1; 497 return -1;
@@ -632,10 +758,20 @@ Friend_Connections *new_friend_connections(Onion_Client *onion_c)
632 temp->onion_c = onion_c; 758 temp->onion_c = onion_c;
633 759
634 new_connection_handler(temp->net_crypto, &handle_new_connections, temp); 760 new_connection_handler(temp->net_crypto, &handle_new_connections, temp);
761 LANdiscovery_init(temp->dht);
635 762
636 return temp; 763 return temp;
637} 764}
638 765
766/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
767static void LANdiscovery(Friend_Connections *fr_c)
768{
769 if (fr_c->last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) {
770 send_LANdiscovery(htons(TOX_PORT_DEFAULT), fr_c->dht);
771 fr_c->last_LANdiscovery = unix_time();
772 }
773}
774
639/* main friend_connections loop. */ 775/* main friend_connections loop. */
640void do_friend_connections(Friend_Connections *fr_c) 776void do_friend_connections(Friend_Connections *fr_c)
641{ 777{
@@ -647,7 +783,7 @@ void do_friend_connections(Friend_Connections *fr_c)
647 783
648 if (friend_con) { 784 if (friend_con) {
649 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) { 785 if (friend_con->status == FRIENDCONN_STATUS_CONNECTING) {
650 if (friend_con->dht_ping_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { 786 if (friend_con->dht_pk_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) {
651 if (friend_con->dht_lock) { 787 if (friend_con->dht_lock) {
652 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock); 788 DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock);
653 friend_con->dht_lock = 0; 789 friend_con->dht_lock = 0;
@@ -660,8 +796,8 @@ void do_friend_connections(Friend_Connections *fr_c)
660 796
661 if (friend_con->dht_lock) { 797 if (friend_con->dht_lock) {
662 if (friend_new_connection(fr_c, i) == 0) { 798 if (friend_new_connection(fr_c, i) == 0) {
663 set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_temp_pk);
664 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port); 799 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port);
800 connect_to_saved_tcp_relays(fr_c, i, (MAX_FRIEND_TCP_CONNECTIONS / 2)); /* Only fill it half up. */
665 } 801 }
666 } 802 }
667 803
@@ -670,6 +806,10 @@ void do_friend_connections(Friend_Connections *fr_c)
670 send_ping(fr_c, i); 806 send_ping(fr_c, i);
671 } 807 }
672 808
809 if (friend_con->share_relays_lastsent + SHARE_RELAYS_INTERVAL < temp_time) {
810 send_relays(fr_c, i);
811 }
812
673 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { 813 if (friend_con->ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
674 /* If we stopped receiving ping packets, kill it. */ 814 /* If we stopped receiving ping packets, kill it. */
675 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id); 815 crypto_kill(fr_c->net_crypto, friend_con->crypt_connection_id);
@@ -679,6 +819,8 @@ void do_friend_connections(Friend_Connections *fr_c)
679 } 819 }
680 } 820 }
681 } 821 }
822
823 LANdiscovery(fr_c);
682} 824}
683 825
684/* Free everything related with friend_connections. */ 826/* Free everything related with friend_connections. */
@@ -693,5 +835,6 @@ void kill_friend_connections(Friend_Connections *fr_c)
693 kill_friend_connection(fr_c, i); 835 kill_friend_connection(fr_c, i);
694 } 836 }
695 837
838 LANdiscovery_kill(fr_c->dht);
696 free(fr_c); 839 free(fr_c);
697} 840}
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h
index b814eb0c..baca4b76 100644
--- a/toxcore/friend_connection.h
+++ b/toxcore/friend_connection.h
@@ -36,6 +36,7 @@
36#define GROUPCHAT_CALLBACK_INDEX 1 36#define GROUPCHAT_CALLBACK_INDEX 1
37 37
38#define PACKET_ID_ALIVE 16 38#define PACKET_ID_ALIVE 16
39#define PACKET_ID_SHARE_RELAYS 17
39#define PACKET_ID_FRIEND_REQUESTS 18 40#define PACKET_ID_FRIEND_REQUESTS 18
40 41
41/* Interval between the sending of ping packets. */ 42/* Interval between the sending of ping packets. */
@@ -47,6 +48,14 @@
47/* Time before friend is removed from the DHT after last hearing about him. */ 48/* Time before friend is removed from the DHT after last hearing about him. */
48#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT 49#define FRIEND_DHT_TIMEOUT BAD_NODE_TIMEOUT
49 50
51#define FRIEND_MAX_STORED_TCP_RELAYS (MAX_FRIEND_TCP_CONNECTIONS * 4)
52
53/* Max number of tcp relays sent to friends */
54#define MAX_SHARED_RELAYS (RECOMMENDED_FRIEND_TCP_CONNECTIONS)
55
56/* Interval between the sending of tcp relay information */
57#define SHARE_RELAYS_INTERVAL (5 * 60)
58
50 59
51enum { 60enum {
52 FRIENDCONN_STATUS_NONE, 61 FRIENDCONN_STATUS_NONE,
@@ -61,12 +70,13 @@ typedef struct {
61 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES]; 70 uint8_t dht_temp_pk[crypto_box_PUBLICKEYBYTES];
62 uint16_t dht_lock; 71 uint16_t dht_lock;
63 IP_Port dht_ip_port; 72 IP_Port dht_ip_port;
64 uint64_t dht_ping_lastrecv, dht_ip_port_lastrecv; 73 uint64_t dht_pk_lastrecv, dht_ip_port_lastrecv;
65 74
66 int onion_friendnum; 75 int onion_friendnum;
67 int crypt_connection_id; 76 int crypt_connection_id;
68 77
69 uint64_t ping_lastrecv, ping_lastsent; 78 uint64_t ping_lastrecv, ping_lastsent;
79 uint64_t share_relays_lastsent;
70 80
71 struct { 81 struct {
72 int (*status_callback)(void *object, int id, uint8_t status); 82 int (*status_callback)(void *object, int id, uint8_t status);
@@ -83,6 +93,9 @@ typedef struct {
83 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS]; 93 } callbacks[MAX_FRIEND_CONNECTION_CALLBACKS];
84 94
85 uint16_t lock_count; 95 uint16_t lock_count;
96
97 Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS];
98 uint16_t tcp_relay_counter;
86} Friend_Conn; 99} Friend_Conn;
87 100
88 101
@@ -96,6 +109,8 @@ typedef struct {
96 109
97 int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len); 110 int (*fr_request_callback)(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t len);
98 void *fr_request_object; 111 void *fr_request_object;
112
113 uint64_t last_LANdiscovery;
99} Friend_Connections; 114} Friend_Connections;
100 115
101/* return friendcon_id corresponding to the real public key on success. 116/* return friendcon_id corresponding to the real public key on success.
@@ -127,6 +142,13 @@ int get_friendcon_public_keys(uint8_t *real_pk, uint8_t *dht_temp_pk, Friend_Con
127 */ 142 */
128void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk); 143void set_dht_temp_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_temp_pk);
129 144
145/* Add a TCP relay associated to the friend.
146 *
147 * return -1 on failure.
148 * return 0 on success.
149 */
150int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_port, const uint8_t *public_key);
151
130/* Set the callbacks for the friend connection. 152/* Set the callbacks for the friend connection.
131 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array. 153 * index is the index (0 to (MAX_FRIEND_CONNECTION_CALLBACKS - 1)) we want the callback to set in the array.
132 * 154 *
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 3e596a5f..0ed855bb 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -35,7 +35,16 @@
35 35
36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id) 36static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_connection_id)
37{ 37{
38 return (uint32_t)crypt_connection_id >= c->crypto_connections_length; 38 if ((uint32_t)crypt_connection_id >= c->crypto_connections_length)
39 return 1;
40
41 if (c->crypto_connections == NULL)
42 return 1;
43
44 if (c->crypto_connections[crypt_connection_id].status == CRYPTO_CONN_NO_CONNECTION)
45 return 1;
46
47 return 0;
39} 48}
40 49
41/* cookie timeout in seconds */ 50/* cookie timeout in seconds */
@@ -206,8 +215,7 @@ static int udp_handle_cookie_request(void *object, IP_Port source, const uint8_t
206 215
207/* Handle the cookie request packet (for TCP) 216/* Handle the cookie request packet (for TCP)
208 */ 217 */
209static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, uint8_t conn_id, 218static int tcp_handle_cookie_request(Net_Crypto *c, int connections_number, const uint8_t *packet, uint16_t length)
210 const uint8_t *packet, uint16_t length)
211{ 219{
212 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 220 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
213 uint8_t shared_key[crypto_box_BEFORENMBYTES]; 221 uint8_t shared_key[crypto_box_BEFORENMBYTES];
@@ -221,15 +229,13 @@ static int tcp_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection
221 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 229 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
222 return -1; 230 return -1;
223 231
224 if (send_data(TCP_con, conn_id, data, sizeof(data)) != 1) 232 int ret = send_packet_tcp_connection(c->tcp_c, connections_number, data, sizeof(data));
225 return -1; 233 return ret;
226
227 return 0;
228} 234}
229 235
230/* Handle the cookie request packet (for TCP oob packets) 236/* Handle the cookie request packet (for TCP oob packets)
231 */ 237 */
232static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connection *TCP_con, 238static int tcp_oob_handle_cookie_request(const Net_Crypto *c, unsigned int tcp_connections_number,
233 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length) 239 const uint8_t *dht_public_key, const uint8_t *packet, uint16_t length)
234{ 240{
235 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH]; 241 uint8_t request_plain[COOKIE_REQUEST_PLAIN_LENGTH];
@@ -247,10 +253,8 @@ static int tcp_oob_handle_cookie_request(const Net_Crypto *c, TCP_Client_Connect
247 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data)) 253 if (create_cookie_response(c, data, request_plain, shared_key, dht_public_key) != sizeof(data))
248 return -1; 254 return -1;
249 255
250 if (send_oob_packet(TCP_con, dht_public_key, data, sizeof(data)) != 1) 256 int ret = tcp_send_oob_packet(c->tcp_c, tcp_connections_number, dht_public_key, data, sizeof(data));
251 return -1; 257 return ret;
252
253 return 0;
254} 258}
255 259
256/* Handle a cookie response packet of length encrypted with shared_key. 260/* Handle a cookie response packet of length encrypted with shared_key.
@@ -346,7 +350,7 @@ static int handle_crypto_handshake(const Net_Crypto *c, uint8_t *nonce, uint8_t
346 return -1; 350 return -1;
347 351
348 if (expected_real_pk) 352 if (expected_real_pk)
349 if (crypto_cmp(cookie_plain, expected_real_pk, crypto_box_PUBLICKEYBYTES) != 0) 353 if (public_key_cmp(cookie_plain, expected_real_pk) != 0)
350 return -1; 354 return -1;
351 355
352 uint8_t cookie_hash[crypto_hash_sha512_BYTES]; 356 uint8_t cookie_hash[crypto_hash_sha512_BYTES];
@@ -400,12 +404,17 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
400 404
401 //TODO: on bad networks, direct connections might not last indefinitely. 405 //TODO: on bad networks, direct connections might not last indefinitely.
402 if (conn->ip_port.ip.family != 0) { 406 if (conn->ip_port.ip.family != 0) {
403 uint8_t direct_connected = 0; 407 _Bool direct_connected = 0;
404 crypto_connection_status(c, crypt_connection_id, &direct_connected); 408 crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL);
405 409
406 if (direct_connected && (uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { 410 if (direct_connected) {
407 pthread_mutex_unlock(&conn->mutex); 411 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) {
408 return 0; 412 pthread_mutex_unlock(&conn->mutex);
413 return 0;
414 } else {
415 pthread_mutex_unlock(&conn->mutex);
416 return -1;
417 }
409 } 418 }
410 419
411 //TODO: a better way of sending packets directly to confirm the others ip. 420 //TODO: a better way of sending packets directly to confirm the others ip.
@@ -413,61 +422,14 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
413 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) 422 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length)
414 direct_send_attempt = 1; 423 direct_send_attempt = 1;
415 } 424 }
416
417 } 425 }
418 426
419 pthread_mutex_unlock(&conn->mutex); 427 pthread_mutex_unlock(&conn->mutex);
428 pthread_mutex_lock(&c->tcp_mutex);
429 int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
430 pthread_mutex_unlock(&c->tcp_mutex);
420 431
421 //TODO: detect and kill bad relays. 432 if (ret == 0 || direct_send_attempt) {
422 uint32_t i;
423
424 unsigned int r;
425
426 if (!conn->last_relay_sentto) {
427 r = rand();
428 } else {
429 r = conn->last_relay_sentto - 1;
430 }
431
432 if (conn->num_tcp_online) {
433 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
434 pthread_mutex_lock(&c->tcp_mutex);
435
436 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
437 int ret = 0;
438
439 if (conn->status_tcp[tcp_index] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
440 ret = send_data(c->tcp_connections[tcp_index], conn->con_number_tcp[tcp_index], data, length);
441 }
442
443 pthread_mutex_unlock(&c->tcp_mutex);
444
445 if (ret == 1) {
446 conn->last_relay_sentto = tcp_index + 1;
447 return 0;
448 }
449 }
450 }
451
452 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
453 pthread_mutex_lock(&c->tcp_mutex);
454
455 unsigned int tcp_index = (i + r) % MAX_TCP_CONNECTIONS;
456 int ret = 0;
457
458 if (conn->status_tcp[tcp_index] == STATUS_TCP_INVISIBLE) {
459 ret = send_oob_packet(c->tcp_connections[tcp_index], conn->dht_public_key, data, length);
460 }
461
462 pthread_mutex_unlock(&c->tcp_mutex);
463
464 if (ret == 1) {
465 conn->last_relay_sentto = tcp_index + 1;
466 return 0;
467 }
468 }
469
470 if (direct_send_attempt) {
471 return 0; 433 return 0;
472 } 434 }
473 435
@@ -1136,13 +1098,26 @@ static int send_kill_packet(Net_Crypto *c, int crypt_connection_id)
1136 &kill_packet, sizeof(kill_packet)); 1098 &kill_packet, sizeof(kill_packet));
1137} 1099}
1138 1100
1101static void connection_kill(Net_Crypto *c, int crypt_connection_id)
1102{
1103 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1104
1105 if (conn == 0)
1106 return;
1107
1108 if (conn->connection_status_callback) {
1109 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
1110 }
1111
1112 crypto_kill(c, crypt_connection_id);
1113}
1114
1139/* Handle a received data packet. 1115/* Handle a received data packet.
1140 * 1116 *
1141 * return -1 on failure. 1117 * return -1 on failure.
1142 * return 0 on success. 1118 * return 0 on success.
1143 */ 1119 */
1144static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, 1120static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, const uint8_t *packet, uint16_t length)
1145 uint16_t length)
1146{ 1121{
1147 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE) 1122 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
1148 return -1; 1123 return -1;
@@ -1179,7 +1154,7 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
1179 } 1154 }
1180 1155
1181 if (real_data[0] == PACKET_ID_KILL) { 1156 if (real_data[0] == PACKET_ID_KILL) {
1182 conn->killed = 1; 1157 connection_kill(c, crypt_connection_id);
1183 return 0; 1158 return 0;
1184 } 1159 }
1185 1160
@@ -1294,19 +1269,19 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons
1294 packet, length, conn->public_key) != 0) 1269 packet, length, conn->public_key) != 0)
1295 return -1; 1270 return -1;
1296 1271
1297 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1272 if (public_key_cmp(dht_public_key, conn->dht_public_key) == 0) {
1298 1273 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1299 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1300 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1301 return -1;
1302 }
1303 1274
1304 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1275 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1305 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1276 if (create_send_handshake(c, crypt_connection_id, cookie, dht_public_key) != 0)
1306 set_connection_dht_public_key(c, crypt_connection_id, dht_public_key); 1277 return -1;
1278 }
1307 1279
1308 if (conn->dht_pk_callback) 1280 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1309 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key); 1281 } else {
1282 if (conn->dht_pk_callback)
1283 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, dht_public_key);
1284 }
1310 1285
1311 } else { 1286 } else {
1312 return -1; 1287 return -1;
@@ -1448,31 +1423,12 @@ static int getcryptconnection_id(const Net_Crypto *c, const uint8_t *public_key)
1448 return -1; 1423 return -1;
1449} 1424}
1450 1425
1451/* Get crypto connection id from public key of peer.
1452 *
1453 * return -1 if there are no connections like we are looking for.
1454 * return id if it found it.
1455 */
1456static int getcryptconnection_id_dht_pubkey(const Net_Crypto *c, const uint8_t *dht_public_key)
1457{
1458 uint32_t i;
1459
1460 for (i = 0; i < c->crypto_connections_length; ++i) {
1461 if (c->crypto_connections[i].status != CRYPTO_CONN_NO_CONNECTION && c->crypto_connections[i].dht_public_key_set)
1462 if (memcmp(dht_public_key, c->crypto_connections[i].dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1463 return i;
1464 }
1465
1466 return -1;
1467}
1468
1469/* Add a source to the crypto connection. 1426/* Add a source to the crypto connection.
1470 * This is to be used only when we have received a packet from that source. 1427 * This is to be used only when we have received a packet from that source.
1471 * 1428 *
1472 * return -1 on failure. 1429 * return -1 on failure.
1473 * return positive number on success. 1430 * return positive number on success.
1474 * 0 if source was a direct UDP connection. 1431 * 0 if source was a direct UDP connection.
1475 * TODO
1476 */ 1432 */
1477static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source) 1433static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id, IP_Port source)
1478{ 1434{
@@ -1490,8 +1446,11 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1490 conn->ip_port = source; 1446 conn->ip_port = source;
1491 } 1447 }
1492 1448
1493 conn->direct_lastrecv_time = current_time_monotonic(); 1449 conn->direct_lastrecv_time = unix_time();
1494 return 0; 1450 return 0;
1451 } else if (source.ip.family == TCP_FAMILY) {
1452 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0)
1453 return 1;
1495 } 1454 }
1496 1455
1497 return -1; 1456 return -1;
@@ -1537,30 +1496,29 @@ static int handle_new_connection_handshake(Net_Crypto *c, IP_Port source, const
1537 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key); 1496 int crypt_connection_id = getcryptconnection_id(c, n_c.public_key);
1538 1497
1539 if (crypt_connection_id != -1) { 1498 if (crypt_connection_id != -1) {
1540 int ret = -1;
1541 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1499 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1542 1500
1543 if (conn != 0 && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) { 1501 if (public_key_cmp(n_c.dht_public_key, conn->dht_public_key) != 0) {
1544 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES); 1502 connection_kill(c, crypt_connection_id);
1545 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES); 1503 } else {
1546 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1504 int ret = -1;
1547
1548 crypto_connection_add_source(c, crypt_connection_id, source);
1549 1505
1550 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) { 1506 if (conn && (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT)) {
1551 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1507 memcpy(conn->recv_nonce, n_c.recv_nonce, crypto_box_NONCEBYTES);
1552 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ 1508 memcpy(conn->peersessionpublic_key, n_c.peersessionpublic_key, crypto_box_PUBLICKEYBYTES);
1553 set_connection_dht_public_key(c, crypt_connection_id, n_c.dht_public_key); 1509 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1554 1510
1555 if (conn->dht_pk_callback) 1511 crypto_connection_add_source(c, crypt_connection_id, source);
1556 conn->dht_pk_callback(conn->dht_pk_callback_object, conn->dht_pk_callback_number, n_c.dht_public_key);
1557 1512
1558 ret = 0; 1513 if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) == 0) {
1514 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1515 ret = 0;
1516 }
1559 } 1517 }
1560 }
1561 1518
1562 free(n_c.cookie); 1519 free(n_c.cookie);
1563 return ret; 1520 return ret;
1521 }
1564 } 1522 }
1565 1523
1566 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); 1524 int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c);
@@ -1583,9 +1541,16 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1583 if (crypt_connection_id == -1) 1541 if (crypt_connection_id == -1)
1584 return -1; 1542 return -1;
1585 1543
1586 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1544 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1587 1545
1588 if (conn == 0) 1546 if (n_c->cookie_length != COOKIE_LENGTH)
1547 return -1;
1548
1549 pthread_mutex_lock(&c->tcp_mutex);
1550 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id);
1551 pthread_mutex_unlock(&c->tcp_mutex);
1552
1553 if (conn->connection_number_tcp == -1)
1589 return -1; 1554 return -1;
1590 1555
1591 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES); 1556 memcpy(conn->public_key, n_c->public_key, crypto_box_PUBLICKEYBYTES);
@@ -1594,16 +1559,17 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1594 random_nonce(conn->sent_nonce); 1559 random_nonce(conn->sent_nonce);
1595 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1560 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1596 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key); 1561 encrypt_precompute(conn->peersessionpublic_key, conn->sessionsecret_key, conn->shared_key);
1562 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1597 1563
1598 if (n_c->cookie_length != COOKIE_LENGTH) 1564 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) {
1599 return -1; 1565 pthread_mutex_lock(&c->tcp_mutex);
1600 1566 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1601 if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) 1567 pthread_mutex_unlock(&c->tcp_mutex);
1568 conn->status = CRYPTO_CONN_NO_CONNECTION;
1602 return -1; 1569 return -1;
1570 }
1603 1571
1604 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1572 memcpy(conn->dht_public_key, n_c->dht_public_key, crypto_box_PUBLICKEYBYTES);
1605 /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
1606 set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key);
1607 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1573 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1608 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1574 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1609 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1575 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
@@ -1616,7 +1582,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1616 * return -1 on failure. 1582 * return -1 on failure.
1617 * return connection id on success. 1583 * return connection id on success.
1618 */ 1584 */
1619int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) 1585int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key)
1620{ 1586{
1621 int crypt_connection_id = getcryptconnection_id(c, real_public_key); 1587 int crypt_connection_id = getcryptconnection_id(c, real_public_key);
1622 1588
@@ -1628,149 +1594,40 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
1628 if (crypt_connection_id == -1) 1594 if (crypt_connection_id == -1)
1629 return -1; 1595 return -1;
1630 1596
1631 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 1597 Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
1632 1598
1633 if (conn == 0) 1599 if (conn == 0)
1634 return -1; 1600 return -1;
1635 1601
1602 pthread_mutex_lock(&c->tcp_mutex);
1603 conn->connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
1604 pthread_mutex_unlock(&c->tcp_mutex);
1605
1606 if (conn->connection_number_tcp == -1)
1607 return -1;
1608
1636 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES); 1609 memcpy(conn->public_key, real_public_key, crypto_box_PUBLICKEYBYTES);
1637 random_nonce(conn->sent_nonce); 1610 random_nonce(conn->sent_nonce);
1638 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1611 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1639 conn->status = CRYPTO_CONN_COOKIE_REQUESTING; 1612 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1640 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; 1613 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1641 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; 1614 conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
1642 return crypt_connection_id; 1615 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES);
1643}
1644
1645/* Set the status for the TCP connection for conn in location to status.
1646 */
1647static void set_conn_tcp_status(Crypto_Connection *conn, unsigned int location, unsigned int status)
1648{
1649 if (conn->status_tcp[location] == status) {
1650 return;
1651 }
1652
1653 if (conn->status_tcp[location] == STATUS_TCP_ONLINE) {
1654 --conn->num_tcp_online;
1655 }
1656
1657 if (status == STATUS_TCP_ONLINE) {
1658 ++conn->num_tcp_online;
1659 }
1660
1661 conn->status_tcp[location] = status;
1662}
1663
1664/* Disconnect peer from all associated TCP connections.
1665 *
1666 * return -1 on failure.
1667 * return 0 on success.
1668 */
1669static int disconnect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1670{
1671 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1672
1673 if (conn == 0)
1674 return -1;
1675
1676 uint32_t i;
1677
1678 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1679 if (conn->status_tcp[i] != STATUS_TCP_NULL) {
1680 pthread_mutex_lock(&c->tcp_mutex);
1681 send_disconnect_request(c->tcp_connections[i], conn->con_number_tcp[i]);
1682 set_conn_tcp_status(conn, i, STATUS_TCP_NULL);
1683 conn->con_number_tcp[i] = 0;
1684 pthread_mutex_unlock(&c->tcp_mutex);
1685 }
1686 }
1687
1688 return 0;
1689}
1690
1691/* Connect peer to all associated TCP connections.
1692 *
1693 * return -1 on failure.
1694 * return 0 on success.
1695 */
1696static int connect_peer_tcp(Net_Crypto *c, int crypt_connection_id)
1697{
1698 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1699
1700 if (conn == 0)
1701 return -1;
1702
1703 uint32_t i;
1704 1616
1705 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1617 conn->cookie_request_number = random_64b();
1706 if (c->tcp_connections[i] == NULL) 1618 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1707 continue;
1708 1619
1620 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1621 conn->shared_key) != sizeof(cookie_request)
1622 || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) {
1709 pthread_mutex_lock(&c->tcp_mutex); 1623 pthread_mutex_lock(&c->tcp_mutex);
1710 //TODO check function return? 1624 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
1711 send_routing_request(c->tcp_connections[i], conn->dht_public_key);
1712 pthread_mutex_unlock(&c->tcp_mutex); 1625 pthread_mutex_unlock(&c->tcp_mutex);
1713 } 1626 conn->status = CRYPTO_CONN_NO_CONNECTION;
1714
1715 return 0;
1716}
1717
1718/* Copy friends DHT public key into dht_key.
1719 *
1720 * return 0 on failure (no key copied).
1721 * return 1 on success (key copied).
1722 */
1723unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key)
1724{
1725 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1726
1727 if (conn == 0)
1728 return 0;
1729
1730 if (conn->dht_public_key_set == 0)
1731 return 0;
1732
1733 memcpy(dht_public_key, conn->dht_public_key, crypto_box_PUBLICKEYBYTES);
1734 return 1;
1735}
1736
1737
1738/* Set the DHT public key of the crypto connection.
1739 *
1740 * return -1 on failure.
1741 * return 0 on success.
1742 */
1743int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key)
1744{
1745 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1746
1747 if (conn == 0)
1748 return -1;
1749
1750 if (conn->dht_public_key_set == 1 && memcmp(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
1751 return -1; 1627 return -1;
1752
1753 if (conn->dht_public_key_set == 1) {
1754 disconnect_peer_tcp(c, crypt_connection_id);
1755 } 1628 }
1756 1629
1757 memcpy(conn->dht_public_key, dht_public_key, crypto_box_PUBLICKEYBYTES); 1630 return crypt_connection_id;
1758 conn->dht_public_key_set = 1;
1759
1760 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING) {
1761 conn->cookie_request_number = random_64b();
1762 uint8_t cookie_request[COOKIE_REQUEST_LENGTH];
1763
1764 if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
1765 conn->shared_key) != sizeof(cookie_request))
1766 return -1;
1767
1768 if (new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0)
1769 return -1;
1770 }//TODO
1771
1772 connect_peer_tcp(c, crypt_connection_id);
1773 return 0;
1774} 1631}
1775 1632
1776/* Set the direct ip of the crypto connection. 1633/* Set the direct ip of the crypto connection.
@@ -1789,8 +1646,13 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1789 return -1; 1646 return -1;
1790 1647
1791 if (!ipport_equal(&ip_port, &conn->ip_port)) { 1648 if (!ipport_equal(&ip_port, &conn->ip_port)) {
1792 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) { 1649 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) {
1793 if (LAN_ip(ip_port.ip) == 0 && LAN_ip(conn->ip_port.ip) == 0 && conn->ip_port.port == ip_port.port) 1650 /* We already know a LAN ip, no need to switch. */
1651 if (LAN_ip(conn->ip_port.ip) == 0)
1652 return -1;
1653
1654 /* Prefer ipv6. */
1655 if (conn->ip_port.ip.family == AF_INET6 && ip_port.ip.family == AF_INET)
1794 return -1; 1656 return -1;
1795 } 1657 }
1796 1658
@@ -1805,93 +1667,25 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
1805 return -1; 1667 return -1;
1806} 1668}
1807 1669
1808static int tcp_response_callback(void *object, uint8_t connection_id, const uint8_t *public_key)
1809{
1810 TCP_Client_Connection *TCP_con = object;
1811 Net_Crypto *c = TCP_con->net_crypto_pointer;
1812
1813 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1814
1815 if (crypt_connection_id == -1)
1816 return -1;
1817
1818 set_tcp_connection_number(TCP_con, connection_id, crypt_connection_id);
1819
1820 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1821
1822 if (conn == 0)
1823 return -1;
1824 1670
1825 uint32_t location = TCP_con->net_crypto_location; 1671static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t length)
1826
1827 if (location >= MAX_TCP_CONNECTIONS)
1828 return -1;
1829
1830 if (c->tcp_connections[location] != TCP_con)
1831 return -1;
1832
1833 conn->con_number_tcp[location] = connection_id;
1834 uint32_t i;
1835
1836 for (i = 0; i < conn->num_tcp_relays; ++i) {
1837 if (memcmp(TCP_con->public_key, conn->tcp_relays[i].public_key, crypto_box_PUBLICKEYBYTES) == 0) {
1838 set_conn_tcp_status(conn, location, STATUS_TCP_INVISIBLE);
1839 return 0;
1840 }
1841 }
1842
1843 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1844 return 0;
1845}
1846
1847static int tcp_status_callback(void *object, uint32_t number, uint8_t connection_id, uint8_t status)
1848{ 1672{
1849 TCP_Client_Connection *TCP_con = object; 1673 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1850 Net_Crypto *c = TCP_con->net_crypto_pointer;
1851
1852 Crypto_Connection *conn = get_crypto_connection(c, number);
1853
1854 if (conn == 0)
1855 return -1;
1856
1857 uint32_t location = TCP_con->net_crypto_location;
1858
1859 if (location >= MAX_TCP_CONNECTIONS)
1860 return -1;
1861
1862 if (c->tcp_connections[location] != TCP_con)
1863 return -1; 1674 return -1;
1864 1675
1865 if (status == 1) { 1676 Net_Crypto *c = object;
1866 set_conn_tcp_status(conn, location, STATUS_TCP_OFFLINE);
1867 } else if (status == 2) {
1868 set_conn_tcp_status(conn, location, STATUS_TCP_ONLINE);
1869 }
1870
1871 conn->con_number_tcp[location] = connection_id;
1872 return 0;
1873}
1874 1677
1875static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length) 1678 Crypto_Connection *conn = get_crypto_connection(c, id);
1876{
1877 1679
1878 if (length == 0) 1680 if (conn == 0)
1879 return -1; 1681 return -1;
1880 1682
1881 TCP_Client_Connection *TCP_con = object;
1882 Net_Crypto *c = TCP_con->net_crypto_pointer;
1883
1884 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1683 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1885 return tcp_handle_cookie_request(c, TCP_con, connection_id, data, length); 1684 return tcp_handle_cookie_request(c, conn->connection_number_tcp, data, length);
1886 } 1685 }
1887 1686
1888 Crypto_Connection *conn = get_crypto_connection(c, number);
1889
1890 if (conn == 0)
1891 return -1;
1892
1893 pthread_mutex_unlock(&c->tcp_mutex); 1687 pthread_mutex_unlock(&c->tcp_mutex);
1894 int ret = handle_packet_connection(c, number, data, length); 1688 int ret = handle_packet_connection(c, id, data, length);
1895 pthread_mutex_lock(&c->tcp_mutex); 1689 pthread_mutex_lock(&c->tcp_mutex);
1896 1690
1897 if (ret != 0) 1691 if (ret != 0)
@@ -1901,92 +1695,29 @@ static int tcp_data_callback(void *object, uint32_t number, uint8_t connection_i
1901 return 0; 1695 return 0;
1902} 1696}
1903 1697
1904static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length) 1698static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned int tcp_connections_number,
1699 const uint8_t *data, uint16_t length)
1905{ 1700{
1906 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE) 1701 if (length == 0 || length > MAX_CRYPTO_PACKET_SIZE)
1907 return -1; 1702 return -1;
1908 1703
1909 TCP_Client_Connection *TCP_con = object; 1704 Net_Crypto *c = object;
1910 Net_Crypto *c = TCP_con->net_crypto_pointer;
1911 uint32_t location = TCP_con->net_crypto_location;
1912 1705
1913 if (data[0] == NET_PACKET_COOKIE_REQUEST) { 1706 if (data[0] == NET_PACKET_COOKIE_REQUEST) {
1914 return tcp_oob_handle_cookie_request(c, TCP_con, public_key, data, length); 1707 return tcp_oob_handle_cookie_request(c, tcp_connections_number, public_key, data, length);
1915 } 1708 } else if (data[0] == NET_PACKET_CRYPTO_HS) {
1916
1917 int crypt_connection_id = getcryptconnection_id_dht_pubkey(c, public_key);
1918
1919 if (crypt_connection_id == -1) {
1920 IP_Port source; 1709 IP_Port source;
1921 source.port = 0; 1710 source.port = 0;
1922 source.ip.family = TCP_FAMILY; 1711 source.ip.family = TCP_FAMILY;
1923 source.ip.ip6.uint32[0] = location; 1712 source.ip.ip6.uint32[0] = tcp_connections_number;
1924
1925 if (data[0] != NET_PACKET_CRYPTO_HS) {
1926 LOGGER_DEBUG("tcp snhappen %u\n", data[0]);
1927 return -1;
1928 }
1929 1713
1930 if (handle_new_connection_handshake(c, source, data, length) != 0) 1714 if (handle_new_connection_handshake(c, source, data, length) != 0)
1931 return -1; 1715 return -1;
1932 1716
1933 return 0; 1717 return 0;
1934 } 1718 } else {
1935
1936 pthread_mutex_unlock(&c->tcp_mutex);
1937 int ret = handle_packet_connection(c, crypt_connection_id, data, length);
1938 pthread_mutex_lock(&c->tcp_mutex);
1939
1940 if (ret != 0)
1941 return -1; 1719 return -1;
1942
1943 return 0;
1944}
1945
1946static int tcp_onion_callback(void *object, const uint8_t *data, uint16_t length)
1947{
1948 Net_Crypto *c = object;
1949
1950 if (c->tcp_onion_callback)
1951 return c->tcp_onion_callback(c->tcp_onion_callback_object, data, length);
1952
1953 return 1;
1954}
1955
1956
1957/* Check if tcp connection to public key can be created.
1958 *
1959 * return -1 if it can't.
1960 * return 0 if it can.
1961 */
1962static int tcp_connection_check(const Net_Crypto *c, const uint8_t *public_key)
1963{
1964 uint32_t i;
1965
1966 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1967 if (c->tcp_connections_new[i] == NULL)
1968 continue;
1969
1970 if (memcmp(c->tcp_connections_new[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1971 return -1;
1972 }
1973
1974 uint32_t num = 0;
1975
1976 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
1977 if (c->tcp_connections[i] == NULL)
1978 continue;
1979
1980 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0)
1981 return -1;
1982
1983 ++num;
1984 } 1720 }
1985
1986 if (num == MAX_TCP_CONNECTIONS)
1987 return -1;
1988
1989 return 0;
1990} 1721}
1991 1722
1992/* Add a tcp relay, associating it to a crypt_connection_id. 1723/* Add a tcp relay, associating it to a crypt_connection_id.
@@ -2001,45 +1732,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2001 if (conn == 0) 1732 if (conn == 0)
2002 return -1; 1733 return -1;
2003 1734
2004 if (ip_port.ip.family == TCP_INET) { 1735 pthread_mutex_lock(&c->tcp_mutex);
2005 ip_port.ip.family = AF_INET; 1736 int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
2006 } else if (ip_port.ip.family == TCP_INET6) { 1737 pthread_mutex_unlock(&c->tcp_mutex);
2007 ip_port.ip.family = AF_INET6; 1738 return ret;
2008 }
2009
2010 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2011 return -1;
2012
2013 uint32_t i;
2014
2015 for (i = 0; i < conn->num_tcp_relays; ++i) {
2016 if (memcmp(conn->tcp_relays[i].public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2017 conn->tcp_relays[i].ip_port = ip_port;
2018 return 0;
2019 }
2020 }
2021
2022 if (conn->num_tcp_relays == MAX_TCP_RELAYS_PEER) {
2023 uint16_t index = rand() % MAX_TCP_RELAYS_PEER;
2024 conn->tcp_relays[index].ip_port = ip_port;
2025 memcpy(conn->tcp_relays[index].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2026 } else {
2027 conn->tcp_relays[conn->num_tcp_relays].ip_port = ip_port;
2028 memcpy(conn->tcp_relays[conn->num_tcp_relays].public_key, public_key, crypto_box_PUBLICKEYBYTES);
2029 ++conn->num_tcp_relays;
2030 }
2031
2032 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2033 if (c->tcp_connections[i] == NULL)
2034 continue;
2035
2036 if (memcmp(c->tcp_connections[i]->public_key, public_key, crypto_box_PUBLICKEYBYTES) == 0) {
2037 if (conn->status_tcp[i] == STATUS_TCP_OFFLINE)
2038 set_conn_tcp_status(conn, i, STATUS_TCP_INVISIBLE);
2039 }
2040 }
2041
2042 return add_tcp_relay(c, ip_port, public_key);
2043} 1739}
2044 1740
2045/* Add a tcp relay to the array. 1741/* Add a tcp relay to the array.
@@ -2049,30 +1745,10 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2049 */ 1745 */
2050int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key) 1746int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2051{ 1747{
2052 if (ip_port.ip.family == TCP_INET) { 1748 pthread_mutex_lock(&c->tcp_mutex);
2053 ip_port.ip.family = AF_INET; 1749 int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
2054 } else if (ip_port.ip.family == TCP_INET6) { 1750 pthread_mutex_unlock(&c->tcp_mutex);
2055 ip_port.ip.family = AF_INET6; 1751 return ret;
2056 }
2057
2058 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6)
2059 return -1;
2060
2061 if (tcp_connection_check(c, public_key) != 0)
2062 return -1;
2063
2064 uint32_t i;
2065
2066 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2067 if (c->tcp_connections_new[i] == NULL) {
2068 c->tcp_connections_new[i] = new_TCP_connection(ip_port, public_key, c->dht->self_public_key, c->dht->self_secret_key,
2069 &c->proxy_info);
2070
2071 return 0;
2072 }
2073 }
2074
2075 return -1;
2076} 1752}
2077 1753
2078/* Return a random TCP connection number for use in send_tcp_onion_request. 1754/* Return a random TCP connection number for use in send_tcp_onion_request.
@@ -2085,47 +1761,25 @@ int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key)
2085 */ 1761 */
2086int get_random_tcp_con_number(Net_Crypto *c) 1762int get_random_tcp_con_number(Net_Crypto *c)
2087{ 1763{
2088 unsigned int i, r = rand(); 1764 pthread_mutex_lock(&c->tcp_mutex);
2089 1765 int ret = get_random_tcp_onion_conn_number(c->tcp_c);
2090 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1766 pthread_mutex_unlock(&c->tcp_mutex);
2091 if (c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS]) {
2092 return (i + r) % MAX_TCP_CONNECTIONS;
2093 }
2094 }
2095 1767
2096 return -1; 1768 return ret;
2097} 1769}
2098 1770
2099/* Send an onion packet via the TCP relay corresponding to TCP_conn_number. 1771/* Send an onion packet via the TCP relay corresponding to tcp_connections_number.
2100 * 1772 *
2101 * return 0 on success. 1773 * return 0 on success.
2102 * return -1 on failure. 1774 * return -1 on failure.
2103 */ 1775 */
2104int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const uint8_t *data, uint16_t length) 1776int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
2105{ 1777{
2106 if (TCP_conn_number > MAX_TCP_CONNECTIONS) { 1778 pthread_mutex_lock(&c->tcp_mutex);
2107 return -1; 1779 int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
2108 } 1780 pthread_mutex_unlock(&c->tcp_mutex);
2109
2110 if (c->tcp_connections[TCP_conn_number]) {
2111 pthread_mutex_lock(&c->tcp_mutex);
2112 int ret = send_onion_request(c->tcp_connections[TCP_conn_number], data, length);
2113 pthread_mutex_unlock(&c->tcp_mutex);
2114
2115 if (ret == 1)
2116 return 0;
2117 }
2118
2119 return -1;
2120}
2121 1781
2122/* Set the function to be called when an onion response packet is received by one of the TCP connections. 1782 return ret;
2123 */
2124void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
2125 uint16_t length), void *object)
2126{
2127 c->tcp_onion_callback = tcp_onion_callback;
2128 c->tcp_onion_callback_object = object;
2129} 1783}
2130 1784
2131/* Copy a maximum of num TCP relays we are connected to to tcp_relays. 1785/* Copy a maximum of num TCP relays we are connected to to tcp_relays.
@@ -2134,173 +1788,47 @@ void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *o
2134 * return number of relays copied to tcp_relays on success. 1788 * return number of relays copied to tcp_relays on success.
2135 * return 0 on failure. 1789 * return 0 on failure.
2136 */ 1790 */
2137unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num) 1791unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
2138{ 1792{
2139 if (num == 0) 1793 if (num == 0)
2140 return 0; 1794 return 0;
2141 1795
2142 uint32_t i; 1796 pthread_mutex_lock(&c->tcp_mutex);
2143 uint16_t copied = 0; 1797 unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
2144 1798 pthread_mutex_unlock(&c->tcp_mutex);
2145 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2146 if (c->tcp_connections[i] != NULL) {
2147 memcpy(tcp_relays[copied].public_key, c->tcp_connections[i]->public_key, crypto_box_PUBLICKEYBYTES);
2148 tcp_relays[copied].ip_port = c->tcp_connections[i]->ip_port;
2149
2150 if (tcp_relays[copied].ip_port.ip.family == AF_INET) {
2151 tcp_relays[copied].ip_port.ip.family = TCP_INET;
2152 } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) {
2153 tcp_relays[copied].ip_port.ip.family = TCP_INET6;
2154 }
2155
2156 ++copied;
2157
2158 if (copied == num)
2159 return copied;
2160 }
2161 }
2162 1799
2163 return copied; 1800 return ret;
2164} 1801}
2165 1802
2166/* Add a connected tcp connection to the tcp_connections array. 1803static void do_tcp(Net_Crypto *c)
2167 *
2168 * return 0 if it was added.
2169 * return -1 if it wasn't.
2170 */
2171static int add_tcp_connected(Net_Crypto *c, TCP_Client_Connection *tcp_con)
2172{ 1804{
2173 uint32_t i; 1805 pthread_mutex_lock(&c->tcp_mutex);
2174 1806 do_tcp_connections(c->tcp_c);
2175 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { 1807 pthread_mutex_unlock(&c->tcp_mutex);
2176 if (c->tcp_connections[i] == NULL)
2177 break;
2178 }
2179
2180 if (i == MAX_TCP_CONNECTIONS)
2181 return -1;
2182 1808
2183 uint32_t tcp_num = i; 1809 uint32_t i;
2184 1810
2185 for (i = 0; i < c->crypto_connections_length; ++i) { 1811 for (i = 0; i < c->crypto_connections_length; ++i) {
2186 Crypto_Connection *conn = get_crypto_connection(c, i); 1812 Crypto_Connection *conn = get_crypto_connection(c, i);
2187 1813
2188 if (conn == 0) 1814 if (conn == 0)
2189 return -1; 1815 return;
2190
2191 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2192 continue;
2193
2194 if (conn->status == CRYPTO_CONN_TIMED_OUT)
2195 continue;
2196
2197 if (conn->dht_public_key_set)
2198 if (send_routing_request(tcp_con, conn->dht_public_key) != 1)
2199 return -1;
2200
2201 }
2202
2203 tcp_con->net_crypto_pointer = c;
2204 tcp_con->net_crypto_location = tcp_num;
2205 routing_response_handler(tcp_con, tcp_response_callback, tcp_con);
2206 routing_status_handler(tcp_con, tcp_status_callback, tcp_con);
2207 routing_data_handler(tcp_con, tcp_data_callback, tcp_con);
2208 oob_data_handler(tcp_con, tcp_oob_callback, tcp_con);
2209 onion_response_handler(tcp_con, tcp_onion_callback, c);
2210 c->tcp_connections[tcp_num] = tcp_con;
2211 return 0;
2212}
2213
2214static void do_tcp(Net_Crypto *c)
2215{
2216 uint32_t i;
2217
2218 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2219 if (c->tcp_connections_new[i] == NULL)
2220 continue;
2221
2222 pthread_mutex_lock(&c->tcp_mutex);
2223 do_TCP_connection(c->tcp_connections_new[i]);
2224 pthread_mutex_unlock(&c->tcp_mutex);
2225 1816
2226 if (c->tcp_connections_new[i]->status == TCP_CLIENT_CONFIRMED) { 1817 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
2227 pthread_mutex_lock(&c->tcp_mutex); 1818 _Bool direct_connected = 0;
2228 int ret = add_tcp_connected(c, c->tcp_connections_new[i]); 1819 crypto_connection_status(c, i, &direct_connected, NULL);
2229 pthread_mutex_unlock(&c->tcp_mutex);
2230 1820
2231 if (ret == 0) { 1821 if (direct_connected) {
2232 c->tcp_connections_new[i] = NULL; 1822 pthread_mutex_lock(&c->tcp_mutex);
1823 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 0);
1824 pthread_mutex_unlock(&c->tcp_mutex);
2233 } else { 1825 } else {
2234 kill_TCP_connection(c->tcp_connections_new[i]); 1826 pthread_mutex_lock(&c->tcp_mutex);
2235 c->tcp_connections_new[i] = NULL; 1827 set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, 1);
1828 pthread_mutex_unlock(&c->tcp_mutex);
2236 } 1829 }
2237 } 1830 }
2238 } 1831 }
2239
2240 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2241 if (c->tcp_connections[i] == NULL)
2242 continue;
2243
2244 pthread_mutex_lock(&c->tcp_mutex);
2245 do_TCP_connection(c->tcp_connections[i]);
2246 pthread_mutex_unlock(&c->tcp_mutex);
2247 }
2248}
2249
2250static void clear_disconnected_tcp_peer(Crypto_Connection *conn, uint32_t number)
2251{
2252 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2253 return;
2254
2255 if (number >= MAX_TCP_CONNECTIONS)
2256 return;
2257
2258 set_conn_tcp_status(conn, number, STATUS_TCP_NULL);
2259 conn->con_number_tcp[number] = 0;
2260}
2261
2262static void clear_disconnected_tcp(Net_Crypto *c)
2263{
2264 uint32_t i, j;
2265
2266 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2267 if (c->tcp_connections_new[i] == NULL)
2268 continue;
2269
2270 if (c->tcp_connections_new[i]->status != TCP_CLIENT_DISCONNECTED)
2271 continue;
2272
2273 kill_TCP_connection(c->tcp_connections_new[i]);
2274 c->tcp_connections_new[i] = NULL;
2275 }
2276
2277 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2278 if (c->tcp_connections[i] == NULL)
2279 continue;
2280
2281 TCP_Client_Connection *tcp_con = c->tcp_connections[i];
2282
2283 if (tcp_con->status != TCP_CLIENT_DISCONNECTED)
2284 continue;
2285
2286 /* Try reconnecting to relay on disconnect. */
2287 add_tcp_relay(c, tcp_con->ip_port, tcp_con->public_key);
2288
2289 pthread_mutex_lock(&c->tcp_mutex);
2290 c->tcp_connections[i] = NULL;
2291 kill_TCP_connection(tcp_con);
2292
2293 for (j = 0; j < c->crypto_connections_length; ++j) {
2294 Crypto_Connection *conn = get_crypto_connection(c, j);
2295
2296 if (conn == 0)
2297 continue;
2298
2299 clear_disconnected_tcp_peer(conn, i);
2300 }
2301
2302 pthread_mutex_unlock(&c->tcp_mutex);
2303 }
2304} 1832}
2305 1833
2306/* Set function to be called when connection with crypt_connection_id goes connects/disconnects. 1834/* Set function to be called when connection with crypt_connection_id goes connects/disconnects.
@@ -2372,8 +1900,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
2372} 1900}
2373 1901
2374 1902
2375/* Set the function for this friend that will be callbacked with object and number 1903/* Set the function for this friend that will be callbacked with object and number if
2376 * when that friend gives us his DHT temporary public key. 1904 * the friend sends us a different dht public key than we have associated to him.
1905 *
1906 * If this function is called, the connection should be recreated with the new public key.
2377 * 1907 *
2378 * object and number will be passed as argument to this function. 1908 * object and number will be passed as argument to this function.
2379 * 1909 *
@@ -2441,7 +1971,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2441 return -1; 1971 return -1;
2442 1972
2443 pthread_mutex_lock(&conn->mutex); 1973 pthread_mutex_lock(&conn->mutex);
2444 conn->direct_lastrecv_time = current_time_monotonic(); 1974 conn->direct_lastrecv_time = unix_time();
2445 pthread_mutex_unlock(&conn->mutex); 1975 pthread_mutex_unlock(&conn->mutex);
2446 return 0; 1976 return 0;
2447} 1977}
@@ -2746,7 +2276,10 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2746 if (conn->status == CRYPTO_CONN_ESTABLISHED) 2276 if (conn->status == CRYPTO_CONN_ESTABLISHED)
2747 send_kill_packet(c, crypt_connection_id); 2277 send_kill_packet(c, crypt_connection_id);
2748 2278
2749 disconnect_peer_tcp(c, crypt_connection_id); 2279 pthread_mutex_lock(&c->tcp_mutex);
2280 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
2281 pthread_mutex_unlock(&c->tcp_mutex);
2282
2750 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id); 2283 bs_list_remove(&c->ip_port_list, &conn->ip_port, crypt_connection_id);
2751 clear_temp_packet(c, crypt_connection_id); 2284 clear_temp_packet(c, crypt_connection_id);
2752 clear_buffer(&conn->send_array); 2285 clear_buffer(&conn->send_array);
@@ -2762,18 +2295,26 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2762/* return one of CRYPTO_CONN_* values indicating the state of the connection. 2295/* return one of CRYPTO_CONN_* values indicating the state of the connection.
2763 * 2296 *
2764 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 2297 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
2298 * sets online_tcp_relays to the number of connected tcp relays this connection has.
2765 */ 2299 */
2766unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected) 2300unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
2301 unsigned int *online_tcp_relays)
2767{ 2302{
2768 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 2303 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
2769 2304
2770 if (conn == 0) 2305 if (conn == 0)
2771 return CRYPTO_CONN_NO_CONNECTION; 2306 return CRYPTO_CONN_NO_CONNECTION;
2772 2307
2773 *direct_connected = 0; 2308 if (direct_connected) {
2309 *direct_connected = 0;
2774 2310
2775 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > current_time_monotonic()) 2311 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time())
2776 *direct_connected = 1; 2312 *direct_connected = 1;
2313 }
2314
2315 if (online_tcp_relays) {
2316 *online_tcp_relays = tcp_connection_to_online_tcp_relays(c->tcp_c, conn->connection_number_tcp);
2317 }
2777 2318
2778 return conn->status; 2319 return conn->status;
2779} 2320}
@@ -2816,8 +2357,19 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2816 if (temp == NULL) 2357 if (temp == NULL)
2817 return NULL; 2358 return NULL;
2818 2359
2360 temp->tcp_c = new_tcp_connections(dht, proxy_info);
2361
2362 if (temp->tcp_c == NULL) {
2363 free(temp);
2364 return NULL;
2365 }
2366
2367 set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
2368 set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
2369
2819 if (create_recursive_mutex(&temp->tcp_mutex) != 0 || 2370 if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
2820 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) { 2371 pthread_mutex_init(&temp->connections_mutex, NULL) != 0) {
2372 kill_tcp_connections(temp->tcp_c);
2821 free(temp); 2373 free(temp);
2822 return NULL; 2374 return NULL;
2823 } 2375 }
@@ -2836,8 +2388,6 @@ Net_Crypto *new_net_crypto(DHT *dht, TCP_Proxy_Info *proxy_info)
2836 2388
2837 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8); 2389 bs_list_init(&temp->ip_port_list, sizeof(IP_Port), 8);
2838 2390
2839 temp->proxy_info = *proxy_info;
2840
2841 return temp; 2391 return temp;
2842} 2392}
2843 2393
@@ -2852,7 +2402,7 @@ static void kill_timedout(Net_Crypto *c)
2852 if (conn == 0) 2402 if (conn == 0)
2853 return; 2403 return;
2854 2404
2855 if (conn->status == CRYPTO_CONN_NO_CONNECTION || conn->status == CRYPTO_CONN_TIMED_OUT) 2405 if (conn->status == CRYPTO_CONN_NO_CONNECTION)
2856 continue; 2406 continue;
2857 2407
2858 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT 2408 if (conn->status == CRYPTO_CONN_COOKIE_REQUESTING || conn->status == CRYPTO_CONN_HANDSHAKE_SENT
@@ -2860,19 +2410,8 @@ static void kill_timedout(Net_Crypto *c)
2860 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES) 2410 if (conn->temp_packet_num_sent < MAX_NUM_SENDPACKET_TRIES)
2861 continue; 2411 continue;
2862 2412
2863 conn->killed = 1; 2413 connection_kill(c, i);
2864
2865 }
2866
2867 if (conn->killed) {
2868 if (conn->connection_status_callback) {
2869 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 0);
2870 crypto_kill(c, i);
2871 continue;
2872 }
2873 2414
2874 conn->status = CRYPTO_CONN_TIMED_OUT;
2875 continue;
2876 } 2415 }
2877 2416
2878 if (conn->status == CRYPTO_CONN_ESTABLISHED) { 2417 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
@@ -2894,7 +2433,6 @@ void do_net_crypto(Net_Crypto *c)
2894 unix_time_update(); 2433 unix_time_update();
2895 kill_timedout(c); 2434 kill_timedout(c);
2896 do_tcp(c); 2435 do_tcp(c);
2897 clear_disconnected_tcp(c);
2898 send_crypto_packets(c); 2436 send_crypto_packets(c);
2899} 2437}
2900 2438
@@ -2906,14 +2444,10 @@ void kill_net_crypto(Net_Crypto *c)
2906 crypto_kill(c, i); 2444 crypto_kill(c, i);
2907 } 2445 }
2908 2446
2909 for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
2910 kill_TCP_connection(c->tcp_connections_new[i]);
2911 kill_TCP_connection(c->tcp_connections[i]);
2912 }
2913
2914 pthread_mutex_destroy(&c->tcp_mutex); 2447 pthread_mutex_destroy(&c->tcp_mutex);
2915 pthread_mutex_destroy(&c->connections_mutex); 2448 pthread_mutex_destroy(&c->connections_mutex);
2916 2449
2450 kill_tcp_connections(c->tcp_c);
2917 bs_list_free(&c->ip_port_list); 2451 bs_list_free(&c->ip_port_list);
2918 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL); 2452 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_REQUEST, NULL, NULL);
2919 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL); 2453 networking_registerhandler(c->dht->net, NET_PACKET_COOKIE_RESPONSE, NULL, NULL);
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index fab72cb3..9eb5e2d3 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -26,7 +26,7 @@
26 26
27#include "DHT.h" 27#include "DHT.h"
28#include "LAN_discovery.h" 28#include "LAN_discovery.h"
29#include "TCP_client.h" 29#include "TCP_connection.h"
30#include <pthread.h> 30#include <pthread.h>
31 31
32#define CRYPTO_CONN_NO_CONNECTION 0 32#define CRYPTO_CONN_NO_CONNECTION 0
@@ -34,7 +34,6 @@
34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets 34#define CRYPTO_CONN_HANDSHAKE_SENT 2 //send handshake packets
35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other 35#define CRYPTO_CONN_NOT_CONFIRMED 3 //send handshake packets, we have received one from the other
36#define CRYPTO_CONN_ESTABLISHED 4 36#define CRYPTO_CONN_ESTABLISHED 4
37#define CRYPTO_CONN_TIMED_OUT 5
38 37
39/* Maximum size of receiving and sending packet buffers. */ 38/* Maximum size of receiving and sending packet buffers. */
40#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */ 39#define CRYPTO_PACKET_BUFFER_SIZE 16384 /* Must be a power of 2 */
@@ -61,7 +60,7 @@
61#define MAX_NUM_SENDPACKET_TRIES 8 60#define MAX_NUM_SENDPACKET_TRIES 8
62 61
63/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */ 62/* The timeout of no received UDP packets before the direct UDP connection is considered dead. */
64#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 2) 63#define UDP_DIRECT_TIMEOUT ((MAX_NUM_SENDPACKET_TRIES * CRYPTO_SEND_PACKET_INTERVAL) / 1000)
65 64
66#define PACKET_ID_PADDING 0 /* Denotes padding */ 65#define PACKET_ID_PADDING 0 /* Denotes padding */
67#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */ 66#define PACKET_ID_REQUEST 1 /* Used to request unreceived packets */
@@ -73,11 +72,6 @@
73#define MAX_TCP_CONNECTIONS 64 72#define MAX_TCP_CONNECTIONS 64
74#define MAX_TCP_RELAYS_PEER 4 73#define MAX_TCP_RELAYS_PEER 4
75 74
76#define STATUS_TCP_NULL 0
77#define STATUS_TCP_OFFLINE 1
78#define STATUS_TCP_INVISIBLE 2 /* we know the other peer is connected to this relay but he isn't appearing online */
79#define STATUS_TCP_ONLINE 3
80
81/* All packets starting with a byte in this range are considered lossy packets. */ 75/* All packets starting with a byte in this range are considered lossy packets. */
82#define PACKET_ID_LOSSY_RANGE_START 192 76#define PACKET_ID_LOSSY_RANGE_START 192
83#define PACKET_ID_LOSSY_RANGE_SIZE 63 77#define PACKET_ID_LOSSY_RANGE_SIZE 63
@@ -112,11 +106,9 @@ typedef struct {
112 * 2 if we are sending handshake packets 106 * 2 if we are sending handshake packets
113 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet), 107 * 3 if connection is not confirmed yet (we have received a handshake but no data packets yet),
114 * 4 if the connection is established. 108 * 4 if the connection is established.
115 * 5 if the connection is timed out.
116 */ 109 */
117 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */ 110 uint64_t cookie_request_number; /* number used in the cookie request packets for this connection */
118 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */ 111 uint8_t dht_public_key[crypto_box_PUBLICKEYBYTES]; /* The dht public key of the peer */
119 uint8_t dht_public_key_set; /* True if the dht public key is set, false if it isn't. */
120 112
121 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */ 113 uint8_t *temp_packet; /* Where the cookie request/handshake packet is stored while it is being sent. */
122 uint16_t temp_packet_length; 114 uint16_t temp_packet_length;
@@ -155,15 +147,8 @@ typedef struct {
155 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE]; 147 long signed int last_num_packets_sent[CONGESTION_QUEUE_ARRAY_SIZE];
156 uint32_t packets_sent; 148 uint32_t packets_sent;
157 149
158 uint8_t killed; /* set to 1 to kill the connection. */ 150 /* TCP_connection connection_number */
159 151 unsigned int connection_number_tcp;
160 uint8_t status_tcp[MAX_TCP_CONNECTIONS]; /* set to one of STATUS_TCP_* */
161 uint8_t con_number_tcp[MAX_TCP_CONNECTIONS];
162 unsigned int last_relay_sentto;
163 unsigned int num_tcp_online;
164
165 Node_format tcp_relays[MAX_TCP_RELAYS_PEER];
166 uint16_t num_tcp_relays;
167 152
168 uint8_t maximum_speed_reached; 153 uint8_t maximum_speed_reached;
169 154
@@ -186,10 +171,9 @@ typedef struct {
186 171
187typedef struct { 172typedef struct {
188 DHT *dht; 173 DHT *dht;
174 TCP_Connections *tcp_c;
189 175
190 Crypto_Connection *crypto_connections; 176 Crypto_Connection *crypto_connections;
191 TCP_Client_Connection *tcp_connections_new[MAX_TCP_CONNECTIONS];
192 TCP_Client_Connection *tcp_connections[MAX_TCP_CONNECTIONS];
193 pthread_mutex_t tcp_mutex; 177 pthread_mutex_t tcp_mutex;
194 178
195 pthread_mutex_t connections_mutex; 179 pthread_mutex_t connections_mutex;
@@ -211,11 +195,6 @@ typedef struct {
211 uint32_t current_sleep_time; 195 uint32_t current_sleep_time;
212 196
213 BS_LIST ip_port_list; 197 BS_LIST ip_port_list;
214
215 int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length);
216 void *tcp_onion_callback_object;
217
218 TCP_Proxy_Info proxy_info;
219} Net_Crypto; 198} Net_Crypto;
220 199
221 200
@@ -241,21 +220,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c);
241 * return -1 on failure. 220 * return -1 on failure.
242 * return connection id on success. 221 * return connection id on success.
243 */ 222 */
244int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key); 223int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const uint8_t *dht_public_key);
245
246/* Copy friends DHT public key into dht_key.
247 *
248 * return 0 on failure (no key copied).
249 * return 1 on success (key copied).
250 */
251unsigned int get_connection_dht_key(const Net_Crypto *c, int crypt_connection_id, uint8_t *dht_public_key);
252
253/* Set the DHT public key of the crypto connection.
254 *
255 * return -1 on failure.
256 * return 0 on success.
257 */
258int set_connection_dht_public_key(Net_Crypto *c, int crypt_connection_id, const uint8_t *dht_public_key);
259 224
260/* Set the direct ip of the crypto connection. 225/* Set the direct ip of the crypto connection.
261 * 226 *
@@ -301,8 +266,10 @@ int connection_lossy_data_handler(Net_Crypto *c, int crypt_connection_id,
301 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object, 266 int (*connection_lossy_data_callback)(void *object, int id, const uint8_t *data, uint16_t length), void *object,
302 int id); 267 int id);
303 268
304/* Set the function for this friend that will be callbacked with object and number 269/* Set the function for this friend that will be callbacked with object and number if
305 * when that friend gives us his DHT temporary public key. 270 * the friend sends us a different dht public key than we have associated to him.
271 *
272 * If this function is called, the connection should be recreated with the new public key.
306 * 273 *
307 * object and number will be passed as argument to this function. 274 * object and number will be passed as argument to this function.
308 * 275 *
@@ -364,11 +331,6 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
364 */ 331 */
365int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key); 332int add_tcp_relay(Net_Crypto *c, IP_Port ip_port, const uint8_t *public_key);
366 333
367/* Set the function to be called when an onion response packet is received by one of the TCP connections.
368 */
369void tcp_onion_response_handler(Net_Crypto *c, int (*tcp_onion_callback)(void *object, const uint8_t *data,
370 uint16_t length), void *object);
371
372/* Return a random TCP connection number for use in send_tcp_onion_request. 334/* Return a random TCP connection number for use in send_tcp_onion_request.
373 * 335 *
374 * return TCP connection number on success. 336 * return TCP connection number on success.
@@ -389,7 +351,7 @@ int send_tcp_onion_request(Net_Crypto *c, unsigned int TCP_conn_number, const ui
389 * return number of relays copied to tcp_relays on success. 351 * return number of relays copied to tcp_relays on success.
390 * return 0 on failure. 352 * return 0 on failure.
391 */ 353 */
392unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num); 354unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num);
393 355
394/* Kill a crypto connection. 356/* Kill a crypto connection.
395 * 357 *
@@ -398,13 +360,13 @@ unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_rel
398 */ 360 */
399int crypto_kill(Net_Crypto *c, int crypt_connection_id); 361int crypto_kill(Net_Crypto *c, int crypt_connection_id);
400 362
401
402/* return one of CRYPTO_CONN_* values indicating the state of the connection. 363/* return one of CRYPTO_CONN_* values indicating the state of the connection.
403 * 364 *
404 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't. 365 * sets direct_connected to 1 if connection connects directly to other, 0 if it isn't.
366 * sets online_tcp_relays to the number of connected tcp relays this connection has.
405 */ 367 */
406unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, uint8_t *direct_connected); 368unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_id, _Bool *direct_connected,
407 369 unsigned int *online_tcp_relays);
408 370
409/* Generate our public and private keys. 371/* Generate our public and private keys.
410 * Only call this function the first time the program starts. 372 * Only call this function the first time the program starts.
diff --git a/toxcore/onion.c b/toxcore/onion.c
index c6093f0c..48e4c769 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -35,8 +35,8 @@
35#define SEND_2 ONION_SEND_2 35#define SEND_2 ONION_SEND_2
36#define SEND_1 ONION_SEND_1 36#define SEND_1 ONION_SEND_1
37 37
38/* Change symmetric keys every hour to make paths expire eventually. */ 38/* Change symmetric keys every 2 hours to make paths expire eventually. */
39#define KEY_REFRESH_INTERVAL (60 * 60) 39#define KEY_REFRESH_INTERVAL (2 * 60 * 60)
40static void change_symmetric_key(Onion *onion) 40static void change_symmetric_key(Onion *onion)
41{ 41{
42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) { 42 if (is_timeout(onion->timestamp, KEY_REFRESH_INTERVAL)) {
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index a9fc1643..ed328fb3 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -1425,7 +1425,6 @@ void do_onion_client(Onion_Client *onion_c)
1425 ++onion_c->onion_connected; 1425 ++onion_c->onion_connected;
1426 } 1426 }
1427 1427
1428 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1429 } else { 1428 } else {
1430 populate_path_nodes_tcp(onion_c); 1429 populate_path_nodes_tcp(onion_c);
1431 1430
@@ -1434,12 +1433,22 @@ void do_onion_client(Onion_Client *onion_c)
1434 } 1433 }
1435 } 1434 }
1436 1435
1436 onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht);
1437
1438 if (is_timeout(onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1439 set_tcp_onion_status(onion_c->c->tcp_c, !onion_c->UDP_connected);
1440 }
1441
1437 if (onion_connection_status(onion_c)) { 1442 if (onion_connection_status(onion_c)) {
1438 for (i = 0; i < onion_c->num_friends; ++i) { 1443 for (i = 0; i < onion_c->num_friends; ++i) {
1439 do_friend(onion_c, i); 1444 do_friend(onion_c, i);
1440 } 1445 }
1441 } 1446 }
1442 1447
1448 if (onion_c->last_run == 0) {
1449 onion_c->first_run = unix_time();
1450 }
1451
1443 onion_c->last_run = unix_time(); 1452 onion_c->last_run = unix_time();
1444} 1453}
1445 1454
@@ -1467,7 +1476,7 @@ Onion_Client *new_onion_client(Net_Crypto *c)
1467 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c); 1476 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
1468 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c); 1477 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
1469 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c); 1478 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
1470 tcp_onion_response_handler(onion_c->c, &handle_tcp_onion, onion_c); 1479 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, &handle_tcp_onion, onion_c);
1471 1480
1472 return onion_c; 1481 return onion_c;
1473} 1482}
@@ -1483,7 +1492,7 @@ void kill_onion_client(Onion_Client *onion_c)
1483 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL); 1492 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, NULL, NULL);
1484 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL); 1493 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, NULL, NULL);
1485 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL); 1494 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, NULL, NULL);
1486 tcp_onion_response_handler(onion_c->c, NULL, NULL); 1495 set_onion_packet_tcp_connection_callback(onion_c->c->tcp_c, NULL, NULL);
1487 memset(onion_c, 0, sizeof(Onion_Client)); 1496 memset(onion_c, 0, sizeof(Onion_Client));
1488 free(onion_c); 1497 free(onion_c);
1489} 1498}
diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h
index e10a86c5..ad28ac51 100644
--- a/toxcore/onion_client.h
+++ b/toxcore/onion_client.h
@@ -136,7 +136,7 @@ typedef struct {
136 Onion_Client_Paths onion_paths_friends; 136 Onion_Client_Paths onion_paths_friends;
137 137
138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES]; 138 uint8_t secret_symmetric_key[crypto_box_KEYBYTES];
139 uint64_t last_run; 139 uint64_t last_run, first_run;
140 140
141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES]; 141 uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES]; 142 uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 8e368851..abd2f051 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -67,23 +67,21 @@ extern "C" {
67 * function will try to use a sane default, but there will be no error code, 67 * function will try to use a sane default, but there will be no error code,
68 * and one possible action for the function to take is to have no effect. 68 * and one possible action for the function to take is to have no effect.
69 */ 69 */
70
71/** \subsection events Events and callbacks 70/** \subsection events Events and callbacks
72 * 71 *
73 * Events are handled by callbacks. One callback can be registered per event. 72 * Events are handled by callbacks. One callback can be registered per event.
74 * All events have a callback function type named `tox_${event}_cb` and a 73 * All events have a callback function type named `tox_{event}_cb` and a
75 * function to register it named `tox_callback_${event}`. Passing a NULL 74 * function to register it named `tox_callback_{event}`. Passing a NULL
76 * callback will result in no callback being registered for that event. Only 75 * callback will result in no callback being registered for that event. Only
77 * one callback per event can be registered, so if a client needs multiple 76 * one callback per event can be registered, so if a client needs multiple
78 * event listeners, it needs to implement the dispatch functionality itself. 77 * event listeners, it needs to implement the dispatch functionality itself.
79 */ 78 */
80
81/** \subsection threading Threading implications 79/** \subsection threading Threading implications
82 * 80 *
83 * It is possible to run multiple concurrent threads with a Tox instance for 81 * It is possible to run multiple concurrent threads with a Tox instance for
84 * each thread. It is also possible to run all Tox instances in the same thread. 82 * each thread. It is also possible to run all Tox instances in the same thread.
85 * A common way to run Tox (multiple or single instance) is to have one thread 83 * A common way to run Tox (multiple or single instance) is to have one thread
86 * running a simple tox_iteration loop, sleeping for tox_iteration_interval 84 * running a simple tox_iterate loop, sleeping for tox_iteration_interval
87 * milliseconds on each iteration. 85 * milliseconds on each iteration.
88 * 86 *
89 * If you want to access a single Tox instance from multiple threads, access 87 * If you want to access a single Tox instance from multiple threads, access
@@ -108,12 +106,9 @@ extern "C" {
108 * \endcode 106 * \endcode
109 * 107 *
110 * If any other thread calls tox_self_set_name while this thread is allocating 108 * If any other thread calls tox_self_set_name while this thread is allocating
111 * memory, the length will have become invalid, and the call to 109 * memory, the length may have become invalid, and the call to
112 * tox_self_get_name may cause undefined behaviour. 110 * tox_self_get_name may cause undefined behaviour.
113 */ 111 */
114
115#ifndef TOX_DEFINED
116#define TOX_DEFINED
117/** 112/**
118 * The Tox instance type. All the state associated with a connection is held 113 * The Tox instance type. All the state associated with a connection is held
119 * within the instance. Multiple instances can exist and operate concurrently. 114 * within the instance. Multiple instances can exist and operate concurrently.
@@ -121,8 +116,10 @@ extern "C" {
121 * device is limited. Note that this is not just a per-process limit, since the 116 * device is limited. Note that this is not just a per-process limit, since the
122 * limiting factor is the number of usable ports on a device. 117 * limiting factor is the number of usable ports on a device.
123 */ 118 */
119#ifndef TOX_DEFINED
120#define TOX_DEFINED
124typedef struct Tox Tox; 121typedef struct Tox Tox;
125#endif 122#endif /* TOX_DEFINED */
126 123
127 124
128/******************************************************************************* 125/*******************************************************************************
@@ -132,17 +129,20 @@ typedef struct Tox Tox;
132 ******************************************************************************/ 129 ******************************************************************************/
133 130
134 131
132
135/** 133/**
136 * The major version number. Incremented when the API or ABI changes in an 134 * The major version number. Incremented when the API or ABI changes in an
137 * incompatible way. 135 * incompatible way.
138 */ 136 */
139#define TOX_VERSION_MAJOR 0u 137#define TOX_VERSION_MAJOR 0u
138
140/** 139/**
141 * The minor version number. Incremented when functionality is added without 140 * The minor version number. Incremented when functionality is added without
142 * breaking the API or ABI. Set to 0 when the major version number is 141 * breaking the API or ABI. Set to 0 when the major version number is
143 * incremented. 142 * incremented.
144 */ 143 */
145#define TOX_VERSION_MINOR 0u 144#define TOX_VERSION_MINOR 0u
145
146/** 146/**
147 * The patch or revision number. Incremented when bugfixes are applied without 147 * The patch or revision number. Incremented when bugfixes are applied without
148 * changing any functionality or API or ABI. 148 * changing any functionality or API or ABI.
@@ -166,7 +166,6 @@ typedef struct Tox Tox;
166#define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \ 166#define TOX_VERSION_REQUIRE(MAJOR, MINOR, PATCH) \
167 typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1] 167 typedef char tox_required_version[TOX_IS_COMPATIBLE(MAJOR, MINOR, PATCH) ? 1 : -1]
168 168
169
170/** 169/**
171 * Return the major version number of the library. Can be used to display the 170 * Return the major version number of the library. Can be used to display the
172 * Tox library version or to check whether the client is compatible with the 171 * Tox library version or to check whether the client is compatible with the
@@ -205,15 +204,16 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
205 ******************************************************************************/ 204 ******************************************************************************/
206 205
207 206
207
208/** 208/**
209 * The size of a Tox Public Key in bytes. 209 * The size of a Tox Public Key in bytes.
210 */ 210 */
211#define TOX_PUBLIC_KEY_SIZE 32 211#define TOX_PUBLIC_KEY_SIZE 32
212 212
213/** 213/**
214 * The size of a Tox Secret Key in bytes. 214 * The size of a Tox Secret Key in bytes.
215 */ 215 */
216#define TOX_SECRET_KEY_SIZE 32 216#define TOX_SECRET_KEY_SIZE 32
217 217
218/** 218/**
219 * The size of a Tox address in bytes. Tox addresses are in the format 219 * The size of a Tox address in bytes. Tox addresses are in the format
@@ -223,47 +223,48 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
223 * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an 223 * byte is an XOR of all the even bytes (0, 2, 4, ...), the second byte is an
224 * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam. 224 * XOR of all the odd bytes (1, 3, 5, ...) of the Public Key and nospam.
225 */ 225 */
226#define TOX_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) 226#define TOX_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
227 227
228/** 228/**
229 * Maximum length of a nickname in bytes. 229 * Maximum length of a nickname in bytes.
230 */ 230 */
231#define TOX_MAX_NAME_LENGTH 128 231#define TOX_MAX_NAME_LENGTH 128
232 232
233/** 233/**
234 * Maximum length of a status message in bytes. 234 * Maximum length of a status message in bytes.
235 */ 235 */
236#define TOX_MAX_STATUS_MESSAGE_LENGTH 1007 236#define TOX_MAX_STATUS_MESSAGE_LENGTH 1007
237 237
238/** 238/**
239 * Maximum length of a friend request message in bytes. 239 * Maximum length of a friend request message in bytes.
240 */ 240 */
241#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016 241#define TOX_MAX_FRIEND_REQUEST_LENGTH 1016
242 242
243/** 243/**
244 * Maximum length of a single message after which it should be split. 244 * Maximum length of a single message after which it should be split.
245 */ 245 */
246#define TOX_MAX_MESSAGE_LENGTH 1372 246#define TOX_MAX_MESSAGE_LENGTH 1372
247 247
248/** 248/**
249 * Maximum size of custom packets. TODO: should be LENGTH? 249 * Maximum size of custom packets. TODO: should be LENGTH?
250 */ 250 */
251#define TOX_MAX_CUSTOM_PACKET_SIZE 1373 251#define TOX_MAX_CUSTOM_PACKET_SIZE 1373
252 252
253/** 253/**
254 * The number of bytes in a hash generated by tox_hash. 254 * The number of bytes in a hash generated by tox_hash.
255 */ 255 */
256#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 256#define TOX_HASH_LENGTH 32
257 257
258/** 258/**
259 * The number of bytes in a file id. 259 * The number of bytes in a file id.
260 */ 260 */
261#define TOX_FILE_ID_LENGTH 32 261#define TOX_FILE_ID_LENGTH 32
262 262
263/** 263/**
264 * Maximum file name length for file tran. 264 * Maximum file name length for file transfers.
265 */ 265 */
266#define TOX_MAX_FILENAME_LENGTH 255 266#define TOX_MAX_FILENAME_LENGTH 255
267
267 268
268/******************************************************************************* 269/*******************************************************************************
269 * 270 *
@@ -272,42 +273,53 @@ bool tox_version_is_compatible(uint32_t major, uint32_t minor, uint32_t patch);
272 ******************************************************************************/ 273 ******************************************************************************/
273 274
274 275
276
275/** 277/**
276 * Represents the possible statuses a client can have. 278 * Represents the possible statuses a client can have.
277 */ 279 */
278typedef enum TOX_USER_STATUS { 280typedef enum TOX_USER_STATUS {
281
279 /** 282 /**
280 * User is online and available. 283 * User is online and available.
281 */ 284 */
282 TOX_USER_STATUS_NONE, 285 TOX_USER_STATUS_NONE,
286
283 /** 287 /**
284 * User is away. Clients can set this e.g. after a user defined 288 * User is away. Clients can set this e.g. after a user defined
285 * inactivity time. 289 * inactivity time.
286 */ 290 */
287 TOX_USER_STATUS_AWAY, 291 TOX_USER_STATUS_AWAY,
292
288 /** 293 /**
289 * User is busy. Signals to other clients that this client does not 294 * User is busy. Signals to other clients that this client does not
290 * currently wish to communicate. 295 * currently wish to communicate.
291 */ 296 */
292 TOX_USER_STATUS_BUSY 297 TOX_USER_STATUS_BUSY,
298
293} TOX_USER_STATUS; 299} TOX_USER_STATUS;
294 300
301
295/** 302/**
296 * Represents message types for friend messages and group chat 303 * Represents message types for tox_friend_send_message and group chat
297 * messages. 304 * messages.
298 */ 305 */
299typedef enum TOX_MESSAGE_TYPE { 306typedef enum TOX_MESSAGE_TYPE {
307
300 /** 308 /**
301 * Normal text message. Similar to PRIVMSG on IRC. 309 * Normal text message. Similar to PRIVMSG on IRC.
302 */ 310 */
303 TOX_MESSAGE_TYPE_NORMAL, 311 TOX_MESSAGE_TYPE_NORMAL,
312
304 /** 313 /**
305 * A message describing an user action. This is similar to /me (CTCP ACTION) 314 * A message describing an user action. This is similar to /me (CTCP ACTION)
306 * on IRC. 315 * on IRC.
307 */ 316 */
308 TOX_MESSAGE_TYPE_ACTION 317 TOX_MESSAGE_TYPE_ACTION,
318
309} TOX_MESSAGE_TYPE; 319} TOX_MESSAGE_TYPE;
310 320
321
322
311/******************************************************************************* 323/*******************************************************************************
312 * 324 *
313 * :: Startup options 325 * :: Startup options
@@ -315,19 +327,27 @@ typedef enum TOX_MESSAGE_TYPE {
315 ******************************************************************************/ 327 ******************************************************************************/
316 328
317 329
330
331/**
332 * Type of proxy used to connect to TCP relays.
333 */
318typedef enum TOX_PROXY_TYPE { 334typedef enum TOX_PROXY_TYPE {
335
319 /** 336 /**
320 * Don't use a proxy. 337 * Don't use a proxy.
321 */ 338 */
322 TOX_PROXY_TYPE_NONE, 339 TOX_PROXY_TYPE_NONE,
340
323 /** 341 /**
324 * HTTP proxy using CONNECT. 342 * HTTP proxy using CONNECT.
325 */ 343 */
326 TOX_PROXY_TYPE_HTTP, 344 TOX_PROXY_TYPE_HTTP,
345
327 /** 346 /**
328 * SOCKS proxy for simple socket pipes. 347 * SOCKS proxy for simple socket pipes.
329 */ 348 */
330 TOX_PROXY_TYPE_SOCKS5 349 TOX_PROXY_TYPE_SOCKS5,
350
331} TOX_PROXY_TYPE; 351} TOX_PROXY_TYPE;
332 352
333 353
@@ -337,6 +357,7 @@ typedef enum TOX_PROXY_TYPE {
337 * tox_options_new to get a new default options object. 357 * tox_options_new to get a new default options object.
338 */ 358 */
339struct Tox_Options { 359struct Tox_Options {
360
340 /** 361 /**
341 * The type of socket to create. 362 * The type of socket to create.
342 * 363 *
@@ -347,6 +368,7 @@ struct Tox_Options {
347 */ 368 */
348 bool ipv6_enabled; 369 bool ipv6_enabled;
349 370
371
350 /** 372 /**
351 * Enable the use of UDP communication when available. 373 * Enable the use of UDP communication when available.
352 * 374 *
@@ -356,11 +378,13 @@ struct Tox_Options {
356 */ 378 */
357 bool udp_enabled; 379 bool udp_enabled;
358 380
381
359 /** 382 /**
360 * Pass communications through a proxy. 383 * Pass communications through a proxy.
361 */ 384 */
362 TOX_PROXY_TYPE proxy_type; 385 TOX_PROXY_TYPE proxy_type;
363 386
387
364 /** 388 /**
365 * The IP address or DNS name of the proxy to be used. 389 * The IP address or DNS name of the proxy to be used.
366 * 390 *
@@ -368,18 +392,20 @@ struct Tox_Options {
368 * exceed 255 characters, and be in a NUL-terminated C string format 392 * exceed 255 characters, and be in a NUL-terminated C string format
369 * (255 chars + 1 NUL byte). 393 * (255 chars + 1 NUL byte).
370 * 394 *
371 * This member is ignored (it can be NULL) if proxy_enabled is false. 395 * This member is ignored (it can be NULL) if proxy_type is TOX_PROXY_TYPE_NONE.
372 */ 396 */
373 const char *proxy_host; 397 const char *proxy_host;
374 398
399
375 /** 400 /**
376 * The port to use to connect to the proxy server. 401 * The port to use to connect to the proxy server.
377 * 402 *
378 * Ports must be in the range (1, 65535). The value is ignored if 403 * Ports must be in the range (1, 65535). The value is ignored if
379 * proxy_enabled is false. 404 * proxy_type is TOX_PROXY_TYPE_NONE.
380 */ 405 */
381 uint16_t proxy_port; 406 uint16_t proxy_port;
382 407
408
383 /** 409 /**
384 * The start port of the inclusive port range to attempt to use. 410 * The start port of the inclusive port range to attempt to use.
385 * 411 *
@@ -394,10 +420,12 @@ struct Tox_Options {
394 */ 420 */
395 uint16_t start_port; 421 uint16_t start_port;
396 422
423
397 /** 424 /**
398 * The end port of the inclusive port range to attempt to use. 425 * The end port of the inclusive port range to attempt to use.
399 */ 426 */
400 uint16_t end_port; 427 uint16_t end_port;
428
401}; 429};
402 430
403 431
@@ -414,15 +442,21 @@ struct Tox_Options {
414 */ 442 */
415void tox_options_default(struct Tox_Options *options); 443void tox_options_default(struct Tox_Options *options);
416 444
417
418typedef enum TOX_ERR_OPTIONS_NEW { 445typedef enum TOX_ERR_OPTIONS_NEW {
446
447 /**
448 * The function returned successfully.
449 */
419 TOX_ERR_OPTIONS_NEW_OK, 450 TOX_ERR_OPTIONS_NEW_OK,
451
420 /** 452 /**
421 * The function failed to allocate enough memory for the options struct. 453 * The function failed to allocate enough memory for the options struct.
422 */ 454 */
423 TOX_ERR_OPTIONS_NEW_MALLOC 455 TOX_ERR_OPTIONS_NEW_MALLOC,
456
424} TOX_ERR_OPTIONS_NEW; 457} TOX_ERR_OPTIONS_NEW;
425 458
459
426/** 460/**
427 * Allocates a new Tox_Options object and initialises it with the default 461 * Allocates a new Tox_Options object and initialises it with the default
428 * options. This function can be used to preserve long term ABI compatibility by 462 * options. This function can be used to preserve long term ABI compatibility by
@@ -435,7 +469,6 @@ typedef enum TOX_ERR_OPTIONS_NEW {
435 */ 469 */
436struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error); 470struct Tox_Options *tox_options_new(TOX_ERR_OPTIONS_NEW *error);
437 471
438
439/** 472/**
440 * Releases all resources associated with an options objects. 473 * Releases all resources associated with an options objects.
441 * 474 *
@@ -452,41 +485,58 @@ void tox_options_free(struct Tox_Options *options);
452 ******************************************************************************/ 485 ******************************************************************************/
453 486
454 487
488
455typedef enum TOX_ERR_NEW { 489typedef enum TOX_ERR_NEW {
490
491 /**
492 * The function returned successfully.
493 */
456 TOX_ERR_NEW_OK, 494 TOX_ERR_NEW_OK,
495
496 /**
497 * One of the arguments to the function was NULL when it was not expected.
498 */
457 TOX_ERR_NEW_NULL, 499 TOX_ERR_NEW_NULL,
500
458 /** 501 /**
459 * The function was unable to allocate enough memory to store the internal 502 * The function was unable to allocate enough memory to store the internal
460 * structures for the Tox object. 503 * structures for the Tox object.
461 */ 504 */
462 TOX_ERR_NEW_MALLOC, 505 TOX_ERR_NEW_MALLOC,
506
463 /** 507 /**
464 * The function was unable to bind to a port. This may mean that all ports 508 * The function was unable to bind to a port. This may mean that all ports
465 * have already been bound, e.g. by other Tox instances, or it may mean 509 * have already been bound, e.g. by other Tox instances, or it may mean
466 * a permission error. You may be able to gather more information from errno. 510 * a permission error. You may be able to gather more information from errno.
467 */ 511 */
468 TOX_ERR_NEW_PORT_ALLOC, 512 TOX_ERR_NEW_PORT_ALLOC,
513
469 /** 514 /**
470 * proxy_type was invalid. 515 * proxy_type was invalid.
471 */ 516 */
472 TOX_ERR_NEW_PROXY_BAD_TYPE, 517 TOX_ERR_NEW_PROXY_BAD_TYPE,
518
473 /** 519 /**
474 * proxy_type was valid but the proxy_host passed had an invalid format 520 * proxy_type was valid but the proxy_host passed had an invalid format
475 * or was NULL. 521 * or was NULL.
476 */ 522 */
477 TOX_ERR_NEW_PROXY_BAD_HOST, 523 TOX_ERR_NEW_PROXY_BAD_HOST,
524
478 /** 525 /**
479 * proxy_type was valid, but the proxy_port was invalid. 526 * proxy_type was valid, but the proxy_port was invalid.
480 */ 527 */
481 TOX_ERR_NEW_PROXY_BAD_PORT, 528 TOX_ERR_NEW_PROXY_BAD_PORT,
529
482 /** 530 /**
483 * The proxy host passed could not be resolved. 531 * The proxy address passed could not be resolved.
484 */ 532 */
485 TOX_ERR_NEW_PROXY_NOT_FOUND, 533 TOX_ERR_NEW_PROXY_NOT_FOUND,
534
486 /** 535 /**
487 * The byte array to be loaded contained an encrypted save. 536 * The byte array to be loaded contained an encrypted save.
488 */ 537 */
489 TOX_ERR_NEW_LOAD_ENCRYPTED, 538 TOX_ERR_NEW_LOAD_ENCRYPTED,
539
490 /** 540 /**
491 * The data format was invalid. This can happen when loading data that was 541 * The data format was invalid. This can happen when loading data that was
492 * saved by an older version of Tox, or when the data has been corrupted. 542 * saved by an older version of Tox, or when the data has been corrupted.
@@ -494,7 +544,8 @@ typedef enum TOX_ERR_NEW {
494 * and the rest is discarded. Passing an invalid length parameter also 544 * and the rest is discarded. Passing an invalid length parameter also
495 * causes this error. 545 * causes this error.
496 */ 546 */
497 TOX_ERR_NEW_LOAD_BAD_FORMAT 547 TOX_ERR_NEW_LOAD_BAD_FORMAT,
548
498} TOX_ERR_NEW; 549} TOX_ERR_NEW;
499 550
500 551
@@ -516,11 +567,10 @@ typedef enum TOX_ERR_NEW {
516 * @param length The length of the byte array data. If this parameter is 0, the 567 * @param length The length of the byte array data. If this parameter is 0, the
517 * data parameter is ignored. 568 * data parameter is ignored.
518 * 569 *
519 * @see tox_iteration for the event loop. 570 * @see tox_iterate for the event loop.
520 */ 571 */
521Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error); 572Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t length, TOX_ERR_NEW *error);
522 573
523
524/** 574/**
525 * Releases all resources associated with the Tox instance and disconnects from 575 * Releases all resources associated with the Tox instance and disconnects from
526 * the network. 576 * the network.
@@ -530,11 +580,9 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng
530 */ 580 */
531void tox_kill(Tox *tox); 581void tox_kill(Tox *tox);
532 582
533
534/** 583/**
535 * Calculates the number of bytes required to store the tox instance with 584 * Calculates the number of bytes required to store the tox instance with
536 * tox_get_savedata. This function cannot fail. The result is always greater 585 * tox_get_savedata. This function cannot fail. The result is always greater than 0.
537 * than 0.
538 * 586 *
539 * @see threading for concurrency implications. 587 * @see threading for concurrency implications.
540 */ 588 */
@@ -547,7 +595,7 @@ size_t tox_get_savedata_size(const Tox *tox);
547 * Call tox_get_savedata_size to find the number of bytes required. If this parameter 595 * Call tox_get_savedata_size to find the number of bytes required. If this parameter
548 * is NULL, this function has no effect. 596 * is NULL, this function has no effect.
549 */ 597 */
550void tox_get_savedata(const Tox *tox, uint8_t *data); 598void tox_get_savedata(const Tox *tox, uint8_t *savedata);
551 599
552 600
553/******************************************************************************* 601/*******************************************************************************
@@ -557,20 +605,33 @@ void tox_get_savedata(const Tox *tox, uint8_t *data);
557 ******************************************************************************/ 605 ******************************************************************************/
558 606
559 607
608
560typedef enum TOX_ERR_BOOTSTRAP { 609typedef enum TOX_ERR_BOOTSTRAP {
610
611 /**
612 * The function returned successfully.
613 */
561 TOX_ERR_BOOTSTRAP_OK, 614 TOX_ERR_BOOTSTRAP_OK,
615
616 /**
617 * One of the arguments to the function was NULL when it was not expected.
618 */
562 TOX_ERR_BOOTSTRAP_NULL, 619 TOX_ERR_BOOTSTRAP_NULL,
620
563 /** 621 /**
564 * The host could not be resolved to an IP address, or the IP address 622 * The address could not be resolved to an IP address, or the IP address
565 * passed was invalid. 623 * passed was invalid.
566 */ 624 */
567 TOX_ERR_BOOTSTRAP_BAD_HOST, 625 TOX_ERR_BOOTSTRAP_BAD_HOST,
626
568 /** 627 /**
569 * The port passed was invalid. The valid port range is (1, 65535). 628 * The port passed was invalid. The valid port range is (1, 65535).
570 */ 629 */
571 TOX_ERR_BOOTSTRAP_BAD_PORT 630 TOX_ERR_BOOTSTRAP_BAD_PORT,
631
572} TOX_ERR_BOOTSTRAP; 632} TOX_ERR_BOOTSTRAP;
573 633
634
574/** 635/**
575 * Sends a "get nodes" request to the given bootstrap node with IP, port, and 636 * Sends a "get nodes" request to the given bootstrap node with IP, port, and
576 * public key to setup connections. 637 * public key to setup connections.
@@ -583,15 +644,14 @@ typedef enum TOX_ERR_BOOTSTRAP {
583 * also use the TCP connection when NAT hole punching is slow, and later switch 644 * also use the TCP connection when NAT hole punching is slow, and later switch
584 * to UDP if hole punching succeeds. 645 * to UDP if hole punching succeeds.
585 * 646 *
586 * @param host The hostname or IP address (IPv4 or IPv6) of the node. 647 * @param address The hostname or IP address (IPv4 or IPv6) of the node.
587 * @param port The port on the host on which the bootstrap Tox instance is 648 * @param port The port on the host on which the bootstrap Tox instance is
588 * listening. 649 * listening.
589 * @param public_key The long term public key of the bootstrap node 650 * @param public_key The long term public key of the bootstrap node
590 * (TOX_PUBLIC_KEY_SIZE bytes). 651 * (TOX_PUBLIC_KEY_SIZE bytes).
591 * @return true on success. 652 * @return true on success.
592 */ 653 */
593bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error); 654bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error);
594
595 655
596/** 656/**
597 * Adds additional host:port pair as TCP relay. 657 * Adds additional host:port pair as TCP relay.
@@ -600,35 +660,41 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub
600 * the same bootstrap node, or to add TCP relays without using them as 660 * the same bootstrap node, or to add TCP relays without using them as
601 * bootstrap nodes. 661 * bootstrap nodes.
602 * 662 *
603 * @param host The hostname or IP address (IPv4 or IPv6) of the TCP relay. 663 * @param address The hostname or IP address (IPv4 or IPv6) of the TCP relay.
604 * @param port The port on the host on which the TCP relay is listening. 664 * @param port The port on the host on which the TCP relay is listening.
605 * @param public_key The long term public key of the TCP relay 665 * @param public_key The long term public key of the TCP relay
606 * (TOX_PUBLIC_KEY_SIZE bytes). 666 * (TOX_PUBLIC_KEY_SIZE bytes).
607 * @return true on success. 667 * @return true on success.
608 */ 668 */
609bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t *public_key, 669bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key,
610 TOX_ERR_BOOTSTRAP *error); 670 TOX_ERR_BOOTSTRAP *error);
611 671
612 672/**
673 * Protocols that can be used to connect to the network or friends.
674 */
613typedef enum TOX_CONNECTION { 675typedef enum TOX_CONNECTION {
676
614 /** 677 /**
615 * There is no connection. This instance, or the friend the state change is 678 * There is no connection. This instance, or the friend the state change is
616 * about, is now offline. 679 * about, is now offline.
617 */ 680 */
618 TOX_CONNECTION_NONE, 681 TOX_CONNECTION_NONE,
682
619 /** 683 /**
620 * A TCP connection has been established. For the own instance, this means it 684 * A TCP connection has been established. For the own instance, this means it
621 * is connected through a TCP relay, only. For a friend, this means that the 685 * is connected through a TCP relay, only. For a friend, this means that the
622 * connection to that particular friend goes through a TCP relay. 686 * connection to that particular friend goes through a TCP relay.
623 */ 687 */
624 TOX_CONNECTION_TCP, 688 TOX_CONNECTION_TCP,
689
625 /** 690 /**
626 * A UDP connection has been established. For the own instance, this means it 691 * A UDP connection has been established. For the own instance, this means it
627 * is able to send UDP packets to DHT nodes, but may still be connected to 692 * is able to send UDP packets to DHT nodes, but may still be connected to
628 * a TCP relay. For a friend, this means that the connection to that 693 * a TCP relay. For a friend, this means that the connection to that
629 * particular friend was built using direct UDP packets. 694 * particular friend was built using direct UDP packets.
630 */ 695 */
631 TOX_CONNECTION_UDP 696 TOX_CONNECTION_UDP,
697
632} TOX_CONNECTION; 698} TOX_CONNECTION;
633 699
634 700
@@ -639,13 +705,11 @@ typedef enum TOX_CONNECTION {
639TOX_CONNECTION tox_self_get_connection_status(const Tox *tox); 705TOX_CONNECTION tox_self_get_connection_status(const Tox *tox);
640 706
641/** 707/**
642 * The function type for the `self_connection_status` callback. 708 * @param connection_status Whether we are connected to the DHT.
643 *
644 * @param connection_status Equal to the return value of
645 * tox_self_get_connection_status.
646 */ 709 */
647typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_status, void *user_data); 710typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_status, void *user_data);
648 711
712
649/** 713/**
650 * Set the callback for the `self_connection_status` event. Pass NULL to unset. 714 * Set the callback for the `self_connection_status` event. Pass NULL to unset.
651 * 715 *
@@ -657,16 +721,14 @@ typedef void tox_self_connection_status_cb(Tox *tox, TOX_CONNECTION connection_s
657 * 721 *
658 * TODO: how long should a client wait before bootstrapping again? 722 * TODO: how long should a client wait before bootstrapping again?
659 */ 723 */
660void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *function, void *user_data); 724void tox_callback_self_connection_status(Tox *tox, tox_self_connection_status_cb *callback, void *user_data);
661
662 725
663/** 726/**
664 * Return the time in milliseconds before tox_iteration() should be called again 727 * Return the time in milliseconds before tox_iterate() should be called again
665 * for optimal performance. 728 * for optimal performance.
666 */ 729 */
667uint32_t tox_iteration_interval(const Tox *tox); 730uint32_t tox_iteration_interval(const Tox *tox);
668 731
669
670/** 732/**
671 * The main loop that needs to be run in intervals of tox_iteration_interval() 733 * The main loop that needs to be run in intervals of tox_iteration_interval()
672 * milliseconds. 734 * milliseconds.
@@ -681,6 +743,7 @@ void tox_iterate(Tox *tox);
681 ******************************************************************************/ 743 ******************************************************************************/
682 744
683 745
746
684/** 747/**
685 * Writes the Tox friend address of the client to a byte array. The address is 748 * Writes the Tox friend address of the client to a byte array. The address is
686 * not in human-readable format. If a client wants to display the address, 749 * not in human-readable format. If a client wants to display the address,
@@ -692,7 +755,6 @@ void tox_iterate(Tox *tox);
692 */ 755 */
693void tox_self_get_address(const Tox *tox, uint8_t *address); 756void tox_self_get_address(const Tox *tox, uint8_t *address);
694 757
695
696/** 758/**
697 * Set the 4-byte nospam part of the address. 759 * Set the 4-byte nospam part of the address.
698 * 760 *
@@ -706,7 +768,7 @@ void tox_self_set_nospam(Tox *tox, uint32_t nospam);
706uint32_t tox_self_get_nospam(const Tox *tox); 768uint32_t tox_self_get_nospam(const Tox *tox);
707 769
708/** 770/**
709 * Copy the Tox Public Key (long term public key) from the Tox object. 771 * Copy the Tox Public Key (long term) from the Tox object.
710 * 772 *
711 * @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If 773 * @param public_key A memory region of at least TOX_PUBLIC_KEY_SIZE bytes. If
712 * this parameter is NULL, this function has no effect. 774 * this parameter is NULL, this function has no effect.
@@ -714,7 +776,7 @@ uint32_t tox_self_get_nospam(const Tox *tox);
714void tox_self_get_public_key(const Tox *tox, uint8_t *public_key); 776void tox_self_get_public_key(const Tox *tox, uint8_t *public_key);
715 777
716/** 778/**
717 * Copy the secret key from the Tox object. 779 * Copy the Tox Secret Key from the Tox object.
718 * 780 *
719 * @param secret_key A memory region of at least TOX_SECRET_KEY_SIZE bytes. If 781 * @param secret_key A memory region of at least TOX_SECRET_KEY_SIZE bytes. If
720 * this parameter is NULL, this function has no effect. 782 * this parameter is NULL, this function has no effect.
@@ -729,17 +791,28 @@ void tox_self_get_secret_key(const Tox *tox, uint8_t *secret_key);
729 ******************************************************************************/ 791 ******************************************************************************/
730 792
731 793
794
732/** 795/**
733 * Common error codes for all functions that set a piece of user-visible 796 * Common error codes for all functions that set a piece of user-visible
734 * client information. 797 * client information.
735 */ 798 */
736typedef enum TOX_ERR_SET_INFO { 799typedef enum TOX_ERR_SET_INFO {
800
801 /**
802 * The function returned successfully.
803 */
737 TOX_ERR_SET_INFO_OK, 804 TOX_ERR_SET_INFO_OK,
805
806 /**
807 * One of the arguments to the function was NULL when it was not expected.
808 */
738 TOX_ERR_SET_INFO_NULL, 809 TOX_ERR_SET_INFO_NULL,
810
739 /** 811 /**
740 * Information length exceeded maximum permissible size. 812 * Information length exceeded maximum permissible size.
741 */ 813 */
742 TOX_ERR_SET_INFO_TOO_LONG 814 TOX_ERR_SET_INFO_TOO_LONG,
815
743} TOX_ERR_SET_INFO; 816} TOX_ERR_SET_INFO;
744 817
745 818
@@ -787,11 +860,10 @@ void tox_self_get_name(const Tox *tox, uint8_t *name);
787 * length is 0, the status parameter is ignored (it can be NULL), and the 860 * length is 0, the status parameter is ignored (it can be NULL), and the
788 * user status is set back to empty. 861 * user status is set back to empty.
789 */ 862 */
790bool tox_self_set_status_message(Tox *tox, const uint8_t *status, size_t length, TOX_ERR_SET_INFO *error); 863bool tox_self_set_status_message(Tox *tox, const uint8_t *status_message, size_t length, TOX_ERR_SET_INFO *error);
791 864
792/** 865/**
793 * Return the length of the current status message as passed to 866 * Return the length of the current status message as passed to tox_self_set_status_message.
794 * tox_self_set_status_message.
795 * 867 *
796 * If no status message was set before calling this function, the status 868 * If no status message was set before calling this function, the status
797 * is empty, and this function returns 0. 869 * is empty, and this function returns 0.
@@ -806,21 +878,20 @@ size_t tox_self_get_status_message_size(const Tox *tox);
806 * If no status message was set before calling this function, the status is 878 * If no status message was set before calling this function, the status is
807 * empty, and this function has no effect. 879 * empty, and this function has no effect.
808 * 880 *
809 * Call tox_self_status_message_size to find out how much memory to allocate for 881 * Call tox_self_get_status_message_size to find out how much memory to allocate for
810 * the result. 882 * the result.
811 * 883 *
812 * @param status A valid memory location large enough to hold the status message. 884 * @param status A valid memory location large enough to hold the status message.
813 * If this parameter is NULL, the function has no effect. 885 * If this parameter is NULL, the function has no effect.
814 */ 886 */
815void tox_self_get_status_message(const Tox *tox, uint8_t *status); 887void tox_self_get_status_message(const Tox *tox, uint8_t *status_message);
816
817 888
818/** 889/**
819 * Set the client's user status. 890 * Set the client's user status.
820 * 891 *
821 * @param user_status One of the user statuses listed in the enumeration above. 892 * @param user_status One of the user statuses listed in the enumeration above.
822 */ 893 */
823void tox_self_set_status(Tox *tox, TOX_USER_STATUS user_status); 894void tox_self_set_status(Tox *tox, TOX_USER_STATUS status);
824 895
825/** 896/**
826 * Returns the client's user status. 897 * Returns the client's user status.
@@ -835,42 +906,60 @@ TOX_USER_STATUS tox_self_get_status(const Tox *tox);
835 ******************************************************************************/ 906 ******************************************************************************/
836 907
837 908
909
838typedef enum TOX_ERR_FRIEND_ADD { 910typedef enum TOX_ERR_FRIEND_ADD {
911
912 /**
913 * The function returned successfully.
914 */
839 TOX_ERR_FRIEND_ADD_OK, 915 TOX_ERR_FRIEND_ADD_OK,
916
917 /**
918 * One of the arguments to the function was NULL when it was not expected.
919 */
840 TOX_ERR_FRIEND_ADD_NULL, 920 TOX_ERR_FRIEND_ADD_NULL,
921
841 /** 922 /**
842 * The length of the friend request message exceeded 923 * The length of the friend request message exceeded
843 * TOX_MAX_FRIEND_REQUEST_LENGTH. 924 * TOX_MAX_FRIEND_REQUEST_LENGTH.
844 */ 925 */
845 TOX_ERR_FRIEND_ADD_TOO_LONG, 926 TOX_ERR_FRIEND_ADD_TOO_LONG,
927
846 /** 928 /**
847 * The friend request message was empty. This, and the TOO_LONG code will 929 * The friend request message was empty. This, and the TOO_LONG code will
848 * never be returned from tox_friend_add_norequest. 930 * never be returned from tox_friend_add_norequest.
849 */ 931 */
850 TOX_ERR_FRIEND_ADD_NO_MESSAGE, 932 TOX_ERR_FRIEND_ADD_NO_MESSAGE,
933
851 /** 934 /**
852 * The friend address belongs to the sending client. 935 * The friend address belongs to the sending client.
853 */ 936 */
854 TOX_ERR_FRIEND_ADD_OWN_KEY, 937 TOX_ERR_FRIEND_ADD_OWN_KEY,
938
855 /** 939 /**
856 * A friend request has already been sent, or the address belongs to a friend 940 * A friend request has already been sent, or the address belongs to a friend
857 * that is already on the friend list. 941 * that is already on the friend list.
858 */ 942 */
859 TOX_ERR_FRIEND_ADD_ALREADY_SENT, 943 TOX_ERR_FRIEND_ADD_ALREADY_SENT,
944
860 /** 945 /**
861 * The friend address checksum failed. 946 * The friend address checksum failed.
862 */ 947 */
863 TOX_ERR_FRIEND_ADD_BAD_CHECKSUM, 948 TOX_ERR_FRIEND_ADD_BAD_CHECKSUM,
949
864 /** 950 /**
865 * The friend was already there, but the nospam value was different. 951 * The friend was already there, but the nospam value was different.
866 */ 952 */
867 TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM, 953 TOX_ERR_FRIEND_ADD_SET_NEW_NOSPAM,
954
868 /** 955 /**
869 * A memory allocation failed when trying to increase the friend list size. 956 * A memory allocation failed when trying to increase the friend list size.
870 */ 957 */
871 TOX_ERR_FRIEND_ADD_MALLOC 958 TOX_ERR_FRIEND_ADD_MALLOC,
959
872} TOX_ERR_FRIEND_ADD; 960} TOX_ERR_FRIEND_ADD;
873 961
962
874/** 963/**
875 * Add a friend to the friend list and send a friend request. 964 * Add a friend to the friend list and send a friend request.
876 * 965 *
@@ -897,7 +986,6 @@ typedef enum TOX_ERR_FRIEND_ADD {
897uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length, 986uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message, size_t length,
898 TOX_ERR_FRIEND_ADD *error); 987 TOX_ERR_FRIEND_ADD *error);
899 988
900
901/** 989/**
902 * Add a friend without sending a friend request. 990 * Add a friend without sending a friend request.
903 * 991 *
@@ -918,28 +1006,31 @@ uint32_t tox_friend_add(Tox *tox, const uint8_t *address, const uint8_t *message
918 */ 1006 */
919uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error); 1007uint32_t tox_friend_add_norequest(Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_ADD *error);
920 1008
921
922typedef enum TOX_ERR_FRIEND_DELETE { 1009typedef enum TOX_ERR_FRIEND_DELETE {
1010
1011 /**
1012 * The function returned successfully.
1013 */
923 TOX_ERR_FRIEND_DELETE_OK, 1014 TOX_ERR_FRIEND_DELETE_OK,
1015
924 /** 1016 /**
925 * There was no friend with the given friend number. No friends were deleted. 1017 * There was no friend with the given friend number. No friends were deleted.
926 */ 1018 */
927 TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND 1019 TOX_ERR_FRIEND_DELETE_FRIEND_NOT_FOUND,
1020
928} TOX_ERR_FRIEND_DELETE; 1021} TOX_ERR_FRIEND_DELETE;
929 1022
1023
930/** 1024/**
931 * Remove a friend from the friend list. 1025 * Remove a friend from the friend list.
932 * Other friend numbers are unchanged.
933 * The friend_number can be reused by toxcore as a friend number for a new friend.
934 * 1026 *
935 * This does not notify the friend of their deletion. After calling this 1027 * This does not notify the friend of their deletion. After calling this
936 * function, this client will appear offline to the friend and no communication 1028 * function, this client will appear offline to the friend and no communication
937 * can occur between the two. 1029 * can occur between the two.
938 * 1030 *
939 * @friend_number Friend number for the friend to be deleted. 1031 * @param friend_number Friend number for the friend to be deleted.
940 * 1032 *
941 * @return true on success. 1033 * @return true on success.
942 * @see tox_friend_add for detailed description of friend numbers.
943 */ 1034 */
944bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error); 1035bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *error);
945 1036
@@ -951,15 +1042,27 @@ bool tox_friend_delete(Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_DELETE *
951 ******************************************************************************/ 1042 ******************************************************************************/
952 1043
953 1044
1045
954typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY { 1046typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
1047
1048 /**
1049 * The function returned successfully.
1050 */
955 TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK, 1051 TOX_ERR_FRIEND_BY_PUBLIC_KEY_OK,
1052
1053 /**
1054 * One of the arguments to the function was NULL when it was not expected.
1055 */
956 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL, 1056 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NULL,
1057
957 /** 1058 /**
958 * No friend with the given Public Key exists on the friend list. 1059 * No friend with the given Public Key exists on the friend list.
959 */ 1060 */
960 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND 1061 TOX_ERR_FRIEND_BY_PUBLIC_KEY_NOT_FOUND,
1062
961} TOX_ERR_FRIEND_BY_PUBLIC_KEY; 1063} TOX_ERR_FRIEND_BY_PUBLIC_KEY;
962 1064
1065
963/** 1066/**
964 * Return the friend number associated with that Public Key. 1067 * Return the friend number associated with that Public Key.
965 * 1068 *
@@ -968,15 +1071,45 @@ typedef enum TOX_ERR_FRIEND_BY_PUBLIC_KEY {
968 */ 1071 */
969uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error); 1072uint32_t tox_friend_by_public_key(const Tox *tox, const uint8_t *public_key, TOX_ERR_FRIEND_BY_PUBLIC_KEY *error);
970 1073
1074/**
1075 * Checks if a friend with the given friend number exists and returns true if
1076 * it does.
1077 */
1078bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
1079
1080/**
1081 * Return the number of friends on the friend list.
1082 *
1083 * This function can be used to determine how much memory to allocate for
1084 * tox_self_get_friend_list.
1085 */
1086size_t tox_self_get_friend_list_size(const Tox *tox);
1087
1088/**
1089 * Copy a list of valid friend numbers into an array.
1090 *
1091 * Call tox_self_get_friend_list_size to determine the number of elements to allocate.
1092 *
1093 * @param list A memory region with enough space to hold the friend list. If
1094 * this parameter is NULL, this function has no effect.
1095 */
1096void tox_self_get_friend_list(const Tox *tox, uint32_t *friend_list);
971 1097
972typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY { 1098typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
1099
1100 /**
1101 * The function returned successfully.
1102 */
973 TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK, 1103 TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK,
1104
974 /** 1105 /**
975 * No friend with the given number exists on the friend list. 1106 * No friend with the given number exists on the friend list.
976 */ 1107 */
977 TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND 1108 TOX_ERR_FRIEND_GET_PUBLIC_KEY_FRIEND_NOT_FOUND,
1109
978} TOX_ERR_FRIEND_GET_PUBLIC_KEY; 1110} TOX_ERR_FRIEND_GET_PUBLIC_KEY;
979 1111
1112
980/** 1113/**
981 * Copies the Public Key associated with a given friend number to a byte array. 1114 * Copies the Public Key associated with a given friend number to a byte array.
982 * 1115 *
@@ -989,21 +1122,21 @@ typedef enum TOX_ERR_FRIEND_GET_PUBLIC_KEY {
989bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key, 1122bool tox_friend_get_public_key(const Tox *tox, uint32_t friend_number, uint8_t *public_key,
990 TOX_ERR_FRIEND_GET_PUBLIC_KEY *error); 1123 TOX_ERR_FRIEND_GET_PUBLIC_KEY *error);
991 1124
992
993/**
994 * Checks if a friend with the given friend number exists and returns true if
995 * it does.
996 */
997bool tox_friend_exists(const Tox *tox, uint32_t friend_number);
998
999typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE { 1125typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
1126
1127 /**
1128 * The function returned successfully.
1129 */
1000 TOX_ERR_FRIEND_GET_LAST_ONLINE_OK, 1130 TOX_ERR_FRIEND_GET_LAST_ONLINE_OK,
1131
1001 /** 1132 /**
1002 * No friend with the given number exists on the friend list. 1133 * No friend with the given number exists on the friend list.
1003 */ 1134 */
1004 TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND, 1135 TOX_ERR_FRIEND_GET_LAST_ONLINE_FRIEND_NOT_FOUND,
1136
1005} TOX_ERR_FRIEND_GET_LAST_ONLINE; 1137} TOX_ERR_FRIEND_GET_LAST_ONLINE;
1006 1138
1139
1007/** 1140/**
1008 * Return a unix-time timestamp of the last time the friend associated with a given 1141 * Return a unix-time timestamp of the last time the friend associated with a given
1009 * friend number was seen online. This function will return UINT64_MAX on error. 1142 * friend number was seen online. This function will return UINT64_MAX on error.
@@ -1012,26 +1145,6 @@ typedef enum TOX_ERR_FRIEND_GET_LAST_ONLINE {
1012 */ 1145 */
1013uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error); 1146uint64_t tox_friend_get_last_online(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_GET_LAST_ONLINE *error);
1014 1147
1015/**
1016 * Return the number of friends on the friend list.
1017 *
1018 * This function can be used to determine how much memory to allocate for
1019 * tox_self_get_friend_list.
1020 */
1021size_t tox_self_get_friend_list_size(const Tox *tox);
1022
1023
1024/**
1025 * Copy a list of valid friend numbers into an array.
1026 *
1027 * Call tox_self_get_friend_list_size to determine the number of elements to allocate.
1028 *
1029 * @param list A memory region with enough space to hold the friend list. If
1030 * this parameter is NULL, this function has no effect.
1031 */
1032void tox_self_get_friend_list(const Tox *tox, uint32_t *list);
1033
1034
1035 1148
1036/******************************************************************************* 1149/*******************************************************************************
1037 * 1150 *
@@ -1040,27 +1153,35 @@ void tox_self_get_friend_list(const Tox *tox, uint32_t *list);
1040 ******************************************************************************/ 1153 ******************************************************************************/
1041 1154
1042 1155
1156
1043/** 1157/**
1044 * Common error codes for friend state query functions. 1158 * Common error codes for friend state query functions.
1045 */ 1159 */
1046typedef enum TOX_ERR_FRIEND_QUERY { 1160typedef enum TOX_ERR_FRIEND_QUERY {
1161
1162 /**
1163 * The function returned successfully.
1164 */
1047 TOX_ERR_FRIEND_QUERY_OK, 1165 TOX_ERR_FRIEND_QUERY_OK,
1166
1048 /** 1167 /**
1049 * The pointer parameter for storing the query result (name, message) was 1168 * The pointer parameter for storing the query result (name, message) was
1050 * NULL. Unlike the `_self_` variants of these functions, which have no effect 1169 * NULL. Unlike the `_self_` variants of these functions, which have no effect
1051 * when a parameter is NULL, these functions return an error in that case. 1170 * when a parameter is NULL, these functions return an error in that case.
1052 */ 1171 */
1053 TOX_ERR_FRIEND_QUERY_NULL, 1172 TOX_ERR_FRIEND_QUERY_NULL,
1173
1054 /** 1174 /**
1055 * The friend_number did not designate a valid friend. 1175 * The friend_number did not designate a valid friend.
1056 */ 1176 */
1057 TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND 1177 TOX_ERR_FRIEND_QUERY_FRIEND_NOT_FOUND,
1178
1058} TOX_ERR_FRIEND_QUERY; 1179} TOX_ERR_FRIEND_QUERY;
1059 1180
1060 1181
1061/** 1182/**
1062 * Return the length of the friend's name. If the friend number is invalid, the 1183 * Return the length of the friend's name. If the friend number is invalid, the
1063 * return value is SIZE_MAX. 1184 * return value is unspecified.
1064 * 1185 *
1065 * The return value is equal to the `length` argument received by the last 1186 * The return value is equal to the `length` argument received by the last
1066 * `friend_name` callback. 1187 * `friend_name` callback.
@@ -1084,8 +1205,6 @@ size_t tox_friend_get_name_size(const Tox *tox, uint32_t friend_number, TOX_ERR_
1084bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error); 1205bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name, TOX_ERR_FRIEND_QUERY *error);
1085 1206
1086/** 1207/**
1087 * The function type for the `friend_name` callback.
1088 *
1089 * @param friend_number The friend number of the friend whose name changed. 1208 * @param friend_number The friend number of the friend whose name changed.
1090 * @param name A byte array containing the same data as 1209 * @param name A byte array containing the same data as
1091 * tox_friend_get_name would write to its `name` parameter. 1210 * tox_friend_get_name would write to its `name` parameter.
@@ -1094,13 +1213,13 @@ bool tox_friend_get_name(const Tox *tox, uint32_t friend_number, uint8_t *name,
1094 */ 1213 */
1095typedef void tox_friend_name_cb(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data); 1214typedef void tox_friend_name_cb(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data);
1096 1215
1216
1097/** 1217/**
1098 * Set the callback for the `friend_name` event. Pass NULL to unset. 1218 * Set the callback for the `friend_name` event. Pass NULL to unset.
1099 * 1219 *
1100 * This event is triggered when a friend changes their name. 1220 * This event is triggered when a friend changes their name.
1101 */ 1221 */
1102void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *function, void *user_data); 1222void tox_callback_friend_name(Tox *tox, tox_friend_name_cb *callback, void *user_data);
1103
1104 1223
1105/** 1224/**
1106 * Return the length of the friend's status message. If the friend number is 1225 * Return the length of the friend's status message. If the friend number is
@@ -1112,37 +1231,35 @@ size_t tox_friend_get_status_message_size(const Tox *tox, uint32_t friend_number
1112 * Write the name of the friend designated by the given friend number to a byte 1231 * Write the name of the friend designated by the given friend number to a byte
1113 * array. 1232 * array.
1114 * 1233 *
1115 * Call tox_friend_get_name_size to determine the allocation size for the `name` 1234 * Call tox_friend_get_status_message_size to determine the allocation size for the `status_name`
1116 * parameter. 1235 * parameter.
1117 * 1236 *
1118 * The data written to `message` is equal to the data received by the last 1237 * The data written to `status_message` is equal to the data received by the last
1119 * `friend_status_message` callback. 1238 * `friend_status_message` callback.
1120 * 1239 *
1121 * @param name A valid memory region large enough to store the friend's name. 1240 * @param name A valid memory region large enough to store the friend's name.
1122 */ 1241 */
1123bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *message, 1242bool tox_friend_get_status_message(const Tox *tox, uint32_t friend_number, uint8_t *status_message,
1124 TOX_ERR_FRIEND_QUERY *error); 1243 TOX_ERR_FRIEND_QUERY *error);
1125 1244
1126/** 1245/**
1127 * The function type for the `friend_status_message` callback.
1128 *
1129 * @param friend_number The friend number of the friend whose status message 1246 * @param friend_number The friend number of the friend whose status message
1130 * changed. 1247 * changed.
1131 * @param message A byte array containing the same data as 1248 * @param message A byte array containing the same data as
1132 * tox_friend_get_status_message would write to its `message` parameter. 1249 * tox_friend_get_status_message would write to its `status_message` parameter.
1133 * @param length A value equal to the return value of 1250 * @param length A value equal to the return value of
1134 * tox_friend_get_status_message_size. 1251 * tox_friend_get_status_message_size.
1135 */ 1252 */
1136typedef void tox_friend_status_message_cb(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, 1253typedef void tox_friend_status_message_cb(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
1137 void *user_data); 1254 void *user_data);
1255
1138 1256
1139/** 1257/**
1140 * Set the callback for the `friend_status_message` event. Pass NULL to unset. 1258 * Set the callback for the `friend_status_message` event. Pass NULL to unset.
1141 * 1259 *
1142 * This event is triggered when a friend changes their status message. 1260 * This event is triggered when a friend changes their status message.
1143 */ 1261 */
1144void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *function, void *user_data); 1262void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *callback, void *user_data);
1145
1146 1263
1147/** 1264/**
1148 * Return the friend's user status (away/busy/...). If the friend number is 1265 * Return the friend's user status (away/busy/...). If the friend number is
@@ -1154,21 +1271,19 @@ void tox_callback_friend_status_message(Tox *tox, tox_friend_status_message_cb *
1154TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1271TOX_USER_STATUS tox_friend_get_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1155 1272
1156/** 1273/**
1157 * The function type for the `friend_status` callback.
1158 *
1159 * @param friend_number The friend number of the friend whose user status 1274 * @param friend_number The friend number of the friend whose user status
1160 * changed. 1275 * changed.
1161 * @param status The new user status. 1276 * @param status The new user status.
1162 */ 1277 */
1163typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, TOX_USER_STATUS status, void *user_data); 1278typedef void tox_friend_status_cb(Tox *tox, uint32_t friend_number, TOX_USER_STATUS status, void *user_data);
1164 1279
1280
1165/** 1281/**
1166 * Set the callback for the `friend_status` event. Pass NULL to unset. 1282 * Set the callback for the `friend_status` event. Pass NULL to unset.
1167 * 1283 *
1168 * This event is triggered when a friend changes their user status. 1284 * This event is triggered when a friend changes their user status.
1169 */ 1285 */
1170void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *function, void *user_data); 1286void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *callback, void *user_data);
1171
1172 1287
1173/** 1288/**
1174 * Check whether a friend is currently connected to this client. 1289 * Check whether a friend is currently connected to this client.
@@ -1185,28 +1300,25 @@ void tox_callback_friend_status(Tox *tox, tox_friend_status_cb *function, void *
1185TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1300TOX_CONNECTION tox_friend_get_connection_status(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1186 1301
1187/** 1302/**
1188 * The function type for the `friend_connection_status` callback.
1189 *
1190 * @param friend_number The friend number of the friend whose connection status 1303 * @param friend_number The friend number of the friend whose connection status
1191 * changed. 1304 * changed.
1192 * @param connection_status The result of calling 1305 * @param connection_status The result of calling
1193 * tox_friend_get_connection_status on the passed friend_number. 1306 * tox_friend_get_connection_status on the passed friend_number.
1194 */ 1307 */
1195typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, TOX_CONNECTION connection_status, 1308typedef void tox_friend_connection_status_cb(Tox *tox, uint32_t friend_number, TOX_CONNECTION connection_status,
1196 void *user_data); 1309 void *user_data);
1310
1197 1311
1198/** 1312/**
1199 * Set the callback for the `friend_connection_status` event. Pass NULL to 1313 * Set the callback for the `friend_connection_status` event. Pass NULL to unset.
1200 * unset.
1201 * 1314 *
1202 * This event is triggered when a friend goes offline after having been online, 1315 * This event is triggered when a friend goes offline after having been online,
1203 * or when a friend goes online. 1316 * or when a friend goes online.
1204 * 1317 *
1205 * This callback is not called when adding friends. It is assumed that when 1318 * This callback is not called when adding friends. It is assumed that when
1206 * adding friends, their connection status is offline. 1319 * adding friends, their connection status is initially offline.
1207 */ 1320 */
1208void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *function, void *user_data); 1321void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_status_cb *callback, void *user_data);
1209
1210 1322
1211/** 1323/**
1212 * Check whether a friend is currently typing a message. 1324 * Check whether a friend is currently typing a message.
@@ -1220,8 +1332,6 @@ void tox_callback_friend_connection_status(Tox *tox, tox_friend_connection_statu
1220bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error); 1332bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEND_QUERY *error);
1221 1333
1222/** 1334/**
1223 * The function type for the `friend_typing` callback.
1224 *
1225 * @param friend_number The friend number of the friend who started or stopped 1335 * @param friend_number The friend number of the friend who started or stopped
1226 * typing. 1336 * typing.
1227 * @param is_typing The result of calling tox_friend_get_typing on the passed 1337 * @param is_typing The result of calling tox_friend_get_typing on the passed
@@ -1229,12 +1339,13 @@ bool tox_friend_get_typing(const Tox *tox, uint32_t friend_number, TOX_ERR_FRIEN
1229 */ 1339 */
1230typedef void tox_friend_typing_cb(Tox *tox, uint32_t friend_number, bool is_typing, void *user_data); 1340typedef void tox_friend_typing_cb(Tox *tox, uint32_t friend_number, bool is_typing, void *user_data);
1231 1341
1342
1232/** 1343/**
1233 * Set the callback for the `friend_typing` event. Pass NULL to unset. 1344 * Set the callback for the `friend_typing` event. Pass NULL to unset.
1234 * 1345 *
1235 * This event is triggered when a friend starts or stops typing. 1346 * This event is triggered when a friend starts or stops typing.
1236 */ 1347 */
1237void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *function, void *user_data); 1348void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *callback, void *user_data);
1238 1349
1239 1350
1240/******************************************************************************* 1351/*******************************************************************************
@@ -1244,90 +1355,115 @@ void tox_callback_friend_typing(Tox *tox, tox_friend_typing_cb *function, void *
1244 ******************************************************************************/ 1355 ******************************************************************************/
1245 1356
1246 1357
1358
1247typedef enum TOX_ERR_SET_TYPING { 1359typedef enum TOX_ERR_SET_TYPING {
1360
1361 /**
1362 * The function returned successfully.
1363 */
1248 TOX_ERR_SET_TYPING_OK, 1364 TOX_ERR_SET_TYPING_OK,
1365
1249 /** 1366 /**
1250 * The friend number did not designate a valid friend. 1367 * The friend number did not designate a valid friend.
1251 */ 1368 */
1252 TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND 1369 TOX_ERR_SET_TYPING_FRIEND_NOT_FOUND,
1370
1253} TOX_ERR_SET_TYPING; 1371} TOX_ERR_SET_TYPING;
1254 1372
1373
1255/** 1374/**
1256 * Set the client's typing status for a friend. 1375 * Set the client's typing status for a friend.
1257 * 1376 *
1258 * The client is responsible for turning it on or off. 1377 * The client is responsible for turning it on or off.
1259 * 1378 *
1260 * @param friend_number The friend to which the client is typing a message. 1379 * @param friend_number The friend to which the client is typing a message.
1261 * @param is_typing The typing status. True means the client is typing. 1380 * @param typing The typing status. True means the client is typing.
1262 * 1381 *
1263 * @return true on success. 1382 * @return true on success.
1264 */ 1383 */
1265bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool is_typing, TOX_ERR_SET_TYPING *error); 1384bool tox_self_set_typing(Tox *tox, uint32_t friend_number, bool typing, TOX_ERR_SET_TYPING *error);
1266
1267 1385
1268typedef enum TOX_ERR_FRIEND_SEND_MESSAGE { 1386typedef enum TOX_ERR_FRIEND_SEND_MESSAGE {
1387
1388 /**
1389 * The function returned successfully.
1390 */
1269 TOX_ERR_FRIEND_SEND_MESSAGE_OK, 1391 TOX_ERR_FRIEND_SEND_MESSAGE_OK,
1392
1393 /**
1394 * One of the arguments to the function was NULL when it was not expected.
1395 */
1270 TOX_ERR_FRIEND_SEND_MESSAGE_NULL, 1396 TOX_ERR_FRIEND_SEND_MESSAGE_NULL,
1397
1271 /** 1398 /**
1272 * The friend number did not designate a valid friend. 1399 * The friend number did not designate a valid friend.
1273 */ 1400 */
1274 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND, 1401 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_FOUND,
1402
1275 /** 1403 /**
1276 * This client is currently not connected to the friend. 1404 * This client is currently not connected to the friend.
1277 */ 1405 */
1278 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED, 1406 TOX_ERR_FRIEND_SEND_MESSAGE_FRIEND_NOT_CONNECTED,
1407
1279 /** 1408 /**
1280 * An allocation error occurred while increasing the send queue size. 1409 * An allocation error occurred while increasing the send queue size.
1281 */ 1410 */
1282 TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ, 1411 TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ,
1412
1283 /** 1413 /**
1284 * Message length exceeded TOX_MAX_MESSAGE_LENGTH. 1414 * Message length exceeded TOX_MAX_MESSAGE_LENGTH.
1285 */ 1415 */
1286 TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, 1416 TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG,
1417
1287 /** 1418 /**
1288 * Attempted to send a zero-length message. 1419 * Attempted to send a zero-length message.
1289 */ 1420 */
1290 TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY 1421 TOX_ERR_FRIEND_SEND_MESSAGE_EMPTY,
1422
1291} TOX_ERR_FRIEND_SEND_MESSAGE; 1423} TOX_ERR_FRIEND_SEND_MESSAGE;
1292 1424
1425
1293/** 1426/**
1294 * Send a text chat message to an online friend. 1427 * Send a text chat message to an online friend.
1295 * 1428 *
1296 * This function creates a chat message packet and pushes it into the send 1429 * This function creates a chat message packet and pushes it into the send
1297 * queue. 1430 * queue.
1298 * 1431 *
1299 * Type corresponds to the message type, for a list of valid types see TOX_MESSAGE_TYPE.
1300 *
1301 * The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages 1432 * The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages
1302 * must be split by the client and sent as separate messages. Other clients can 1433 * must be split by the client and sent as separate messages. Other clients can
1303 * then reassemble the fragments. Messages may not be empty. 1434 * then reassemble the fragments. Messages may not be empty.
1304 * 1435 *
1305 * The return value of this function is the message ID. If a read receipt is 1436 * The return value of this function is the message ID. If a read receipt is
1306 * received, the triggered `read_receipt` event will be passed this message ID. 1437 * received, the triggered `friend_read_receipt` event will be passed this message ID.
1307 * 1438 *
1308 * Message IDs are unique per friend. The first message ID is 0. Message IDs are 1439 * Message IDs are unique per friend. The first message ID is 0. Message IDs are
1309 * incremented by 1 each time a message is sent. If UINT32_MAX messages were 1440 * incremented by 1 each time a message is sent. If UINT32_MAX messages were
1310 * sent, the next message ID is 0. 1441 * sent, the next message ID is 0.
1442 *
1443 * @param type Message type (normal, action, ...).
1444 * @param friend_number The friend number of the friend to send the message to.
1445 * @param message A non-NULL pointer to the first element of a byte array
1446 * containing the message text.
1447 * @param length Length of the message to be sent.
1311 */ 1448 */
1312uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message, 1449uint32_t tox_friend_send_message(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
1313 size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error); 1450 size_t length, TOX_ERR_FRIEND_SEND_MESSAGE *error);
1314 1451
1315/** 1452/**
1316 * The function type for the `read_receipt` callback.
1317 *
1318 * @param friend_number The friend number of the friend who received the message. 1453 * @param friend_number The friend number of the friend who received the message.
1319 * @param message_id The message ID as returned from tox_friend_send_message 1454 * @param message_id The message ID as returned from tox_friend_send_message
1320 * corresponding to the message sent. 1455 * corresponding to the message sent.
1321 */ 1456 */
1322typedef void tox_friend_read_receipt_cb(Tox *tox, uint32_t friend_number, uint32_t message_id, void *user_data); 1457typedef void tox_friend_read_receipt_cb(Tox *tox, uint32_t friend_number, uint32_t message_id, void *user_data);
1323 1458
1459
1324/** 1460/**
1325 * Set the callback for the `read_receipt` event. Pass NULL to unset. 1461 * Set the callback for the `friend_read_receipt` event. Pass NULL to unset.
1326 * 1462 *
1327 * This event is triggered when the friend receives the message sent with 1463 * This event is triggered when the friend receives the message sent with
1328 * tox_friend_send_message with the corresponding message ID. 1464 * tox_friend_send_message with the corresponding message ID.
1329 */ 1465 */
1330void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *function, void *user_data); 1466void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *callback, void *user_data);
1331 1467
1332 1468
1333/******************************************************************************* 1469/*******************************************************************************
@@ -1337,41 +1473,46 @@ void tox_callback_friend_read_receipt(Tox *tox, tox_friend_read_receipt_cb *func
1337 ******************************************************************************/ 1473 ******************************************************************************/
1338 1474
1339 1475
1476
1340/** 1477/**
1341 * The function type for the `friend_request` callback.
1342 *
1343 * @param public_key The Public Key of the user who sent the friend request. 1478 * @param public_key The Public Key of the user who sent the friend request.
1479 * @param time_delta A delta in seconds between when the message was composed
1480 * and when it is being transmitted. For messages that are sent immediately,
1481 * it will be 0. If a message was written and couldn't be sent immediately
1482 * (due to a connection failure, for example), the time_delta is an
1483 * approximation of when it was composed.
1344 * @param message The message they sent along with the request. 1484 * @param message The message they sent along with the request.
1345 * @param length The size of the message byte array. 1485 * @param length The size of the message byte array.
1346 */ 1486 */
1347typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length, 1487typedef void tox_friend_request_cb(Tox *tox, const uint8_t *public_key, const uint8_t *message, size_t length,
1348 void *user_data); 1488 void *user_data);
1349 1489
1490
1350/** 1491/**
1351 * Set the callback for the `friend_request` event. Pass NULL to unset. 1492 * Set the callback for the `friend_request` event. Pass NULL to unset.
1352 * 1493 *
1353 * This event is triggered when a friend request is received. 1494 * This event is triggered when a friend request is received.
1354 */ 1495 */
1355void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *function, void *user_data); 1496void tox_callback_friend_request(Tox *tox, tox_friend_request_cb *callback, void *user_data);
1356
1357 1497
1358/** 1498/**
1359 * The function type for the `friend_message` callback.
1360 *
1361 * @param friend_number The friend number of the friend who sent the message. 1499 * @param friend_number The friend number of the friend who sent the message.
1362 * @param type The message type, for a list of valid types see TOX_MESSAGE_TYPE. 1500 * @param time_delta Time between composition and sending.
1363 * @param message The message data they sent. 1501 * @param message The message data they sent.
1364 * @param length The size of the message byte array. 1502 * @param length The size of the message byte array.
1503 *
1504 * @see friend_request for more information on time_delta.
1365 */ 1505 */
1366typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message, 1506typedef void tox_friend_message_cb(Tox *tox, uint32_t friend_number, TOX_MESSAGE_TYPE type, const uint8_t *message,
1367 size_t length, void *user_data); 1507 size_t length, void *user_data);
1368 1508
1509
1369/** 1510/**
1370 * Set the callback for the `friend_message` event. Pass NULL to unset. 1511 * Set the callback for the `friend_message` event. Pass NULL to unset.
1371 * 1512 *
1372 * This event is triggered when a message from a friend is received. 1513 * This event is triggered when a message from a friend is received.
1373 */ 1514 */
1374void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void *user_data); 1515void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *callback, void *user_data);
1375 1516
1376 1517
1377/******************************************************************************* 1518/*******************************************************************************
@@ -1381,12 +1522,36 @@ void tox_callback_friend_message(Tox *tox, tox_friend_message_cb *function, void
1381 ******************************************************************************/ 1522 ******************************************************************************/
1382 1523
1383 1524
1525
1526/**
1527 * Generates a cryptographic hash of the given data.
1528 *
1529 * This function may be used by clients for any purpose, but is provided
1530 * primarily for validating cached avatars. This use is highly recommended to
1531 * avoid unnecessary avatar updates.
1532 *
1533 * If hash is NULL or data is NULL while length is not 0 the function returns false,
1534 * otherwise it returns true.
1535 *
1536 * This function is a wrapper to internal message-digest functions.
1537 *
1538 * @param hash A valid memory location the hash data. It must be at least
1539 * TOX_HASH_LENGTH bytes in size.
1540 * @param data Data to be hashed or NULL.
1541 * @param length Size of the data array or 0.
1542 *
1543 * @return true if hash was not NULL.
1544 */
1545bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length);
1546
1384enum TOX_FILE_KIND { 1547enum TOX_FILE_KIND {
1548
1385 /** 1549 /**
1386 * Arbitrary file data. Clients can choose to handle it based on the file name 1550 * Arbitrary file data. Clients can choose to handle it based on the file name
1387 * or magic or any other way they choose. 1551 * or magic or any other way they choose.
1388 */ 1552 */
1389 TOX_FILE_KIND_DATA, 1553 TOX_FILE_KIND_DATA,
1554
1390 /** 1555 /**
1391 * Avatar filename. This consists of tox_hash(image). 1556 * Avatar filename. This consists of tox_hash(image).
1392 * Avatar data. This consists of the image data. 1557 * Avatar data. This consists of the image data.
@@ -1404,41 +1569,22 @@ enum TOX_FILE_KIND {
1404 * this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL to terminate the avatar 1569 * this hash with a saved hash and send TOX_FILE_CONTROL_CANCEL to terminate the avatar
1405 * transfer if it matches. 1570 * transfer if it matches.
1406 * 1571 *
1407 * When file_size is set to 0 in the transfer request it means that the client has no 1572 * When file_size is set to 0 in the transfer request it means that the client
1408 * avatar. 1573 * has no avatar.
1409 */ 1574 */
1410 TOX_FILE_KIND_AVATAR 1575 TOX_FILE_KIND_AVATAR,
1411};
1412
1413 1576
1414/** 1577};
1415 * Generates a cryptographic hash of the given data.
1416 *
1417 * This function may be used by clients for any purpose, but is provided
1418 * primarily for validating cached avatars. This use is highly recommended to
1419 * avoid unnecessary avatar updates.
1420 *
1421 * If hash is NULL or data is NULL while length is not 0 the function returns false,
1422 * otherwise it returns true.
1423 *
1424 * This function is a wrapper to internal message-digest functions.
1425 *
1426 * @param hash A valid memory location the hash data. It must be at least
1427 * TOX_HASH_LENGTH bytes in size.
1428 * @param data Data to be hashed or NULL.
1429 * @param length Size of the data array or 0.
1430 *
1431 * @return true if hash was not NULL.
1432 */
1433bool tox_hash(uint8_t *hash, const uint8_t *data, size_t length);
1434 1578
1435 1579
1436typedef enum TOX_FILE_CONTROL { 1580typedef enum TOX_FILE_CONTROL {
1581
1437 /** 1582 /**
1438 * Sent by the receiving side to accept a file send request. Also sent after a 1583 * Sent by the receiving side to accept a file send request. Also sent after a
1439 * TOX_FILE_CONTROL_PAUSE command to continue sending or receiving. 1584 * TOX_FILE_CONTROL_PAUSE command to continue sending or receiving.
1440 */ 1585 */
1441 TOX_FILE_CONTROL_RESUME, 1586 TOX_FILE_CONTROL_RESUME,
1587
1442 /** 1588 /**
1443 * Sent by clients to pause the file transfer. The initial state of a file 1589 * Sent by clients to pause the file transfer. The initial state of a file
1444 * transfer is always paused on the receiving side and running on the sending 1590 * transfer is always paused on the receiving side and running on the sending
@@ -1446,47 +1592,62 @@ typedef enum TOX_FILE_CONTROL {
1446 * need to send TOX_FILE_CONTROL_RESUME for the transfer to resume. 1592 * need to send TOX_FILE_CONTROL_RESUME for the transfer to resume.
1447 */ 1593 */
1448 TOX_FILE_CONTROL_PAUSE, 1594 TOX_FILE_CONTROL_PAUSE,
1595
1449 /** 1596 /**
1450 * Sent by the receiving side to reject a file send request before any other 1597 * Sent by the receiving side to reject a file send request before any other
1451 * commands are sent. Also sent by either side to terminate a file transfer. 1598 * commands are sent. Also sent by either side to terminate a file transfer.
1452 */ 1599 */
1453 TOX_FILE_CONTROL_CANCEL 1600 TOX_FILE_CONTROL_CANCEL,
1601
1454} TOX_FILE_CONTROL; 1602} TOX_FILE_CONTROL;
1455 1603
1456 1604
1457typedef enum TOX_ERR_FILE_CONTROL { 1605typedef enum TOX_ERR_FILE_CONTROL {
1606
1607 /**
1608 * The function returned successfully.
1609 */
1458 TOX_ERR_FILE_CONTROL_OK, 1610 TOX_ERR_FILE_CONTROL_OK,
1611
1459 /** 1612 /**
1460 * The friend_number passed did not designate a valid friend. 1613 * The friend_number passed did not designate a valid friend.
1461 */ 1614 */
1462 TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND, 1615 TOX_ERR_FILE_CONTROL_FRIEND_NOT_FOUND,
1616
1463 /** 1617 /**
1464 * This client is currently not connected to the friend. 1618 * This client is currently not connected to the friend.
1465 */ 1619 */
1466 TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED, 1620 TOX_ERR_FILE_CONTROL_FRIEND_NOT_CONNECTED,
1621
1467 /** 1622 /**
1468 * No file transfer with the given file number was found for the given friend. 1623 * No file transfer with the given file number was found for the given friend.
1469 */ 1624 */
1470 TOX_ERR_FILE_CONTROL_NOT_FOUND, 1625 TOX_ERR_FILE_CONTROL_NOT_FOUND,
1626
1471 /** 1627 /**
1472 * A RESUME control was sent, but the file transfer is running normally. 1628 * A RESUME control was sent, but the file transfer is running normally.
1473 */ 1629 */
1474 TOX_ERR_FILE_CONTROL_NOT_PAUSED, 1630 TOX_ERR_FILE_CONTROL_NOT_PAUSED,
1631
1475 /** 1632 /**
1476 * A RESUME control was sent, but the file transfer was paused by the other 1633 * A RESUME control was sent, but the file transfer was paused by the other
1477 * party. Only the party that paused the transfer can resume it. 1634 * party. Only the party that paused the transfer can resume it.
1478 */ 1635 */
1479 TOX_ERR_FILE_CONTROL_DENIED, 1636 TOX_ERR_FILE_CONTROL_DENIED,
1637
1480 /** 1638 /**
1481 * A PAUSE control was sent, but the file transfer was already paused. 1639 * A PAUSE control was sent, but the file transfer was already paused.
1482 */ 1640 */
1483 TOX_ERR_FILE_CONTROL_ALREADY_PAUSED, 1641 TOX_ERR_FILE_CONTROL_ALREADY_PAUSED,
1642
1484 /** 1643 /**
1485 * Packet queue is full. 1644 * Packet queue is full.
1486 */ 1645 */
1487 TOX_ERR_FILE_CONTROL_SENDQ 1646 TOX_ERR_FILE_CONTROL_SENDQ,
1647
1488} TOX_ERR_FILE_CONTROL; 1648} TOX_ERR_FILE_CONTROL;
1489 1649
1650
1490/** 1651/**
1491 * Sends a file control command to a friend for a given file transfer. 1652 * Sends a file control command to a friend for a given file transfer.
1492 * 1653 *
@@ -1500,10 +1661,7 @@ typedef enum TOX_ERR_FILE_CONTROL {
1500bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, 1661bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
1501 TOX_ERR_FILE_CONTROL *error); 1662 TOX_ERR_FILE_CONTROL *error);
1502 1663
1503
1504/** 1664/**
1505 * The function type for the `file_control` callback.
1506 *
1507 * When receiving TOX_FILE_CONTROL_CANCEL, the client should release the 1665 * When receiving TOX_FILE_CONTROL_CANCEL, the client should release the
1508 * resources associated with the file number and consider the transfer failed. 1666 * resources associated with the file number and consider the transfer failed.
1509 * 1667 *
@@ -1515,43 +1673,55 @@ bool tox_file_control(Tox *tox, uint32_t friend_number, uint32_t file_number, TO
1515typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control, 1673typedef void tox_file_recv_control_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, TOX_FILE_CONTROL control,
1516 void *user_data); 1674 void *user_data);
1517 1675
1676
1518/** 1677/**
1519 * Set the callback for the `file_control` event. Pass NULL to unset. 1678 * Set the callback for the `file_recv_control` event. Pass NULL to unset.
1520 * 1679 *
1521 * This event is triggered when a file control command is received from a 1680 * This event is triggered when a file control command is received from a
1522 * friend. 1681 * friend.
1523 */ 1682 */
1524void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *function, void *user_data); 1683void tox_callback_file_recv_control(Tox *tox, tox_file_recv_control_cb *callback, void *user_data);
1525
1526 1684
1527typedef enum TOX_ERR_FILE_SEEK { 1685typedef enum TOX_ERR_FILE_SEEK {
1686
1687 /**
1688 * The function returned successfully.
1689 */
1528 TOX_ERR_FILE_SEEK_OK, 1690 TOX_ERR_FILE_SEEK_OK,
1691
1529 /** 1692 /**
1530 * The friend_number passed did not designate a valid friend. 1693 * The friend_number passed did not designate a valid friend.
1531 */ 1694 */
1532 TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND, 1695 TOX_ERR_FILE_SEEK_FRIEND_NOT_FOUND,
1696
1533 /** 1697 /**
1534 * This client is currently not connected to the friend. 1698 * This client is currently not connected to the friend.
1535 */ 1699 */
1536 TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED, 1700 TOX_ERR_FILE_SEEK_FRIEND_NOT_CONNECTED,
1701
1537 /** 1702 /**
1538 * No file transfer with the given file number was found for the given friend. 1703 * No file transfer with the given file number was found for the given friend.
1539 */ 1704 */
1540 TOX_ERR_FILE_SEEK_NOT_FOUND, 1705 TOX_ERR_FILE_SEEK_NOT_FOUND,
1706
1541 /** 1707 /**
1542 * File was not in a state where it could be seeked. 1708 * File was not in a state where it could be seeked.
1543 */ 1709 */
1544 TOX_ERR_FILE_SEEK_DENIED, 1710 TOX_ERR_FILE_SEEK_DENIED,
1711
1545 /** 1712 /**
1546 * Seek position was invalid 1713 * Seek position was invalid
1547 */ 1714 */
1548 TOX_ERR_FILE_SEEK_INVALID_POSITION, 1715 TOX_ERR_FILE_SEEK_INVALID_POSITION,
1716
1549 /** 1717 /**
1550 * Packet queue is full. 1718 * Packet queue is full.
1551 */ 1719 */
1552 TOX_ERR_FILE_SEEK_SENDQ 1720 TOX_ERR_FILE_SEEK_SENDQ,
1721
1553} TOX_ERR_FILE_SEEK; 1722} TOX_ERR_FILE_SEEK;
1554 1723
1724
1555/** 1725/**
1556 * Sends a file seek control command to a friend for a given file transfer. 1726 * Sends a file seek control command to a friend for a given file transfer.
1557 * 1727 *
@@ -1563,26 +1733,33 @@ typedef enum TOX_ERR_FILE_SEEK {
1563 * @param file_number The friend-specific identifier for the file transfer. 1733 * @param file_number The friend-specific identifier for the file transfer.
1564 * @param position The position that the file should be seeked to. 1734 * @param position The position that the file should be seeked to.
1565 */ 1735 */
1566bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 1736bool tox_file_seek(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, TOX_ERR_FILE_SEEK *error);
1567 TOX_ERR_FILE_SEEK *error);
1568 1737
1569typedef enum TOX_ERR_FILE_GET { 1738typedef enum TOX_ERR_FILE_GET {
1739
1740 /**
1741 * The function returned successfully.
1742 */
1570 TOX_ERR_FILE_GET_OK, 1743 TOX_ERR_FILE_GET_OK,
1744
1571 /** 1745 /**
1572 * The friend_number passed did not designate a valid friend. 1746 * The friend_number passed did not designate a valid friend.
1573 */ 1747 */
1574 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND, 1748 TOX_ERR_FILE_GET_FRIEND_NOT_FOUND,
1749
1575 /** 1750 /**
1576 * No file transfer with the given file number was found for the given friend. 1751 * No file transfer with the given file number was found for the given friend.
1577 */ 1752 */
1578 TOX_ERR_FILE_GET_NOT_FOUND 1753 TOX_ERR_FILE_GET_NOT_FOUND,
1754
1579} TOX_ERR_FILE_GET; 1755} TOX_ERR_FILE_GET;
1580 1756
1757
1581/** 1758/**
1582 * Copy the file id associated to the file transfer to a byte array. 1759 * Copy the file id associated to the file transfer to a byte array.
1583 * 1760 *
1584 * @param friend_number The friend number of the friend the file is being 1761 * @param friend_number The friend number of the friend the file is being
1585 * transferred to. 1762 * transferred to or received from.
1586 * @param file_number The friend-specific identifier for the file transfer. 1763 * @param file_number The friend-specific identifier for the file transfer.
1587 * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If 1764 * @param file_id A memory region of at least TOX_FILE_ID_LENGTH bytes. If
1588 * this parameter is NULL, this function has no effect. 1765 * this parameter is NULL, this function has no effect.
@@ -1592,6 +1769,7 @@ typedef enum TOX_ERR_FILE_GET {
1592bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id, 1769bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_number, uint8_t *file_id,
1593 TOX_ERR_FILE_GET *error); 1770 TOX_ERR_FILE_GET *error);
1594 1771
1772
1595/******************************************************************************* 1773/*******************************************************************************
1596 * 1774 *
1597 * :: File transmission: sending 1775 * :: File transmission: sending
@@ -1599,36 +1777,51 @@ bool tox_file_get_file_id(const Tox *tox, uint32_t friend_number, uint32_t file_
1599 ******************************************************************************/ 1777 ******************************************************************************/
1600 1778
1601 1779
1780
1602typedef enum TOX_ERR_FILE_SEND { 1781typedef enum TOX_ERR_FILE_SEND {
1782
1783 /**
1784 * The function returned successfully.
1785 */
1603 TOX_ERR_FILE_SEND_OK, 1786 TOX_ERR_FILE_SEND_OK,
1787
1788 /**
1789 * One of the arguments to the function was NULL when it was not expected.
1790 */
1604 TOX_ERR_FILE_SEND_NULL, 1791 TOX_ERR_FILE_SEND_NULL,
1792
1605 /** 1793 /**
1606 * The friend_number passed did not designate a valid friend. 1794 * The friend_number passed did not designate a valid friend.
1607 */ 1795 */
1608 TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND, 1796 TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND,
1797
1609 /** 1798 /**
1610 * This client is currently not connected to the friend. 1799 * This client is currently not connected to the friend.
1611 */ 1800 */
1612 TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED, 1801 TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED,
1802
1613 /** 1803 /**
1614 * Filename length exceeded TOX_MAX_FILENAME_LENGTH bytes. 1804 * Filename length exceeded TOX_MAX_FILENAME_LENGTH bytes.
1615 */ 1805 */
1616 TOX_ERR_FILE_SEND_NAME_TOO_LONG, 1806 TOX_ERR_FILE_SEND_NAME_TOO_LONG,
1807
1617 /** 1808 /**
1618 * Too many ongoing transfers. The maximum number of concurrent file transfers 1809 * Too many ongoing transfers. The maximum number of concurrent file transfers
1619 * is 256 per friend per direction (sending and receiving). 1810 * is 256 per friend per direction (sending and receiving).
1620 */ 1811 */
1621 TOX_ERR_FILE_SEND_TOO_MANY 1812 TOX_ERR_FILE_SEND_TOO_MANY,
1813
1622} TOX_ERR_FILE_SEND; 1814} TOX_ERR_FILE_SEND;
1623 1815
1816
1624/** 1817/**
1625 * Send a file transmission request. 1818 * Send a file transmission request.
1626 * 1819 *
1627 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename should generally just be 1820 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename
1628 * a file name, not a path with directory names. 1821 * should generally just be a file name, not a path with directory names.
1629 * 1822 *
1630 * If a non-zero file size is provided, this can be used by both sides to 1823 * If a non-UINT64_MAX file size is provided, it can be used by both sides to
1631 * determine the sending progress. File size can be set to zero for streaming 1824 * determine the sending progress. File size can be set to UINT64_MAX for streaming
1632 * data of unknown size. 1825 * data of unknown size.
1633 * 1826 *
1634 * File transmission occurs in chunks, which are requested through the 1827 * File transmission occurs in chunks, which are requested through the
@@ -1642,13 +1835,14 @@ typedef enum TOX_ERR_FILE_SEND {
1642 * was modified and how the client determines the file size. 1835 * was modified and how the client determines the file size.
1643 * 1836 *
1644 * - If the file size was increased 1837 * - If the file size was increased
1645 * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour will be as 1838 * - and sending mode was streaming (file_size = UINT64_MAX), the behaviour
1646 * expected. 1839 * will be as expected.
1647 * - and sending mode was file (file_size != UINT64_MAX), the file_chunk_request 1840 * - and sending mode was file (file_size != UINT64_MAX), the
1648 * callback will receive length = 0 when Core thinks the file transfer has 1841 * file_chunk_request callback will receive length = 0 when Core thinks
1649 * finished. If the client remembers the file size as it was when sending 1842 * the file transfer has finished. If the client remembers the file size as
1650 * the request, it will terminate the transfer normally. If the client 1843 * it was when sending the request, it will terminate the transfer normally.
1651 * re-reads the size, it will think the friend cancelled the transfer. 1844 * If the client re-reads the size, it will think the friend cancelled the
1845 * transfer.
1652 * - If the file size was decreased 1846 * - If the file size was decreased
1653 * - and sending mode was streaming, the behaviour is as expected. 1847 * - and sending mode was streaming, the behaviour is as expected.
1654 * - and sending mode was file, the callback will return 0 at the new 1848 * - and sending mode was file, the callback will return 0 at the new
@@ -1676,52 +1870,65 @@ typedef enum TOX_ERR_FILE_SEND {
1676 * 1870 *
1677 * @return A file number used as an identifier in subsequent callbacks. This 1871 * @return A file number used as an identifier in subsequent callbacks. This
1678 * number is per friend. File numbers are reused after a transfer terminates. 1872 * number is per friend. File numbers are reused after a transfer terminates.
1679 * on failure, this function returns UINT32_MAX. Any pattern in file numbers 1873 * On failure, this function returns UINT32_MAX. Any pattern in file numbers
1680 * should not be relied on. 1874 * should not be relied on.
1681 */ 1875 */
1682uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id, 1876uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t file_size, const uint8_t *file_id,
1683 const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error); 1877 const uint8_t *filename, size_t filename_length, TOX_ERR_FILE_SEND *error);
1684 1878
1685
1686typedef enum TOX_ERR_FILE_SEND_CHUNK { 1879typedef enum TOX_ERR_FILE_SEND_CHUNK {
1880
1881 /**
1882 * The function returned successfully.
1883 */
1687 TOX_ERR_FILE_SEND_CHUNK_OK, 1884 TOX_ERR_FILE_SEND_CHUNK_OK,
1885
1688 /** 1886 /**
1689 * The length parameter was non-zero, but data was NULL. 1887 * The length parameter was non-zero, but data was NULL.
1690 */ 1888 */
1691 TOX_ERR_FILE_SEND_CHUNK_NULL, 1889 TOX_ERR_FILE_SEND_CHUNK_NULL,
1890
1692 /** 1891 /**
1693 * The friend_number passed did not designate a valid friend. 1892 * The friend_number passed did not designate a valid friend.
1694 */ 1893 */
1695 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND, 1894 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_FOUND,
1895
1696 /** 1896 /**
1697 * This client is currently not connected to the friend. 1897 * This client is currently not connected to the friend.
1698 */ 1898 */
1699 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED, 1899 TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED,
1900
1700 /** 1901 /**
1701 * No file transfer with the given file number was found for the given friend. 1902 * No file transfer with the given file number was found for the given friend.
1702 */ 1903 */
1703 TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND, 1904 TOX_ERR_FILE_SEND_CHUNK_NOT_FOUND,
1905
1704 /** 1906 /**
1705 * File transfer was found but isn't in a transferring state: (paused, done, 1907 * File transfer was found but isn't in a transferring state: (paused, done,
1706 * broken, etc...) (happens only when not called from the request chunk callback). 1908 * broken, etc...) (happens only when not called from the request chunk callback).
1707 */ 1909 */
1708 TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING, 1910 TOX_ERR_FILE_SEND_CHUNK_NOT_TRANSFERRING,
1911
1709 /** 1912 /**
1710 * Attempted to send more or less data than requested. The requested data size is 1913 * Attempted to send more or less data than requested. The requested data size is
1711 * adjusted according to maximum transmission unit and the expected end of 1914 * adjusted according to maximum transmission unit and the expected end of
1712 * the file. Trying to send less or more than requested will return this error. 1915 * the file. Trying to send less or more than requested will return this error.
1713 */ 1916 */
1714 TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH, 1917 TOX_ERR_FILE_SEND_CHUNK_INVALID_LENGTH,
1918
1715 /** 1919 /**
1716 * Packet queue is full. 1920 * Packet queue is full.
1717 */ 1921 */
1718 TOX_ERR_FILE_SEND_CHUNK_SENDQ, 1922 TOX_ERR_FILE_SEND_CHUNK_SENDQ,
1923
1719 /** 1924 /**
1720 * Position parameter was wrong. 1925 * Position parameter was wrong.
1721 */ 1926 */
1722 TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION 1927 TOX_ERR_FILE_SEND_CHUNK_WRONG_POSITION,
1928
1723} TOX_ERR_FILE_SEND_CHUNK; 1929} TOX_ERR_FILE_SEND_CHUNK;
1724 1930
1931
1725/** 1932/**
1726 * Send a chunk of file data to a friend. 1933 * Send a chunk of file data to a friend.
1727 * 1934 *
@@ -1741,10 +1948,7 @@ typedef enum TOX_ERR_FILE_SEND_CHUNK {
1741bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data, 1948bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, const uint8_t *data,
1742 size_t length, TOX_ERR_FILE_SEND_CHUNK *error); 1949 size_t length, TOX_ERR_FILE_SEND_CHUNK *error);
1743 1950
1744
1745/** 1951/**
1746 * The function type for the `file_chunk_request` callback.
1747 *
1748 * If the length parameter is 0, the file transfer is finished, and the client's 1952 * If the length parameter is 0, the file transfer is finished, and the client's
1749 * resources associated with the file number should be released. After a call 1953 * resources associated with the file number should be released. After a call
1750 * with zero length, the file number can be reused for future file transfers. 1954 * with zero length, the file number can be reused for future file transfers.
@@ -1769,10 +1973,13 @@ bool tox_file_send_chunk(Tox *tox, uint32_t friend_number, uint32_t file_number,
1769typedef void tox_file_chunk_request_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 1973typedef void tox_file_chunk_request_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
1770 size_t length, void *user_data); 1974 size_t length, void *user_data);
1771 1975
1976
1772/** 1977/**
1773 * Set the callback for the `file_chunk_request` event. Pass NULL to unset. 1978 * Set the callback for the `file_chunk_request` event. Pass NULL to unset.
1979 *
1980 * This event is triggered when Core is ready to send more file data.
1774 */ 1981 */
1775void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *function, void *user_data); 1982void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *callback, void *user_data);
1776 1983
1777 1984
1778/******************************************************************************* 1985/*******************************************************************************
@@ -1782,12 +1989,8 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *functi
1782 ******************************************************************************/ 1989 ******************************************************************************/
1783 1990
1784 1991
1992
1785/** 1993/**
1786 * The function type for the `file_receive` callback.
1787 *
1788 * Maximum filename length is TOX_MAX_FILENAME_LENGTH bytes. The filename should generally just be
1789 * a file name, not a path with directory names.
1790 *
1791 * The client should acquire resources to be associated with the file transfer. 1994 * The client should acquire resources to be associated with the file transfer.
1792 * Incoming file transfers start in the PAUSED state. After this callback 1995 * Incoming file transfers start in the PAUSED state. After this callback
1793 * returns, a transfer can be rejected by sending a TOX_FILE_CONTROL_CANCEL 1996 * returns, a transfer can be rejected by sending a TOX_FILE_CONTROL_CANCEL
@@ -1799,27 +2002,24 @@ void tox_callback_file_chunk_request(Tox *tox, tox_file_chunk_request_cb *functi
1799 * @param file_number The friend-specific file number the data received is 2002 * @param file_number The friend-specific file number the data received is
1800 * associated with. 2003 * associated with.
1801 * @param kind The meaning of the file to be sent. 2004 * @param kind The meaning of the file to be sent.
1802 * @param file_size Size in bytes of the file about to be received from the client, 2005 * @param file_size Size in bytes of the file the client wants to send,
1803 * UINT64_MAX if unknown or streaming. 2006 * UINT64_MAX if unknown or streaming.
2007 * @param filename Name of the file. Does not need to be the actual name. This
2008 * name will be sent along with the file send request.
1804 * @param filename_length Size in bytes of the filename. 2009 * @param filename_length Size in bytes of the filename.
1805 */ 2010 */
1806typedef void tox_file_recv_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, 2011typedef void tox_file_recv_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t file_size,
1807 uint64_t file_size, const uint8_t *filename, size_t filename_length, void *user_data); 2012 const uint8_t *filename, size_t filename_length, void *user_data);
2013
1808 2014
1809/** 2015/**
1810 * Set the callback for the `file_receive` event. Pass NULL to unset. 2016 * Set the callback for the `file_recv` event. Pass NULL to unset.
1811 * 2017 *
1812 * This event is triggered when a file transfer request is received. 2018 * This event is triggered when a file transfer request is received.
1813 */ 2019 */
1814void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *function, void *user_data); 2020void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *callback, void *user_data);
1815
1816 2021
1817/** 2022/**
1818 * The function type for the `file_receive_chunk` callback.
1819 *
1820 * This function is first called when a file transfer request is received, and
1821 * subsequently when a chunk of file data for an accepted request was received.
1822 *
1823 * When length is 0, the transfer is finished and the client should release the 2023 * When length is 0, the transfer is finished and the client should release the
1824 * resources it acquired for the transfer. After a call with length = 0, the 2024 * resources it acquired for the transfer. After a call with length = 0, the
1825 * file number can be reused for new file transfers. 2025 * file number can be reused for new file transfers.
@@ -1838,10 +2038,14 @@ void tox_callback_file_recv(Tox *tox, tox_file_recv_cb *function, void *user_dat
1838typedef void tox_file_recv_chunk_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, 2038typedef void tox_file_recv_chunk_cb(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
1839 const uint8_t *data, size_t length, void *user_data); 2039 const uint8_t *data, size_t length, void *user_data);
1840 2040
2041
1841/** 2042/**
1842 * Set the callback for the `file_receive_chunk` event. Pass NULL to unset. 2043 * Set the callback for the `file_recv_chunk` event. Pass NULL to unset.
2044 *
2045 * This event is first triggered when a file transfer request is received, and
2046 * subsequently when a chunk of file data for an accepted request was received.
1843 */ 2047 */
1844void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, void *user_data); 2048void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *callback, void *user_data);
1845 2049
1846 2050
1847/******************************************************************************* 2051/*******************************************************************************
@@ -1851,13 +2055,16 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, vo
1851 ******************************************************************************/ 2055 ******************************************************************************/
1852 2056
1853 2057
1854/****************************************************************************** 2058
2059
2060/*******************************************************************************
1855 * 2061 *
1856 * :: Group chat message sending and receiving 2062 * :: Group chat message sending and receiving
1857 * 2063 *
1858 ******************************************************************************/ 2064 ******************************************************************************/
1859 2065
1860/* See: tox_old.h for now. */ 2066
2067
1861 2068
1862/******************************************************************************* 2069/*******************************************************************************
1863 * 2070 *
@@ -1866,34 +2073,50 @@ void tox_callback_file_recv_chunk(Tox *tox, tox_file_recv_chunk_cb *function, vo
1866 ******************************************************************************/ 2073 ******************************************************************************/
1867 2074
1868 2075
2076
1869typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET { 2077typedef enum TOX_ERR_FRIEND_CUSTOM_PACKET {
2078
2079 /**
2080 * The function returned successfully.
2081 */
1870 TOX_ERR_FRIEND_CUSTOM_PACKET_OK, 2082 TOX_ERR_FRIEND_CUSTOM_PACKET_OK,
2083
2084 /**
2085 * One of the arguments to the function was NULL when it was not expected.
2086 */
1871 TOX_ERR_FRIEND_CUSTOM_PACKET_NULL, 2087 TOX_ERR_FRIEND_CUSTOM_PACKET_NULL,
2088
1872 /** 2089 /**
1873 * The friend number did not designate a valid friend. 2090 * The friend number did not designate a valid friend.
1874 */ 2091 */
1875 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND, 2092 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_FOUND,
2093
1876 /** 2094 /**
1877 * This client is currently not connected to the friend. 2095 * This client is currently not connected to the friend.
1878 */ 2096 */
1879 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED, 2097 TOX_ERR_FRIEND_CUSTOM_PACKET_FRIEND_NOT_CONNECTED,
2098
1880 /** 2099 /**
1881 * The first byte of data was not in the specified range for the packet type. 2100 * The first byte of data was not in the specified range for the packet type.
1882 * This range is 200-254 for lossy, and 160-191 for lossless packets. 2101 * This range is 200-254 for lossy, and 160-191 for lossless packets.
1883 */ 2102 */
1884 TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID, 2103 TOX_ERR_FRIEND_CUSTOM_PACKET_INVALID,
2104
1885 /** 2105 /**
1886 * Attempted to send an empty packet. 2106 * Attempted to send an empty packet.
1887 */ 2107 */
1888 TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY, 2108 TOX_ERR_FRIEND_CUSTOM_PACKET_EMPTY,
2109
1889 /** 2110 /**
1890 * Packet data length exceeded TOX_MAX_CUSTOM_PACKET_SIZE. 2111 * Packet data length exceeded TOX_MAX_CUSTOM_PACKET_SIZE.
1891 */ 2112 */
1892 TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG, 2113 TOX_ERR_FRIEND_CUSTOM_PACKET_TOO_LONG,
2114
1893 /** 2115 /**
1894 * Send queue size exceeded. 2116 * Packet queue is full.
1895 */ 2117 */
1896 TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ 2118 TOX_ERR_FRIEND_CUSTOM_PACKET_SENDQ,
2119
1897} TOX_ERR_FRIEND_CUSTOM_PACKET; 2120} TOX_ERR_FRIEND_CUSTOM_PACKET;
1898 2121
1899 2122
@@ -1921,22 +2144,6 @@ bool tox_friend_send_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_
1921 TOX_ERR_FRIEND_CUSTOM_PACKET *error); 2144 TOX_ERR_FRIEND_CUSTOM_PACKET *error);
1922 2145
1923/** 2146/**
1924 * The function type for the `friend_lossy_packet` callback.
1925 *
1926 * @param friend_number The friend number of the friend who sent a lossy packet.
1927 * @param data A byte array containing the received packet data.
1928 * @param length The length of the packet data byte array.
1929 */
1930typedef void tox_friend_lossy_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
1931 void *user_data);
1932
1933/**
1934 * Set the callback for the `friend_lossy_packet` event. Pass NULL to unset.
1935 */
1936void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *function, void *user_data);
1937
1938
1939/**
1940 * Send a custom lossless packet to a friend. 2147 * Send a custom lossless packet to a friend.
1941 * 2148 *
1942 * The first byte of data must be in the range 160-191. Maximum length of a 2149 * The first byte of data must be in the range 160-191. Maximum length of a
@@ -1956,20 +2163,34 @@ bool tox_friend_send_lossless_packet(Tox *tox, uint32_t friend_number, const uin
1956 TOX_ERR_FRIEND_CUSTOM_PACKET *error); 2163 TOX_ERR_FRIEND_CUSTOM_PACKET *error);
1957 2164
1958/** 2165/**
1959 * The function type for the `friend_lossless_packet` callback. 2166 * @param friend_number The friend number of the friend who sent a lossy packet.
2167 * @param data A byte array containing the received packet data.
2168 * @param length The length of the packet data byte array.
2169 */
2170typedef void tox_friend_lossy_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
2171 void *user_data);
2172
2173
2174/**
2175 * Set the callback for the `friend_lossy_packet` event. Pass NULL to unset.
1960 * 2176 *
2177 */
2178void tox_callback_friend_lossy_packet(Tox *tox, tox_friend_lossy_packet_cb *callback, void *user_data);
2179
2180/**
1961 * @param friend_number The friend number of the friend who sent the packet. 2181 * @param friend_number The friend number of the friend who sent the packet.
1962 * @param data A byte array containing the received packet data. 2182 * @param data A byte array containing the received packet data.
1963 * @param length The length of the packet data byte array. 2183 * @param length The length of the packet data byte array.
1964 */ 2184 */
1965typedef void tox_friend_lossless_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, 2185typedef void tox_friend_lossless_packet_cb(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
1966 void *user_data); 2186 void *user_data);
2187
1967 2188
1968/** 2189/**
1969 * Set the callback for the `friend_lossless_packet` event. Pass NULL to unset. 2190 * Set the callback for the `friend_lossless_packet` event. Pass NULL to unset.
2191 *
1970 */ 2192 */
1971void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *function, void *user_data); 2193void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb *callback, void *user_data);
1972
1973 2194
1974 2195
1975/******************************************************************************* 2196/*******************************************************************************
@@ -1979,11 +2200,12 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb
1979 ******************************************************************************/ 2200 ******************************************************************************/
1980 2201
1981 2202
2203
1982/** 2204/**
1983 * Writes the temporary DHT public key of this instance to a byte array. 2205 * Writes the temporary DHT public key of this instance to a byte array.
1984 * 2206 *
1985 * This can be used in combination with an externally accessible IP address and 2207 * This can be used in combination with an externally accessible IP address and
1986 * the bound port (from tox_get_udp_port) to run a temporary bootstrap node. 2208 * the bound port (from tox_self_get_udp_port) to run a temporary bootstrap node.
1987 * 2209 *
1988 * Be aware that every time a new instance is created, the DHT public key 2210 * Be aware that every time a new instance is created, the DHT public key
1989 * changes, meaning this cannot be used to run a permanent bootstrap node. 2211 * changes, meaning this cannot be used to run a permanent bootstrap node.
@@ -1993,15 +2215,21 @@ void tox_callback_friend_lossless_packet(Tox *tox, tox_friend_lossless_packet_cb
1993 */ 2215 */
1994void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id); 2216void tox_self_get_dht_id(const Tox *tox, uint8_t *dht_id);
1995 2217
1996
1997typedef enum TOX_ERR_GET_PORT { 2218typedef enum TOX_ERR_GET_PORT {
2219
2220 /**
2221 * The function returned successfully.
2222 */
1998 TOX_ERR_GET_PORT_OK, 2223 TOX_ERR_GET_PORT_OK,
2224
1999 /** 2225 /**
2000 * The instance was not bound to any port. 2226 * The instance was not bound to any port.
2001 */ 2227 */
2002 TOX_ERR_GET_PORT_NOT_BOUND 2228 TOX_ERR_GET_PORT_NOT_BOUND,
2229
2003} TOX_ERR_GET_PORT; 2230} TOX_ERR_GET_PORT;
2004 2231
2232
2005/** 2233/**
2006 * Return the UDP port this Tox instance is bound to. 2234 * Return the UDP port this Tox instance is bound to.
2007 */ 2235 */