diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index bdf5cd4c..0d859435 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c @@ -548,6 +548,30 @@ int discard_packet(Lossless_UDP *ludp, int connection_id) } #define MAX_SYNC_RATE 20 +#define MIN_SLOTS 16 +/* returns the number of packet slots left in the sendbuffer. + * return 0 if failure. + */ +uint32_t num_free_sendqueue_slots(Lossless_UDP *ludp, int connection_id) +{ + if ((unsigned int)connection_id >= ludp->connections.len) + return 0; + + Connection *connection = &tox_array_get(&ludp->connections, connection_id, Connection); + uint32_t max_slots = (connection->data_rate / MAX_SYNC_RATE) * 1.5; + + if (max_slots > MAX_QUEUE_NUM) + max_slots = MAX_QUEUE_NUM; + + if (max_slots < MIN_SLOTS) + max_slots = MIN_SLOTS; + + if (sendqueue(ludp, connection_id) > max_slots) + return 0; + + return max_slots - sendqueue(ludp, connection_id); +} + /* return 0 if data could not be put in packet queue. * return 1 if data was put into the queue. @@ -565,9 +589,10 @@ int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t if (length > MAX_DATA_SIZE || length == 0 || sendqueue(ludp, connection_id) >= MAX_QUEUE_NUM) return 0; + if (num_free_sendqueue_slots(ludp, connection_id) == 0) + return 0; + if (sendqueue(ludp, connection_id) >= connection->sendbuffer_length && connection->sendbuffer_length != 0) { - if (sendqueue(ludp, connection_id) > connection->data_rate/MAX_SYNC_RATE) - return 0; uint32_t newlen = connection->sendbuffer_length = resize_queue(&connection->sendbuffer, connection->sendbuffer_length, connection->sendbuffer_length * 2, connection->successful_sent, connection->sendbuff_packetnum); @@ -578,7 +603,6 @@ int write_packet(Lossless_UDP *ludp, int connection_id, uint8_t *data, uint32_t return write_packet(ludp, connection_id, data, length); } - uint32_t index = connection->sendbuff_packetnum % connection->sendbuffer_length; memcpy(connection->sendbuffer[index].data, data, length); connection->sendbuffer[index].size = length; diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h index 8a1c9c53..3d782be7 100644 --- a/toxcore/Lossless_UDP.h +++ b/toxcore/Lossless_UDP.h @@ -217,6 +217,11 @@ int read_packet_silent(Lossless_UDP *ludp, int connection_id, uint8_t *data); */ int discard_packet(Lossless_UDP *ludp, int connection_id); +/* returns the number of packet slots left in the sendbuffer. + * return 0 if failure. + */ +uint32_t num_free_sendqueue_slots(Lossless_UDP *ludp, int connection_id); + /* return 0 if data could not be put in packet queue. * return 1 if data was put into the queue. */ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 60fcc0ba..5ed94bb7 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1091,7 +1091,7 @@ int file_control(Messenger *m, int friendnumber, uint8_t send_receive, uint8_t f } } - +#define MIN_SLOTS_FREE 4 /* Send file data. * * return 1 on success @@ -1108,6 +1108,10 @@ int file_data(Messenger *m, int friendnumber, uint8_t filenumber, uint8_t *data, if (m->friendlist[friendnumber].file_sending[filenumber].status != FILESTATUS_TRANSFERRING) return 0; + /* Prevent file sending from filling up the entire buffer preventing messages from being sent. */ + if (crypto_num_free_sendqueue_slots(m->net_crypto, m->friendlist[friendnumber].crypt_connection_id) < MIN_SLOTS_FREE) + return 0; + uint8_t packet[MAX_DATA_SIZE]; packet[0] = filenumber; memcpy(packet + 1, data, length); diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 9a840d11..14398c53 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -198,6 +198,17 @@ int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data) return -1; } +/* returns the number of packet slots left in the sendbuffer. + * return 0 if failure. + */ +uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id) +{ + if (crypt_connection_id_not_valid(c, crypt_connection_id)) + return 0; + + return num_free_sendqueue_slots(c->lossless_udp, c->crypto_connections[crypt_connection_id].number); +} + /* return 0 if data could not be put in packet queue. * return 1 if data was put into the queue. */ @@ -579,9 +590,6 @@ int accept_crypto_inbound(Net_Crypto *c, int connection_id, uint8_t *public_key, * } */ - /* Connection is accepted. */ - confirm_connection(c->lossless_udp, connection_id); - if (realloc_cryptoconnection(c, c->crypto_connections_length + 1) == -1 || c->crypto_connections == NULL) return -1; @@ -721,6 +729,8 @@ static void receive_crypto(Net_Crypto *c) c->crypto_connections[i].shared_key); c->crypto_connections[i].status = CONN_ESTABLISHED; c->crypto_connections[i].timeout = ~0; + /* Connection is accepted. */ + confirm_connection(c->lossless_udp, c->crypto_connections[i].number); } else { /* This should not happen, timeout the connection if it does. */ c->crypto_connections[i].status = CONN_TIMED_OUT; diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 5d21e4b6..0c1bffe6 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -121,6 +121,11 @@ void new_nonce(uint8_t *nonce); */ int read_cryptpacket(Net_Crypto *c, int crypt_connection_id, uint8_t *data); +/* returns the number of packet slots left in the sendbuffer. + * return 0 if failure. + */ +uint32_t crypto_num_free_sendqueue_slots(Net_Crypto *c, int crypt_connection_id); + /* return 0 if data could not be put in packet queue. * return 1 if data was put into the queue. */