summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/Messenger.c2
-rw-r--r--toxcore/net_crypto.c305
-rw-r--r--toxcore/net_crypto.h34
3 files changed, 306 insertions, 35 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 37feccf5..a84c391b 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -849,7 +849,7 @@ int write_cryptpacket_id(Messenger *m, int32_t friendnumber, uint8_t packet_id,
849 if (length != 0) 849 if (length != 0)
850 memcpy(packet + 1, data, length); 850 memcpy(packet + 1, data, length);
851 851
852 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 852 return write_cryptpacket(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id, packet, length + 1) != -1;
853} 853}
854 854
855/**********GROUP CHATS************/ 855/**********GROUP CHATS************/
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index d4922380..9f8048be 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -358,6 +358,138 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, uint8_t *data,
358 return 0; 358 return 0;
359} 359}
360 360
361/** START: Array Related functions **/
362
363
364/* Return number of packets in array
365 * Note that holes are counted too.
366 */
367static uint32_t num_packets_array(Packets_Array *array)
368{
369 return array->buffer_end - array->buffer_start;
370}
371
372/* Add data with packet number to array.
373 *
374 * return -1 on failure.
375 * return 0 on success.
376 */
377static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data *data)
378{
379 if (number - array->buffer_start > CRYPTO_PACKET_BUFFER_SIZE)
380 return -1;
381
382 uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
383
384 if (array->buffer[num])
385 return -1;
386
387 Packet_Data *new_d = malloc(sizeof(Packet_Data));
388
389 if (new_d == NULL)
390 return -1;
391
392 memcpy(new_d, data, sizeof(Packet_Data));
393 array->buffer[num] = new_d;
394
395 if ((number - array->buffer_start) >= (array->buffer_end - array->buffer_start))
396 array->buffer_end = number + 1;
397
398 return 0;
399}
400
401/* Copy data with packet number to data.
402 *
403 * return -1 on failure.
404 * return 0 on success.
405 */
406static int copy_data_number(Packets_Array *array, Packet_Data *data, uint32_t number)
407{
408 uint32_t num_spots = array->buffer_end - array->buffer_start;
409
410 if (array->buffer_end - number > num_spots || number - array->buffer_start >= num_spots)
411 return -1;
412
413 uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE;
414
415 if (!array->buffer[num])
416 return -1;
417
418 memcpy(data, array->buffer[num], sizeof(Packet_Data));
419 return 0;
420}
421
422/* Add data to end of array.
423 *
424 * return -1 on failure.
425 * return packet number on success.
426 */
427static int64_t add_data_end_of_buffer(Packets_Array *array, Packet_Data *data)
428{
429 if (num_packets_array(array) >= CRYPTO_PACKET_BUFFER_SIZE)
430 return -1;
431
432 Packet_Data *new_d = malloc(sizeof(Packet_Data));
433
434 if (new_d == NULL)
435 return -1;
436
437 memcpy(new_d, data, sizeof(Packet_Data));
438 uint32_t id = array->buffer_end;
439 array->buffer[id % CRYPTO_PACKET_BUFFER_SIZE] = new_d;
440 ++array->buffer_end;
441 return id;
442}
443
444/* Read data from begginning of array.
445 *
446 * return -1 on failure.
447 * return packet number on success.
448 */
449static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data)
450{
451 if (array->buffer_end == array->buffer_start)
452 return -1;
453
454 uint32_t num = array->buffer_start % CRYPTO_PACKET_BUFFER_SIZE;
455
456 if (!array->buffer[num])
457 return -1;
458
459 memcpy(data, array->buffer[num], sizeof(Packet_Data));
460 uint32_t id = array->buffer_start;
461 ++array->buffer_start;
462 return id;
463}
464
465/* Delete all packets in array before number (but not number)
466 *
467 * return -1 on failure.
468 * return 0 on success
469 */
470static int clear_buffer_until(Packets_Array *array, uint32_t number)
471{
472 uint32_t num_spots = array->buffer_end - array->buffer_start;
473
474 if (array->buffer_end - number >= num_spots || number - array->buffer_start > num_spots)
475 return -1;
476
477 uint32_t i;
478
479 for (i = array->buffer_start; i != number; ++i) {
480 uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE;
481
482 if (array->buffer[num]) {
483 free(array->buffer[num]);
484 array->buffer[num] = NULL;
485 }
486 }
487
488 array->buffer_start = i;
489 return 0;
490}
491/** END: Array Related functions **/
492
361#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) 493#define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES))
362 494
363static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) 495static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length)
@@ -383,6 +515,47 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *dat
383 return send_packet_to(c, crypt_connection_id, packet, sizeof(packet)); 515 return send_packet_to(c, crypt_connection_id, packet, sizeof(packet));
384} 516}
385 517
518static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num,
519 uint8_t *data, uint32_t length)
520{
521 num = htonl(num);
522 buffer_start = htonl(buffer_start);
523 uint8_t packet[sizeof(uint32_t) + sizeof(uint32_t) + length];
524 memcpy(packet, &buffer_start, sizeof(uint32_t));
525 memcpy(packet + sizeof(uint32_t), &num, sizeof(uint32_t));
526 memcpy(packet + (sizeof(uint32_t) * 2), data, length);
527
528 return send_data_packet(c, crypt_connection_id, packet, sizeof(packet));
529}
530
531/* return -1 if data could not be put in packet queue.
532 * return positive packet number if data was put into the queue.
533 */
534static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
535{
536 if (length == 0 || length > MAX_CRYPTO_DATA_SIZE)
537 return -1;
538
539 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
540
541 if (conn == 0)
542 return -1;
543
544 Packet_Data dt;
545 dt.time = current_time_monotonic();
546 dt.length = length;
547 memcpy(dt.data, data, length);
548 int64_t packet_num = add_data_end_of_buffer(&conn->send_array, &dt);
549
550 if (packet_num == -1)
551 return -1;
552
553 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0)
554 printf("send_data_packet failed\n");
555
556 return packet_num;
557}
558
386/* Get the lowest 2 bytes from the nonce and convert 559/* Get the lowest 2 bytes from the nonce and convert
387 * them to host byte format before returning them. 560 * them to host byte format before returning them.
388 */ 561 */
@@ -433,6 +606,7 @@ static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *d
433 return len; 606 return len;
434} 607}
435 608
609
436/* Add a new temp packet to send repeatedly. 610/* Add a new temp packet to send repeatedly.
437 * 611 *
438 * return -1 on failure. 612 * return -1 on failure.
@@ -536,6 +710,80 @@ static int create_send_handshake(Net_Crypto *c, int crypt_connection_id, uint8_t
536 return 0; 710 return 0;
537} 711}
538 712
713/* Handle a recieved data packet.
714 *
715 * return -1 on failure.
716 * return 0 on success.
717 */
718static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint8_t *packet, uint16_t length)
719{
720 if (length > MAX_CRYPTO_PACKET_SIZE || length <= CRYPTO_DATA_PACKET_MIN_SIZE)
721 return -1;
722
723 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
724
725 if (conn == 0)
726 return -1;
727
728 uint8_t data[MAX_DATA_DATA_PACKET_SIZE];
729 int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
730
731 if (len <= (int)(sizeof(uint32_t) * 2))
732 return -1;
733
734 uint32_t buffer_start, num;
735 memcpy(&buffer_start, data, sizeof(uint32_t));
736 memcpy(&num, data + sizeof(uint32_t), sizeof(uint32_t));
737 buffer_start = ntohl(buffer_start);
738 num = ntohl(num);
739
740 if (buffer_start != conn->send_array.buffer_start && clear_buffer_until(&conn->send_array, buffer_start) != 0)
741 return -1;
742
743 uint8_t *real_data = data + (sizeof(uint32_t) * 2);
744 uint16_t real_length = len - (sizeof(uint32_t) * 2);
745
746 while (real_data[0] == 0) { /* Remove Padding */
747 ++real_data;
748 --real_length;
749
750 if (real_length == 0)
751 return -1;
752 }
753
754 if (real_data[0] == PACKET_ID_REQUEST) {
755 if (real_length <= 1)
756 return -1;
757
758
759 //TODO
760 } else {
761 Packet_Data dt;
762 dt.time = current_time_monotonic();
763 dt.length = real_length;
764 memcpy(dt.data, real_data, real_length);
765
766 if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0)
767 return -1;
768
769 while (read_data_beg_buffer(&conn->recv_array, &dt) != -1) {
770 if (conn->connection_data_callback)
771 conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data,
772 dt.length);
773 }
774 }
775
776 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
777 if (conn->connection_status_callback)
778 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
779
780 clear_temp_packet(c, crypt_connection_id);
781 conn->status = CRYPTO_CONN_ESTABLISHED;
782 }
783
784 return 0;
785}
786
539/* Handle a packet that was recieved for the connection. 787/* Handle a packet that was recieved for the connection.
540 * 788 *
541 * return -1 on failure. 789 * return -1 on failure.
@@ -598,24 +846,7 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, uint
598 846
599 case NET_PACKET_CRYPTO_DATA: { 847 case NET_PACKET_CRYPTO_DATA: {
600 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) { 848 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) {
601 uint8_t data[MAX_DATA_DATA_PACKET_SIZE]; 849 return handle_data_packet_helper(c, crypt_connection_id, packet, length);
602 int len = handle_data_packet(c, crypt_connection_id, data, packet, length);
603
604 if (len == -1)
605 return -1;
606
607 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
608 if (conn->connection_status_callback)
609 conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
610
611 clear_temp_packet(c, crypt_connection_id);
612 conn->status = CRYPTO_CONN_ESTABLISHED;
613 }
614
615 if (conn->connection_data_callback)
616 conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, data, len);
617
618 //TODO add buffers and packet requesting.
619 } else { 850 } else {
620 return -1; 851 return -1;
621 } 852 }
@@ -1053,8 +1284,8 @@ static void send_crypto_packets(Net_Crypto *c)
1053 1284
1054 if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED 1285 if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED
1055 && (500ULL + conn->last_data_packet_sent) < temp_time) {//TODO remove this. 1286 && (500ULL + conn->last_data_packet_sent) < temp_time) {//TODO remove this.
1056 uint8_t data[4] = {}; 1287 uint8_t data[4] = {5, 2};
1057 send_data_packet(c, i, data, 4); 1288 send_lossless_packet(c, i, data, 4);
1058 } 1289 }
1059 } 1290 }
1060} 1291}
@@ -1065,20 +1296,38 @@ static void send_crypto_packets(Net_Crypto *c)
1065 */ 1296 */
1066uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) 1297uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
1067{ 1298{
1299 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1300
1301 if (conn == 0)
1302 return 0;
1303
1068 //TODO 1304 //TODO
1069 return 0; 1305 return CRYPTO_PACKET_BUFFER_SIZE - num_packets_array(&conn->send_array);
1070} 1306}
1071 1307
1072/* return 0 if data could not be put in packet queue. 1308
1073 * return 1 if data was put into the queue. 1309
1310
1311/* return -1 if data could not be put in packet queue.
1312 * return positive packet number if data was put into the queue.
1074 */ 1313 */
1075int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length) 1314int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length)
1076{ 1315{
1077 //TODO 1316 if (length == 0)
1078 if (send_data_packet(c, crypt_connection_id, data, length) == 0) 1317 return -1;
1079 return 1;
1080 1318
1081 return 0; 1319 if (data[0] < CRYPTO_RESERVED_PACKETS)
1320 return -1;
1321
1322 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
1323
1324 if (conn == 0)
1325 return -1;
1326
1327 if (conn->status != CRYPTO_CONN_ESTABLISHED)
1328 return -1;
1329
1330 return send_lossless_packet(c, crypt_connection_id, data, length);
1082} 1331}
1083 1332
1084/* Kill a crypto connection. 1333/* Kill a crypto connection.
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index 0389f283..7c090aaa 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -35,18 +35,37 @@
35#define CRYPTO_CONN_ESTABLISHED 4 35#define CRYPTO_CONN_ESTABLISHED 4
36#define CRYPTO_CONN_TIMED_OUT 5 36#define CRYPTO_CONN_TIMED_OUT 5
37 37
38#define CRYPTO_PACKET_BUFFER_SIZE 64 38#define CRYPTO_PACKET_BUFFER_SIZE 64 /* Must be a power of 2 */
39 39
40#define MAX_CRYPTO_PACKET_SIZE 1400 40#define MAX_CRYPTO_PACKET_SIZE 1400
41 41
42#define CRYPTO_DATA_PACKET_MIN_SIZE (1 + sizeof(uint16_t) + (sizeof(uint32_t) + sizeof(uint32_t)) + crypto_box_MACBYTES)
43
42/* Max size of data in packets TODO*/ 44/* Max size of data in packets TODO*/
43#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) 45#define MAX_CRYPTO_DATA_SIZE (MAX_CRYPTO_PACKET_SIZE - CRYPTO_DATA_PACKET_MIN_SIZE)
44 46
45/* Interval in ms between sending cookie request/handshake packets. */ 47/* Interval in ms between sending cookie request/handshake packets. */
46#define CRYPTO_SEND_PACKET_INTERVAL 500 48#define CRYPTO_SEND_PACKET_INTERVAL 500
47/* The maximum number of times we try to send the cookie request and handshake 49/* The maximum number of times we try to send the cookie request and handshake
48 before giving up. */ 50 before giving up. */
49#define MAX_NUM_SENDPACKET_TRIES 10 51#define MAX_NUM_SENDPACKET_TRIES 8
52
53#define PACKET_ID_PADDING 0
54#define PACKET_ID_REQUEST 1
55
56#define CRYPTO_RESERVED_PACKETS 16
57
58typedef struct {
59 uint64_t time;
60 uint16_t length;
61 uint8_t data[MAX_CRYPTO_DATA_SIZE];
62} Packet_Data;
63
64typedef struct {
65 Packet_Data *buffer[CRYPTO_PACKET_BUFFER_SIZE];
66 uint32_t buffer_start;
67 uint32_t buffer_end; /* packet numbers in array: {buffer_start, buffer_end) */
68} Packets_Array;
50 69
51typedef struct { 70typedef struct {
52 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */ 71 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; /* The real public key of the peer. */
@@ -74,6 +93,8 @@ typedef struct {
74 IP_Port ip_port; /* The ip and port to contact this guy directly.*/ 93 IP_Port ip_port; /* The ip and port to contact this guy directly.*/
75 uint64_t direct_lastrecv_time; /* The Time at which we last received a direct packet in ms. */ 94 uint64_t direct_lastrecv_time; /* The Time at which we last received a direct packet in ms. */
76 95
96 Packets_Array send_array;
97 Packets_Array recv_array;
77 98
78 int (*connection_status_callback)(void *object, int id, uint8_t status); 99 int (*connection_status_callback)(void *object, int id, uint8_t status);
79 void *connection_status_callback_object; 100 void *connection_status_callback_object;
@@ -99,6 +120,7 @@ typedef struct {
99 DHT *dht; 120 DHT *dht;
100 121
101 Crypto_Connection *crypto_connections; 122 Crypto_Connection *crypto_connections;
123 //TCP_Client_Connection *tcp_connections;
102 124
103 uint32_t crypto_connections_length; /* Length of connections array. */ 125 uint32_t crypto_connections_length; /* Length of connections array. */
104 126
@@ -182,10 +204,10 @@ int connection_data_handler(Net_Crypto *c, int crypt_connection_id, int (*connec
182 */ 204 */
183uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); 205uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id);
184 206
185/* return 0 if data could not be put in packet queue. 207/* return -1 if data could not be put in packet queue.
186 * return 1 if data was put into the queue. 208 * return positive packet number if data was put into the queue.
187 */ 209 */
188int write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length); 210int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint32_t length);
189 211
190 212
191/* Kill a crypto connection. 213/* Kill a crypto connection.