diff options
Diffstat (limited to 'toxcore/net_crypto.c')
-rw-r--r-- | toxcore/net_crypto.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index e0319f34..ac2359ee 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -37,21 +37,6 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn | |||
37 | return (uint32_t)crypt_connection_id >= c->crypto_connections_length; | 37 | return (uint32_t)crypt_connection_id >= c->crypto_connections_length; |
38 | } | 38 | } |
39 | 39 | ||
40 | /* return 0 if connection is dead. | ||
41 | * return 1 if connection is alive. | ||
42 | */ | ||
43 | static int is_alive(uint8_t status) | ||
44 | { | ||
45 | if (status == CRYPTO_CONN_COOKIE_REQUESTING || | ||
46 | status == CRYPTO_CONN_HANDSHAKE_SENT || | ||
47 | status == CRYPTO_CONN_NOT_CONFIRMED || | ||
48 | status == CRYPTO_CONN_ESTABLISHED) { | ||
49 | return 1; | ||
50 | } | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | /* cookie timeout in seconds */ | 40 | /* cookie timeout in seconds */ |
56 | #define COOKIE_TIMEOUT 10 | 41 | #define COOKIE_TIMEOUT 10 |
57 | #define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2) | 42 | #define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2) |
@@ -426,19 +411,22 @@ static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const ui | |||
426 | 411 | ||
427 | } | 412 | } |
428 | 413 | ||
429 | //TODO: spread packets over many relays, detect and kill bad relays. | 414 | //TODO: detect and kill bad relays. |
430 | uint32_t i; | 415 | uint32_t i; |
431 | 416 | ||
417 | unsigned int r = rand(); | ||
418 | |||
432 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 419 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
433 | if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ | 420 | if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */ |
434 | if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1) | 421 | if (send_data(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->con_number_tcp[(i + r) % MAX_TCP_CONNECTIONS], |
422 | data, length) == 1) | ||
435 | return 0; | 423 | return 0; |
436 | } | 424 | } |
437 | } | 425 | } |
438 | 426 | ||
439 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { | 427 | for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) { |
440 | if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) { | 428 | if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_INVISIBLE) { |
441 | if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1) | 429 | if (send_oob_packet(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->dht_public_key, data, length) == 1) |
442 | return 0; | 430 | return 0; |
443 | } | 431 | } |
444 | } | 432 | } |
@@ -1106,6 +1094,14 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i | |||
1106 | return -1; | 1094 | return -1; |
1107 | } | 1095 | } |
1108 | 1096 | ||
1097 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { | ||
1098 | clear_temp_packet(c, crypt_connection_id); | ||
1099 | conn->status = CRYPTO_CONN_ESTABLISHED; | ||
1100 | |||
1101 | if (conn->connection_status_callback) | ||
1102 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1); | ||
1103 | } | ||
1104 | |||
1109 | if (real_data[0] == PACKET_ID_REQUEST) { | 1105 | if (real_data[0] == PACKET_ID_REQUEST) { |
1110 | int requested = handle_request_packet(&conn->send_array, real_data, real_length); | 1106 | int requested = handle_request_packet(&conn->send_array, real_data, real_length); |
1111 | 1107 | ||
@@ -1148,14 +1144,6 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i | |||
1148 | return -1; | 1144 | return -1; |
1149 | } | 1145 | } |
1150 | 1146 | ||
1151 | if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) { | ||
1152 | if (conn->connection_status_callback) | ||
1153 | conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1); | ||
1154 | |||
1155 | clear_temp_packet(c, crypt_connection_id); | ||
1156 | conn->status = CRYPTO_CONN_ESTABLISHED; | ||
1157 | } | ||
1158 | |||
1159 | return 0; | 1147 | return 0; |
1160 | } | 1148 | } |
1161 | 1149 | ||
@@ -1485,6 +1473,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c) | |||
1485 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ | 1473 | /* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */ |
1486 | set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic()); | 1474 | set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic()); |
1487 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 1475 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
1476 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; | ||
1488 | crypto_connection_add_source(c, crypt_connection_id, n_c->source); | 1477 | crypto_connection_add_source(c, crypt_connection_id, n_c->source); |
1489 | return crypt_connection_id; | 1478 | return crypt_connection_id; |
1490 | } | 1479 | } |
@@ -1517,6 +1506,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key) | |||
1517 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); | 1506 | crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key); |
1518 | conn->status = CRYPTO_CONN_COOKIE_REQUESTING; | 1507 | conn->status = CRYPTO_CONN_COOKIE_REQUESTING; |
1519 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 1508 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
1509 | conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH; | ||
1520 | return crypt_connection_id; | 1510 | return crypt_connection_id; |
1521 | } | 1511 | } |
1522 | 1512 | ||
@@ -2250,6 +2240,15 @@ static void send_crypto_packets(Net_Crypto *c) | |||
2250 | notes: needs improvement but seems to work fine for packet loss <1% | 2240 | notes: needs improvement but seems to work fine for packet loss <1% |
2251 | */ | 2241 | */ |
2252 | 2242 | ||
2243 | /* additional step: adjust the send rate based on the size change of the send queue */ | ||
2244 | uint32_t queue_size = num_packets_array(&conn->send_array); | ||
2245 | |||
2246 | if (queue_size > conn->packet_send_rate && queue_size > conn->last_queue_size) { | ||
2247 | conn->rate_increase = 0; | ||
2248 | conn->packets_resent = conn->packets_sent; | ||
2249 | } | ||
2250 | |||
2251 | |||
2253 | //hack to prevent 1 packet lost from affecting calculations at low send rates | 2252 | //hack to prevent 1 packet lost from affecting calculations at low send rates |
2254 | if (conn->packets_resent == 1) { | 2253 | if (conn->packets_resent == 1) { |
2255 | conn->packets_resent = 0; | 2254 | conn->packets_resent = 0; |
@@ -2300,18 +2299,27 @@ static void send_crypto_packets(Net_Crypto *c) | |||
2300 | double linear_increase = realrate * 0.0025 + 1.0; | 2299 | double linear_increase = realrate * 0.0025 + 1.0; |
2301 | 2300 | ||
2302 | //final send rate: average of "real" and previous send rates + increases | 2301 | //final send rate: average of "real" and previous send rates + increases |
2303 | conn->packet_send_rate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase; | 2302 | double newrate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase; |
2303 | conn->last_send_rate = conn->packet_send_rate; | ||
2304 | conn->packet_send_rate = newrate; | ||
2304 | 2305 | ||
2305 | 2306 | ||
2306 | conn->dropped = dropped; | 2307 | conn->dropped = dropped; |
2307 | conn->drop_ignore = drop_ignore_new; | 2308 | conn->drop_ignore = drop_ignore_new; |
2308 | conn->packets_resent = 0; | 2309 | conn->packets_resent = 0; |
2310 | conn->last_queue_size = queue_size; | ||
2309 | 2311 | ||
2310 | if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) { | 2312 | if (!conn->sending || !conn->packets_sent) { |
2311 | conn->rate_increase = 0; | 2313 | conn->rate_increase = 0; |
2314 | conn->packet_send_rate /= 2; | ||
2315 | } | ||
2316 | |||
2317 | if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) { | ||
2312 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; | 2318 | conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE; |
2313 | } | 2319 | } |
2314 | 2320 | ||
2321 | conn->packets_sent = 0; | ||
2322 | |||
2315 | if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH / 2) { | 2323 | if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH / 2) { |
2316 | --conn->sending; | 2324 | --conn->sending; |
2317 | } | 2325 | } |
@@ -2342,6 +2350,7 @@ static void send_crypto_packets(Net_Crypto *c) | |||
2342 | 2350 | ||
2343 | conn->packets_resent += ret; | 2351 | conn->packets_resent += ret; |
2344 | conn->packets_left -= ret; | 2352 | conn->packets_left -= ret; |
2353 | conn->packets_sent += ret; | ||
2345 | } | 2354 | } |
2346 | 2355 | ||
2347 | if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) { | 2356 | if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) { |
@@ -2421,6 +2430,7 @@ int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const ui | |||
2421 | return -1; | 2430 | return -1; |
2422 | 2431 | ||
2423 | --conn->packets_left; | 2432 | --conn->packets_left; |
2433 | conn->packets_sent++; | ||
2424 | conn->sending = CONN_SENDING_VALUE; | 2434 | conn->sending = CONN_SENDING_VALUE; |
2425 | return ret; | 2435 | return ret; |
2426 | } | 2436 | } |