Skip to content

Commit 1670917

Browse files
authored
Merge pull request #1934 from private-octopus/monopath-keep-alive
NAT and monopath keep alive
2 parents 259c952 + 33b4f5f commit 1670917

File tree

10 files changed

+177
-85
lines changed

10 files changed

+177
-85
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ else()
88
endif()
99

1010
project(picoquic
11-
VERSION 1.1.38.3
11+
VERSION 1.1.38.4
1212
DESCRIPTION "picoquic library"
1313
LANGUAGES C CXX)
1414

UnitTest1/unittest1.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,12 @@ namespace UnitTest1
27572757
Assert::AreEqual(ret, 0);
27582758
}
27592759

2760+
TEST_METHOD(monopath_keep_alive) {
2761+
int ret = monopath_keep_alive_test();
2762+
2763+
Assert::AreEqual(ret, 0);
2764+
}
2765+
27602766
TEST_METHOD(monopath_rotation) {
27612767
int ret = monopath_rotation_test();
27622768

picoquic/paths.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ int picoquic_prepare_path_control_packet(picoquic_cnx_t* cnx, picoquic_path_t* p
217217
length = 0;
218218
}
219219
packet->length = length;
220-
picoquic_finalize_and_protect_packet(cnx, packet,
220+
picoquic_finalize_and_protect_packet_tuple(cnx, packet,
221221
ret, length, header_length, checksum_overhead,
222222
send_length, send_buffer, send_buffer_min_max,
223-
path_x, current_time);
223+
path_x, current_time, tuple);
224224

225225
if (*send_length > 0) {
226226
*next_wake_time = current_time;
@@ -272,7 +272,7 @@ void picoquic_delete_demoted_tuples(picoquic_cnx_t* cnx, uint64_t current_time,
272272
while (tuple != NULL && (next_tuple = tuple->next_tuple) != NULL) {
273273
if (next_tuple->challenge_failed) {
274274
if (current_time > next_tuple->demotion_time) {
275-
picoquic_delete_tuple(path_x, next_tuple);
275+
picoquic_delete_tuple(path_x, next_tuple, 0);
276276
continue;
277277
}
278278
else if (*next_wake_time > next_tuple->demotion_time) {
@@ -711,21 +711,21 @@ int picoquic_find_incoming_path(picoquic_cnx_t* cnx,
711711
if (picoquic_check_cid_for_new_tuple(cnx, path_x->unique_path_id) == 0 &&
712712
(tuple = picoquic_create_tuple(path_x, addr_to, addr_from, if_index_to)) != NULL &&
713713
picoquic_assign_peer_cnxid_to_tuple(cnx, path_x, tuple) == 0) {
714+
picoquic_set_tuple_challenge(tuple, current_time, cnx->quic->use_constant_challenges);
714715
if (picoquic_compare_connection_id(&path_x->first_tuple->p_local_cnxid->cnx_id, &ph->dest_cnx_id) != 0 &&
715-
(cnx->is_multipath_enabled ||
716-
!picoquic_is_path_challenging_packet(decrypted_data->data + decrypted_data->offset,
717-
decrypted_data->length - (size_t)decrypted_data->offset))) {
716+
cnx->is_multipath_enabled) {
718717
/* Treat this as a NAT rebinding. */
719718
picoquic_tuple_t* old_tuple = path_x->first_tuple;
720719
/* We need to replace the first tuple by this tuple. */
721720
picoquic_set_first_tuple(path_x, tuple);
721+
tuple->challenge_verified = 1;
722722
/* set a challenge on the old tuple to recover from spoofed addresses */
723723
picoquic_set_tuple_challenge(old_tuple, current_time, cnx->quic->use_constant_challenges);
724724
old_tuple->challenge_required = 1;
725+
old_tuple->challenge_verified = 0;
725726
}
726727
else {
727728
/* Treat this a new tuple challenge. */
728-
picoquic_set_tuple_challenge(tuple, current_time, cnx->quic->use_constant_challenges);
729729
tuple->challenge_required = 1;
730730
}
731731
}

picoquic/picoquic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
extern "C" {
4141
#endif
4242

43-
#define PICOQUIC_VERSION "1.1.38.3"
43+
#define PICOQUIC_VERSION "1.1.38.4"
4444
#define PICOQUIC_ERROR_CLASS 0x400
4545
#define PICOQUIC_ERROR_DUPLICATE (PICOQUIC_ERROR_CLASS + 1)
4646
#define PICOQUIC_ERROR_AEAD_CHECK (PICOQUIC_ERROR_CLASS + 3)

picoquic/picoquic_internal.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,6 @@ typedef struct st_picoquic_path_t {
11211121
unsigned int is_nat_challenge : 1;
11221122
unsigned int is_cc_data_updated : 1;
11231123
unsigned int is_multipath_probe_needed : 1;
1124-
unsigned int was_local_cnxid_retired : 1;
11251124
unsigned int is_ssthresh_initialized : 1;
11261125
unsigned int is_token_published : 1;
11271126
unsigned int is_ticket_seeded : 1; /* Whether the current ticket has been updated with RTT and CWIN */
@@ -1594,7 +1593,7 @@ void picoquic_create_local_cnx_id(picoquic_quic_t* quic, picoquic_connection_id_
15941593
/* Management of address tuples */
15951594
picoquic_tuple_t * picoquic_create_tuple(picoquic_path_t* path_x, const struct sockaddr* local_addr, const struct sockaddr* peer_addr, int if_index);
15961595
void picoquic_delete_demoted_tuples(picoquic_cnx_t* cnx, uint64_t current_time, uint64_t* next_wake_time);
1597-
void picoquic_delete_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple);
1596+
void picoquic_delete_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple, int is_deleting_path);
15981597
void picoquic_set_first_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple);
15991598
/* Management of path */
16001599
int picoquic_create_path(picoquic_cnx_t* cnx, uint64_t start_time,
@@ -1650,6 +1649,7 @@ picoquic_remote_cnxid_t* picoquic_remove_stashed_cnxid(picoquic_cnx_t* cnx, uint
16501649
picoquic_remote_cnxid_t* picoquic_get_cnxid_from_stash(picoquic_remote_cnxid_stash_t* stash);
16511650
picoquic_remote_cnxid_t* picoquic_obtain_stashed_cnxid(picoquic_cnx_t* cnx, uint64_t unique_path_id);
16521651
void picoquic_dereference_stashed_cnxid(picoquic_cnx_t* cnx, picoquic_path_t* path_x, int is_deleting_cnx);
1652+
void picoquic_dereference_stashed_cnxid_tuple(picoquic_cnx_t* cnx, picoquic_path_t* path_x, picoquic_tuple_t* tuple, int is_deleting_cnx);
16531653
uint64_t picoquic_remove_not_before_from_stash(picoquic_cnx_t* cnx, picoquic_remote_cnxid_stash_t* cnxid_stash, uint64_t not_before, uint64_t current_time);
16541654
void picoquic_delete_remote_cnxid_stash(picoquic_cnx_t* cnx, picoquic_remote_cnxid_stash_t* cnxid_stash);
16551655

@@ -1780,10 +1780,14 @@ int picoquic_remove_header_protection_inner(uint8_t* bytes, size_t length, uint8
17801780

17811781
size_t picoquic_pad_to_target_length(uint8_t* bytes, size_t length, size_t target);
17821782

1783-
void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx, picoquic_packet_t * packet, int ret,
1783+
void picoquic_finalize_and_protect_packet_tuple(picoquic_cnx_t *cnx, picoquic_packet_t * packet, int ret,
17841784
size_t length, size_t header_length, size_t checksum_overhead,
17851785
size_t * send_length, uint8_t * send_buffer, size_t send_buffer_max,
1786-
picoquic_path_t * path_x, uint64_t current_time);
1786+
picoquic_path_t * path_x, uint64_t current_time, picoquic_tuple_t * tuple);
1787+
void picoquic_finalize_and_protect_packet(picoquic_cnx_t* cnx, picoquic_packet_t* packet, int ret,
1788+
size_t length, size_t header_length, size_t checksum_overhead,
1789+
size_t* send_length, uint8_t* send_buffer, size_t send_buffer_max,
1790+
picoquic_path_t* path_x, uint64_t current_time);
17871791

17881792
void picoquic_implicit_handshake_ack(picoquic_cnx_t* cnx, picoquic_packet_context_enum pc, uint64_t current_time);
17891793
void picoquic_false_start_transition(picoquic_cnx_t* cnx, uint64_t current_time);

picoquic/quicctx.c

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,9 +1629,16 @@ void picoquic_unchain_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple)
16291629
}
16301630
}
16311631

1632-
void picoquic_delete_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple)
1632+
void picoquic_delete_tuple(picoquic_path_t* path_x, picoquic_tuple_t* tuple, int is_deleting_path)
16331633
{
1634+
/* TODO: dereference local CID, retire remote CID ??? */
1635+
/* Dereference the remote CID */
1636+
if (tuple->p_remote_cnxid != NULL) {
1637+
picoquic_dereference_stashed_cnxid_tuple(path_x->cnx, path_x, tuple, is_deleting_path);
1638+
}
1639+
/* Remove from chain to the path */
16341640
picoquic_unchain_tuple(path_x, tuple);
1641+
/* And finally free */
16351642
free(tuple);
16361643
}
16371644

@@ -1762,7 +1769,7 @@ static void picoquic_clear_path_data(picoquic_cnx_t* cnx, picoquic_path_t * path
17621769
}
17631770
/* Remove the list of tuples */
17641771
while (path_x->first_tuple != NULL) {
1765-
picoquic_delete_tuple(path_x, path_x->first_tuple);
1772+
picoquic_delete_tuple(path_x, path_x->first_tuple, 1);
17661773
}
17671774

17681775
/* Free the record */
@@ -2973,30 +2980,35 @@ picoquic_remote_cnxid_t* picoquic_obtain_stashed_cnxid(picoquic_cnx_t* cnx, uint
29732980
return stashed;
29742981
}
29752982

2976-
void picoquic_dereference_stashed_cnxid(picoquic_cnx_t* cnx, picoquic_path_t * path_x, int is_deleting_cnx)
2983+
void picoquic_dereference_stashed_cnxid_tuple(picoquic_cnx_t* cnx, picoquic_path_t * path_x, picoquic_tuple_t * tuple, int is_deleting_cnx)
29772984
{
2978-
if (path_x->first_tuple->p_remote_cnxid != NULL) {
2979-
if (path_x->first_tuple->p_remote_cnxid->nb_path_references <= 1) {
2985+
if (tuple->p_remote_cnxid != NULL) {
2986+
if (tuple->p_remote_cnxid->nb_path_references <= 1) {
29802987
uint64_t unique_path_id = (cnx->is_multipath_enabled) ? path_x->unique_path_id : 0;
2981-
if (!is_deleting_cnx && !path_x->first_tuple->p_remote_cnxid->retire_sent) {
2988+
if (!is_deleting_cnx && !tuple->p_remote_cnxid->retire_sent) {
29822989
/* if this was the last reference, retire the old cnxid */
2983-
if (picoquic_queue_retire_connection_id_frame(cnx, unique_path_id, path_x->first_tuple->p_remote_cnxid->sequence) != 0) {
2984-
DBG_PRINTF("Could not properly retire CID[%" PRIu64 "]", path_x->first_tuple->p_remote_cnxid->sequence);
2990+
if (picoquic_queue_retire_connection_id_frame(cnx, unique_path_id, tuple->p_remote_cnxid->sequence) != 0) {
2991+
DBG_PRINTF("Could not properly retire CID[%" PRIu64 "]", tuple->p_remote_cnxid->sequence);
29852992
}
29862993
else {
2987-
path_x->first_tuple->p_remote_cnxid->retire_sent = 1;
2994+
tuple->p_remote_cnxid->retire_sent = 1;
29882995
}
29892996
}
2990-
if (is_deleting_cnx || path_x->first_tuple->p_remote_cnxid->retire_acked) {
2997+
if (is_deleting_cnx || tuple->p_remote_cnxid->retire_acked) {
29912998
/* Delete and perhaps recycle the queued packets */
2992-
(void)picoquic_remove_stashed_cnxid(cnx, path_x->unique_path_id, path_x->first_tuple->p_remote_cnxid, NULL);
2999+
(void)picoquic_remove_stashed_cnxid(cnx, path_x->unique_path_id, tuple->p_remote_cnxid, NULL);
29933000
}
29943001
}
29953002
else {
2996-
path_x->first_tuple->p_remote_cnxid->nb_path_references--;
3003+
tuple->p_remote_cnxid->nb_path_references--;
29973004
}
29983005
}
2999-
path_x->first_tuple->p_remote_cnxid = NULL;
3006+
tuple->p_remote_cnxid = NULL;
3007+
}
3008+
3009+
void picoquic_dereference_stashed_cnxid(picoquic_cnx_t* cnx, picoquic_path_t* path_x, int is_deleting_cnx)
3010+
{
3011+
picoquic_dereference_stashed_cnxid_tuple(cnx, path_x, path_x->first_tuple, is_deleting_cnx);
30003012
}
30013013

30023014
uint64_t picoquic_remove_not_before_from_stash(picoquic_cnx_t* cnx, picoquic_remote_cnxid_stash_t* cnxid_stash, uint64_t not_before, uint64_t current_time)
@@ -3716,12 +3728,17 @@ void picoquic_delete_local_cnxid_listed(picoquic_cnx_t* cnx,
37163728
picoquic_local_cnxid_list_t* local_cnxid_list, picoquic_local_cnxid_t* l_cid)
37173729
{
37183730
picoquic_local_cnxid_t* previous = NULL;
3719-
3720-
/* Set l_cid references to NULL in path contexts */
3721-
for (int i = 0; i < cnx->nb_paths; i++) {
3722-
if (cnx->path[i]->first_tuple->p_local_cnxid == l_cid) {
3723-
cnx->path[i]->first_tuple->p_local_cnxid = NULL;
3724-
cnx->path[i]->was_local_cnxid_retired = 1;
3731+
/* Find the path referenced by the cnxid */
3732+
int path_index = picoquic_find_path_by_unique_id(cnx, l_cid->path_id);
3733+
3734+
if (path_index >= 0) {
3735+
/* Set l_cid references to NULL in path contexts */
3736+
picoquic_tuple_t* tuple = cnx->path[path_index]->first_tuple;
3737+
while (tuple != NULL) {
3738+
if (tuple->p_local_cnxid == l_cid) {
3739+
tuple->p_local_cnxid = NULL;
3740+
}
3741+
tuple = tuple->next_tuple;
37253742
}
37263743
}
37273744

picoquic/sender.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,11 +1133,11 @@ void picoquic_insert_hole_in_send_sequence_if_needed(picoquic_cnx_t* cnx, picoqu
11331133
* Final steps of encoding and protecting the packet before sending
11341134
*/
11351135

1136-
void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx,
1137-
picoquic_packet_t * packet, int ret,
1136+
void picoquic_finalize_and_protect_packet_tuple(picoquic_cnx_t* cnx,
1137+
picoquic_packet_t* packet, int ret,
11381138
size_t length, size_t header_length, size_t checksum_overhead,
1139-
size_t * send_length, uint8_t * send_buffer, size_t send_buffer_max,
1140-
picoquic_path_t * path_x, uint64_t current_time)
1139+
size_t* send_length, uint8_t* send_buffer, size_t send_buffer_max,
1140+
picoquic_path_t* path_x, uint64_t current_time, picoquic_tuple_t* tuple)
11411141
{
11421142
if (length != 0 && length < header_length) {
11431143
length = 0;
@@ -1196,7 +1196,7 @@ void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx,
11961196
length = picoquic_protect_packet(cnx, packet->ptype, packet->bytes, packet->sequence_number,
11971197
length, header_length,
11981198
send_buffer, send_buffer_max, cnx->crypto_context[picoquic_epoch_1rtt].aead_encrypt, cnx->crypto_context[picoquic_epoch_1rtt].pn_enc,
1199-
path_x, NULL, current_time);
1199+
path_x, tuple, current_time);
12001200
break;
12011201
default:
12021202
/* Packet type error. Do nothing at all. */
@@ -1220,6 +1220,18 @@ void picoquic_finalize_and_protect_packet(picoquic_cnx_t *cnx,
12201220
}
12211221
}
12221222

1223+
void picoquic_finalize_and_protect_packet(picoquic_cnx_t* cnx,
1224+
picoquic_packet_t* packet, int ret,
1225+
size_t length, size_t header_length, size_t checksum_overhead,
1226+
size_t* send_length, uint8_t* send_buffer, size_t send_buffer_max,
1227+
picoquic_path_t* path_x, uint64_t current_time)
1228+
{
1229+
picoquic_finalize_and_protect_packet_tuple(cnx, packet, ret,
1230+
length, header_length, checksum_overhead,
1231+
send_length, send_buffer, send_buffer_max,
1232+
path_x, current_time, path_x->first_tuple);
1233+
}
1234+
12231235
/*
12241236
* Returns true if there is nothing to repeat in the retransmission queue
12251237
*/

picoquic_t/picoquic_t.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ static const picoquic_test_def_t test_table[] = {
472472
{ "openssl_cert", openssl_cert_test },
473473
{ "monopath_basic", monopath_basic_test },
474474
{ "monopath_hole", monopath_hole_test },
475+
{ "monopath_keep_alive", monopath_keep_alive_test },
475476
{ "monopath_rotation", monopath_rotation_test },
476477
{ "monopath_0rtt", monopath_0rtt_test },
477478
{ "monopath_0rtt_loss", monopath_0rtt_loss_test },

0 commit comments

Comments
 (0)