diff options
author | irungentoo <irungentoo@gmail.com> | 2014-05-08 18:04:46 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-05-08 18:04:46 -0400 |
commit | 98f20c76de801d042c695b3034056b2cfbfeaab5 (patch) | |
tree | 5591978196e456147f5d132a28417b7e7d4c8f62 /toxcore/net_crypto.c | |
parent | 9fccb80eec1398c887e2c01103770e2ffd8f27f7 (diff) |
Connection between toxes is lossless once again.
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r-- | toxcore/net_crypto.c | 217 |
1 files changed, 205 insertions, 12 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 0f06de0f..049e2690 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -398,12 +398,13 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, Packet_Data | |||
398 | return 0; | 398 | return 0; |
399 | } | 399 | } |
400 | 400 | ||
401 | /* Copy data with packet number to data. | 401 | /* Get pointer of data with packet number. |
402 | * | 402 | * |
403 | * return -1 on failure. | 403 | * return -1 on failure. |
404 | * return 0 on success. | 404 | * return 0 if data at number is empty. |
405 | * return 1 if data pointer was put in data. | ||
405 | */ | 406 | */ |
406 | static int copy_data_number(Packets_Array *array, Packet_Data *data, uint32_t number) | 407 | static int get_data_pointer(Packets_Array *array, Packet_Data **data, uint32_t number) |
407 | { | 408 | { |
408 | uint32_t num_spots = array->buffer_end - array->buffer_start; | 409 | uint32_t num_spots = array->buffer_end - array->buffer_start; |
409 | 410 | ||
@@ -413,10 +414,10 @@ static int copy_data_number(Packets_Array *array, Packet_Data *data, uint32_t nu | |||
413 | uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE; | 414 | uint32_t num = number % CRYPTO_PACKET_BUFFER_SIZE; |
414 | 415 | ||
415 | if (!array->buffer[num]) | 416 | if (!array->buffer[num]) |
416 | return -1; | 417 | return 0; |
417 | 418 | ||
418 | memcpy(data, array->buffer[num], sizeof(Packet_Data)); | 419 | *data = array->buffer[num]; |
419 | return 0; | 420 | return 1; |
420 | } | 421 | } |
421 | 422 | ||
422 | /* Add data to end of array. | 423 | /* Add data to end of array. |
@@ -490,10 +491,126 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number) | |||
490 | array->buffer_start = i; | 491 | array->buffer_start = i; |
491 | return 0; | 492 | return 0; |
492 | } | 493 | } |
494 | |||
495 | /* Create a packet request packet from recv_array and send_buffer_end into | ||
496 | * data of length. | ||
497 | * | ||
498 | * return -1 on failure. | ||
499 | * return length of packet on success. | ||
500 | */ | ||
501 | static int generate_request_packet(uint8_t *data, uint16_t length, Packets_Array *recv_array, uint32_t send_buffer_end) | ||
502 | { | ||
503 | if (length <= (sizeof(uint32_t) * 2)) | ||
504 | return -1; | ||
505 | |||
506 | uint32_t recv_buffer_start = htonl(recv_array->buffer_start); | ||
507 | send_buffer_end = htonl(send_buffer_end); | ||
508 | memcpy(data, &recv_buffer_start, sizeof(uint32_t)); | ||
509 | memcpy(data + sizeof(uint32_t), &send_buffer_end, sizeof(uint32_t)); | ||
510 | data[sizeof(uint32_t) * 2] = PACKET_ID_REQUEST; | ||
511 | |||
512 | uint16_t cur_len = sizeof(uint32_t) * 2 + 1; | ||
513 | |||
514 | if (recv_array->buffer_start == recv_array->buffer_end) | ||
515 | return cur_len; | ||
516 | |||
517 | if (length <= cur_len) | ||
518 | return cur_len; | ||
519 | |||
520 | uint32_t i, n = 1; | ||
521 | |||
522 | for (i = recv_array->buffer_start; i != recv_array->buffer_end; ++i) { | ||
523 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; | ||
524 | |||
525 | if (!recv_array->buffer[num]) { | ||
526 | data[cur_len] = n; | ||
527 | n = 0; | ||
528 | ++cur_len; | ||
529 | |||
530 | if (length <= cur_len) | ||
531 | return cur_len; | ||
532 | |||
533 | } else if (n == 255) { | ||
534 | data[cur_len] = 0; | ||
535 | n = 0; | ||
536 | ++cur_len; | ||
537 | |||
538 | if (length <= cur_len) | ||
539 | return cur_len; | ||
540 | } | ||
541 | |||
542 | ++n; | ||
543 | } | ||
544 | |||
545 | return cur_len; | ||
546 | } | ||
547 | |||
548 | /* Handle a request data packet. | ||
549 | * Remove all the packets the other recieved from the array. | ||
550 | * | ||
551 | * return -1 on failure. | ||
552 | * return 0 on success. | ||
553 | */ | ||
554 | static int handle_request_packet(Packets_Array *send_array, uint8_t *data, uint16_t length) | ||
555 | { | ||
556 | if (length < 1) | ||
557 | return -1; | ||
558 | |||
559 | if (data[0] != PACKET_ID_REQUEST) | ||
560 | return -1; | ||
561 | |||
562 | if (length == 1) | ||
563 | return 0; | ||
564 | |||
565 | ++data; | ||
566 | --length; | ||
567 | |||
568 | uint32_t i, n = 1; | ||
569 | |||
570 | for (i = send_array->buffer_start; i != send_array->buffer_end; ++i) { | ||
571 | if (length == 0) | ||
572 | break; | ||
573 | |||
574 | uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; | ||
575 | |||
576 | if (n == data[0]) { | ||
577 | if (send_array->buffer[num]) { | ||
578 | send_array->buffer[num]->time = 0; | ||
579 | } | ||
580 | |||
581 | ++data; | ||
582 | --length; | ||
583 | n = 0; | ||
584 | } else { | ||
585 | free(send_array->buffer[num]); | ||
586 | send_array->buffer[num] = NULL; | ||
587 | } | ||
588 | |||
589 | if (n == 255) { | ||
590 | n = 1; | ||
591 | |||
592 | if (data[0] != 0) | ||
593 | return -1; | ||
594 | |||
595 | ++data; | ||
596 | --length; | ||
597 | } else { | ||
598 | ++n; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
493 | /** END: Array Related functions **/ | 605 | /** END: Array Related functions **/ |
494 | 606 | ||
495 | #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) | 607 | #define MAX_DATA_DATA_PACKET_SIZE (MAX_CRYPTO_PACKET_SIZE - (1 + sizeof(uint16_t) + crypto_box_MACBYTES)) |
496 | 608 | ||
609 | /* Creates and sends a data packet to the peer using the fastest route. | ||
610 | * | ||
611 | * return -1 on failure. | ||
612 | * return 0 on success. | ||
613 | */ | ||
497 | static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) | 614 | static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *data, uint16_t length) |
498 | { | 615 | { |
499 | if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE) | 616 | if (length == 0 || length + (1 + sizeof(uint16_t) + crypto_box_MACBYTES) > MAX_CRYPTO_PACKET_SIZE) |
@@ -517,6 +634,11 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *dat | |||
517 | return send_packet_to(c, crypt_connection_id, packet, sizeof(packet)); | 634 | return send_packet_to(c, crypt_connection_id, packet, sizeof(packet)); |
518 | } | 635 | } |
519 | 636 | ||
637 | /* Creates and sends a data packet with buffer_start and num to the peer using the fastest route. | ||
638 | * | ||
639 | * return -1 on failure. | ||
640 | * return 0 on success. | ||
641 | */ | ||
520 | static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, | 642 | static int send_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uint32_t buffer_start, uint32_t num, |
521 | uint8_t *data, uint32_t length) | 643 | uint8_t *data, uint32_t length) |
522 | { | 644 | { |
@@ -608,6 +730,64 @@ static int handle_data_packet(Net_Crypto *c, int crypt_connection_id, uint8_t *d | |||
608 | return len; | 730 | return len; |
609 | } | 731 | } |
610 | 732 | ||
733 | /* Send a request packet. | ||
734 | * | ||
735 | * return -1 on failure. | ||
736 | * return 0 on success. | ||
737 | */ | ||
738 | static int send_request_packet(Net_Crypto *c, int crypt_connection_id) | ||
739 | { | ||
740 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
741 | |||
742 | if (conn == 0) | ||
743 | return -1; | ||
744 | |||
745 | uint8_t packet[MAX_DATA_DATA_PACKET_SIZE]; | ||
746 | int len = generate_request_packet(packet, sizeof(packet), &conn->recv_array, conn->send_array.buffer_end); | ||
747 | |||
748 | if (len == -1) | ||
749 | return -1; | ||
750 | |||
751 | return send_data_packet(c, crypt_connection_id, packet, len); | ||
752 | } | ||
753 | |||
754 | /* Send up to max num previously requested data packets. | ||
755 | * | ||
756 | * return -1 on failure. | ||
757 | * return 0 on success. | ||
758 | */ | ||
759 | static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) | ||
760 | { | ||
761 | Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); | ||
762 | |||
763 | if (conn == 0) | ||
764 | return -1; | ||
765 | |||
766 | uint32_t i; | ||
767 | |||
768 | for (i = 0; i < max_num; ++i) { | ||
769 | Packet_Data *dt; | ||
770 | uint32_t packet_num = (i + conn->send_array.buffer_start); | ||
771 | int ret = get_data_pointer(&conn->send_array, &dt, packet_num); | ||
772 | |||
773 | if (ret == -1) { | ||
774 | return -1; | ||
775 | } else if (ret == 0) { | ||
776 | continue; | ||
777 | } | ||
778 | |||
779 | if (dt->time != 0) { | ||
780 | continue; | ||
781 | } | ||
782 | |||
783 | dt->time = current_time_monotonic(); | ||
784 | |||
785 | if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, | ||
786 | dt->length) != 0) | ||
787 | printf("send_data_packet failed\n"); | ||
788 | } | ||
789 | } | ||
790 | |||
611 | 791 | ||
612 | /* Add a new temp packet to send repeatedly. | 792 | /* Add a new temp packet to send repeatedly. |
613 | * | 793 | * |
@@ -754,11 +934,12 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin | |||
754 | } | 934 | } |
755 | 935 | ||
756 | if (real_data[0] == PACKET_ID_REQUEST) { | 936 | if (real_data[0] == PACKET_ID_REQUEST) { |
757 | if (real_length <= 1) | 937 | if (handle_request_packet(&conn->send_array, real_data, real_length) != 0) { |
938 | printf("fail %u %u\n", real_data[0], real_length); | ||
758 | return -1; | 939 | return -1; |
940 | } | ||
759 | 941 | ||
760 | 942 | //TODO: use num. | |
761 | //TODO | ||
762 | } else { | 943 | } else { |
763 | Packet_Data dt; | 944 | Packet_Data dt; |
764 | dt.time = current_time_monotonic(); | 945 | dt.time = current_time_monotonic(); |
@@ -773,6 +954,16 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin | |||
773 | conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data, | 954 | conn->connection_data_callback(conn->connection_data_callback_object, conn->connection_data_callback_id, dt.data, |
774 | dt.length); | 955 | dt.length); |
775 | } | 956 | } |
957 | |||
958 | //send a data request packet for every x number of data packets recieved. | ||
959 | ++conn->packet_counter; | ||
960 | |||
961 | if (conn->packet_counter > (CRYPTO_PACKET_BUFFER_SIZE / 4)) { | ||
962 | if (send_request_packet(c, crypt_connection_id) != 0) | ||
963 | return -1; | ||
964 | |||
965 | conn->packet_counter = 0; | ||
966 | } | ||
776 | } | 967 | } |
777 | 968 | ||
778 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { | 969 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { |
@@ -1285,10 +1476,12 @@ static void send_crypto_packets(Net_Crypto *c) | |||
1285 | } | 1476 | } |
1286 | 1477 | ||
1287 | if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED | 1478 | if (conn->status >= CRYPTO_CONN_NOT_CONFIRMED |
1288 | && (500ULL + conn->last_data_packet_sent) < temp_time) {//TODO remove this. | 1479 | && (CRYPTO_SEND_PACKET_INTERVAL + conn->last_data_packet_sent) < temp_time) { |
1289 | uint8_t data[4] = {5, 2}; | 1480 | send_request_packet(c, i); |
1290 | send_lossless_packet(c, i, data, 4); | ||
1291 | } | 1481 | } |
1482 | |||
1483 | //TODO | ||
1484 | send_requested_packets(c, i, ~0); | ||
1292 | } | 1485 | } |
1293 | } | 1486 | } |
1294 | 1487 | ||