Skip to content

Commit 072e3be

Browse files
committed
fix: issues with packet broadcast error reporting
commit 5b9c420 introduced some undesirable behaviour with packet send functions returning error when they shouldn't. We now only return an error if the packet fails to be added to the send queue or cannot be wrapped/encrypted. We no longer error if we fail to send the packet over the wire, because toxcore will keep trying to re-send the packet until the connection times out. Additionally, we now make sure that our packet broadcast functions aren't returning an error when failing to send packets to peers that we have not successfully handshaked with yet, since this is expected behaviour.
1 parent 6b6718e commit 072e3be

4 files changed

Lines changed: 37 additions & 20 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c98b35f18f351c9a3a05137e69a43e634ab5963d364b9337e89ad89469ebd8c2 /usr/local/bin/tox-bootstrapd
1+
a6701e463517907cdb450f3210389633feb6c1cc3a1d3faec48c8b99a4aebf3c /usr/local/bin/tox-bootstrapd

toxcore/group_chats.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,12 +2264,14 @@ static int handle_gc_invite_request(GC_Chat *chat, uint32_t peer_number, const u
22642264

22652265
/** @brief Sends a lossless packet of type and length to all confirmed peers.
22662266
*
2267-
* Return true if packet is successfully sent to at least one peer.
2267+
* Return true if packet is successfully sent to at least one peer or the
2268+
* group is empty.
22682269
*/
22692270
non_null()
22702271
static bool send_gc_lossless_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
22712272
{
22722273
uint32_t sent = 0;
2274+
uint32_t confirmed_peers = 0;
22732275

22742276
for (uint32_t i = 1; i < chat->numpeers; ++i) {
22752277
GC_Connection *gconn = get_gc_connection(chat, i);
@@ -2280,22 +2282,26 @@ static bool send_gc_lossless_packet_all_peers(const GC_Chat *chat, const uint8_t
22802282
continue;
22812283
}
22822284

2285+
++confirmed_peers;
2286+
22832287
if (send_lossless_group_packet(chat, gconn, data, length, type)) {
22842288
++sent;
22852289
}
22862290
}
22872291

2288-
return sent > 0 || chat->numpeers <= 1;
2292+
return sent > 0 || confirmed_peers == 0;
22892293
}
22902294

22912295
/** @brief Sends a lossy packet of type and length to all confirmed peers.
22922296
*
2293-
* Return true if packet is successfully sent to at least one peer.
2297+
* Return true if packet is successfully sent to at least one peer or the
2298+
* group is empty.
22942299
*/
22952300
non_null()
22962301
static bool send_gc_lossy_packet_all_peers(const GC_Chat *chat, const uint8_t *data, uint16_t length, uint8_t type)
22972302
{
22982303
uint32_t sent = 0;
2304+
uint32_t confirmed_peers = 0;
22992305

23002306
for (uint32_t i = 1; i < chat->numpeers; ++i) {
23012307
const GC_Connection *gconn = get_gc_connection(chat, i);
@@ -2306,12 +2312,14 @@ static bool send_gc_lossy_packet_all_peers(const GC_Chat *chat, const uint8_t *d
23062312
continue;
23072313
}
23082314

2315+
++confirmed_peers;
2316+
23092317
if (send_lossy_group_packet(chat, gconn, data, length, type)) {
23102318
++sent;
23112319
}
23122320
}
23132321

2314-
return sent > 0 || chat->numpeers <= 1;
2322+
return sent > 0 || confirmed_peers == 0;
23152323
}
23162324

23172325
/** @brief Creates packet with broadcast header info followed by data of length.
@@ -5318,7 +5326,7 @@ static int handle_gc_message_ack(const GC_Chat *chat, GC_Connection *gconn, cons
53185326
if (gcc_encrypt_and_send_lossless_packet(chat, gconn, gconn->send_array[idx].data,
53195327
gconn->send_array[idx].data_length,
53205328
gconn->send_array[idx].message_id,
5321-
gconn->send_array[idx].packet_type)) {
5329+
gconn->send_array[idx].packet_type) == 0) {
53225330
gconn->send_array[idx].last_send_try = tm;
53235331
LOGGER_DEBUG(chat->log, "Re-sent requested packet %llu", (unsigned long long)message_id);
53245332
} else {

toxcore/group_connection.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static bool create_array_entry(const Logger *log, const Mono_Time *mono_time, GC
137137

138138
/** @brief Adds data of length to gconn's send_array.
139139
*
140-
* Returns true on success and increments gconn's send_message_id.
140+
* Returns true and increments gconn's send_message_id on success.
141141
*/
142142
non_null(1, 2, 3) nullable(4)
143143
static bool add_to_send_array(const Logger *log, const Mono_Time *mono_time, GC_Connection *gconn, const uint8_t *data,
@@ -171,8 +171,15 @@ int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const ui
171171
return -1;
172172
}
173173

174-
if (!gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type)) {
175-
LOGGER_DEBUG(chat->log, "Failed to send payload: (type: 0x%02x, length: %d)", packet_type, length);
174+
// If the packet fails to wrap/encrypt, we remove it from the send array, since trying to-resend
175+
// the same bad packet probably won't help much. Otherwise we don't care if it doesn't successfully
176+
// send through the wire as it will keep retrying until the connection times out.
177+
if (gcc_encrypt_and_send_lossless_packet(chat, gconn, data, length, message_id, packet_type) == -1) {
178+
const uint16_t idx = gcc_get_array_index(message_id);
179+
GC_Message_Array_Entry *array_entry = &gconn->send_array[idx];
180+
clear_array_entry(array_entry);
181+
gconn->send_message_id = message_id;
182+
LOGGER_ERROR(chat->log, "Failed to encrypt payload: (type: 0x%02x, length: %d)", packet_type, length);
176183
return -2;
177184
}
178185

@@ -616,15 +623,15 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
616623
return ret == 0 || direct_send_attempt;
617624
}
618625

