diff options
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r-- | core/Lossless_UDP.c | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index f9d20b2f..0194375a 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* Lossless_UDP.c | 1 | /* Lossless_UDP.c |
2 | * | 2 | * |
3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt | 3 | * An implementation of the Lossless_UDP protocol as seen in docs/Lossless_UDP.txt |
4 | * | 4 | * |
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | 5 | * Copyright (C) 2013 Tox project All Rights Reserved. |
6 | * | 6 | * |
7 | * This file is part of Tox. | 7 | * This file is part of Tox. |
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* TODO: clean this file a bit. | 24 | /* TODO: clean this file a bit. |
@@ -47,18 +47,18 @@ timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION | |||
47 | typedef struct { | 47 | typedef struct { |
48 | uint8_t data[MAX_DATA_SIZE]; | 48 | uint8_t data[MAX_DATA_SIZE]; |
49 | uint16_t size; | 49 | uint16_t size; |
50 | }Data; | 50 | } Data; |
51 | 51 | ||
52 | typedef struct { | 52 | typedef struct { |
53 | IP_Port ip_port; | 53 | IP_Port ip_port; |
54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, | 54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, |
55 | 2 if handshake is done (we start sending SYNC packets) | 55 | 2 if handshake is done (we start sending SYNC packets) |
56 | 3 if we are sending SYNC packets and can send data | 56 | 3 if we are sending SYNC packets and can send data |
57 | 4 if the connection has timed out. */ | 57 | 4 if the connection has timed out. */ |
58 | 58 | ||
59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. | 59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. |
60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ | 60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ |
61 | 61 | ||
62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | 62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ |
63 | uint16_t data_rate; /* current data packet send rate packets per second. */ | 63 | uint16_t data_rate; /* current data packet send rate packets per second. */ |
64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ | 64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ |
@@ -82,7 +82,7 @@ typedef struct { | |||
82 | uint8_t recv_counter; | 82 | uint8_t recv_counter; |
83 | uint8_t send_counter; | 83 | uint8_t send_counter; |
84 | uint8_t timeout; /* connection timeout in seconds. */ | 84 | uint8_t timeout; /* connection timeout in seconds. */ |
85 | }Connection; | 85 | } Connection; |
86 | 86 | ||
87 | #define MAX_CONNECTIONS 256 | 87 | #define MAX_CONNECTIONS 256 |
88 | 88 | ||
@@ -95,10 +95,11 @@ static Connection connections[MAX_CONNECTIONS]; | |||
95 | /* get connection id from IP_Port | 95 | /* get connection id from IP_Port |
96 | return -1 if there are no connections like we are looking for | 96 | return -1 if there are no connections like we are looking for |
97 | return id if it found it */ | 97 | return id if it found it */ |
98 | int getconnection_id(IP_Port ip_port) { | 98 | int getconnection_id(IP_Port ip_port) |
99 | { | ||
99 | uint32_t i; | 100 | uint32_t i; |
100 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 101 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
101 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 102 | if (connections[i].ip_port.ip.i == ip_port.ip.i && |
102 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) | 103 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) |
103 | return i; | 104 | return i; |
104 | } | 105 | } |
@@ -384,10 +385,10 @@ int send_data_packet(uint32_t connection_id, uint32_t packet_num) | |||
384 | packet[0] = 18; | 385 | packet[0] = 18; |
385 | temp = htonl(packet_num); | 386 | temp = htonl(packet_num); |
386 | memcpy(packet + 1, &temp, 4); | 387 | memcpy(packet + 1, &temp, 4); |
387 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, | 388 | memcpy(packet + 5, connections[connection_id].sendbuffer[index].data, |
388 | connections[connection_id].sendbuffer[index].size); | 389 | connections[connection_id].sendbuffer[index].size); |
389 | return sendpacket(connections[connection_id].ip_port, packet, | 390 | return sendpacket(connections[connection_id].ip_port, packet, |
390 | 1 + 4 + connections[connection_id].sendbuffer[index].size); | 391 | 1 + 4 + connections[connection_id].sendbuffer[index].size); |
391 | } | 392 | } |
392 | 393 | ||
393 | /* sends 1 data packet */ | 394 | /* sends 1 data packet */ |
@@ -395,7 +396,7 @@ int send_DATA(uint32_t connection_id) | |||
395 | { | 396 | { |
396 | int ret; | 397 | int ret; |
397 | uint32_t buffer[BUFFER_PACKET_NUM]; | 398 | uint32_t buffer[BUFFER_PACKET_NUM]; |
398 | if (connections[connection_id].num_req_paquets > 0) { | 399 | if (connections[connection_id].num_req_paquets > 0) { |
399 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); | 400 | ret = send_data_packet(connection_id, connections[connection_id].req_packets[0]); |
400 | connections[connection_id].num_req_paquets--; | 401 | connections[connection_id].num_req_paquets--; |
401 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); | 402 | memcpy(buffer, connections[connection_id].req_packets + 1, connections[connection_id].num_req_paquets * 4); |
@@ -416,9 +417,9 @@ int send_DATA(uint32_t connection_id) | |||
416 | One to handle each type of packets we receive | 417 | One to handle each type of packets we receive |
417 | return 0 if handled correctly, 1 if packet is bad. */ | 418 | return 0 if handled correctly, 1 if packet is bad. */ |
418 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 419 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
419 | { | 420 | { |
420 | if (length != (1 + 4 + 4)) | 421 | if (length != (1 + 4 + 4)) |
421 | return 1; | 422 | return 1; |
422 | uint32_t temp; | 423 | uint32_t temp; |
423 | uint32_t handshake_id1, handshake_id2; | 424 | uint32_t handshake_id1, handshake_id2; |
424 | int connection = getconnection_id(source); | 425 | int connection = getconnection_id(source); |
@@ -426,7 +427,7 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
426 | handshake_id1 = ntohl(temp); | 427 | handshake_id1 = ntohl(temp); |
427 | memcpy(&temp, packet + 5, 4); | 428 | memcpy(&temp, packet + 5, 4); |
428 | handshake_id2 = ntohl(temp); | 429 | handshake_id2 = ntohl(temp); |
429 | 430 | ||
430 | if (handshake_id2 == 0) { | 431 | if (handshake_id2 == 0) { |
431 | send_handshake(source, handshake_id(source), handshake_id1); | 432 | send_handshake(source, handshake_id(source), handshake_id1); |
432 | return 0; | 433 | return 0; |
@@ -452,7 +453,7 @@ int SYNC_valid(uint32_t length) | |||
452 | { | 453 | { |
453 | if (length < 4 + 4 + 2) | 454 | if (length < 4 + 4 + 2) |
454 | return 0; | 455 | return 0; |
455 | if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || | 456 | if (length > (BUFFER_PACKET_NUM*4 + 4 + 4 + 2) || |
456 | ((length - 4 - 4 - 2) % 4) != 0) | 457 | ((length - 4 - 4 - 2) % 4) != 0) |
457 | return 0; | 458 | return 0; |
458 | return 1; | 459 | return 1; |
@@ -482,7 +483,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
482 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 483 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
483 | { | 484 | { |
484 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 485 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { |
485 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ | 486 | /* && sent_packetnum == connections[connection_id].osent_packetnum) */ |
486 | connections[connection_id].status = 3; | 487 | connections[connection_id].status = 3; |
487 | connections[connection_id].recv_counter = counter; | 488 | connections[connection_id].recv_counter = counter; |
488 | ++connections[connection_id].send_counter; | 489 | ++connections[connection_id].send_counter; |
@@ -522,14 +523,14 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
522 | { | 523 | { |
523 | 524 | ||
524 | if (!SYNC_valid(length)) | 525 | if (!SYNC_valid(length)) |
525 | return 1; | 526 | return 1; |
526 | int connection = getconnection_id(source); | 527 | int connection = getconnection_id(source); |
527 | uint8_t counter; | 528 | uint8_t counter; |
528 | uint32_t temp; | 529 | uint32_t temp; |
529 | uint32_t recv_packetnum, sent_packetnum; | 530 | uint32_t recv_packetnum, sent_packetnum; |
530 | uint32_t req_packets[BUFFER_PACKET_NUM]; | 531 | uint32_t req_packets[BUFFER_PACKET_NUM]; |
531 | uint16_t number = (length - 4 - 4 - 2)/ 4; | 532 | uint16_t number = (length - 4 - 4 - 2)/ 4; |
532 | 533 | ||
533 | memcpy(&counter, packet + 1, 1); | 534 | memcpy(&counter, packet + 1, 1); |
534 | memcpy(&temp, packet + 2, 4); | 535 | memcpy(&temp, packet + 2, 4); |
535 | recv_packetnum = ntohl(temp); | 536 | recv_packetnum = ntohl(temp); |
@@ -556,7 +557,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
556 | uint32_t i; | 557 | uint32_t i; |
557 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 558 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
558 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 559 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; |
559 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 560 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
560 | if (i == data_num) { | 561 | if (i == data_num) { |
561 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 562 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
562 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 563 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
@@ -568,7 +569,7 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
568 | } | 569 | } |
569 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 570 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
570 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 571 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
571 | connections[connection_id].recv_packetnum = i; | 572 | connections[connection_id].recv_packetnum = i; |
572 | else | 573 | else |
573 | break; | 574 | break; |
574 | } | 575 | } |
@@ -603,15 +604,15 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | |||
603 | { | 604 | { |
604 | switch (packet[0]) { //TODO: check if no break statement is correct??? | 605 | switch (packet[0]) { //TODO: check if no break statement is correct??? |
605 | case 16: | 606 | case 16: |
606 | return handle_handshake(packet, length, source); | 607 | return handle_handshake(packet, length, source); |
607 | 608 | ||
608 | case 17: | 609 | case 17: |
609 | return handle_SYNC(packet, length, source); | 610 | return handle_SYNC(packet, length, source); |
610 | 611 | ||
611 | case 18: | 612 | case 18: |
612 | return handle_data(packet, length, source); | 613 | return handle_data(packet, length, source); |
613 | 614 | ||
614 | default: | 615 | default: |
615 | return 1; | 616 | return 1; |
616 | } | 617 | } |
617 | 618 | ||
@@ -627,13 +628,13 @@ void doNew() | |||
627 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 628 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
628 | if (connections[i].status == 1) | 629 | if (connections[i].status == 1) |
629 | if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { | 630 | if ((connections[i].last_sent + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
630 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); | 631 | send_handshake(connections[i].ip_port, connections[i].handshake_id1, 0); |
631 | connections[i].last_sent = temp_time; | 632 | connections[i].last_sent = temp_time; |
632 | } | 633 | } |
633 | 634 | ||
634 | /* kill all timed out connections */ | 635 | /* kill all timed out connections */ |
635 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 636 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && |
636 | connections[i].status != 4) | 637 | connections[i].status != 4) |
637 | /* kill_connection(i); */ | 638 | /* kill_connection(i); */ |
638 | connections[i].status = 4; | 639 | connections[i].status = 4; |
639 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 640 | if (connections[i].status > 0 && connections[i].killat < temp_time) |
@@ -648,8 +649,8 @@ void doSYNC() | |||
648 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 649 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
649 | if (connections[i].status == 2 || connections[i].status == 3) | 650 | if (connections[i].status == 2 || connections[i].status == 3) |
650 | if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { | 651 | if ((connections[i].last_SYNC + (1000000UL/connections[i].SYNC_rate)) <= temp_time) { |
651 | send_SYNC(i); | 652 | send_SYNC(i); |
652 | connections[i].last_SYNC = temp_time; | 653 | connections[i].last_SYNC = temp_time; |
653 | } | 654 | } |
654 | } | 655 | } |
655 | } | 656 | } |
@@ -682,10 +683,9 @@ void adjustRates() | |||
682 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 683 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
683 | if (connections[i].status == 3) { | 684 | if (connections[i].status == 3) { |
684 | if (sendqueue(i) != 0) { | 685 | if (sendqueue(i) != 0) { |
685 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; | 686 | connections[i].data_rate = (BUFFER_PACKET_NUM - connections[i].num_req_paquets) * MAX_SYNC_RATE; |
686 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 687 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
687 | } | 688 | } else if (connections[i].last_recvdata + 1000000UL > temp_time) |
688 | else if (connections[i].last_recvdata + 1000000UL > temp_time) | ||
689 | connections[i].SYNC_rate = MAX_SYNC_RATE; | 689 | connections[i].SYNC_rate = MAX_SYNC_RATE; |
690 | else | 690 | else |
691 | connections[i].SYNC_rate = SYNC_RATE; | 691 | connections[i].SYNC_rate = SYNC_RATE; |