summaryrefslogtreecommitdiff
path: root/toxcore/net_crypto.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-05-10 13:42:59 -0400
committerirungentoo <irungentoo@gmail.com>2014-05-10 13:42:59 -0400
commit1e485b2c2f210f173dbae0a480e43daadd32a71a (patch)
tree863f0c049c436ade79a7bacd46b9a34e6af1fb1f /toxcore/net_crypto.c
parentb0731f54cd6c891283565e0082ad06481c274415 (diff)
Added basic congestion control to net_crypto.
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r--toxcore/net_crypto.c103
1 files changed, 86 insertions, 17 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index b95791f1..9d0b6cca 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -693,7 +693,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, uint
693 return -1; 693 return -1;
694 694
695 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0) 695 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, data, length) != 0)
696 printf("send_data_packet failed\n"); 696 fprintf(stderr, "send_data_packet failed\n");
697 697
698 return packet_num; 698 return packet_num;
699} 699}
@@ -776,14 +776,17 @@ static int send_request_packet(Net_Crypto *c, int crypt_connection_id)
776 */ 776 */
777static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num) 777static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16_t max_num)
778{ 778{
779 if (max_num == 0)
780 return -1;
781
779 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 782 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
780 783
781 if (conn == 0) 784 if (conn == 0)
782 return -1; 785 return -1;
783 786
784 uint32_t i, num_sent = 0; 787 uint32_t i, num_sent = 0, array_size = num_packets_array(&conn->send_array);
785 788
786 for (i = 0; i < max_num; ++i) { 789 for (i = 0; i < array_size; ++i) {
787 Packet_Data *dt; 790 Packet_Data *dt;
788 uint32_t packet_num = (i + conn->send_array.buffer_start); 791 uint32_t packet_num = (i + conn->send_array.buffer_start);
789 int ret = get_data_pointer(&conn->send_array, &dt, packet_num); 792 int ret = get_data_pointer(&conn->send_array, &dt, packet_num);
@@ -803,6 +806,9 @@ static int send_requested_packets(Net_Crypto *c, int crypt_connection_id, uint16
803 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data, 806 if (send_data_packet_helper(c, crypt_connection_id, conn->recv_array.buffer_start, packet_num, dt->data,
804 dt->length) == 0) 807 dt->length) == 0)
805 ++num_sent; 808 ++num_sent;
809
810 if (num_sent >= max_num)
811 break;
806 } 812 }
807 813
808 return num_sent; 814 return num_sent;
@@ -957,8 +963,9 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin
957 int requested = handle_request_packet(&conn->send_array, real_data, real_length); 963 int requested = handle_request_packet(&conn->send_array, real_data, real_length);
958 964
959 if (requested == -1) { 965 if (requested == -1) {
960 printf("fail %u %u\n", real_data[0], real_length);
961 return -1; 966 return -1;
967 } else {
968 //TODO?
962 } 969 }
963 970
964 set_buffer_end(&conn->recv_array, num); 971 set_buffer_end(&conn->recv_array, num);
@@ -977,15 +984,8 @@ static int handle_data_packet_helper(Net_Crypto *c, int crypt_connection_id, uin
977 dt.length); 984 dt.length);
978 } 985 }
979 986
980 //send a data request packet for every x number of data packets recieved. 987 /* Packet counter. */
981 ++conn->packet_counter; 988 ++conn->packet_counter;
982
983 if (conn->packet_counter > (CRYPTO_PACKET_BUFFER_SIZE / 4)) {
984 if (send_request_packet(c, crypt_connection_id) != 0)
985 return -1;
986
987 conn->packet_counter = 0;
988 }
989 } 989 }
990 990
991 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { 991 if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
@@ -1291,6 +1291,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
1291 1291
1292 send_temp_packet(c, crypt_connection_id); 1292 send_temp_packet(c, crypt_connection_id);
1293 conn->status = CRYPTO_CONN_NOT_CONFIRMED; 1293 conn->status = CRYPTO_CONN_NOT_CONFIRMED;
1294 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1294 crypto_connection_add_source(c, crypt_connection_id, n_c->source); 1295 crypto_connection_add_source(c, crypt_connection_id, n_c->source);
1295 return crypt_connection_id; 1296 return crypt_connection_id;
1296} 1297}
@@ -1322,6 +1323,7 @@ int new_crypto_connection(Net_Crypto *c, uint8_t *real_public_key)
1322 random_nonce(conn->sent_nonce); 1323 random_nonce(conn->sent_nonce);
1323 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); 1324 crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
1324 conn->status = CRYPTO_CONN_COOKIE_REQUESTING; 1325 conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
1326 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1325 return crypt_connection_id; 1327 return crypt_connection_id;
1326} 1328}
1327 1329
@@ -1482,6 +1484,14 @@ static int udp_handle_packet(void *object, IP_Port source, uint8_t *packet, uint
1482 return 0; 1484 return 0;
1483} 1485}
1484 1486
1487/* The dT for the average packet recieving rate calculations.
1488 Also used as the */
1489#define PACKET_COUNTER_AVERAGE_INTERVAL 200
1490
1491/* Ratio of recv queue size / recv packet rate (in seconds) times
1492 * the number of ms between request packets to send at that ratio
1493 */
1494#define REQUEST_PACKETS_COMPARE_CONSTANT (0.5 * 100.0)
1485static void send_crypto_packets(Net_Crypto *c) 1495static void send_crypto_packets(Net_Crypto *c)
1486{ 1496{
1487 uint32_t i; 1497 uint32_t i;
@@ -1505,8 +1515,58 @@ static void send_crypto_packets(Net_Crypto *c)
1505 1515
1506 } 1516 }
1507 1517
1508 //TODO 1518 if (conn->status == CRYPTO_CONN_ESTABLISHED) {
1509 send_requested_packets(c, i, ~0); 1519 if (((double)num_packets_array(&conn->recv_array) / (conn->packet_recv_rate + 1.0)) * (double)(
1520 temp_time - conn->last_request_packet_sent) > REQUEST_PACKETS_COMPARE_CONSTANT) {
1521 if (send_request_packet(c, i) == 0) {
1522 conn->last_request_packet_sent = temp_time;
1523 }
1524 }
1525
1526 if ((PACKET_COUNTER_AVERAGE_INTERVAL + conn->packet_counter_set) < temp_time) {
1527 conn->packet_recv_rate = (double)conn->packet_counter / ((double)(temp_time - conn->packet_counter_set) / 1000.0);
1528 conn->packet_counter = 0;
1529 conn->packet_counter_set = temp_time;
1530
1531 if ((double)num_packets_array(&conn->send_array) < 0.3 * (conn->packet_send_rate)) {
1532 conn->packet_send_rate *= 1.2;
1533 } else if ((double)num_packets_array(&conn->send_array) > 0.5 * (conn->packet_send_rate)) {
1534 conn->packet_send_rate *= 0.8;
1535 }
1536
1537 if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending)
1538 conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
1539
1540 if (conn->packet_send_rate > CRYPTO_PACKET_BUFFER_SIZE * 8)
1541 conn->packet_send_rate = CRYPTO_PACKET_BUFFER_SIZE * 8;
1542
1543 }
1544
1545 if (conn->last_packets_left_set == 0) {
1546 conn->last_packets_left_set = temp_time;
1547 conn->packets_left = conn->packet_send_rate;
1548 } else if (((1000.0 / conn->packet_send_rate) + conn->last_packets_left_set) < temp_time) {
1549 uint32_t num_packets = conn->packet_send_rate * ((double)(temp_time - conn->last_packets_left_set) / 1000.0);
1550
1551 if (conn->packets_left > num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH) {
1552 conn->packets_left = num_packets * 2 + CRYPTO_MIN_QUEUE_LENGTH;
1553 } else {
1554 conn->packets_left += num_packets;
1555 }
1556
1557 conn->last_packets_left_set = temp_time;
1558 }
1559
1560 int ret = send_requested_packets(c, i, conn->packets_left);
1561
1562 if (ret != -1) {
1563 conn->packets_left -= ret;
1564 }
1565
1566 if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH) {
1567 --conn->sending;
1568 }
1569 }
1510 } 1570 }
1511} 1571}
1512 1572
@@ -1521,8 +1581,7 @@ uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id)
1521 if (conn == 0) 1581 if (conn == 0)
1522 return 0; 1582 return 0;
1523 1583
1524 //TODO 1584 return conn->packets_left;
1525 return CRYPTO_PACKET_BUFFER_SIZE - num_packets_array(&conn->send_array);
1526} 1585}
1527 1586
1528 1587
@@ -1547,7 +1606,17 @@ int64_t write_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data,
1547 if (conn->status != CRYPTO_CONN_ESTABLISHED) 1606 if (conn->status != CRYPTO_CONN_ESTABLISHED)
1548 return -1; 1607 return -1;
1549 1608
1550 return send_lossless_packet(c, crypt_connection_id, data, length); 1609 if (conn->packets_left == 0)
1610 return -1;
1611
1612 int64_t ret = send_lossless_packet(c, crypt_connection_id, data, length);
1613
1614 if (ret == -1)
1615 return -1;
1616
1617 --conn->packets_left;
1618 conn->sending = CRYPTO_MIN_QUEUE_LENGTH;
1619 return ret;
1551} 1620}
1552 1621
1553/* Kill a crypto connection. 1622/* Kill a crypto connection.