Skip to content

Commit 8a65adb

Browse files
authored
Merge pull request #1919 from private-octopus/path-0-re-add
Fix definition of available path
2 parents c0ef1d4 + ec4ca10 commit 8a65adb

File tree

8 files changed

+97
-24
lines changed

8 files changed

+97
-24
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.0
11+
VERSION 1.1.38.1
1212
DESCRIPTION "picoquic library"
1313
LANGUAGES C CXX)
1414

UnitTest1/unittest1.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2846,12 +2846,24 @@ namespace UnitTest1
28462846
Assert::AreEqual(ret, 0);
28472847
}
28482848

2849+
TEST_METHOD(multipath_socket0_error) {
2850+
int ret = multipath_socket0_error_test();
2851+
2852+
Assert::AreEqual(ret, 0);
2853+
}
2854+
28492855
TEST_METHOD(multipath_abandon) {
28502856
int ret = multipath_abandon_test();
28512857

28522858
Assert::AreEqual(ret, 0);
28532859
}
28542860

2861+
TEST_METHOD(multipath_back0) {
2862+
int ret = multipath_back0_test();
2863+
2864+
Assert::AreEqual(ret, 0);
2865+
}
2866+
28552867
TEST_METHOD(multipath_back1) {
28562868
int ret = multipath_back1_test();
28572869

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.0"
43+
#define PICOQUIC_VERSION "1.1.38.1"
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,7 @@ typedef struct st_picoquic_cnx_t {
15321532
* */
15331533
uint64_t nb_local_cnxid_lists;
15341534
uint64_t next_path_id_in_lists;
1535+
uint64_t max_path_id_in_cnxid_lists;
15351536
picoquic_local_cnxid_list_t * first_local_cnxid_list;
15361537

15371538
/* Management of ACK frequency */

picoquic/quicctx.c

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,23 +1531,32 @@ uint64_t picoquic_find_avalaible_unique_path_id(picoquic_cnx_t* cnx, uint64_t re
15311531
{
15321532
uint64_t unique_path_id = requested_id;
15331533

1534-
if (requested_id == UINT64_MAX) {
1535-
if (!cnx->is_multipath_enabled) {
1536-
unique_path_id = cnx->unique_path_id_next;
1537-
cnx->unique_path_id_next++;
1534+
if (!cnx->is_multipath_enabled) {
1535+
if (requested_id != 0 && requested_id != UINT64_MAX) {
1536+
unique_path_id = UINT64_MAX;
15381537
}
15391538
else {
1540-
/* Look at available stashes. exlcude stash if id=0, as this is the
1541-
* always used.
1542-
*/
1543-
picoquic_remote_cnxid_stash_t* stash = cnx->first_remote_cnxid_stash;
1544-
1545-
while (stash != NULL && (stash->is_in_use || stash->unique_path_id == 0)){
1546-
stash = stash->next_stash;
1547-
}
1548-
if (stash != NULL) {
1549-
unique_path_id = stash->unique_path_id;
1550-
}
1539+
unique_path_id = 0;
1540+
}
1541+
}
1542+
else {
1543+
/* Unique path ID are allocated in sequence on the client. The server should
1544+
* always use the number proposed by the client in incoming packets */
1545+
if (requested_id == UINT64_MAX && (cnx->client_mode || cnx->nb_paths == 0)) {
1546+
while (cnx->unique_path_id_next < cnx->max_path_id_remote &&
1547+
cnx->unique_path_id_next < cnx->max_path_id_local &&
1548+
cnx->unique_path_id_next < cnx->max_path_id_in_cnxid_lists) {
1549+
/* Find next non used CID */
1550+
unique_path_id = cnx->unique_path_id_next++;
1551+
/* There should be an available of CNX_ID for this path_id,
1552+
* and that path_id should not be already created.
1553+
*/
1554+
if (picoquic_find_or_create_local_cnxid_list(cnx, unique_path_id, 0) != NULL &&
1555+
picoquic_find_path_by_unique_id(cnx, unique_path_id) < 0) {
1556+
/* this CID was not already deleted */
1557+
break;
1558+
}
1559+
}
15511560
}
15521561
}
15531562
return unique_path_id;
@@ -3630,8 +3639,6 @@ picoquic_local_cnxid_list_t* picoquic_find_or_create_local_cnxid_list(picoquic_c
36303639
return local_cnxid_list;
36313640
}
36323641

3633-
3634-
36353642
picoquic_local_cnxid_t* picoquic_create_local_cnxid(picoquic_cnx_t* cnx,
36363643
uint64_t unique_path_id, picoquic_connection_id_t* suggested_value, uint64_t current_time)
36373644
{
@@ -3690,6 +3697,9 @@ picoquic_local_cnxid_t* picoquic_create_local_cnxid(picoquic_cnx_t* cnx,
36903697
}
36913698
if (l_cid->sequence == 0) {
36923699
local_cnxid_list->local_cnxid_oldest_created = current_time;
3700+
if (local_cnxid_list->unique_path_id > cnx->max_path_id_in_cnxid_lists) {
3701+
cnx->max_path_id_in_cnxid_lists = local_cnxid_list->unique_path_id;
3702+
}
36933703
}
36943704
}
36953705
else {

picoquic_t/picoquic_t.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,9 @@ static const picoquic_test_def_t test_table[] = {
485485
{ "multipath_rotation", multipath_rotation_test },
486486
{ "multipath_break1", multipath_break1_test },
487487
{ "multipath_socket_error", multipath_socket_error_test },
488+
{ "multipath_socket0_error", multipath_socket0_error_test },
488489
{ "multipath_abandon", multipath_abandon_test },
490+
{ "multipath_back0", multipath_back0_test },
489491
{ "multipath_back1", multipath_back1_test },
490492
{ "multipath_nat", multipath_nat_test },
491493
{ "multipath_nat_challenge", multipath_nat_challenge_test },

picoquictest/multipath_test.c

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ static void multipath_test_set_unreachable(picoquic_test_tls_api_ctx_t* test_ctx
9696
}
9797
}
9898

99+
static void multipath_test_set_reachable(picoquic_test_tls_api_ctx_t* test_ctx, int link_id)
100+
{
101+
if (link_id == 0) {
102+
test_ctx->c_to_s_link->is_unreachable = 0;
103+
test_ctx->s_to_c_link->is_unreachable = 0;
104+
}
105+
else {
106+
test_ctx->c_to_s_link_2->is_unreachable = 0;
107+
test_ctx->s_to_c_link_2->is_unreachable = 0;
108+
}
109+
}
110+
99111
static void multipath_test_unkill_links(picoquic_test_tls_api_ctx_t* test_ctx, int link_id, uint64_t current_time)
100112
{
101113
/* Make sure that nothing gets sent on the old links */
@@ -438,6 +450,8 @@ typedef enum {
438450
multipath_test_nat_challenge,
439451
multipath_test_break1,
440452
multipath_test_break2,
453+
multipath_test_break3,
454+
multipath_test_back0,
441455
multipath_test_back1,
442456
multipath_test_perf,
443457
multipath_test_callback,
@@ -911,8 +925,8 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
911925

912926
if (ret == 0 && (test_id == multipath_test_drop_first || test_id == multipath_test_drop_second ||
913927
test_id == multipath_test_renew || test_id == multipath_test_nat || test_id == multipath_test_nat_challenge ||
914-
test_id == multipath_test_break1 || test_id == multipath_test_break2 ||
915-
test_id == multipath_test_back1 || test_id == multipath_test_standup ||
928+
test_id == multipath_test_break1 || test_id == multipath_test_break2 || test_id == multipath_test_break3 ||
929+
test_id == multipath_test_back0 || test_id == multipath_test_back1 || test_id == multipath_test_standup ||
916930
test_id == multipath_test_abandon || test_id == multipath_test_tunnel)) {
917931
/* If testing a final link drop before completion, perform a
918932
* partial sending loop and then kill the initial link.
@@ -950,6 +964,10 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
950964
/* Trigger "destination unreachable" error on next socket call to link 1 */
951965
multipath_test_set_unreachable(test_ctx, 1);
952966
}
967+
else if (test_id == multipath_test_back0 || test_id == multipath_test_break3) {
968+
/* Trigger "destination unreachable" error on next socket call to link 0 */
969+
multipath_test_set_unreachable(test_ctx, 0);
970+
}
953971
else if (test_id == multipath_test_tunnel) {
954972
/* Break both links */
955973
multipath_test_kill_links(test_ctx, 0);
@@ -964,7 +982,7 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
964982
/* For the "backup scenario", wait a small interval, then bring the path # 1 back up
965983
* For the "tunnel" scenario, do the same but wait 5 seconds and then restore both links.
966984
*/
967-
if (ret == 0 && (test_id == multipath_test_back1 || test_id == multipath_test_tunnel)) {
985+
if (ret == 0 && (test_id == multipath_test_back0 || test_id == multipath_test_back1 || test_id == multipath_test_tunnel)) {
968986
uint64_t timeout = (test_id == multipath_test_tunnel)?5000000:1000000;
969987

970988
ret = tls_api_wait_for_timeout(test_ctx, &simulated_time, timeout);
@@ -973,6 +991,15 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
973991
{
974992
DBG_PRINTF("Wait for %" PRIu64 "us returns %d\n", timeout, ret);
975993
}
994+
else if (test_id == multipath_test_back0) {
995+
multipath_test_set_reachable(test_ctx, 0);
996+
997+
ret = picoquic_probe_new_path(test_ctx->cnx_client, (struct sockaddr*)&test_ctx->server_addr,
998+
(struct sockaddr*)&test_ctx->client_addr, simulated_time);
999+
if (ret != 0) {
1000+
DBG_PRINTF("Create path on default address returns %d\n", ret);
1001+
}
1002+
}
9761003
else {
9771004
if (test_id == multipath_test_tunnel) {
9781005
multipath_test_unkill_links(test_ctx, 0, simulated_time);
@@ -1140,7 +1167,7 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
11401167
}
11411168
}
11421169

1143-
if (ret == 0 && (test_id == multipath_test_break1 || test_id == multipath_test_break2 || test_id == multipath_test_abandon)) {
1170+
if (ret == 0 && (test_id == multipath_test_break1 || test_id == multipath_test_break2 || test_id == multipath_test_break3 || test_id == multipath_test_abandon)) {
11441171
if (test_ctx->cnx_server->nb_paths != 1) {
11451172
DBG_PRINTF("After break, %d paths on server connection.\n", test_ctx->cnx_server->nb_paths);
11461173
ret = -1;
@@ -1150,7 +1177,7 @@ int multipath_test_one(uint64_t max_completion_microsec, multipath_test_enum_t t
11501177
}
11511178
}
11521179

1153-
if (ret == 0 && test_id == multipath_test_back1) {
1180+
if (ret == 0 && (test_id == multipath_test_back0 || test_id == multipath_test_back1)) {
11541181
if (test_ctx->cnx_server->nb_paths != 2) {
11551182
DBG_PRINTF("After break and back, %d paths on server connection.\n", test_ctx->cnx_server->nb_paths);
11561183
ret = -1;
@@ -1347,6 +1374,15 @@ int multipath_socket_error_test()
13471374
return multipath_test_one(max_completion_microsec, multipath_test_break2);
13481375
}
13491376

1377+
/* Test reaction to socket error on first path
1378+
*/
1379+
int multipath_socket0_error_test()
1380+
{
1381+
uint64_t max_completion_microsec = 10900000;
1382+
1383+
return multipath_test_one(max_completion_microsec, multipath_test_break3);
1384+
}
1385+
13501386
/* Test that abandoned paths are removed after some time
13511387
*/
13521388
int multipath_abandon_test()
@@ -1356,6 +1392,16 @@ int multipath_abandon_test()
13561392
return multipath_test_one(max_completion_microsec, multipath_test_abandon);
13571393
}
13581394

1395+
/* Test that after breaking path 0 we can establish a new path on the
1396+
* same link when it comes back up.
1397+
*/
1398+
int multipath_back0_test()
1399+
{
1400+
uint64_t max_completion_microsec = 3300000;
1401+
1402+
return multipath_test_one(max_completion_microsec, multipath_test_back0);
1403+
}
1404+
13591405
/* Test that breaking paths can come back up after some time
13601406
*/
13611407
int multipath_back1_test()

picoquictest/picoquictest.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ int multipath_nat_test();
501501
int multipath_nat_challenge_test();
502502
int multipath_break1_test();
503503
int multipath_socket_error_test();
504+
int multipath_socket0_error_test();
504505
int multipath_abandon_test();
506+
int multipath_back0_test();
505507
int multipath_back1_test();
506508
int multipath_perf_test();
507509
int multipath_callback_test();

0 commit comments

Comments
 (0)