summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src/toxcore/Messenger.c
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2021-12-09 19:45:20 +0300
committerdartraiden <wowemuh@gmail.com>2021-12-09 19:45:20 +0300
commitb40119891c2f73c4726ab64ac2a2f327cf781ee2 (patch)
treef06adb7527462996a95160921693b7361f2f5d87 /protocols/Tox/libtox/src/toxcore/Messenger.c
parentf4f1858d08a927e48cf05169b53dd79f19f21794 (diff)
Update libtox to 0.2.13
Diffstat (limited to 'protocols/Tox/libtox/src/toxcore/Messenger.c')
-rw-r--r--protocols/Tox/libtox/src/toxcore/Messenger.c166
1 files changed, 74 insertions, 92 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/Messenger.c b/protocols/Tox/libtox/src/toxcore/Messenger.c
index 556acc272f..22c3e9e856 100644
--- a/protocols/Tox/libtox/src/toxcore/Messenger.c
+++ b/protocols/Tox/libtox/src/toxcore/Messenger.c
@@ -239,7 +239,8 @@ int32_t m_addfriend(Messenger *m, const uint8_t *address, const uint8_t *data, u
return FAERR_BADCHECKSUM;
}
- uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
+ uint16_t check;
+ uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
memcpy(&check, address + CRYPTO_PUBLIC_KEY_SIZE + sizeof(uint32_t), sizeof(check));
if (check != checksum) {
@@ -443,26 +444,31 @@ int m_get_friend_connectionstatus(const Messenger *m, int32_t friendnumber)
return -1;
}
- if (m->friendlist[friendnumber].status == FRIEND_ONLINE) {
- bool direct_connected = 0;
- unsigned int num_online_relays = 0;
- int crypt_conn_id = friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id);
+ if (m->friendlist[friendnumber].status != FRIEND_ONLINE) {
+ return CONNECTION_NONE;
+ }
- // FIXME(sudden6): handle return value
- crypto_connection_status(m->net_crypto, crypt_conn_id, &direct_connected, &num_online_relays);
+ bool direct_connected = 0;
+ unsigned int num_online_relays = 0;
+ int crypt_conn_id = friend_connection_crypt_connection_id(m->fr_c, m->friendlist[friendnumber].friendcon_id);
- if (direct_connected) {
- return CONNECTION_UDP;
- }
+ if (!crypto_connection_status(m->net_crypto, crypt_conn_id, &direct_connected, &num_online_relays)) {
+ return CONNECTION_NONE;
+ }
- if (num_online_relays) {
- return CONNECTION_TCP;
- }
+ if (direct_connected) {
+ return CONNECTION_UDP;
+ }
- return CONNECTION_UNKNOWN;
+ if (num_online_relays) {
+ return CONNECTION_TCP;
}
- return CONNECTION_NONE;
+ /* if we have a valid friend connection but do not have an established connection
+ * we leave the connection status unchanged until the friend connection is either
+ * established or dropped.
+ */
+ return m->friendlist[friendnumber].last_connection_udp_tcp;
}
int m_friend_exists(const Messenger *m, int32_t friendnumber)
@@ -898,21 +904,13 @@ static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber, void *userd
return;
}
- if (ret == CONNECTION_UNKNOWN) {
- if (last_connection_udp_tcp == CONNECTION_UDP) {
- return;
- }
-
- ret = CONNECTION_TCP;
- }
-
if (last_connection_udp_tcp != ret) {
if (m->friend_connectionstatuschange) {
m->friend_connectionstatuschange(m, friendnumber, ret, userdata);
}
}
- m->friendlist[friendnumber].last_connection_udp_tcp = ret;
+ m->friendlist[friendnumber].last_connection_udp_tcp = (Connection_Status)ret;
}
static void break_files(const Messenger *m, int32_t friendnumber);
@@ -1046,7 +1044,8 @@ int file_get_id(const Messenger *m, int32_t friendnumber, uint32_t filenumber, u
}
uint32_t temp_filenum;
- uint8_t send_receive, file_number;
+ uint8_t send_receive;
+ uint8_t file_number;
if (filenumber >= (1 << 16)) {
send_receive = 1;
@@ -1154,8 +1153,6 @@ long int new_filesender(const Messenger *m, int32_t friendnumber, uint32_t file_
ft->requested = 0;
- ft->slots_allocated = 0;
-
ft->paused = FILE_PAUSE_NOT;
memcpy(ft->id, file_id, FILE_ID_LENGTH);
@@ -1208,7 +1205,8 @@ int file_control(const Messenger *m, int32_t friendnumber, uint32_t filenumber,
}
uint32_t temp_filenum;
- uint8_t send_receive, file_number;
+ uint8_t send_receive;
+ uint8_t file_number;
if (filenumber >= (1 << 16)) {
send_receive = 1;
@@ -1435,10 +1433,6 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
// TODO(irungentoo): record packet ids to check if other received complete file.
ft->transferred += length;
- if (ft->slots_allocated) {
- --ft->slots_allocated;
- }
-
if (length != MAX_FILE_DATA_SIZE || ft->size == ft->transferred) {
ft->status = FILESTATUS_FINISHED;
ft->last_packet_number = ret;
@@ -1461,52 +1455,46 @@ int file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uin
* @param userdata The client userdata to pass along to chunk request callbacks.
* @param free_slots A pointer to the number of free send queue slots in the
* crypto connection.
+ * @return true if there's still work to do, false otherwise.
*
- * @return true if there are still file transfers ongoing, false if all file
- * transfers are complete.
*/
static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userdata, uint32_t *free_slots)
{
Friend *const friendcon = &m->friendlist[friendnumber];
- uint32_t num = friendcon->num_sending_files;
-
- bool any_active_fts = false;
- // Iterate over all file transfers, including inactive ones. I.e. we always
- // iterate exactly MAX_CONCURRENT_FILE_PIPES times.
+ // Iterate over file transfers as long as we're sending files
for (uint32_t i = 0; i < MAX_CONCURRENT_FILE_PIPES; ++i) {
- struct File_Transfers *const ft = &friendcon->file_sending[i];
+ if (friendcon->num_sending_files == 0) {
+ // no active file transfers anymore
+ return false;
+ }
- // Any status other than NONE means the file transfer is active.
- if (ft->status != FILESTATUS_NONE) {
- any_active_fts = true;
- --num;
+ if (*free_slots == 0) {
+ // send buffer full enough
+ return false;
+ }
- // If the file transfer is complete, we request a chunk of size 0.
- if (ft->status == FILESTATUS_FINISHED && friend_received_packet(m, friendnumber, ft->last_packet_number) == 0) {
- if (m->file_reqchunk) {
- m->file_reqchunk(m, friendnumber, i, ft->transferred, 0, userdata);
- }
+ if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id(
+ m->fr_c, friendcon->friendcon_id))) {
+ LOGGER_TRACE(m->log, "Maximum connection speed reached");
+ // connection doesn't support any more data
+ return false;
+ }
- // Now it's inactive, we're no longer sending this.
- ft->status = FILESTATUS_NONE;
- --friendcon->num_sending_files;
+ struct File_Transfers *const ft = &friendcon->file_sending[i];
+
+ // If the file transfer is complete, we request a chunk of size 0.
+ if (ft->status == FILESTATUS_FINISHED && friend_received_packet(m, friendnumber, ft->last_packet_number) == 0) {
+ if (m->file_reqchunk) {
+ m->file_reqchunk(m, friendnumber, i, ft->transferred, 0, userdata);
}
- // Decrease free slots by the number of slots this FT uses.
- *free_slots = max_s32(0, (int32_t) * free_slots - ft->slots_allocated);
+ // Now it's inactive, we're no longer sending this.
+ ft->status = FILESTATUS_NONE;
+ --friendcon->num_sending_files;
}
if (ft->status == FILESTATUS_TRANSFERRING && ft->paused == FILE_PAUSE_NOT) {
- if (max_speed_reached(m->net_crypto, friend_connection_crypt_connection_id(
- m->fr_c, friendcon->friendcon_id))) {
- *free_slots = 0;
- }
-
- if (*free_slots == 0) {
- continue;
- }
-
if (ft->size == 0) {
/* Send 0 data to friend if file is 0 length. */
file_data(m, friendnumber, i, 0, nullptr, 0);
@@ -1518,9 +1506,6 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd
continue;
}
- // Allocate 1 slot to this file transfer.
- ++ft->slots_allocated;
-
const uint16_t length = min_u64(ft->size - ft->requested, MAX_FILE_DATA_SIZE);
const uint64_t position = ft->requested;
ft->requested += length;
@@ -1532,13 +1517,9 @@ static bool do_all_filetransfers(Messenger *m, int32_t friendnumber, void *userd
// The allocated slot is no longer free.
--*free_slots;
}
-
- if (num == 0) {
- continue;
- }
}
- return any_active_fts;
+ return true;
}
static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber, void *userdata)
@@ -1560,19 +1541,22 @@ static void do_reqchunk_filecb(Messenger *m, int32_t friendnumber, void *userdat
// transfers might block other traffic for a long time.
free_slots = max_s32(0, (int32_t)free_slots - MIN_SLOTS_FREE);
- bool any_active_fts = true;
- uint32_t loop_counter = 0;
// Maximum number of outer loops below. If the client doesn't send file
// chunks from within the chunk request callback handler, we never realise
// that the file transfer has finished and may end up in an infinite loop.
//
- // TODO(zoff99): Fix this to exit the loop properly when we're done
- // requesting all chunks for all file transfers.
+ // Request up to that number of chunks per file from the client
const uint32_t max_ft_loops = 16;
- while (((free_slots > 0) || loop_counter == 0) && any_active_fts && (loop_counter < max_ft_loops)) {
- any_active_fts = do_all_filetransfers(m, friendnumber, userdata, &free_slots);
- ++loop_counter;
+ for (uint32_t i = 0; i < max_ft_loops; ++i) {
+ if (!do_all_filetransfers(m, friendnumber, userdata, &free_slots)) {
+ break;
+ }
+
+ if (free_slots == 0) {
+ // stop when the buffer is full enough
+ break;
+ }
}
}
@@ -1977,8 +1961,8 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
m->onion = new_onion(m->mono_time, m->dht);
m->onion_a = new_onion_announce(m->mono_time, m->dht);
- m->onion_c = new_onion_client(m->mono_time, m->net_crypto);
- m->fr_c = new_friend_connections(m->mono_time, m->onion_c, options->local_discovery_enabled);
+ m->onion_c = new_onion_client(m->log, m->mono_time, m->net_crypto);
+ m->fr_c = new_friend_connections(m->log, m->mono_time, m->onion_c, options->local_discovery_enabled);
if (!(m->onion && m->onion_a && m->onion_c && m->fr_c)) {
kill_friend_connections(m->fr_c);
@@ -1995,8 +1979,8 @@ Messenger *new_messenger(Mono_Time *mono_time, Messenger_Options *options, unsig
}
if (options->tcp_server_port) {
- m->tcp_server = new_TCP_server(options->ipv6enabled, 1, &options->tcp_server_port, dht_get_self_secret_key(m->dht),
- m->onion);
+ m->tcp_server = new_TCP_server(m->log, options->ipv6enabled, 1, &options->tcp_server_port,
+ dht_get_self_secret_key(m->dht), m->onion);
if (m->tcp_server == nullptr) {
kill_friend_connections(m->fr_c);
@@ -2507,7 +2491,7 @@ static char *id_to_string(const uint8_t *pk, char *id_str, size_t length)
}
/* Minimum messenger run interval in ms
- TODO(mannol): A/V */
+ * TODO(mannol): A/V */
#define MIN_RUN_INTERVAL 50
/* Return the time in milliseconds before do_messenger() should be called again
@@ -2567,9 +2551,9 @@ void do_messenger(Messenger *m, void *userdata)
if (mono_time_get(m->mono_time) > m->lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
m->lastdump = mono_time_get(m->mono_time);
- uint32_t client, last_pinged;
+ uint32_t last_pinged;
- for (client = 0; client < LCLIENT_LIST; ++client) {
+ for (uint32_t client = 0; client < LCLIENT_LIST; ++client) {
const Client_data *cptr = dht_get_close_client(m->dht, client);
const IPPTsPng *const assocs[] = { &cptr->assoc4, &cptr->assoc6, nullptr };
@@ -2594,14 +2578,12 @@ void do_messenger(Messenger *m, void *userdata)
}
- uint32_t friend_idx, dhtfriend;
-
/* dht contains additional "friends" (requests) */
uint32_t num_dhtfriends = dht_get_num_friends(m->dht);
VLA(int32_t, m2dht, num_dhtfriends);
VLA(int32_t, dht2m, num_dhtfriends);
- for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
+ for (uint32_t friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
m2dht[friend_idx] = -1;
dht2m[friend_idx] = -1;
@@ -2609,7 +2591,7 @@ void do_messenger(Messenger *m, void *userdata)
continue;
}
- for (dhtfriend = 0; dhtfriend < dht_get_num_friends(m->dht); ++dhtfriend) {
+ for (uint32_t dhtfriend = 0; dhtfriend < dht_get_num_friends(m->dht); ++dhtfriend) {
if (id_equal(m->friendlist[friend_idx].real_pk, dht_get_friend_public_key(m->dht, dhtfriend))) {
m2dht[friend_idx] = dhtfriend;
break;
@@ -2617,7 +2599,7 @@ void do_messenger(Messenger *m, void *userdata)
}
}
- for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
+ for (uint32_t friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
if (m2dht[friend_idx] >= 0) {
dht2m[m2dht[friend_idx]] = friend_idx;
}
@@ -2630,7 +2612,7 @@ void do_messenger(Messenger *m, void *userdata)
Friend *msgfptr;
DHT_Friend *dhtfptr;
- for (friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
+ for (uint32_t friend_idx = 0; friend_idx < num_dhtfriends; ++friend_idx) {
if (dht2m[friend_idx] >= 0) {
msgfptr = &m->friendlist[dht2m[friend_idx]];
} else {
@@ -2650,7 +2632,7 @@ void do_messenger(Messenger *m, void *userdata)
id_to_string(dht_friend_public_key(dhtfptr), id_str, sizeof(id_str)));
}
- for (client = 0; client < MAX_FRIEND_CLIENTS; ++client) {
+ for (uint32_t client = 0; client < MAX_FRIEND_CLIENTS; ++client) {
const Client_data *cptr = dht_friend_client(dhtfptr, client);
const IPPTsPng *const assocs[] = {&cptr->assoc4, &cptr->assoc6};