619-
bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
626+
int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
620627
uint16_t length, uint64_t message_id, uint8_t packet_type)
621628
{
622629
const uint16_t packet_size = gc_get_wrapped_packet_size(length, NET_PACKET_GC_LOSSLESS);
623630
uint8_t *packet = (uint8_t *)malloc(packet_size);
624631

625632
if (packet == nullptr) {
626633
LOGGER_ERROR(chat->log, "Failed to allocate memory for packet buffer");
627-
return false;
634+
return -1;
628635
}
629636

630637
const int enc_len = group_packet_wrap(
@@ -634,18 +641,18 @@ bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connecti
634641
if (enc_len < 0) {
635642
LOGGER_ERROR(chat->log, "Failed to wrap packet (type: 0x%02x, error: %d)", packet_type, enc_len);
636643
free(packet);
637-
return false;
644+
return -1;
638645
}
639646

640647
if (!gcc_send_packet(chat, gconn, packet, (uint16_t)enc_len)) {
641648
LOGGER_DEBUG(chat->log, "Failed to send packet (type: 0x%02x, enc_len: %d)", packet_type, enc_len);
642649
free(packet);
643-
return false;
650+
return -2;
644651
}
645652

646653
free(packet);
647654

648-
return true;
655+
return 0;
649656
}
650657

651658
void gcc_make_session_shared_key(GC_Connection *gconn, const uint8_t *sender_pk)

toxcore/group_connection.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ bool gcc_send_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint
143143
/** @brief Sends a lossless packet to `gconn` comprised of `data` of size `length`.
144144
*
145145
* This function will add the packet to the lossless send array, encrypt/wrap it using the
146-
* shared key associated with `gconn`, and send it over the wire.
146+
* shared key associated with `gconn`, and try to send it over the wire.
147147
*
148-
* Return 0 on success.
148+
* Return 0 if the packet was successfully encrypted and added to the send array.
149149
* Return -1 if the packet couldn't be added to the send array.
150-
* Return -2 if the packet failed to be encrypted or failed to send.
150+
* Return -2 if the packet failed to be wrapped or encrypted.
151151
*/
152152
non_null(1, 2) nullable(3)
153153
int gcc_send_lossless_packet(const GC_Chat *chat, GC_Connection *gconn, const uint8_t *data, uint16_t length,
@@ -172,11 +172,13 @@ bool gcc_send_lossless_packet_fragments(const GC_Chat *chat, GC_Connection *gcon
172172
*
173173
* This function does not add the packet to the send array.
174174
*
175-
* Return true on success.
175+
* Return 0 on success.
176+
* Return -1 if packet wrapping and encryption fails.
177+
* Return -2 if the packet fails to send.
176178
*/
177179
non_null(1, 2) nullable(3)
178-
bool gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
179-
uint16_t length, uint64_t message_id, uint8_t packet_type);
180+
int gcc_encrypt_and_send_lossless_packet(const GC_Chat *chat, const GC_Connection *gconn, const uint8_t *data,
181+
uint16_t length, uint64_t message_id, uint8_t packet_type);
180182

181183
/** @brief Called when a peer leaves the group. */
182184
non_null()

0 commit comments

Comments
 (0)