Skip to content

Commit 7ae96cf

Browse files
committed
introduce tuple structure
1 parent 959e26b commit 7ae96cf

17 files changed

+297
-205
lines changed

picoquic/frames.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4653,22 +4653,22 @@ const uint8_t* picoquic_decode_path_challenge_frame(picoquic_cnx_t* cnx, const u
46534653
/* If multipath is not enabled, we must verify that the addresses
46544654
* source (addr_from) matches the peer address if known. */
46554655
if (addr_from == NULL ||
4656-
picoquic_compare_addr(addr_from, (struct sockaddr*)&path_x->peer_addr) == 0) {
4656+
picoquic_compare_addr(addr_from, (struct sockaddr*)&path_x->first_tuple->peer_addr) == 0) {
46574657
/* If the source address matches, we must verify that the destination
46584658
* address also matches. Given how the socket code works there will be cases
46594659
* when the local port is now yet known. In that case, we only compare
46604660
* the IP address component . Otherwise, we compare the whole address.
46614661
*/
46624662
if (addr_to == NULL ||
4663-
(picoquic_get_addr_port((struct sockaddr*)&path_x->local_addr) == 0 &&
4664-
picoquic_compare_ip_addr(addr_to, (struct sockaddr*)&path_x->local_addr) == 0) ||
4665-
picoquic_compare_addr(addr_to, (struct sockaddr*)&path_x->local_addr) == 0) {
4663+
(picoquic_get_addr_port((struct sockaddr*)&path_x->first_tuple->local_addr) == 0 &&
4664+
picoquic_compare_ip_addr(addr_to, (struct sockaddr*)&path_x->first_tuple->local_addr) == 0) ||
4665+
picoquic_compare_addr(addr_to, (struct sockaddr*)&path_x->first_tuple->local_addr) == 0) {
46664666
is_valid = 1;
46674667
}
46684668
}
46694669
}
46704670
if (is_valid) {
4671-
path_x->challenge_response = challenge_response;
4671+
path_x->first_tuple->challenge_response = challenge_response;
46724672
path_x->response_required = 1;
46734673
}
46744674
else {
@@ -4678,8 +4678,8 @@ const uint8_t* picoquic_decode_path_challenge_frame(picoquic_cnx_t* cnx, const u
46784678
path_x->unique_path_id,
46794679
picoquic_addr_text(addr_from, buf1, sizeof(buf1)),
46804680
picoquic_addr_text(addr_to, buf2, sizeof(buf2)),
4681-
picoquic_addr_text((struct sockaddr*)&path_x->peer_addr, buf3, sizeof(buf3)),
4682-
picoquic_addr_text((struct sockaddr*)&path_x->local_addr, buf4, sizeof(buf4))
4681+
picoquic_addr_text((struct sockaddr*)&path_x->first_tuple->peer_addr, buf3, sizeof(buf3)),
4682+
picoquic_addr_text((struct sockaddr*)&path_x->first_tuple->local_addr, buf4, sizeof(buf4))
46834683
);
46844684
}
46854685
}
@@ -4717,7 +4717,7 @@ const uint8_t* picoquic_decode_path_response_frame(picoquic_cnx_t* cnx, const ui
47174717
int found_nat_challenge = 0;
47184718

47194719
for (int ichal = 0; ichal < PICOQUIC_CHALLENGE_REPEAT_MAX; ichal++) {
4720-
if (response == path_x->challenge[ichal]) {
4720+
if (response == path_x->first_tuple->challenge[ichal]) {
47214721
found_challenge = 1;
47224722
break;
47234723
}
@@ -4733,9 +4733,9 @@ const uint8_t* picoquic_decode_path_response_frame(picoquic_cnx_t* cnx, const ui
47334733
if (found_nat_challenge && !path_x->challenge_verified) {
47344734
/* while probing NAT, the NAT response arrived before the normal path response */
47354735
/* Update the addresses */
4736-
picoquic_store_addr(&path_x->local_addr, (struct sockaddr*)&path_x->nat_local_addr);
4736+
picoquic_store_addr(&path_x->first_tuple->local_addr, (struct sockaddr*)&path_x->nat_local_addr);
47374737
picoquic_update_peer_addr(path_x, (struct sockaddr*)&path_x->nat_peer_addr);
4738-
path_x->if_index_dest = path_x->if_index_nat_dest;
4738+
path_x->first_tuple->if_index_dest = path_x->if_index_nat_dest;
47394739
/* if useful, update the CID */
47404740
if (path_x->p_remote_nat_cnxid != NULL) {
47414741
picoquic_dereference_stashed_cnxid(cnx, path_x, 0);
@@ -4751,7 +4751,7 @@ const uint8_t* picoquic_decode_path_response_frame(picoquic_cnx_t* cnx, const ui
47514751
path_x->challenge_verified = 1;
47524752

47534753
/* Provide a qualified time estimate from challenge time */
4754-
picoquic_update_path_rtt(cnx, path_x, path_x, -1, path_x->challenge_time_first, current_time, 0, 0);
4754+
picoquic_update_path_rtt(cnx, path_x, path_x, -1, path_x->first_tuple->challenge_time_first, current_time, 0, 0);
47554755

47564756
if (cnx->are_path_callbacks_enabled &&
47574757
cnx->callback_fn(cnx, path_x->unique_path_id, NULL, 0, picoquic_callback_path_available,
@@ -4788,7 +4788,7 @@ int picoquic_should_repeat_path_response_frame(picoquic_cnx_t* cnx, const uint8_
47884788
int path_index = -1;
47894789

47904790
for (int i = 0; i < cnx->nb_paths; i++) {
4791-
if (cnx->path[i]->challenge_response == response) {
4791+
if (cnx->path[i]->first_tuple->challenge_response == response) {
47924792
path_index = i;
47934793
break;
47944794
}
@@ -6077,7 +6077,7 @@ uint8_t* picoquic_prepare_observed_address_frame(uint8_t* bytes, const uint8_t*
60776077
{
60786078
if (!path_x->observed_addr_acked &&
60796079
path_x->nb_observed_repeat < 4 &&
6080-
path_x->peer_addr.ss_family != AF_UNSPEC) {
6080+
path_x->first_tuple->peer_addr.ss_family != AF_UNSPEC) {
60816081
int is_needed = 0;
60826082

60836083
if (path_x->nb_observed_repeat == 0) {
@@ -6100,14 +6100,14 @@ uint8_t* picoquic_prepare_observed_address_frame(uint8_t* bytes, const uint8_t*
61006100
uint8_t* ip_addr = NULL;
61016101
uint16_t port = 0;
61026102

6103-
if (path_x->peer_addr.ss_family == AF_INET6) {
6104-
struct sockaddr_in6* addr = (struct sockaddr_in6*)&path_x->peer_addr;
6103+
if (path_x->first_tuple->peer_addr.ss_family == AF_INET6) {
6104+
struct sockaddr_in6* addr = (struct sockaddr_in6*)&path_x->first_tuple->peer_addr;
61056105
ftype = picoquic_frame_type_observed_address_v6;
61066106
ip_addr = (uint8_t*)&addr->sin6_addr;
61076107
port = ntohs(addr->sin6_port);
61086108
}
61096109
else {
6110-
struct sockaddr_in* addr = (struct sockaddr_in*)&path_x->peer_addr;
6110+
struct sockaddr_in* addr = (struct sockaddr_in*)&path_x->first_tuple->peer_addr;
61116111
ftype = picoquic_frame_type_observed_address_v4;
61126112
ip_addr = (uint8_t*)&addr->sin_addr;
61136113
port = ntohs(addr->sin_port);
@@ -6174,18 +6174,18 @@ const uint8_t* picoquic_decode_observed_address_frame(picoquic_cnx_t* cnx, const
61746174
picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR,
61756175
ftype, "bad observed address frame");
61766176
}
6177-
else if (sequence > path_x->observed_address_received || (path_x->observed_address_received == 0 && path_x->observed_addr.ss_family == AF_UNSPEC)) {
6177+
else if (sequence > path_x->observed_address_received || (path_x->observed_address_received == 0 && path_x->first_tuple->observed_addr.ss_family == AF_UNSPEC)) {
61786178
/* We only update the observed address if this is a new value*/
61796179
path_x->observed_address_received = sequence;
61806180
if ((ftype & 1) == 0) {
6181-
struct sockaddr_in* o_addr = (struct sockaddr_in *)&path_x->observed_addr;
6181+
struct sockaddr_in* o_addr = (struct sockaddr_in *)&path_x->first_tuple->observed_addr;
61826182
memset(o_addr, 0, sizeof(struct sockaddr_in));
61836183
o_addr->sin_family = AF_INET;
61846184
memcpy(&o_addr->sin_addr, addr, 4);
61856185
o_addr->sin_port = htons(port);
61866186
}
61876187
else {
6188-
struct sockaddr_in6* o_addr = (struct sockaddr_in6*)&path_x->observed_addr;
6188+
struct sockaddr_in6* o_addr = (struct sockaddr_in6*)&path_x->first_tuple->observed_addr;
61896189
memset(o_addr, 0, sizeof(struct sockaddr_in6));
61906190
o_addr->sin6_family = AF_INET6;
61916191
memcpy(&o_addr->sin6_addr, addr, 16);
@@ -6278,7 +6278,7 @@ const uint8_t* picoquic_decode_bdp_frame(picoquic_cnx_t* cnx, const uint8_t* byt
62786278
else if (lifetime > current_time) {
62796279
uint8_t* client_ip;
62806280
uint8_t client_ip_length;
6281-
picoquic_get_ip_addr((struct sockaddr*) & path_x->peer_addr, &client_ip, &client_ip_length);
6281+
picoquic_get_ip_addr((struct sockaddr*) & path_x->first_tuple->peer_addr, &client_ip, &client_ip_length);
62826282
/* Store received BDP, but only if the IP address of the client matches the
62836283
* value found in the ticket */
62846284
if (saved_ip_length > 0 && client_ip_length == saved_ip_length &&

picoquic/logger.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ static void textlog_outgoing_segment(void* F_log, int log_cnxid, picoquic_cnx_t*
18701870

18711871
ret = picoquic_parse_packet_header((cnx == NULL) ? NULL : cnx->quic, send_buffer, send_length,
18721872
((cnx == NULL || cnx->path[0] == NULL) ? (struct sockaddr *)&default_addr :
1873-
(struct sockaddr *)&cnx->path[0]->local_addr), &ph, &pcnx, 0);
1873+
(struct sockaddr *)&cnx->path[0]->first_tuple->local_addr), &ph, &pcnx, 0);
18741874

18751875
ph.pn64 = sequence_number;
18761876
ph.pn = (uint32_t)ph.pn64;

picoquic/logwriter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ void binlog_outgoing_packet(picoquic_cnx_t* cnx, picoquic_path_t * path_x,
842842

843843
picoquic_parse_packet_header((cnx == NULL) ? NULL : cnx->quic, send_buffer, send_length,
844844
((cnx == NULL || cnx->path[0] == NULL) ? (struct sockaddr *)&default_addr :
845-
(struct sockaddr *)&cnx->path[0]->local_addr), &ph, &pcnx, 0);
845+
(struct sockaddr *)&cnx->path[0]->first_tuple->local_addr), &ph, &pcnx, 0);
846846

847847
if (cnx != NULL) {
848848
picoquic_epoch_enum epoch = (ph.ptype == picoquic_packet_1rtt_protected) ? picoquic_epoch_1rtt :

picoquic/packet.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,13 +1410,13 @@ int picoquic_incoming_client_initial(
14101410
}
14111411
else if ((*pcnx)->cnx_state < picoquic_state_server_almost_ready) {
14121412
/* Document the incoming addresses */
1413-
if ((*pcnx)->path[0]->local_addr.ss_family == 0 && addr_to != NULL) {
1414-
picoquic_store_addr(&(*pcnx)->path[0]->local_addr, addr_to);
1413+
if ((*pcnx)->path[0]->first_tuple->local_addr.ss_family == 0 && addr_to != NULL) {
1414+
picoquic_store_addr(&(*pcnx)->path[0]->first_tuple->local_addr, addr_to);
14151415
}
1416-
if ((*pcnx)->path[0]->peer_addr.ss_family == 0 && addr_from != NULL) {
1417-
picoquic_store_addr(&(*pcnx)->path[0]->peer_addr, addr_from);
1416+
if ((*pcnx)->path[0]->first_tuple->peer_addr.ss_family == 0 && addr_from != NULL) {
1417+
picoquic_store_addr(&(*pcnx)->path[0]->first_tuple->peer_addr, addr_from);
14181418
}
1419-
(*pcnx)->path[0]->if_index_dest = if_index_to;
1419+
(*pcnx)->path[0]->first_tuple->if_index_dest = if_index_to;
14201420

14211421
/* decode the incoming frames */
14221422
if (ret == 0) {
@@ -1617,10 +1617,10 @@ int picoquic_incoming_server_initial(
16171617
if (ret == 0) {
16181618
if (cnx->cnx_state <= picoquic_state_client_handshake_start) {
16191619
/* Document local address if not present */
1620-
if (cnx->path[0]->local_addr.ss_family == 0 && addr_to != NULL) {
1621-
picoquic_store_addr(&cnx->path[0]->local_addr, addr_to);
1620+
if (cnx->path[0]->first_tuple->local_addr.ss_family == 0 && addr_to != NULL) {
1621+
picoquic_store_addr(&cnx->path[0]->first_tuple->local_addr, addr_to);
16221622
}
1623-
cnx->path[0]->if_index_dest = if_index_to;
1623+
cnx->path[0]->first_tuple->if_index_dest = if_index_to;
16241624
/* Accept the incoming frames */
16251625
if (ph->payload_length == 0) {
16261626
/* empty payload! */
@@ -1933,7 +1933,7 @@ int picoquic_find_incoming_unique_path(picoquic_cnx_t* cnx, picoquic_packet_head
19331933
*/
19341934
path_id = cnx->nb_paths - 1;
19351935
path_x = cnx->path[path_id];
1936-
path_x->if_index_dest = if_index_to;
1936+
path_x->first_tuple->if_index_dest = if_index_to;
19371937

19381938
/* when creating the path, we need to copy the dest CID and chose
19391939
* destination CID with the matching path ID.
@@ -1959,10 +1959,10 @@ int picoquic_find_incoming_unique_path(picoquic_cnx_t* cnx, picoquic_packet_head
19591959
}
19601960
}
19611961
/* If the addresses match, we are good. */
1962-
if (picoquic_compare_addr(addr_from, (struct sockaddr*)&path_x->peer_addr) == 0) {
1962+
if (picoquic_compare_addr(addr_from, (struct sockaddr*)&path_x->first_tuple->peer_addr) == 0) {
19631963
/* Consider whether to document the local address */
1964-
if (path_x->local_addr.ss_family == AF_UNSPEC) {
1965-
picoquic_store_addr(&cnx->path[path_id]->local_addr, addr_to);
1964+
if (path_x->first_tuple->local_addr.ss_family == AF_UNSPEC) {
1965+
picoquic_store_addr(&cnx->path[path_id]->first_tuple->local_addr, addr_to);
19661966
}
19671967
}
19681968
/* Else, this might be a NAT rebinding. But we only handle one NAT rebinding at a time.
@@ -2011,7 +2011,7 @@ int picoquic_find_incoming_path(picoquic_cnx_t* cnx, picoquic_packet_header* ph,
20112011
if (path_id < 0 && partial_match_path >= 0) {
20122012
/* Document the source address and promote to full match. */
20132013
path_id = partial_match_path;
2014-
picoquic_store_addr(&cnx->path[path_id]->local_addr, addr_to);
2014+
picoquic_store_addr(&cnx->path[path_id]->first_tuple->local_addr, addr_to);
20152015
}
20162016

20172017
if (path_id >= 0) {
@@ -2228,7 +2228,7 @@ int picoquic_incoming_1rtt(
22282228
else if (ret == 0) {
22292229
picoquic_path_t* path_x = cnx->path[path_id];
22302230

2231-
path_x->if_index_dest = if_index_to;
2231+
path_x->first_tuple->if_index_dest = if_index_to;
22322232
cnx->is_1rtt_received = 1;
22332233
picoquic_spin_function_table[cnx->spin_policy].spinbit_incoming(cnx, path_x, ph);
22342234
/* Accept the incoming frames */

picoquic/picoquic_internal.h

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,36 @@ typedef struct st_picoquic_pacing_t {
10171017
int64_t packet_time_nanosec;
10181018
} picoquic_pacing_t;
10191019

1020+
/* Tuple context.
1021+
* Tuple context are created to hold address and port pairs used to contact peers.
1022+
* Address pairs are "verified" by successful path challenge/response exchanges.
1023+
* On the client side, they are placed in "validated" or "backup" state by
1024+
* local interactions. On the server side, they move from "backup" to
1025+
* "validated" when the client starts using them.
1026+
*
1027+
* The tuple context contains the data necessary for managing the challenge/response.
1028+
*/
1029+
typedef struct st_picoquic_tuple_t {
1030+
/* Path for which the tuple is registered */
1031+
uint64_t unique_path_id;
1032+
/* Next tuple registered for this path */
1033+
struct st_picoquic_tuple_t* next_tuple;
1034+
/* Peer address. */
1035+
struct sockaddr_storage peer_addr;
1036+
/* Local address, on the local network */
1037+
struct sockaddr_storage local_addr;
1038+
unsigned long if_index_dest;
1039+
/* Address observed by the peer */
1040+
struct sockaddr_storage observed_addr;
1041+
/* Challenge used for this path */
1042+
uint64_t challenge_response;
1043+
uint64_t challenge[PICOQUIC_CHALLENGE_REPEAT_MAX];
1044+
uint64_t challenge_time;
1045+
uint64_t demotion_time;
1046+
uint64_t challenge_time_first;
1047+
uint8_t challenge_repeat_count;
1048+
} picoquic_tuple_t;
1049+
10201050
/*
10211051
* Per path context.
10221052
* Path contexts are created:
@@ -1044,18 +1074,22 @@ typedef struct st_picoquic_path_t {
10441074
picohash_item net_id_hash_item;
10451075
struct st_picoquic_cnx_t* cnx;
10461076
uint64_t unique_path_id;
1047-
10481077
void* app_path_ctx;
10491078
/* If using unique path id multipath */
10501079
picoquic_ack_context_t ack_ctx;
10511080
picoquic_packet_context_t pkt_ctx;
1081+
#if 1
1082+
/* First tuple is the one used by default for the path */
1083+
picoquic_tuple_t* first_tuple;
1084+
#else
10521085
/* Peer address. */
10531086
struct sockaddr_storage peer_addr;
10541087
/* Local address, on the local network */
10551088
struct sockaddr_storage local_addr;
10561089
unsigned long if_index_dest;
10571090
/* Address observed by the peer */
10581091
struct sockaddr_storage observed_addr;
1092+
#endif
10591093
/* Manage the reception of observed addresses */
10601094
uint64_t observed_address_received;
10611095
/* Manage the publishing of observed addresses */
@@ -1065,13 +1099,16 @@ typedef struct st_picoquic_path_t {
10651099
uint64_t observed_time;
10661100
/* Manage path probing logic */
10671101
uint64_t last_non_path_probing_pn;
1102+
#if 1
1103+
#else
10681104
/* Challenge used for this path */
10691105
uint64_t challenge_response;
10701106
uint64_t challenge[PICOQUIC_CHALLENGE_REPEAT_MAX];
10711107
uint64_t challenge_time;
1072-
uint64_t demotion_time;
10731108
uint64_t challenge_time_first;
10741109
uint8_t challenge_repeat_count;
1110+
#endif
1111+
uint64_t demotion_time;
10751112
/* NAT Challenge for this path, if using unique path id */
10761113
uint64_t nat_challenge[PICOQUIC_CHALLENGE_REPEAT_MAX];
10771114
uint64_t nat_challenge_time;

0 commit comments

Comments
 (0)