diff options
Diffstat (limited to 'toxcore/TCP_server.c')
-rw-r--r-- | toxcore/TCP_server.c | 109 |
1 files changed, 94 insertions, 15 deletions
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index e7ef0d3a..8b7d5fdd 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c | |||
@@ -306,25 +306,94 @@ static int send_pending_data(TCP_Secure_Connection *con) | |||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
308 | 308 | ||
309 | if (len > left) | ||
310 | return -1; | ||
311 | |||
312 | con->last_packet_sent += len; | 309 | con->last_packet_sent += len; |
313 | return -1; | 310 | return -1; |
314 | 311 | ||
315 | } | 312 | } |
316 | 313 | ||
314 | /* return 0 if pending data was sent completely | ||
315 | * return -1 if it wasn't | ||
316 | */ | ||
317 | static int send_pending_data_priority(TCP_Secure_Connection *con) | ||
318 | { | ||
319 | TCP_Priority_List *p = con->priority_queue_start; | ||
320 | |||
321 | while(p) { | ||
322 | uint16_t left = p->size - p->sent; | ||
323 | int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL); | ||
324 | |||
325 | if(len != left) { | ||
326 | if(len > 0) { | ||
327 | p->sent += len; | ||
328 | } | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | TCP_Priority_List *pp = p; | ||
333 | p = p->next; | ||
334 | free(pp); | ||
335 | } | ||
336 | |||
337 | con->priority_queue_start = p; | ||
338 | if(!p) { | ||
339 | con->priority_queue_end = NULL; | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | return -1; | ||
344 | } | ||
345 | |||
346 | /* return 0 on failure (only if malloc fails) | ||
347 | * return 1 on success | ||
348 | */ | ||
349 | static _Bool add_priority(TCP_Secure_Connection *con, const uint8_t *packet, uint16_t size, int sent) | ||
350 | { | ||
351 | if(sent == size) { | ||
352 | return 1; | ||
353 | } | ||
354 | |||
355 | if(sent <= 0) { | ||
356 | sent = 0; | ||
357 | } | ||
358 | |||
359 | TCP_Priority_List *p = con->priority_queue_end, *new; | ||
360 | new = malloc(sizeof(TCP_Priority_List) + size); | ||
361 | if(!new) { | ||
362 | return 0; | ||
363 | } | ||
364 | |||
365 | new->next = NULL; | ||
366 | new->size = size; | ||
367 | new->sent = sent; | ||
368 | memcpy(new->data, packet, size); | ||
369 | |||
370 | if(p) { | ||
371 | p->next = new; | ||
372 | } else { | ||
373 | con->priority_queue_start = new; | ||
374 | } | ||
375 | |||
376 | con->priority_queue_end = new; | ||
377 | return 1; | ||
378 | } | ||
379 | |||
317 | /* return 1 on success. | 380 | /* return 1 on success. |
318 | * return 0 if could not send packet. | 381 | * return 0 if could not send packet. |
319 | * return -1 on failure (connection must be killed). | 382 | * return -1 on failure (connection must be killed). |
320 | */ | 383 | */ |
321 | static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length) | 384 | static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length, _Bool priority) |
322 | { | 385 | { |
323 | if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) | 386 | if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) |
324 | return -1; | 387 | return -1; |
325 | 388 | ||
326 | if (send_pending_data(con) == -1) | 389 | _Bool sendpriority = 1; |
327 | return 0; | 390 | if (send_pending_data_priority(con) == -1) { |
391 | if (priority) { | ||
392 | sendpriority = 0; | ||
393 | } else { | ||
394 | return 0; | ||
395 | } | ||
396 | } | ||
328 | 397 | ||
329 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; | 398 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; |
330 | 399 | ||
@@ -332,6 +401,13 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const | |||
332 | memcpy(packet, &c_length, sizeof(uint16_t)); | 401 | memcpy(packet, &c_length, sizeof(uint16_t)); |
333 | int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); | 402 | int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); |
334 | 403 | ||
404 | if (priority) { | ||
405 | return add_priority(con, packet, sizeof(packet), sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0); | ||
406 | } | ||
407 | |||
408 | if (send_pending_data(con) == -1) | ||
409 | return 0; | ||
410 | |||
335 | if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) | 411 | if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) |
336 | return -1; | 412 | return -1; |
337 | 413 | ||
@@ -459,7 +535,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const | |||
459 | data[1] = rpid; | 535 | data[1] = rpid; |
460 | memcpy(data + 2, public_key, crypto_box_PUBLICKEYBYTES); | 536 | memcpy(data + 2, public_key, crypto_box_PUBLICKEYBYTES); |
461 | 537 | ||
462 | return write_packet_TCP_secure_connection(con, data, sizeof(data)); | 538 | return write_packet_TCP_secure_connection(con, data, sizeof(data), 1); |
463 | } | 539 | } |
464 | 540 | ||
465 | /* return 1 on success. | 541 | /* return 1 on success. |
@@ -469,7 +545,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const | |||
469 | static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id) | 545 | static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id) |
470 | { | 546 | { |
471 | uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS}; | 547 | uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS}; |
472 | return write_packet_TCP_secure_connection(con, data, sizeof(data)); | 548 | return write_packet_TCP_secure_connection(con, data, sizeof(data), 1); |
473 | } | 549 | } |
474 | 550 | ||
475 | /* return 1 on success. | 551 | /* return 1 on success. |
@@ -479,7 +555,7 @@ static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id) | |||
479 | static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) | 555 | static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id) |
480 | { | 556 | { |
481 | uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS}; | 557 | uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS}; |
482 | return write_packet_TCP_secure_connection(con, data, sizeof(data)); | 558 | return write_packet_TCP_secure_connection(con, data, sizeof(data), 1); |
483 | } | 559 | } |
484 | 560 | ||
485 | /* return 0 on success. | 561 | /* return 0 on success. |
@@ -579,7 +655,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui | |||
579 | memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES); | 655 | memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES); |
580 | memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); | 656 | memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); |
581 | write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, | 657 | write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet, |
582 | sizeof(resp_packet)); | 658 | sizeof(resp_packet), 0); |
583 | } | 659 | } |
584 | 660 | ||
585 | return 0; | 661 | return 0; |
@@ -637,7 +713,7 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, | |||
637 | memcpy(packet + 1, data, length); | 713 | memcpy(packet + 1, data, length); |
638 | packet[0] = TCP_PACKET_ONION_RESPONSE; | 714 | packet[0] = TCP_PACKET_ONION_RESPONSE; |
639 | 715 | ||
640 | if (write_packet_TCP_secure_connection(con, packet, sizeof(packet)) != 1) | 716 | if (write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0) != 1) |
641 | return 1; | 717 | return 1; |
642 | 718 | ||
643 | return 0; | 719 | return 0; |
@@ -682,7 +758,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint | |||
682 | uint8_t response[1 + sizeof(uint64_t)]; | 758 | uint8_t response[1 + sizeof(uint64_t)]; |
683 | response[0] = TCP_PACKET_PONG; | 759 | response[0] = TCP_PACKET_PONG; |
684 | memcpy(response + 1, data + 1, sizeof(uint64_t)); | 760 | memcpy(response + 1, data + 1, sizeof(uint64_t)); |
685 | write_packet_TCP_secure_connection(con, response, sizeof(response)); | 761 | write_packet_TCP_secure_connection(con, response, sizeof(response), 1); |
686 | return 0; | 762 | return 0; |
687 | } | 763 | } |
688 | 764 | ||
@@ -752,7 +828,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint | |||
752 | uint8_t new_data[length]; | 828 | uint8_t new_data[length]; |
753 | memcpy(new_data, data, length); | 829 | memcpy(new_data, data, length); |
754 | new_data[0] = other_c_id; | 830 | new_data[0] = other_c_id; |
755 | int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length); | 831 | int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0); |
756 | 832 | ||
757 | if (ret == -1) | 833 | if (ret == -1) |
758 | return -1; | 834 | return -1; |
@@ -1058,7 +1134,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) | |||
1058 | ++ping_id; | 1134 | ++ping_id; |
1059 | 1135 | ||
1060 | memcpy(ping + 1, &ping_id, sizeof(uint64_t)); | 1136 | memcpy(ping + 1, &ping_id, sizeof(uint64_t)); |
1061 | int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping)); | 1137 | int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping), 1); |
1062 | 1138 | ||
1063 | if (ret == 1) { | 1139 | if (ret == 1) { |
1064 | conn->last_pinged = unix_time(); | 1140 | conn->last_pinged = unix_time(); |
@@ -1076,7 +1152,10 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) | |||
1076 | continue; | 1152 | continue; |
1077 | } | 1153 | } |
1078 | 1154 | ||
1079 | send_pending_data(conn); | 1155 | /* try sending queued priority packets first */ |
1156 | if(send_pending_data_priority(conn) == 0) { | ||
1157 | send_pending_data(conn); | ||
1158 | } | ||
1080 | 1159 | ||
1081 | #ifndef TCP_SERVER_USE_EPOLL | 1160 | #ifndef TCP_SERVER_USE_EPOLL |
1082 | 1161 | ||