diff --git a/CMakeLists.txt b/CMakeLists.txt index edb576c39..0d072899f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ else() endif() project(picoquic - VERSION 1.1.29.1 + VERSION 1.1.30.0 DESCRIPTION "picoquic library" LANGUAGES C CXX) diff --git a/loglib/logconvert.c b/loglib/logconvert.c index e23c3a462..0205ebd59 100644 --- a/loglib/logconvert.c +++ b/loglib/logconvert.c @@ -121,8 +121,10 @@ const char * ftype2str(picoquic_frame_type_enum_t ftype) return "bdp"; case picoquic_frame_type_max_path_id: return "max_path_id"; - case picoquic_frame_type_path_blocked: - return "path_blocked"; + case picoquic_frame_type_paths_blocked: + return "paths_blocked"; + case picoquic_frame_type_path_cid_blocked: + return "path_cid_blocked"; case picoquic_frame_type_observed_address_v4: return "observed_address_v4"; case picoquic_frame_type_observed_address_v6: diff --git a/loglib/qlog.c b/loglib/qlog.c index 95974b9f2..88885be65 100644 --- a/loglib/qlog.c +++ b/loglib/qlog.c @@ -823,13 +823,20 @@ void qlog_max_path_id_frame(FILE* f, bytestream* s) fprintf(f, ", \"max_path_id\": %"PRIu64, max_path_id); } -void qlog_path_blocked_frame(FILE* f, bytestream* s) +void qlog_paths_blocked_frame(FILE* f, bytestream* s) { uint64_t max_path_id = 0; byteread_vint(s, &max_path_id); fprintf(f, ", \"max_path_id\": %"PRIu64, max_path_id); } +void qlog_path_cid_blocked_frame(FILE* f, bytestream* s) +{ + uint64_t path_id = 0; + byteread_vint(s, &path_id); + fprintf(f, ", \"path_id\": %"PRIu64, path_id); +} + void qlog_reset_stream_frame(FILE* f, bytestream* s) { uint64_t stream_id = 0; @@ -1321,8 +1328,11 @@ int qlog_packet_frame(bytestream * s, void * ptr) case picoquic_frame_type_max_path_id: qlog_max_path_id_frame(f, s); break; - case picoquic_frame_type_path_blocked: - qlog_path_blocked_frame(f, s); + case picoquic_frame_type_paths_blocked: + qlog_paths_blocked_frame(f, s); + break; + case picoquic_frame_type_path_cid_blocked: + qlog_path_cid_blocked_frame(f, s); break; case picoquic_frame_type_observed_address_v4: case picoquic_frame_type_observed_address_v6: diff --git a/picoquic/frames.c b/picoquic/frames.c index 1ab080215..a184d27c5 100644 --- a/picoquic/frames.c +++ b/picoquic/frames.c @@ -42,9 +42,13 @@ int picoquic_max_path_id_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* const uint8_t* bytes_max, int* no_need_to_repeat); int picoquic_process_ack_of_max_path_id_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, size_t bytes_max, size_t* consumed); -int picoquic_path_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, +int picoquic_paths_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, const uint8_t* bytes_max, int* no_need_to_repeat); -int picoquic_process_ack_of_path_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, +int picoquic_process_ack_of_paths_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, + size_t bytes_max, size_t* consumed); +int picoquic_path_cid_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, + const uint8_t* bytes_max, int* no_need_to_repeat); +int picoquic_process_ack_of_path_cid_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, size_t bytes_max, size_t* consumed); int picoquic_process_ack_of_observed_address_frame(picoquic_cnx_t* cnx, picoquic_path_t* path_x, const uint8_t* bytes, size_t bytes_max, uint64_t ftype, size_t* consumed); @@ -3365,8 +3369,12 @@ int picoquic_check_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, (void)picoquic_max_path_id_frame_needs_repeat(cnx, bytes, p_bytes_max, no_need_to_repeat); break; - case picoquic_frame_type_path_blocked: - (void)picoquic_path_blocked_frame_needs_repeat(cnx, bytes, + case picoquic_frame_type_paths_blocked: + (void)picoquic_paths_blocked_frame_needs_repeat(cnx, bytes, + p_bytes_max, no_need_to_repeat); + break; + case picoquic_frame_type_path_cid_blocked: + (void)picoquic_path_cid_blocked_frame_needs_repeat(cnx, bytes, p_bytes_max, no_need_to_repeat); break; case picoquic_frame_type_path_new_connection_id: @@ -3517,8 +3525,12 @@ void picoquic_process_ack_of_frames(picoquic_cnx_t* cnx, picoquic_packet_t* p, ret = picoquic_process_ack_of_max_path_id_frame(cnx, &p->bytes[byte_index], p->length - byte_index, &frame_length); byte_index += frame_length; break; - case picoquic_frame_type_path_blocked: - ret = picoquic_process_ack_of_path_blocked_frame(cnx, &p->bytes[byte_index], p->length - byte_index, &frame_length); + case picoquic_frame_type_paths_blocked: + ret = picoquic_process_ack_of_paths_blocked_frame(cnx, &p->bytes[byte_index], p->length - byte_index, &frame_length); + byte_index += frame_length; + break; + case picoquic_frame_type_path_cid_blocked: + ret = picoquic_process_ack_of_path_cid_blocked_frame(cnx, &p->bytes[byte_index], p->length - byte_index, &frame_length); byte_index += frame_length; break; case picoquic_frame_type_observed_address_v4: @@ -5740,13 +5752,13 @@ int picoquic_process_ack_of_max_path_id_frame(picoquic_cnx_t* cnx, const uint8_t return ret; } -/* PATH BLOCKED frame */ -uint8_t* picoquic_format_path_blocked_frame( +/* PATHS BLOCKED frame */ +uint8_t* picoquic_format_paths_blocked_frame( uint8_t* bytes, const uint8_t* bytes_max, uint64_t max_path_id, int * more_data) { /* This code assumes that the frame type is already skipped */ uint8_t* bytes0 = bytes; - if ((bytes = picoquic_frames_varint_encode(bytes, bytes_max, picoquic_frame_type_path_blocked)) == NULL || + if ((bytes = picoquic_frames_varint_encode(bytes, bytes_max, picoquic_frame_type_paths_blocked)) == NULL || (bytes = picoquic_frames_varint_encode(bytes, bytes_max, max_path_id)) == NULL){ bytes = bytes0; *more_data = 1; @@ -5754,7 +5766,7 @@ uint8_t* picoquic_format_path_blocked_frame( return bytes; } -int picoquic_queue_path_blocked_frame( +int picoquic_queue_paths_blocked_frame( picoquic_cnx_t* cnx) { /* Call to format will always succeed */ @@ -5762,7 +5774,7 @@ int picoquic_queue_path_blocked_frame( uint8_t frame_buffer[256]; int is_pure_ack = 0; int more_data = 0; - uint8_t* bytes_next = picoquic_format_path_blocked_frame( + uint8_t* bytes_next = picoquic_format_paths_blocked_frame( frame_buffer, frame_buffer + sizeof(frame_buffer), cnx->max_path_id_remote, & more_data); size_t consumed = bytes_next - frame_buffer; ret = picoquic_queue_misc_frame(cnx, frame_buffer, consumed, is_pure_ack, @@ -5770,21 +5782,21 @@ int picoquic_queue_path_blocked_frame( return ret; } -const uint8_t* picoquic_skip_path_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max) +const uint8_t* picoquic_skip_paths_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max) { /* This code assumes that the frame type is already skipped */ bytes = picoquic_frames_varint_skip(bytes, bytes_max); return bytes; } -const uint8_t* picoquic_parse_path_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, +const uint8_t* picoquic_parse_paths_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, uint64_t* max_path_id) { bytes = picoquic_frames_varint_decode(bytes, bytes_max, max_path_id); return bytes; } -const uint8_t* picoquic_decode_path_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, +const uint8_t* picoquic_decode_paths_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, picoquic_cnx_t* cnx) { uint64_t max_path_id; @@ -5794,17 +5806,17 @@ const uint8_t* picoquic_decode_path_blocked_frame(const uint8_t* bytes, const ui if (!cnx->is_multipath_enabled) { /* Frame is unexpected */ picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR, - picoquic_frame_type_path_blocked, "multipath extension not negotiated"); + picoquic_frame_type_paths_blocked, "multipath extension not negotiated"); } - else if ((bytes = picoquic_parse_path_blocked_frame(bytes, bytes_max, &max_path_id)) == NULL) { + else if ((bytes = picoquic_parse_paths_blocked_frame(bytes, bytes_max, &max_path_id)) == NULL) { /* Bad frame encoding */ picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR, - picoquic_frame_type_path_blocked, "bad path blocked frame"); + picoquic_frame_type_paths_blocked, "bad path blocked frame"); } return bytes; } -int picoquic_path_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, +int picoquic_paths_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, const uint8_t* bytes_max, int* no_need_to_repeat) { int ret = 0; @@ -5812,14 +5824,14 @@ int picoquic_path_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* *no_need_to_repeat = 0; - if ((bytes = picoquic_parse_path_blocked_frame(bytes, bytes_max, &max_path_id)) == NULL) { + if ((bytes = picoquic_parse_paths_blocked_frame(bytes, bytes_max, &max_path_id)) == NULL) { /* Malformed frame, do not retransmit */ *no_need_to_repeat = 1; } else { /* check whether this is the last frame sent, and whether we already * have received an ack */ - if (max_path_id <= cnx->max_path_id_remote || max_path_id <= cnx->path_blocked_acknowledged) { + if (max_path_id <= cnx->max_path_id_remote || max_path_id <= cnx->paths_blocked_acknowledged) { *no_need_to_repeat = 1; } } @@ -5827,17 +5839,138 @@ int picoquic_path_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* } -int picoquic_process_ack_of_path_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, +int picoquic_process_ack_of_paths_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, size_t bytes_max, size_t* consumed) { int ret = 0; uint64_t max_path_id = 0; - const uint8_t* bytes_next = picoquic_parse_path_blocked_frame(bytes, bytes + bytes_max, &max_path_id); + const uint8_t* bytes_next = picoquic_parse_paths_blocked_frame(bytes, bytes + bytes_max, &max_path_id); if (bytes_next != NULL) { - if (cnx->path_blocked_acknowledged < max_path_id) { - cnx->path_blocked_acknowledged = max_path_id; + if (cnx->paths_blocked_acknowledged < max_path_id) { + cnx->paths_blocked_acknowledged = max_path_id; + } + *consumed = bytes_next - bytes; + } + else { + /* Internal error -- cannot parse the stored packet */ + *consumed = bytes_max; + ret = -1; + } + + return ret; +} + +/* PATH CID BLOCKED frame */ +uint8_t* picoquic_format_path_cid_blocked_frame( + uint8_t* bytes, const uint8_t* bytes_max, uint64_t path_id, int* more_data) +{ + /* This code assumes that the frame type is already skipped */ + uint8_t* bytes0 = bytes; + if ((bytes = picoquic_frames_varint_encode(bytes, bytes_max, picoquic_frame_type_path_cid_blocked)) == NULL || + (bytes = picoquic_frames_varint_encode(bytes, bytes_max, path_id)) == NULL) { + bytes = bytes0; + *more_data = 1; + } + return bytes; +} + +int picoquic_queue_path_cid_blocked_frame( + picoquic_path_t * path_x) +{ + /* Call to format will always succeed */ + int ret = 0; + uint8_t frame_buffer[256]; + int is_pure_ack = 0; + int more_data = 0; + uint8_t* bytes_next = picoquic_format_path_cid_blocked_frame( + frame_buffer, frame_buffer + sizeof(frame_buffer), path_x->unique_path_id, &more_data); + size_t consumed = bytes_next - frame_buffer; + ret = picoquic_queue_misc_frame(path_x->cnx, frame_buffer, consumed, is_pure_ack, + picoquic_packet_context_application); + if (ret == 0) { + path_x->sending_path_cid_blocked_frame = 1; + } + return ret; +} + +const uint8_t* picoquic_skip_path_cid_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max) +{ + /* This code assumes that the frame type is already skipped */ + bytes = picoquic_frames_varint_skip(bytes, bytes_max); + return bytes; +} + +const uint8_t* picoquic_parse_path_cid_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, + uint64_t* max_path_id) +{ + bytes = picoquic_frames_varint_decode(bytes, bytes_max, max_path_id); + return bytes; +} + +const uint8_t* picoquic_decode_path_cid_blocked_frame(const uint8_t* bytes, const uint8_t* bytes_max, + picoquic_cnx_t* cnx) +{ + uint64_t path_id; + + /* This code assumes that the frame type is already skipped */ + + if (!cnx->is_multipath_enabled) { + /* Frame is unexpected */ + picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR, + picoquic_frame_type_path_cid_blocked, "multipath extension not negotiated"); + } + else if ((bytes = picoquic_parse_path_cid_blocked_frame(bytes, bytes_max, &path_id)) == NULL) { + /* Bad frame encoding */ + picoquic_connection_error_ex(cnx, PICOQUIC_TRANSPORT_FRAME_FORMAT_ERROR, + picoquic_frame_type_path_cid_blocked, "bad path blocked frame"); + } + return bytes; +} + +int picoquic_path_cid_blocked_frame_needs_repeat(picoquic_cnx_t* cnx, const uint8_t* bytes, + const uint8_t* bytes_max, int* no_need_to_repeat) +{ + int ret = 0; + uint64_t unique_path_id = 0; + + *no_need_to_repeat = 0; + + if ((bytes = picoquic_parse_path_cid_blocked_frame(bytes, bytes_max, &unique_path_id)) == NULL) { + /* Malformed frame, do not retransmit */ + *no_need_to_repeat = 1; + } + else { + /* check whether this is the last frame sent, and whether we already + * have received an ack */ + int path_index = picoquic_find_path_by_unique_id(cnx, unique_path_id); + if (path_index < 0) { + /* The path does not exist any more */ + *no_need_to_repeat = 1; + } + else if (!cnx->path[path_index]->sending_path_cid_blocked_frame) { + /* the blocked frame was already acknowledged */ + *no_need_to_repeat = 1; + } + } + return ret; +} + +int picoquic_process_ack_of_path_cid_blocked_frame(picoquic_cnx_t* cnx, const uint8_t* bytes, + size_t bytes_max, size_t* consumed) +{ + int ret = 0; + uint64_t unique_path_id = 0; + + const uint8_t* bytes_next = picoquic_parse_path_cid_blocked_frame(bytes, bytes + bytes_max, &unique_path_id); + + if (bytes_next != NULL) { + /* Find the path context for the path ID */ + int path_index = picoquic_find_path_by_unique_id(cnx, unique_path_id); + if (path_index >= 0) { + /* path is still valid. Notice that there is no need for repeating this frame. */ + cnx->path[path_index]->sending_path_cid_blocked_frame = 0; } *consumed = bytes_next - bytes; } @@ -6371,8 +6504,12 @@ int picoquic_decode_frames(picoquic_cnx_t* cnx, picoquic_path_t * path_x, const bytes = picoquic_decode_max_path_id_frame(bytes, bytes_max, cnx); ack_needed = 1; break; - case picoquic_frame_type_path_blocked: - bytes = picoquic_decode_path_blocked_frame(bytes, bytes_max, cnx); + case picoquic_frame_type_paths_blocked: + bytes = picoquic_decode_paths_blocked_frame(bytes, bytes_max, cnx); + ack_needed = 1; + break; + case picoquic_frame_type_path_cid_blocked: + bytes = picoquic_decode_path_cid_blocked_frame(bytes, bytes_max, cnx); ack_needed = 1; break; case picoquic_frame_type_path_new_connection_id: @@ -6715,8 +6852,12 @@ int picoquic_skip_frame(const uint8_t* bytes, size_t bytes_maxsize, size_t* cons bytes = picoquic_skip_max_path_id_frame(bytes, bytes_max); *pure_ack = 0; break; - case picoquic_frame_type_path_blocked: - bytes = picoquic_skip_path_blocked_frame(bytes, bytes_max); + case picoquic_frame_type_paths_blocked: + bytes = picoquic_skip_paths_blocked_frame(bytes, bytes_max); + *pure_ack = 0; + break; + case picoquic_frame_type_path_cid_blocked: + bytes = picoquic_skip_paths_blocked_frame(bytes, bytes_max); *pure_ack = 0; break; case picoquic_frame_type_bdp: diff --git a/picoquic/logger.c b/picoquic/logger.c index 80cf5c7a7..abf58826a 100644 --- a/picoquic/logger.c +++ b/picoquic/logger.c @@ -328,8 +328,11 @@ char const* textlog_frame_names(uint64_t frame_type) case picoquic_frame_type_path_retire_connection_id: frame_name = "path_retire_connection_id"; break; - case picoquic_frame_type_path_blocked: - frame_name = "path_blocked"; + case picoquic_frame_type_paths_blocked: + frame_name = "paths_blocked"; + break; + case picoquic_frame_type_path_cid_blocked: + frame_name = "path_cid_blocked"; break; case picoquic_frame_type_bdp: frame_name = "bdp_frame"; @@ -1459,7 +1462,7 @@ size_t textlog_max_path_id_frame(FILE* F, const uint8_t* bytes, size_t bytes_max return byte_index; } -size_t textlog_path_blocked_frame(FILE* F, const uint8_t* bytes, size_t bytes_max) +size_t textlog_paths_blocked_frame(FILE* F, const uint8_t* bytes, size_t bytes_max) { const uint8_t* bytes_end = bytes + bytes_max; @@ -1483,13 +1486,45 @@ size_t textlog_path_blocked_frame(FILE* F, const uint8_t* bytes, size_t bytes_ma } else { fprintf(F, " %s, max_path_id: %" PRIu64 "\n", - textlog_frame_names(picoquic_frame_type_path_blocked), + textlog_frame_names(picoquic_frame_type_paths_blocked), max_path_id); byte_index = (bytes - bytes0); } return byte_index; } +size_t textlog_path_cid_blocked_frame(FILE* F, const uint8_t* bytes, size_t bytes_max) +{ + + const uint8_t* bytes_end = bytes + bytes_max; + const uint8_t* bytes0 = bytes; + uint64_t frame_id = 0; + uint64_t path_id; + size_t byte_index = 0; + if ((bytes = picoquic_frames_varint_decode(bytes, bytes_end, &frame_id)) == NULL || + (bytes = picoquic_frames_varint_decode(bytes, bytes_end, &path_id)) == NULL) { + /* log format error */ + fprintf(F, " Malformed %s frame: ", textlog_frame_names(frame_id)); + /* log format error */ + for (size_t i = 0; i < bytes_max && i < 8; i++) { + fprintf(F, "%02x", bytes0[i]); + } + if (bytes_max > 8) { + fprintf(F, "..."); + } + fprintf(F, "\n"); + byte_index = bytes_max; + } + else { + fprintf(F, " %s, path_id: %" PRIu64 "\n", + textlog_frame_names(picoquic_frame_type_path_cid_blocked), + path_id); + byte_index = (bytes - bytes0); + } + return byte_index; +} + + size_t textlog_bdp_frame(FILE* F, const uint8_t* bytes, size_t bytes_max) { const uint8_t* bytes_end = bytes + bytes_max; @@ -1723,8 +1758,11 @@ void picoquic_textlog_frames(FILE* F, uint64_t cnx_id64, const uint8_t* bytes, s case picoquic_frame_type_max_path_id: byte_index += textlog_max_path_id_frame(F, bytes + byte_index, length - byte_index); break; - case picoquic_frame_type_path_blocked: - byte_index += textlog_path_blocked_frame(F, bytes + byte_index, length - byte_index); + case picoquic_frame_type_paths_blocked: + byte_index += textlog_paths_blocked_frame(F, bytes + byte_index, length - byte_index); + break; + case picoquic_frame_type_path_cid_blocked: + byte_index += textlog_path_cid_blocked_frame(F, bytes + byte_index, length - byte_index); break; case picoquic_frame_type_bdp: byte_index += textlog_bdp_frame(F, bytes + byte_index, length - byte_index); diff --git a/picoquic/picoquic.h b/picoquic/picoquic.h index 1540af0a1..2221b375a 100644 --- a/picoquic/picoquic.h +++ b/picoquic/picoquic.h @@ -40,7 +40,7 @@ extern "C" { #endif -#define PICOQUIC_VERSION "1.1.29.1" +#define PICOQUIC_VERSION "1.1.30.0" #define PICOQUIC_ERROR_CLASS 0x400 #define PICOQUIC_ERROR_DUPLICATE (PICOQUIC_ERROR_CLASS + 1) #define PICOQUIC_ERROR_AEAD_CHECK (PICOQUIC_ERROR_CLASS + 3) diff --git a/picoquic/picoquic_internal.h b/picoquic/picoquic_internal.h index dc3cb493b..ff5e737cf 100644 --- a/picoquic/picoquic_internal.h +++ b/picoquic/picoquic_internal.h @@ -161,7 +161,8 @@ typedef enum { picoquic_frame_type_path_available = 0x15228c08, picoquic_frame_type_bdp = 0xebd9, picoquic_frame_type_max_path_id = 0x15228c0c, - picoquic_frame_type_path_blocked = 0x15228c0d, + picoquic_frame_type_paths_blocked = 0x15228c0d, + picoquic_frame_type_path_cid_blocked = 0x15228c0e, picoquic_frame_type_observed_address_v4 = 0x9f81a6, picoquic_frame_type_observed_address_v6 = 0x9f81a7 } picoquic_frame_type_enum_t; @@ -587,7 +588,7 @@ typedef uint64_t picoquic_tp_enum; #define picoquic_tp_grease_quic_bit 0x2ab2 #define picoquic_tp_version_negotiation 0x11 #define picoquic_tp_enable_bdp_frame 0xebd9 /* per draft-kuhn-quic-0rtt-bdp-09 */ -#define picoquic_tp_initial_max_path_id 0x0f739bbc1b666d11ull /* per draft quic multipath 11 */ +#define picoquic_tp_initial_max_path_id 0x0f739bbc1b666d0cull /* per draft quic multipath 12 */ #define picoquic_tp_address_discovery 0x9f81a176 /* per draft-seemann-quic-address-discovery */ /* Callback for converting binary log to quic log at the end of a connection. @@ -1118,6 +1119,7 @@ typedef struct st_picoquic_path_t { unsigned int is_lost_feedback_notified : 1; /* Lost feedback has been notified */ unsigned int is_cca_probing_up : 1; /* congestion control algorithm is seeking more bandwidth */ unsigned int rtt_is_initialized : 1; /* RTT was measured at least once. */ + unsigned int sending_path_cid_blocked_frame : 1; /* Sending a path CID blocked, not acked yet. */ /* Management of retransmissions in a path. * The "path_packet" variables are used for the RACK algorithm, per path, to avoid @@ -1501,7 +1503,7 @@ typedef struct st_picoquic_cnx_t { uint64_t max_path_id_local; uint64_t max_path_id_acknowledged; uint64_t max_path_id_remote; - uint64_t path_blocked_acknowledged; + uint64_t paths_blocked_acknowledged; /* Management of the CNX-ID stash */ picoquic_remote_cnxid_stash_t * first_remote_cnxid_stash; /* management of local CID stash. diff --git a/picoquictest/binlog_ref.log b/picoquictest/binlog_ref.log index b0e0fff59..7d08b89b2 100644 Binary files a/picoquictest/binlog_ref.log and b/picoquictest/binlog_ref.log differ diff --git a/picoquictest/binlog_ref.qlog b/picoquictest/binlog_ref.qlog index 1816f88db..2b92ebfe5 100644 --- a/picoquictest/binlog_ref.qlog +++ b/picoquictest/binlog_ref.qlog @@ -83,16 +83,18 @@ [0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 6, "packet_number": 38, "dcid": "01020304" }, "frames": [{ "frame_type": "path_retire_connection_id", "path_id": 0, "sequence_number": 2}]}], [0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 5, "packet_number": 39, "dcid": "01020304" }, "frames": [{ - "frame_type": "path_blocked", "max_path_id": 17}]}], -[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 12, "packet_number": 40, "dcid": "01020304" }, "frames": [{ + "frame_type": "paths_blocked", "max_path_id": 17}]}], +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 5, "packet_number": 40, "dcid": "01020304" }, "frames": [{ + "frame_type": "path_cid_blocked", "path_id": 7}]}], +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 12, "packet_number": 41, "dcid": "01020304" }, "frames": [{ "frame_type": "bdp", "lifetime": 1, "bytes_in_flight": 2, "min_rtt": 3, "ip": "0a000001"}]}], -[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 11, "packet_number": 41, "dcid": "01020304" }, "frames": [{ +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 11, "packet_number": 42, "dcid": "01020304" }, "frames": [{ "frame_type": "observed_address_v4", "sequence": 1, "address": "1.2.3.4", "port": 4660}]}], -[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 23, "packet_number": 42, "dcid": "01020304" }, "frames": [{ +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 23, "packet_number": 43, "dcid": "01020304" }, "frames": [{ "frame_type": "observed_address_v6", "sequence": 2, "address": "102:304:506:708:90a:b0c:d0e:f00", "port": 17767}]}], -[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 21, "packet_number": 43, "dcid": "01020304" }, "frames": [{ +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 21, "packet_number": 44, "dcid": "01020304" }, "frames": [{ "frame_type": "path_ack", "path_id": 0, "ack_delay": 1024, "acked_ranges": [[4328719360, 4328719365], [4328719358, 4328719358], [4328719339, 4328719351]]}]}], -[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 24, "packet_number": 44, "dcid": "01020304" }, "frames": [{ +[0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 24, "packet_number": 45, "dcid": "01020304" }, "frames": [{ "frame_type": "path_ack", "path_id": 0, "ack_delay": 1024, "acked_ranges": [[4328719360, 4328719365], [4328719358, 4328719358], [4328719339, 4328719351]], "ect0": 3, "ect1": 0, "ce": 1}]}], [0, "transport", "packet_sent", { "packet_type": "1RTT", "header": { "packet_size": 11, "packet_number": 0, "dcid": "01020304" }, "frames": [{ "frame_type": "reset_stream", "stream_id": 17, "error_code": 1, "final_size": 4611686018427387903}]}], diff --git a/picoquictest/log_test_ref.txt b/picoquictest/log_test_ref.txt index dc4f45332..a701fdda2 100644 --- a/picoquictest/log_test_ref.txt +++ b/picoquictest/log_test_ref.txt @@ -39,7 +39,8 @@ max_path_id, max_path_id: 17 path_retire_connection_id[1, 7]: 0x0102030405060708, a1a2a3a4a5a6a7a8a9aaabacadaeafb0 path_retire_connection_id[0, 2] - path_blocked, max_path_id: 17 + paths_blocked, max_path_id: 17 + path_cid_blocked, path_id: 7 bdp_frame, lifetime: 1, bytes_in_flight: 2, min_rtt: 3, ip: 0a000001 observed_address_v4, sequence: 1, addr: 1.2.3.4, port: 4660 observed_address_v6, sequence: 2, addr: 102:304:506:708:90a:b0c:d0e:f00, port: 17767 diff --git a/picoquictest/log_tp_test_ref.txt b/picoquictest/log_tp_test_ref.txt index 5176cd4dd..0f251bb26 100644 --- a/picoquictest/log_tp_test_ref.txt +++ b/picoquictest/log_tp_test_ref.txt @@ -56,7 +56,7 @@ 0102030405060708: Extension type: 1 (idle_timeout), length 1, 1e 0102030405060708: Extension type: 3 (max_packet_size), length 2, 45c8 0102030405060708: Extension type: 15 (hcid), length 8, 0203040506070809 -0102030405060708: Extension type: 1113404765106498833 (initial_max_path_id), length 1, 04 +0102030405060708: Extension type: 1113404765106498828 (initial_max_path_id), length 1, 04 0102030405060708: Extension list (36 bytes): 0102030405060708: Extension type: 1 (idle_timeout), length 2, 400a diff --git a/picoquictest/skip_frame_test.c b/picoquictest/skip_frame_test.c index eef50ae18..3d559ed13 100644 --- a/picoquictest/skip_frame_test.c +++ b/picoquictest/skip_frame_test.c @@ -319,12 +319,18 @@ static uint8_t test_frame_type_path_retire_connection_id[] = { 2 }; -static uint8_t test_frame_type_path_blocked[] = { - (uint8_t)(0x80 | (picoquic_frame_type_path_blocked >> 24)), (uint8_t)(picoquic_frame_type_path_blocked >> 16), - (uint8_t)(picoquic_frame_type_path_blocked >> 8), (uint8_t)(picoquic_frame_type_path_blocked & 0xFF), +static uint8_t test_frame_type_paths_blocked[] = { + (uint8_t)(0x80 | (picoquic_frame_type_paths_blocked >> 24)), (uint8_t)(picoquic_frame_type_paths_blocked >> 16), + (uint8_t)(picoquic_frame_type_paths_blocked >> 8), (uint8_t)(picoquic_frame_type_paths_blocked & 0xFF), 0x11, /* max paths = 17 */ }; +static uint8_t test_frame_type_path_cid_blocked[] = { + (uint8_t)(0x80 | (picoquic_frame_type_path_cid_blocked >> 24)), (uint8_t)(picoquic_frame_type_path_cid_blocked >> 16), + (uint8_t)(picoquic_frame_type_path_cid_blocked >> 8), (uint8_t)(picoquic_frame_type_path_cid_blocked & 0xFF), + 0x07, /* path id = 7 */ +}; + static uint8_t test_frame_observed_address_v4[] = { (uint8_t)(0x80 | (picoquic_frame_type_observed_address_v4 >> 24)), (uint8_t)(picoquic_frame_type_observed_address_v4 >> 16), (uint8_t)(picoquic_frame_type_observed_address_v4 >> 8), (uint8_t)(picoquic_frame_type_observed_address_v4 & 0xFF), @@ -409,7 +415,8 @@ test_skip_frames_t test_skip_list[] = { TEST_SKIP_ITEM_MPATH("max paths", test_frame_type_max_path_id, 0, 0, 3, 0, 0, 1, 1), TEST_SKIP_ITEM_MPATH("path_new_connection_id", test_frame_type_path_new_connection_id, 0, 0, 3, 0, 0, 1, 5), TEST_SKIP_ITEM_MPATH("path_retire_connection_id", test_frame_type_path_retire_connection_id, 0, 0, 3, 0, 0, 1, 2), - TEST_SKIP_ITEM_MPATH("paths blocked", test_frame_type_path_blocked, 0, 0, 3, 0, 0, 1, 1), + TEST_SKIP_ITEM_MPATH("paths blocked", test_frame_type_paths_blocked, 0, 0, 3, 0, 0, 1, 1), + TEST_SKIP_ITEM_MPATH("path cid blocked", test_frame_type_path_cid_blocked, 0, 0, 3, 0, 0, 1, 1), TEST_SKIP_ITEM("bdp", test_frame_type_bdp, 0, 0, 3, 0, 0, 4), TEST_SKIP_ITEM_MPATH("observed_address_v4", test_frame_observed_address_v4, 0, 0, 3, 0, 0, 2, 1), @@ -1550,7 +1557,9 @@ uint8_t* picoquic_format_datagram_frame(uint8_t* bytes, uint8_t* bytes_max, int* uint8_t* picoquic_format_path_available_or_standby_frame( uint8_t* bytes, const uint8_t* bytes_max, uint64_t frame_type, uint64_t path_id, uint64_t sequence, int * more_data); -uint8_t* picoquic_format_path_blocked_frame( +uint8_t* picoquic_format_paths_blocked_frame( + uint8_t* bytes, const uint8_t* bytes_max, uint64_t max_path_id, int* more_data); +uint8_t* picoquic_format_path_cid_blocked_frame( uint8_t* bytes, const uint8_t* bytes_max, uint64_t max_path_id, int* more_data); int frames_format_test() @@ -1622,7 +1631,8 @@ int frames_format_test() FRAME_FORMAT_TEST(picoquic_format_path_abandon_frame, bytes, bytes_max, &more_data, 1, 3); FRAME_FORMAT_TEST(picoquic_format_path_available_or_standby_frame, bytes, bytes_max, picoquic_frame_type_path_available, 1, 17, &more_data); FRAME_FORMAT_TEST(picoquic_format_max_path_id_frame, bytes, bytes_max, 123, &more_data); - FRAME_FORMAT_TEST(picoquic_format_path_blocked_frame, bytes, bytes_max, 123, &more_data); + FRAME_FORMAT_TEST(picoquic_format_paths_blocked_frame, bytes, bytes_max, 123, &more_data); + FRAME_FORMAT_TEST(picoquic_format_path_cid_blocked_frame, bytes, bytes_max, 123, &more_data); FRAME_FORMAT_TEST(picoquic_format_observed_address_frame, bytes, bytes_max, picoquic_frame_type_observed_address_v4, 13, addr_bytes, 4433, &more_data); }