summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxav/bwcontroller.c4
-rw-r--r--toxav/bwcontroller.h4
-rw-r--r--toxav/toxav.c2
-rw-r--r--toxcore/net_crypto.c174
-rw-r--r--toxcore/net_crypto.h8
5 files changed, 142 insertions, 50 deletions
diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c
index 503627c1..1725e193 100644
--- a/toxav/bwcontroller.c
+++ b/toxav/bwcontroller.c
@@ -63,8 +63,8 @@ int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, ui
63void send_update(BWController *bwc); 63void send_update(BWController *bwc);
64 64
65BWController *bwc_new(Messenger *m, uint32_t friendnumber, 65BWController *bwc_new(Messenger *m, uint32_t friendnumber,
66 void (*mcb) (BWController *, uint32_t, float, void *), 66 void (*mcb) (BWController *, uint32_t, float, void *),
67 void *udata) 67 void *udata)
68{ 68{
69 BWController *retu = calloc(sizeof(struct BWController_s), 1); 69 BWController *retu = calloc(sizeof(struct BWController_s), 1);
70 70
diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h
index 48472dff..5e7ae9df 100644
--- a/toxav/bwcontroller.h
+++ b/toxav/bwcontroller.h
@@ -26,8 +26,8 @@
26typedef struct BWController_s BWController; 26typedef struct BWController_s BWController;
27 27
28BWController *bwc_new(Messenger *m, uint32_t friendnumber, 28BWController *bwc_new(Messenger *m, uint32_t friendnumber,
29 void (*mcb) (BWController *, uint32_t, float, void *), 29 void (*mcb) (BWController *, uint32_t, float, void *),
30 void *udata); 30 void *udata);
31void bwc_kill(BWController *bwc); 31void bwc_kill(BWController *bwc);
32 32
33void bwc_feed_avg(BWController *bwc, uint32_t bytes); 33void bwc_feed_avg(BWController *bwc, uint32_t bytes);
diff --git a/toxav/toxav.c b/toxav/toxav.c
index a3aadcfa..3d4004cf 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -513,7 +513,7 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL co
513 goto END; 513 goto END;
514 } 514 }
515 515
516 rtp_allow_receiving(call->audio.first); 516 rtp_allow_receiving(call->video.first);
517 } else { 517 } else {
518 rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION; 518 rc = TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
519 goto END; 519 goto END;
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index 4d76e659..b4640c61 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -384,6 +384,78 @@ static Crypto_Connection *get_crypto_connection(const Net_Crypto *c, int crypt_c
384} 384}
385 385
386 386
387/* Associate an ip_port to a connection.
388 *
389 * return -1 on failure.
390 * return 0 on success.
391 */
392static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port)
393{
394 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
395
396 if (conn == 0)
397 return -1;
398
399 if (ip_port.ip.family == AF_INET) {
400 if (!ipport_equal(&ip_port, &conn->ip_portv4) && LAN_ip(conn->ip_portv4.ip) != 0) {
401 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id))
402 return -1;
403
404 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
405 conn->ip_portv4 = ip_port;
406 return 0;
407 }
408 } else if (ip_port.ip.family == AF_INET6) {
409 if (!ipport_equal(&ip_port, &conn->ip_portv6)) {
410 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id))
411 return -1;
412
413 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
414 conn->ip_portv6 = ip_port;
415 return 0;
416 }
417 }
418
419 return -1;
420}
421
422/* Return the IP_Port that should be used to send packets to the other peer.
423 *
424 * return IP_Port with family 0 on failure.
425 * return IP_Port on success.
426 */
427IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
428{
429 IP_Port empty;
430 empty.ip.family = 0;
431
432 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
433
434 if (conn == 0)
435 return empty;
436
437 uint64_t current_time = unix_time();
438 _Bool v6 = 0, v4 = 0;
439
440 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time) {
441 v4 = 1;
442 }
443
444 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time) {
445 v6 = 1;
446 }
447
448 if (v4 && LAN_ip(conn->ip_portv4.ip) == 0) {
449 return conn->ip_portv4;
450 } else if (v6 && conn->ip_portv6.ip.family == AF_INET6) {
451 return conn->ip_portv6;
452 } else if (conn->ip_portv4.ip.family == AF_INET) {
453 return conn->ip_portv4;
454 } else {
455 return empty;
456 }
457}
458
387/* Sends a packet to the peer using the fastest route. 459/* Sends a packet to the peer using the fastest route.
388 * 460 *
389 * return -1 on failure. 461 * return -1 on failure.
@@ -400,14 +472,15 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
400 int direct_send_attempt = 0; 472 int direct_send_attempt = 0;
401 473
402 pthread_mutex_lock(&conn->mutex); 474 pthread_mutex_lock(&conn->mutex);
475 IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
403 476
404 //TODO: on bad networks, direct connections might not last indefinitely. 477 //TODO: on bad networks, direct connections might not last indefinitely.
405 if (conn->ip_port.ip.family != 0) { 478 if (ip_port.ip.family != 0) {
406 _Bool direct_connected = 0; 479 _Bool direct_connected = 0;
407 crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL); 480 crypto_connection_status(c, crypt_connection_id, &direct_connected, NULL);
408 481
409 if (direct_connected) { 482 if (direct_connected) {
410 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) { 483 if ((uint32_t)sendpacket(c->dht->net, ip_port, data, length) == length) {
411 pthread_mutex_unlock(&conn->mutex); 484 pthread_mutex_unlock(&conn->mutex);
412 return 0; 485 return 0;
413 } else { 486 } else {
@@ -418,7 +491,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
418 491
419 //TODO: a better way of sending packets directly to confirm the others ip. 492 //TODO: a better way of sending packets directly to confirm the others ip.
420 if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) { 493 if (length < 96 || data[0] == NET_PACKET_COOKIE_REQUEST || data[0] == NET_PACKET_CRYPTO_HS) {
421 if ((uint32_t)sendpacket(c->dht->net, conn->ip_port, data, length) == length) 494 if ((uint32_t)sendpacket(c->dht->net, ip_port, data, length) == length)
422 direct_send_attempt = 1; 495 direct_send_attempt = 1;
423 } 496 }
424 } 497 }
@@ -1474,15 +1547,15 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1474 return -1; 1547 return -1;
1475 1548
1476 if (source.ip.family == AF_INET || source.ip.family == AF_INET6) { 1549 if (source.ip.family == AF_INET || source.ip.family == AF_INET6) {
1477 if (!ipport_equal(&source, &conn->ip_port)) { 1550 if (add_ip_port_connection(c, crypt_connection_id, source) != 0)
1478 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&source, crypt_connection_id)) 1551 return -1;
1479 return -1;
1480 1552
1481 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id); 1553 if (source.ip.family == AF_INET) {
1482 conn->ip_port = source; 1554 conn->direct_lastrecv_timev4 = unix_time();
1555 } else {
1556 conn->direct_lastrecv_timev6 = unix_time();
1483 } 1557 }
1484 1558
1485 conn->direct_lastrecv_time = unix_time();
1486 return 0; 1559 return 0;
1487 } else if (source.ip.family == TCP_FAMILY) { 1560 } else if (source.ip.family == TCP_FAMILY) {
1488 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0) 1561 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip6.uint32[0]) == 0)
@@ -1684,32 +1757,22 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
1684 if (conn == 0) 1757 if (conn == 0)
1685 return -1; 1758 return -1;
1686 1759
1687 if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) 1760 if (add_ip_port_connection(c, crypt_connection_id, ip_port) == 0) {
1688 return -1; 1761 if (connected) {
1689 1762 if (ip_port.ip.family == AF_INET) {
1690 if (!ipport_equal(&ip_port, &conn->ip_port)) { 1763 conn->direct_lastrecv_timev4 = unix_time();
1691 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) {
1692 /* We already know a LAN ip, no need to switch. */
1693 if (LAN_ip(conn->ip_port.ip) == 0)
1694 return -1;
1695
1696 /* Prefer ipv6. */
1697 if (conn->ip_port.ip.family == AF_INET6 && ip_port.ip.family == AF_INET)
1698 return -1;
1699 }
1700
1701 if (bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
1702 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id);
1703 conn->ip_port = ip_port;
1704
1705 if (connected) {
1706 conn->direct_lastrecv_time = unix_time();
1707 } else { 1764 } else {
1708 conn->direct_lastrecv_time = 0; 1765 conn->direct_lastrecv_timev6 = unix_time();
1766 }
1767 } else {
1768 if (ip_port.ip.family == AF_INET) {
1769 conn->direct_lastrecv_timev4 = 0;
1770 } else {
1771 conn->direct_lastrecv_timev6 = 0;
1709 } 1772 }
1710
1711 return 0;
1712 } 1773 }
1774
1775 return 0;
1713 } 1776 }
1714 1777
1715 return -1; 1778 return -1;
@@ -2019,7 +2082,13 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2019 return -1; 2082 return -1;
2020 2083
2021 pthread_mutex_lock(&conn->mutex); 2084 pthread_mutex_lock(&conn->mutex);
2022 conn->direct_lastrecv_time = unix_time(); 2085
2086 if (source.ip.family == AF_INET) {
2087 conn->direct_lastrecv_timev4 = unix_time();
2088 } else {
2089 conn->direct_lastrecv_timev6 = unix_time();
2090 }
2091
2023 pthread_mutex_unlock(&conn->mutex); 2092 pthread_mutex_unlock(&conn->mutex);
2024 return 0; 2093 return 0;
2025} 2094}
@@ -2033,12 +2102,15 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2033 */ 2102 */
2034#define REQUEST_PACKETS_COMPARE_CONSTANT (0.125 * 100.0) 2103#define REQUEST_PACKETS_COMPARE_CONSTANT (0.125 * 100.0)
2035 2104
2036/* Multiplier for maximum allowed resends. */
2037#define PACKET_RESEND_MULTIPLIER 3.5
2038
2039/* Timeout for increasing speed after congestion event (in ms). */ 2105/* Timeout for increasing speed after congestion event (in ms). */
2040#define CONGESTION_EVENT_TIMEOUT 1000 2106#define CONGESTION_EVENT_TIMEOUT 1000
2041 2107
2108/* If the send queue is SEND_QUEUE_RATIO times larger than the
2109 * calculated link speed the packet send speed will be reduced
2110 * by a value depending on this number.
2111 */
2112#define SEND_QUEUE_RATIO 2.0
2113
2042static void send_crypto_packets(Net_Crypto *c) 2114static void send_crypto_packets(Net_Crypto *c)
2043{ 2115{
2044 uint32_t i; 2116 uint32_t i;
@@ -2057,7 +2129,7 @@ static void send_crypto_packets(Net_Crypto *c)
2057 } 2129 }
2058 2130
2059 if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED) 2131 if ((conn->status == CRYPTO_CONN_NOT_CONFIRMED || conn->status == CRYPTO_CONN_ESTABLISHED)
2060 && ((CRYPTO_SEND_PACKET_INTERVAL / 4) + conn->last_request_packet_sent) < temp_time) { 2132 && ((CRYPTO_SEND_PACKET_INTERVAL) + conn->last_request_packet_sent) < temp_time) {
2061 if (send_request_packet(c, i) == 0) { 2133 if (send_request_packet(c, i) == 0) {
2062 conn->last_request_packet_sent = temp_time; 2134 conn->last_request_packet_sent = temp_time;
2063 } 2135 }
@@ -2069,6 +2141,18 @@ static void send_crypto_packets(Net_Crypto *c)
2069 double request_packet_interval = (REQUEST_PACKETS_COMPARE_CONSTANT / (((double)num_packets_array( 2141 double request_packet_interval = (REQUEST_PACKETS_COMPARE_CONSTANT / (((double)num_packets_array(
2070 &conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0))); 2142 &conn->recv_array) + 1.0) / (conn->packet_recv_rate + 1.0)));
2071 2143
2144 double request_packet_interval2 = ((CRYPTO_PACKET_MIN_RATE / conn->packet_recv_rate) *
2145 (double)CRYPTO_SEND_PACKET_INTERVAL) + (double)PACKET_COUNTER_AVERAGE_INTERVAL;
2146
2147 if (request_packet_interval2 < request_packet_interval)
2148 request_packet_interval = request_packet_interval2;
2149
2150 if (request_packet_interval < PACKET_COUNTER_AVERAGE_INTERVAL)
2151 request_packet_interval = PACKET_COUNTER_AVERAGE_INTERVAL;
2152
2153 if (request_packet_interval > CRYPTO_SEND_PACKET_INTERVAL)
2154 request_packet_interval = CRYPTO_SEND_PACKET_INTERVAL;
2155
2072 if (temp_time - conn->last_request_packet_sent > (uint64_t)request_packet_interval) { 2156 if (temp_time - conn->last_request_packet_sent > (uint64_t)request_packet_interval) {
2073 if (send_request_packet(c, i) == 0) { 2157 if (send_request_packet(c, i) == 0) {
2074 conn->last_request_packet_sent = temp_time; 2158 conn->last_request_packet_sent = temp_time;
@@ -2130,8 +2214,8 @@ static void send_crypto_packets(Net_Crypto *c)
2130 double send_array_ratio = (((double)npackets) / min_speed); 2214 double send_array_ratio = (((double)npackets) / min_speed);
2131 2215
2132 //TODO: Improve formula? 2216 //TODO: Improve formula?
2133 if (send_array_ratio > 2.0 && CRYPTO_MIN_QUEUE_LENGTH * 3 < npackets) { 2217 if (send_array_ratio > SEND_QUEUE_RATIO && CRYPTO_MIN_QUEUE_LENGTH < npackets) {
2134 conn->packet_send_rate = min_speed * (1.0 / (send_array_ratio / 2.0)); 2218 conn->packet_send_rate = min_speed * (1.0 / (send_array_ratio / SEND_QUEUE_RATIO));
2135 } else if (conn->last_congestion_event + CONGESTION_EVENT_TIMEOUT < temp_time) { 2219 } else if (conn->last_congestion_event + CONGESTION_EVENT_TIMEOUT < temp_time) {
2136 conn->packet_send_rate = min_speed * 1.2; 2220 conn->packet_send_rate = min_speed * 1.2;
2137 } else { 2221 } else {
@@ -2163,7 +2247,7 @@ static void send_crypto_packets(Net_Crypto *c)
2163 conn->last_packets_left_set = temp_time - adj; 2247 conn->last_packets_left_set = temp_time - adj;
2164 } 2248 }
2165 2249
2166 int ret = send_requested_packets(c, i, conn->packets_left * PACKET_RESEND_MULTIPLIER); 2250 int ret = send_requested_packets(c, i, conn->packets_left);
2167 2251
2168 if (ret != -1) { 2252 if (ret != -1) {
2169 if ((unsigned int)ret < conn->packets_left) { 2253 if ((unsigned int)ret < conn->packets_left) {
@@ -2364,7 +2448,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
2364 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp); 2448 kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
2365 pthread_mutex_unlock(&c->tcp_mutex); 2449 pthread_mutex_unlock(&c->tcp_mutex);
2366 2450
2367 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_port, crypt_connection_id); 2451 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
2452 bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
2368 clear_temp_packet(c, crypt_connection_id); 2453 clear_temp_packet(c, crypt_connection_id);
2369 clear_buffer(&conn->send_array); 2454 clear_buffer(&conn->send_array);
2370 clear_buffer(&conn->recv_array); 2455 clear_buffer(&conn->recv_array);
@@ -2392,7 +2477,12 @@ unsigned int crypto_connection_status(const Net_Crypto *c, int crypt_connection_
2392 if (direct_connected) { 2477 if (direct_connected) {
2393 *direct_connected = 0; 2478 *direct_connected = 0;
2394 2479
2395 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_time) > unix_time()) 2480 uint64_t current_time = unix_time();
2481
2482 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev4) > current_time)
2483 *direct_connected = 1;
2484
2485 if ((UDP_DIRECT_TIMEOUT + conn->direct_lastrecv_timev6) > current_time)
2396 *direct_connected = 1; 2486 *direct_connected = 1;
2397 } 2487 }
2398 2488
diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h
index e5484e1e..cfeeaca5 100644
--- a/toxcore/net_crypto.h
+++ b/toxcore/net_crypto.h
@@ -39,7 +39,7 @@
39#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 */
40 40
41/* Minimum packet rate per second. */ 41/* Minimum packet rate per second. */
42#define CRYPTO_PACKET_MIN_RATE 8.0 42#define CRYPTO_PACKET_MIN_RATE 4.0
43 43
44/* Minimum packet queue max length. */ 44/* Minimum packet queue max length. */
45#define CRYPTO_MIN_QUEUE_LENGTH 64 45#define CRYPTO_MIN_QUEUE_LENGTH 64
@@ -119,8 +119,10 @@ typedef struct {
119 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */ 119 uint64_t temp_packet_sent_time; /* The time at which the last temp_packet was sent in ms. */
120 uint32_t temp_packet_num_sent; 120 uint32_t temp_packet_num_sent;
121 121
122 IP_Port ip_port; /* The ip and port to contact this guy directly.*/ 122 IP_Port ip_portv4; /* The ip and port to contact this guy directly.*/
123 uint64_t direct_lastrecv_time; /* The Time at which we last received a direct packet in ms. */ 123 IP_Port ip_portv6;
124 uint64_t direct_lastrecv_timev4; /* The Time at which we last received a direct packet in ms. */
125 uint64_t direct_lastrecv_timev6;
124 126
125 Packets_Array send_array; 127 Packets_Array send_array;
126 Packets_Array recv_array; 128 Packets_Array recv_array;