From b7d04fa633776767223370c4d40fba5797476ee0 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 13:56:44 +0800 Subject: [PATCH 01/36] [+] enable draft-11 transport parameter --- include/xquic/xquic.h | 3 ++- src/transport/xqc_multipath.c | 1 + src/transport/xqc_transport_params.c | 12 ++++++++++++ src/transport/xqc_transport_params.h | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index 392caf49..7b845276 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -1246,7 +1246,8 @@ typedef struct xqc_linger_s { typedef enum { XQC_ERR_MULTIPATH_VERSION = 0x00, - XQC_MULTIPATH_10 = 0x0a, + XQC_MULTIPATH_10 = 0x0a, + XQC_MULTIPATH_11 = 0x0b, } xqc_multipath_version_t; typedef enum { diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index 34a624c4..98fa7d13 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -413,6 +413,7 @@ xqc_conn_is_current_mp_version_supported(xqc_multipath_version_t mp_version) xqc_int_t ret; switch (mp_version) { case XQC_MULTIPATH_10: + case XQC_MULTIPATH_11: ret = XQC_OK; break; default: diff --git a/src/transport/xqc_transport_params.c b/src/transport/xqc_transport_params.c index 53412c75..a3d5287e 100644 --- a/src/transport/xqc_transport_params.c +++ b/src/transport/xqc_transport_params.c @@ -163,6 +163,10 @@ xqc_transport_params_calc_length(const xqc_transport_params_t *params, xqc_put_varint_len(xqc_put_varint_len(params->init_max_path_id)) + xqc_put_varint_len(params->init_max_path_id); + } else if (params->multipath_version == XQC_MULTIPATH_11) { + len += xqc_put_varint_len(XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11) + + xqc_put_varint_len(xqc_put_varint_len(params->init_max_path_id)) + + xqc_put_varint_len(params->init_max_path_id); } } @@ -393,6 +397,8 @@ xqc_encode_transport_params(const xqc_transport_params_t *params, if (params->multipath_version == XQC_MULTIPATH_10) { p = xqc_put_varint_param(p, XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V10, params->init_max_path_id); + } else if (params->multipath_version == XQC_MULTIPATH_11) { + p = xqc_put_varint_param(p, XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11, params->init_max_path_id); } } @@ -699,6 +705,11 @@ xqc_decode_enable_multipath(xqc_transport_params_t *params, xqc_transport_params params->multipath_version = XQC_MULTIPATH_10; XQC_DECODE_VINT_VALUE(¶ms->init_max_path_id, p, end); return XQC_OK; + } else if (param_type == XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11) { + params->enable_multipath = 1; + params->multipath_version = XQC_MULTIPATH_11; + XQC_DECODE_VINT_VALUE(¶ms->init_max_path_id, p, end); + return XQC_OK; } return XQC_OK; } @@ -891,6 +902,7 @@ xqc_trans_param_get_index(uint64_t param_type) return param_type; case XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V10: + case XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11: return XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_PARSER; case XQC_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE: diff --git a/src/transport/xqc_transport_params.h b/src/transport/xqc_transport_params.h index 083c2ebe..609d0dec 100644 --- a/src/transport/xqc_transport_params.h +++ b/src/transport/xqc_transport_params.h @@ -87,6 +87,7 @@ typedef enum { /* multipath quic attributes */ XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V10 = 0x0f739bbc1b666d09, + XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11 = 0x0f739bbc1b666d11, /* google connection options */ XQC_TRANSPORT_PARAM_GOOGLE_CO = 0x3128, From e0484f97c0b4c36f0e8efe891454dad785738473 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 14:52:21 +0800 Subject: [PATCH 02/36] [+] add default parameter value --- src/transport/xqc_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_conn.c b/src/transport/xqc_conn.c index 55704b29..ab3c189e 100644 --- a/src/transport/xqc_conn.c +++ b/src/transport/xqc_conn.c @@ -729,7 +729,7 @@ xqc_conn_create(xqc_engine_t *engine, xqc_cid_t *dcid, xqc_cid_t *scid, } if (xqc_conn_is_current_mp_version_supported(xc->conn_settings.multipath_version) != XQC_OK) { - xc->conn_settings.multipath_version = XQC_MULTIPATH_10; + xc->conn_settings.multipath_version = XQC_MULTIPATH_11; } if (xc->conn_settings.init_max_path_id == 0) { From 8d1931c84960917cca1a7294904c23c1e0837e3d Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 15:15:03 +0800 Subject: [PATCH 03/36] [+] update draft-11 path abandon encoding / decoding --- src/transport/xqc_frame.c | 3 +- src/transport/xqc_frame_parser.c | 58 ++++++++++++++++++-------------- src/transport/xqc_frame_parser.h | 2 +- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 5ef9ebd0..a7b50a58 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1670,7 +1670,8 @@ xqc_process_path_abandon_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i uint64_t path_id = 0; uint64_t error_code; - ret = xqc_parse_path_abandon_frame(packet_in, &path_id, &error_code); + ret = xqc_parse_path_abandon_frame(packet_in, &path_id, &error_code, + conn->remote_settings.multipath_version == XQC_MULTIPATH_10? 1 : 0); if (ret != XQC_OK) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_parse_path_abandon_frame error|"); return ret; diff --git a/src/transport/xqc_frame_parser.c b/src/transport/xqc_frame_parser.c index 040b4ff0..78f61579 100644 --- a/src/transport/xqc_frame_parser.c +++ b/src/transport/xqc_frame_parser.c @@ -2444,12 +2444,11 @@ xqc_parse_ack_mp_frame(xqc_packet_in_t *packet_in, xqc_connection_t *conn, /* + * * PATH_ABANDON Frame { - * Type (i) = TBD-03, - * Path ID (i), - * Error Code (i), - * Reason Phrase Length (i), - * Reason Phrase (..), + * Type (i) = TBD-02 (experiments use 0x15228c05), + * Path Identifier (i), + * Error Code (i), * } * */ @@ -2483,9 +2482,13 @@ xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, need = xqc_vint_len(frame_type_bits) + xqc_vint_len(path_id_bits) - + xqc_vint_len(error_code_bits) - + xqc_vint_len(reason_len_bits) - + reason_len; + + xqc_vint_len(error_code_bits); + + /* only draft-10 use reason field */ + if (conn->conn_settings.multipath_version == XQC_MULTIPATH_10) { + need += xqc_vint_len(reason_len_bits) + + reason_len; + } po_remained_size = xqc_get_po_remained_size(packet_out); @@ -2506,14 +2509,17 @@ xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, xqc_vint_write(dst_buf, error_code, error_code_bits, xqc_vint_len(error_code_bits)); dst_buf += xqc_vint_len(error_code_bits); - /* Reason Phrase Length (i) */ - xqc_vint_write(dst_buf, reason_len, reason_len_bits, xqc_vint_len(reason_len_bits)); - dst_buf += xqc_vint_len(reason_len_bits); + /* only draft-10 use reason field */ + if (conn->conn_settings.multipath_version == XQC_MULTIPATH_10) { + /* Reason Phrase Length (i) */ + xqc_vint_write(dst_buf, reason_len, reason_len_bits, xqc_vint_len(reason_len_bits)); + dst_buf += xqc_vint_len(reason_len_bits); - /* Reason Phrase (..) */ - if (reason_len > 0) { - xqc_memcpy(dst_buf, reason, reason_len); - dst_buf += reason_len; + /* Reason Phrase (..) */ + if (reason_len > 0) { + xqc_memcpy(dst_buf, reason, reason_len); + dst_buf += reason_len; + } } packet_out->po_frame_types |= XQC_FRAME_BIT_PATH_ABANDON; @@ -2523,7 +2529,7 @@ xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, xqc_int_t xqc_parse_path_abandon_frame(xqc_packet_in_t *packet_in, - uint64_t *path_id, uint64_t *error_code) + uint64_t *path_id, uint64_t *error_code, uint8_t has_reason) { unsigned char *p = packet_in->pos; const unsigned char *end = packet_in->last; @@ -2552,16 +2558,18 @@ xqc_parse_path_abandon_frame(xqc_packet_in_t *packet_in, } p += vlen; - /* Reason Phrase Length (i) */ - vlen = xqc_vint_read(p, end, &reason_len); - if (vlen < 0) { - return -XQC_EVINTREAD; - } - p += vlen; + if (has_reason) { + /* Reason Phrase Length (i) */ + vlen = xqc_vint_read(p, end, &reason_len); + if (vlen < 0) { + return -XQC_EVINTREAD; + } + p += vlen; - /* Reason Phrase (..) */ - if (reason_len > 0) { - p += reason_len; + /* Reason Phrase (..) */ + if (reason_len > 0) { + p += reason_len; + } } packet_in->pos = p; diff --git a/src/transport/xqc_frame_parser.h b/src/transport/xqc_frame_parser.h index 2a71fc7d..bb7701ab 100644 --- a/src/transport/xqc_frame_parser.h +++ b/src/transport/xqc_frame_parser.h @@ -143,7 +143,7 @@ ssize_t xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, uint64_t path_id, uint64_t error_code); xqc_int_t xqc_parse_path_abandon_frame(xqc_packet_in_t *packet_in, - uint64_t *path_id, uint64_t *error_code); + uint64_t *path_id, uint64_t *error_code, uint8_t has_reason); ssize_t xqc_gen_path_status_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, From c2727df5287c926984a4ce06f0a100ec5ec2deef Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 19:06:41 +0800 Subject: [PATCH 04/36] [+] Add PATH_BLOCKED frame --- src/transport/xqc_frame.c | 44 ++++++++++++++++++++++++ src/transport/xqc_frame.h | 5 +++ src/transport/xqc_frame_parser.c | 58 ++++++++++++++++++++++++++++++++ src/transport/xqc_frame_parser.h | 4 +++ src/transport/xqc_packet_out.c | 29 ++++++++++++++++ src/transport/xqc_packet_out.h | 2 +- 6 files changed, 141 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index a7b50a58..90d015d7 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -352,7 +352,16 @@ xqc_process_frames(xqc_connection_t *conn, xqc_packet_in_t *packet_in) ret = -XQC_EMP_INVALID_MP_VERTION; } break; + case XQC_TRANS_FRAME_TYPE_PATH_BLOCKED: + if (conn->conn_settings.multipath_version >= XQC_MULTIPATH_11) { + ret = xqc_process_path_blocked_frame(conn, packet_in); + } else { + xqc_log(conn->log, XQC_LOG_ERROR, "|mp_version error|v:%ud|f:%xL|", + conn->conn_settings.multipath_version, frame_type); + ret = -XQC_EMP_INVALID_MP_VERTION; + } + break; #ifdef XQC_ENABLE_FEC case 0xfec5: if (conn->conn_settings.enable_decode_fec @@ -2027,6 +2036,41 @@ xqc_process_max_path_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in return ret; } + +xqc_int_t +xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in) +{ + xqc_int_t ret = XQC_ERROR; + uint64_t max_path_id, new_max_path_id; + + ret = xqc_parse_path_blocked_frame(packet_in, &max_path_id); + if (ret != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|xqc_process_max_paths_frame error|"); + return ret; + } + + xqc_log(conn->log, XQC_LOG_DEBUG, + "|max_path_id:%ui|pre_local_max_path_id:%ui|", max_path_id, conn->local_max_path_id); + + if (conn->remote_max_path_id < max_path_id) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|invalid path blocked frame|"); + return -XQC_EIGNORE_PKT; + } + + conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; + ret = xqc_write_max_path_id_to_packet(conn, conn->local_max_path_id); + if (ret != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|xqc_process_path_blocked_frame error|"); + return ret; + } + + return ret; +} + + #ifdef XQC_ENABLE_FEC uint32_t diff --git a/src/transport/xqc_frame.h b/src/transport/xqc_frame.h index bf7ca5af..10ca5b3b 100644 --- a/src/transport/xqc_frame.h +++ b/src/transport/xqc_frame.h @@ -36,6 +36,7 @@ typedef enum { XQC_FRAME_MP_NEW_CONNECTION_ID, XQC_FRAME_MP_RETIRE_CONNECTION_ID, XQC_FRAME_MAX_PATH_ID, + XQC_FRAME_PATH_BLOCKED, XQC_FRAME_PATH_FROZEN, XQC_FRAME_DATAGRAM, XQC_FRAME_Extension, @@ -73,6 +74,7 @@ typedef enum { XQC_FRAME_BIT_MP_NEW_CONNECTION_ID = 1ULL << XQC_FRAME_MP_NEW_CONNECTION_ID, XQC_FRAME_BIT_MP_RETIRE_CONNECTION_ID = 1ULL << XQC_FRAME_MP_RETIRE_CONNECTION_ID, XQC_FRAME_BIT_MAX_PATH_ID = 1ULL << XQC_FRAME_MAX_PATH_ID, + XQC_FRAME_BIT_PATH_BLOCKED = 1ULL << XQC_FRAME_PATH_BLOCKED, XQC_FRAME_BIT_PATH_FROZEN = 1ULL << XQC_FRAME_PATH_FROZEN, XQC_FRAME_BIT_DATAGRAM = 1ULL << XQC_FRAME_DATAGRAM, XQC_FRAME_BIT_Extension = 1ULL << XQC_FRAME_Extension, @@ -180,4 +182,7 @@ xqc_int_t xqc_process_mp_retire_conn_id_frame(xqc_connection_t *conn, xqc_packet xqc_int_t xqc_process_max_path_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in); +xqc_int_t xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in); + + #endif /* _XQC_FRAME_H_INCLUDED_ */ diff --git a/src/transport/xqc_frame_parser.c b/src/transport/xqc_frame_parser.c index 78f61579..0e5b21b7 100644 --- a/src/transport/xqc_frame_parser.c +++ b/src/transport/xqc_frame_parser.c @@ -2960,5 +2960,63 @@ xqc_parse_max_path_id_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id) packet_in->pi_frame_types |= XQC_FRAME_BIT_MAX_PATH_ID; + return XQC_OK; +} + +/* + * + * PATHS_BLOCKED Frame { + * Type (i) = TBD-08 (experiments use 0x15228c0d), + * Maximum Path Identifier (i), + * } + * Figure 10: MAX_PATH_ID_BLOCKED Frame Format + * + * */ +ssize_t +xqc_gen_path_blocked_frame(xqc_packet_out_t *packet_out, uint64_t max_path_id) +{ + unsigned char *dst_buf = packet_out->po_buf + packet_out->po_used_size; + const unsigned char *begin = dst_buf; + + /* write frame type */ + uint64_t frame_type = XQC_TRANS_FRAME_TYPE_PATH_BLOCKED; + unsigned frame_type_bits = xqc_vint_get_2bit(frame_type); + xqc_vint_write(dst_buf, frame_type, frame_type_bits, xqc_vint_len(frame_type_bits)); + dst_buf += xqc_vint_len(frame_type_bits); + + unsigned max_paths_bits = xqc_vint_get_2bit(max_path_id); + xqc_vint_write(dst_buf, max_path_id, max_paths_bits, xqc_vint_len(max_paths_bits)); + dst_buf += xqc_vint_len(max_paths_bits); + + packet_out->po_frame_types |= XQC_FRAME_BIT_PATH_BLOCKED; + + return dst_buf - begin; +} + +xqc_int_t +xqc_parse_path_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id) +{ + unsigned char *p = packet_in->pos; + const unsigned char *end = packet_in->last; + int vlen; + + /* frame type */ + uint64_t frame_type = 0; + vlen = xqc_vint_read(p, end, &frame_type); /* get frame_type */ + if (vlen < 0) { + return -XQC_EVINTREAD; + } + p += vlen; + + vlen = xqc_vint_read(p, end, max_path_id); + if (vlen < 0) { + return -XQC_EVINTREAD; + } + p += vlen; + + packet_in->pos = p; + + packet_in->pi_frame_types |= XQC_FRAME_BIT_PATH_BLOCKED; + return XQC_OK; } \ No newline at end of file diff --git a/src/transport/xqc_frame_parser.h b/src/transport/xqc_frame_parser.h index bb7701ab..caec0e8d 100644 --- a/src/transport/xqc_frame_parser.h +++ b/src/transport/xqc_frame_parser.h @@ -24,6 +24,7 @@ #define XQC_TRANS_FRAME_TYPE_MP_NEW_CONN_ID 0x15228c09 #define XQC_TRANS_FRAME_TYPE_MP_RETIRE_CONN_ID 0x15228c0a #define XQC_TRANS_FRAME_TYPE_MAX_PATH_ID 0x15228c0c +#define XQC_TRANS_FRAME_TYPE_PATH_BLOCKED 0x15228c0d #define XQC_TRANS_FRAME_TYPE_MP_FROZEN 0x15228cff /** @@ -178,5 +179,8 @@ xqc_int_t xqc_parse_mp_retire_conn_id_frame(xqc_packet_in_t *packet_in, uint64_t ssize_t xqc_gen_max_path_id_frame(xqc_packet_out_t *packet_out, uint64_t max_path_id); xqc_int_t xqc_parse_max_path_id_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id); +ssize_t xqc_gen_path_blocked_frame(xqc_packet_out_t *packet_out, uint64_t max_path_id); +xqc_int_t xqc_parse_path_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id); + void xqc_try_process_fec_decode(xqc_connection_t *conn, xqc_int_t block_id); #endif /*_XQC_FRAME_PARSER_H_INCLUDED_*/ diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 697f338f..bfc2a619 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1813,4 +1813,33 @@ xqc_write_max_path_id_to_packet(xqc_connection_t *conn, uint64_t max_path_id) error: xqc_maybe_recycle_packet_out(packet_out, conn); return -XQC_EWRITE_PKT; +} + + +int +xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id) +{ + ssize_t ret = XQC_ERROR; + xqc_packet_out_t *packet_out; + xqc_log(conn->log, XQC_LOG_DEBUG, "|path blocked max_path_id:%ui|", max_path_id); + + packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); + if (packet_out == NULL) { + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); + return -XQC_EWRITE_PKT; + } + + ret = xqc_gen_path_blocked_frame(packet_out, max_path_id); + if (ret < 0) { + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_max_streams_frame error|"); + goto error; + } + packet_out->po_used_size += ret; + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + xqc_log(conn->log, XQC_LOG_DEBUG, "|max_path_id:%ui|", max_path_id); + return XQC_OK; + + error: + xqc_maybe_recycle_packet_out(packet_out, conn); + return -XQC_EWRITE_PKT; } \ No newline at end of file diff --git a/src/transport/xqc_packet_out.h b/src/transport/xqc_packet_out.h index c988920a..0168a85c 100644 --- a/src/transport/xqc_packet_out.h +++ b/src/transport/xqc_packet_out.h @@ -232,7 +232,7 @@ xqc_int_t xqc_write_mp_new_conn_id_frame_to_packet(xqc_connection_t *conn, uint6 xqc_int_t xqc_write_mp_retire_conn_id_frame_to_packet(xqc_connection_t *conn, uint64_t seq_num, uint64_t path_id); int xqc_write_max_path_id_to_packet(xqc_connection_t *conn, uint64_t max_path_id); - +int xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id); /** * @brief Get remained space size in packet out buff. * From ca0f6b8bbd731a07f27172d611dcf205b14db06e Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 19:53:58 +0800 Subject: [PATCH 05/36] =?UTF-8?q?[=3D]=20=E5=8F=82=E6=95=B0=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/transport/xqc_frame.c | 2 +- src/transport/xqc_frame_parser.c | 12 ++++++------ src/transport/xqc_frame_parser.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 90d015d7..cdd69d62 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1680,7 +1680,7 @@ xqc_process_path_abandon_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i uint64_t error_code; ret = xqc_parse_path_abandon_frame(packet_in, &path_id, &error_code, - conn->remote_settings.multipath_version == XQC_MULTIPATH_10? 1 : 0); + (conn->remote_settings.multipath_version == XQC_MULTIPATH_10? 1 : 0)); if (ret != XQC_OK) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_parse_path_abandon_frame error|"); return ret; diff --git a/src/transport/xqc_frame_parser.c b/src/transport/xqc_frame_parser.c index 0e5b21b7..2eaed895 100644 --- a/src/transport/xqc_frame_parser.c +++ b/src/transport/xqc_frame_parser.c @@ -2463,15 +2463,15 @@ xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, uint64_t frame_type; need = po_remained_size = 0; - - if (conn->conn_settings.multipath_version >= XQC_MULTIPATH_10) { - /* same frame type in 05 and 06 */ - frame_type = XQC_TRANS_FRAME_TYPE_MP_ABANDON; - } else { + xqc_log(conn->log, XQC_LOG_DEBUG, "|multipath_version|%ui|", conn->conn_settings.multipath_version); + + if (conn->conn_settings.multipath_version < XQC_MULTIPATH_10) { return -XQC_EMP_INVALID_MP_VERTION; } + frame_type = XQC_TRANS_FRAME_TYPE_MP_ABANDON; + uint64_t reason_len = 0; uint8_t *reason = NULL; @@ -2529,7 +2529,7 @@ xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, xqc_int_t xqc_parse_path_abandon_frame(xqc_packet_in_t *packet_in, - uint64_t *path_id, uint64_t *error_code, uint8_t has_reason) + uint64_t *path_id, uint64_t *error_code, uint64_t has_reason) { unsigned char *p = packet_in->pos; const unsigned char *end = packet_in->last; diff --git a/src/transport/xqc_frame_parser.h b/src/transport/xqc_frame_parser.h index caec0e8d..8281e01a 100644 --- a/src/transport/xqc_frame_parser.h +++ b/src/transport/xqc_frame_parser.h @@ -144,7 +144,7 @@ ssize_t xqc_gen_path_abandon_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, uint64_t path_id, uint64_t error_code); xqc_int_t xqc_parse_path_abandon_frame(xqc_packet_in_t *packet_in, - uint64_t *path_id, uint64_t *error_code, uint8_t has_reason); + uint64_t *path_id, uint64_t *error_code, uint64_t has_reason); ssize_t xqc_gen_path_status_frame(xqc_connection_t *conn, xqc_packet_out_t *packet_out, From 95ce836cb8649cfbf8cb892ec5b9626c0e236b4f Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 20:30:30 +0800 Subject: [PATCH 06/36] [+] add path blocked trigger --- src/transport/xqc_engine.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index ecc57e9e..17a03283 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -739,6 +739,16 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) conn->conn_flag |= XQC_CONN_FLAG_MP_READY_NOTIFY; conn->conn_flag &= ~XQC_CONN_FLAG_MP_WAIT_MP_READY; } + + xqc_log(conn->log, XQC_LOG_DEBUG, "|create_path_count:%ui|remote_max_path_id:%ui|", + conn->create_path_count, conn->remote_max_path_id); + if (conn->create_path_count == conn->remote_max_path_id) { + conn->remote_max_path_id += (conn->remote_max_path_id + 1) / 2; + ret = xqc_write_path_blocked_to_packet(conn, conn->remote_max_path_id); + if (ret) { + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_path_blocked_to_packet error|"); + } + } } /* for multi-path */ From 0dae7ac9f2a635a1a7938b0e2c3e5225998ae5aa Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 20:38:35 +0800 Subject: [PATCH 07/36] [~] fix remote_max_path_id update --- src/transport/xqc_engine.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index 17a03283..b18d385f 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -743,7 +743,6 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) xqc_log(conn->log, XQC_LOG_DEBUG, "|create_path_count:%ui|remote_max_path_id:%ui|", conn->create_path_count, conn->remote_max_path_id); if (conn->create_path_count == conn->remote_max_path_id) { - conn->remote_max_path_id += (conn->remote_max_path_id + 1) / 2; ret = xqc_write_path_blocked_to_packet(conn, conn->remote_max_path_id); if (ret) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_path_blocked_to_packet error|"); From 4cbb87ab20b56063130a2be60c42f8e738d16561 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 29 Oct 2024 20:45:43 +0800 Subject: [PATCH 08/36] [+] update for remote_max_path_id and local_max_path_id --- src/transport/xqc_frame.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index cdd69d62..a9609fc1 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -2053,12 +2053,18 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i xqc_log(conn->log, XQC_LOG_DEBUG, "|max_path_id:%ui|pre_local_max_path_id:%ui|", max_path_id, conn->local_max_path_id); - if (conn->remote_max_path_id < max_path_id) { + if (conn->local_max_path_id < max_path_id) { xqc_log(conn->log, XQC_LOG_ERROR, "|invalid path blocked frame|"); return -XQC_EIGNORE_PKT; } + if (conn->local_max_path_id > max_path_id) { + xqc_log(conn->log, XQC_LOG_DEBUG, + "|received out-dated path blocked frame|local_max_path_id:%ui|max_path_id:%ui|", conn->local_max_path_id, max_path_id); + return XQC_OK; + } + conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; ret = xqc_write_max_path_id_to_packet(conn, conn->local_max_path_id); if (ret != XQC_OK) { From ea5184d45ba328846807cd95713f3c2b1c0f4e76 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 00:51:47 +0800 Subject: [PATCH 09/36] [+] limit that the path blocked could only sent by client side --- demo/demo_client.c | 6 ++++++ src/transport/xqc_engine.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/demo/demo_client.c b/demo/demo_client.c index cf408ac4..04f96d0b 100644 --- a/demo/demo_client.c +++ b/demo/demo_client.c @@ -1866,6 +1866,12 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args case 'a': printf("option addr :%s\n", optarg); snprintf(args->net_cfg.server_addr, sizeof(args->net_cfg.server_addr), optarg); + + /*if (strlen(args->net_cfg.server_addr) != 0) { + args->net_cfg.addr_len = strlen(args->net_cfg.server_addr); + memcpy(&args->net_cfg.addr, args->net_cfg.server_addr, args->net_cfg.addr_len); + printf("using address %s from option -a\n", args->net_cfg.server_addr); + }*/ break; /* server port */ diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index b18d385f..b29d4301 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -742,7 +742,9 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) xqc_log(conn->log, XQC_LOG_DEBUG, "|create_path_count:%ui|remote_max_path_id:%ui|", conn->create_path_count, conn->remote_max_path_id); - if (conn->create_path_count == conn->remote_max_path_id) { + if (conn->create_path_count == conn->remote_max_path_id + && conn->conn_type == XQC_CONN_TYPE_CLIENT) + { ret = xqc_write_path_blocked_to_packet(conn, conn->remote_max_path_id); if (ret) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_path_blocked_to_packet error|"); From 3889531e4d99cb528383c2103d59d02d4e259a19 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 01:39:19 +0800 Subject: [PATCH 10/36] =?UTF-8?q?[~]=20=E8=B0=83=E6=95=B4=E5=9B=BA?= =?UTF-8?q?=E5=AE=9A=E8=B7=AF=E5=BE=84=E9=99=90=E5=88=B6=E4=B8=BA=E5=BD=93?= =?UTF-8?q?=E5=89=8Dremote=E5=92=8Clocal=E6=9C=80=E5=B0=8F=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/transport/xqc_multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index 98fa7d13..804bb492 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -75,7 +75,7 @@ xqc_path_create(xqc_connection_t *conn, xqc_cid_t *scid, xqc_cid_t *dcid, uint64 { xqc_path_ctx_t *path = NULL; - if (conn->create_path_count >= XQC_MAX_PATHS_COUNT) { + if (conn->create_path_count > xqc_min(conn->local_max_path_id, conn->remote_max_path_id)) { xqc_log(conn->log, XQC_LOG_ERROR, "|too many paths|current maximum:%d|", XQC_MAX_PATHS_COUNT); return NULL; From 416c981c4e26925a26e13741f558d027224cec20 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 03:37:39 +0800 Subject: [PATCH 11/36] [+] raise up the limit for max paths --- include/xquic/xquic.h | 2 +- src/transport/xqc_frame.c | 4 ++-- src/transport/xqc_packet_out.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index 7b845276..f38e1aec 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -1457,7 +1457,7 @@ typedef enum { } xqc_0rtt_flag_t; -#define XQC_MAX_PATHS_COUNT 8 +#define XQC_MAX_PATHS_COUNT 32 #define XQC_CONN_INFO_LEN 400 typedef struct xqc_path_metrics_s { diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index a9609fc1..d5f2b904 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1803,9 +1803,9 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet return -XQC_EILLEGAL_FRAME; } - xqc_log(conn->log, XQC_LOG_DEBUG, "|new_conn_id|%s|sr_token:%s", + xqc_log(conn->log, XQC_LOG_DEBUG, "|new_conn_id|%s|sr_token:%s|path_id:%ui|", xqc_scid_str(conn->engine, &new_conn_cid), - xqc_sr_token_str(conn->engine, new_conn_cid.sr_token)); + xqc_sr_token_str(conn->engine, new_conn_cid.sr_token), path_id); if (retire_prior_to > new_conn_cid.cid_seq_num) { /* diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index bfc2a619..9ee37997 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1802,7 +1802,7 @@ xqc_write_max_path_id_to_packet(xqc_connection_t *conn, uint64_t max_path_id) ret = xqc_gen_max_path_id_frame(packet_out, max_path_id); if (ret < 0) { - xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_max_streams_frame error|"); + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_max_path_id_frame error|"); goto error; } packet_out->po_used_size += ret; @@ -1831,7 +1831,7 @@ xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id) ret = xqc_gen_path_blocked_frame(packet_out, max_path_id); if (ret < 0) { - xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_max_streams_frame error|"); + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_path_blocked_frame error|"); goto error; } packet_out->po_used_size += ret; From 25dd73d917a1c529ea11c8ec8959a5f5adf46711 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 04:15:41 +0800 Subject: [PATCH 12/36] [~] bug fix for xqc_cid_set_get_largest_seq_or_rpt --- include/xquic/xquic.h | 1 + src/transport/xqc_cid.c | 3 ++- src/transport/xqc_frame_parser.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index f38e1aec..198a79c9 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -1505,6 +1505,7 @@ typedef struct xqc_conn_stats_s { * 0: 不支持MP * 1: 支持MP, 采用 Single PNS * 2: 支持MP, 采用 Multiple PNS + * */ int enable_multipath; diff --git a/src/transport/xqc_cid.c b/src/transport/xqc_cid.c index d9eea4b4..11a2850a 100644 --- a/src/transport/xqc_cid.c +++ b/src/transport/xqc_cid.c @@ -248,7 +248,8 @@ xqc_cid_set_get_largest_seq_or_rpt(xqc_cid_set_t *cid_set, uint64_t path_id) if (inner_set) { return inner_set->largest_scid_seq_num; } - return XQC_ERROR; + /* if the path id is larger than expected, should return 0 here */ + return 0; } xqc_int_t diff --git a/src/transport/xqc_frame_parser.c b/src/transport/xqc_frame_parser.c index 2eaed895..d250a264 100644 --- a/src/transport/xqc_frame_parser.c +++ b/src/transport/xqc_frame_parser.c @@ -2832,7 +2832,7 @@ xqc_parse_mp_new_conn_id_frame(xqc_packet_in_t *packet_in, packet_in->pi_frame_types |= XQC_FRAME_BIT_MP_NEW_CONNECTION_ID; - xqc_log_event(conn->log, TRA_FRAMES_PROCESSED, XQC_FRAME_NEW_CONNECTION_ID, new_cid, retire_prior_to); + xqc_log_event(conn->log, TRA_FRAMES_PROCESSED, XQC_FRAME_MP_NEW_CONNECTION_ID, new_cid, retire_prior_to); return XQC_OK; } From d3b3daba3e1bd70d9f43daacae77a75f5286265f Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 04:39:08 +0800 Subject: [PATCH 13/36] [~] bugfix for xqc_cid_set_get_largest_seq_or_rpt --- src/transport/xqc_cid.c | 1 + src/transport/xqc_frame.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_cid.c b/src/transport/xqc_cid.c index 11a2850a..f2bfe775 100644 --- a/src/transport/xqc_cid.c +++ b/src/transport/xqc_cid.c @@ -142,6 +142,7 @@ xqc_cid_set_inner_init(xqc_cid_set_inner_t *cid_set_inner) xqc_memzero(cid_set_inner, sizeof(xqc_cid_set_inner_t)); xqc_init_list_head(&cid_set_inner->cid_list); xqc_init_list_head(&cid_set_inner->next); + cid_set_inner->largest_retire_prior_to = 0; } void diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index d5f2b904..75aa6ce1 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1781,7 +1781,8 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet { xqc_int_t ret = XQC_ERROR; xqc_cid_t new_conn_cid; - uint64_t retire_prior_to, curr_rpi; + uint64_t retire_prior_to; + int64_t curr_rpi; xqc_cid_inner_t *inner_cid; xqc_list_head_t *pos, *next; @@ -1821,6 +1822,9 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet /* TODO: write_retire_conn_id_frame 可能涉及到 替换 path.dcid (当前无 retire_prior_to 因此不涉及) */ curr_rpi = xqc_cid_set_get_largest_seq_or_rpt(&conn->dcid_set, path_id); + xqc_log(conn->log, XQC_LOG_DEBUG, "|new_conn_id|%s|path_id:%ui|prior:%ui|", + xqc_scid_str(conn->engine, &new_conn_cid), path_id, curr_rpi); + if (curr_rpi < 0) { xqc_log(conn->log, XQC_LOG_ERROR, "|current retire_prior_to error:%i|path:%ui|", curr_rpi, path_id); From d095a170abb3dded0ac4782bd13965b762f5bd96 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 04:41:39 +0800 Subject: [PATCH 14/36] [=] add more logs --- src/transport/xqc_frame.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 75aa6ce1..63d74dca 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1804,9 +1804,9 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet return -XQC_EILLEGAL_FRAME; } - xqc_log(conn->log, XQC_LOG_DEBUG, "|new_conn_id|%s|sr_token:%s|path_id:%ui|", + xqc_log(conn->log, XQC_LOG_DEBUG, "|new_conn_id|%s|sr_token:%s|path_id:%ui|prior:%ui|", xqc_scid_str(conn->engine, &new_conn_cid), - xqc_sr_token_str(conn->engine, new_conn_cid.sr_token), path_id); + xqc_sr_token_str(conn->engine, new_conn_cid.sr_token), path_id, retire_prior_to); if (retire_prior_to > new_conn_cid.cid_seq_num) { /* From 22e2ddb6de5b3ef81aa43be6a5447cc54789b557 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Sun, 3 Nov 2024 13:18:31 +0000 Subject: [PATCH 15/36] [+] fix path block trigger xqc_conn_add_path_cid_sets --- demo/demo_client.c | 65 +++++++++++++++++++++++++++++++-------- src/transport/xqc_conn.c | 6 ++-- src/transport/xqc_conn.h | 2 +- src/transport/xqc_frame.c | 12 ++++++-- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/demo/demo_client.c b/demo/demo_client.c index 04f96d0b..c5318070 100644 --- a/demo/demo_client.c +++ b/demo/demo_client.c @@ -40,7 +40,7 @@ #define XQC_PACKET_TMP_BUF_LEN 1600 #define MAX_BUF_SIZE (100*1024*1024) #define XQC_INTEROP_TLS_GROUPS "X25519:P-256:P-384:P-521" -#define MAX_PATH_CNT 2 +#define MAX_PATH_CNT 16 typedef enum xqc_demo_cli_alpn_type_s { @@ -183,6 +183,7 @@ typedef struct xqc_demo_cli_quic_config_s { uint8_t mp_version; uint64_t init_max_path_id; + uint64_t extra_paths_num; /* support interop test */ int is_interop_mode; @@ -858,16 +859,47 @@ xqc_demo_cli_conn_create_path(const xqc_cid_t *cid, void *conn_user_data) xqc_demo_cli_user_conn_t *user_conn = conn_user_data; xqc_demo_cli_ctx_t *ctx = user_conn->ctx; uint64_t path_id; - int ret; + int ret, i; int backup = 0; - printf("ready to create path notify\n"); + printf("ready to create path notify: trying to create %"PRIu64" paths, current path %i, ifcnt: %i, init_max_path_id: %"PRIu64"\n", + ctx->args->quic_cfg.extra_paths_num, + user_conn->total_path_cnt, + ctx->args->net_cfg.ifcnt, + ctx->args->quic_cfg.init_max_path_id); - if (user_conn->total_path_cnt < ctx->args->net_cfg.ifcnt - && user_conn->total_path_cnt < ctx->args->quic_cfg.init_max_path_id) - { + for (i = 0; i < ctx->args->quic_cfg.extra_paths_num; i++) { + + if (user_conn->total_path_cnt < ctx->args->net_cfg.ifcnt + && user_conn->total_path_cnt <= ctx->args->quic_cfg.init_max_path_id) + { + + if (user_conn->total_path_cnt == 1 && ctx->args->quic_cfg.mp_backup) { + backup = 1; + } + + ret = xqc_conn_create_path(ctx->engine, &(user_conn->cid), &path_id, backup); + if (ret < 0) { + printf("not support mp, xqc_conn_create_path err = %d path_id: %"PRIu64"\n", ret, path_id); + return; + } + + printf("client created path: path_id %"PRIu64"\n", path_id); + + ret = xqc_demo_cli_init_user_path(user_conn, user_conn->total_path_cnt, path_id); + if (ret < 0) { + xqc_conn_close_path(ctx->engine, &(user_conn->cid), path_id); + return; + } + + user_conn->path_create_time = xqc_now(); - if (user_conn->total_path_cnt == 1 && ctx->args->quic_cfg.mp_backup) { - backup = 1; + if (user_conn->total_path_cnt == 2 && ctx->args->quic_cfg.mp_backup) { + if (backup == 1) { + printf("Init No.%d path (id = %"PRIu64") to STANDBY state\n", 1, path_id); + } + printf("set No.%d path (id = %"PRIu64") to STANDBY state\n", 1, path_id); + xqc_conn_mark_path_standby(ctx->engine, &(user_conn->cid), path_id); + } } ret = xqc_conn_create_path(ctx->engine, &(user_conn->cid), &path_id, backup); @@ -892,7 +924,6 @@ xqc_demo_cli_conn_create_path(const xqc_cid_t *cid, void *conn_user_data) printf("set No.%d path (id = %"PRIu64") to STANDBY state\n", 1, path_id); xqc_conn_mark_path_standby(ctx->engine, &(user_conn->cid), path_id); } - } } @@ -1727,6 +1758,7 @@ xqc_demo_cli_init_args(xqc_demo_cli_client_args_t *args) args->quic_cfg.mp_version = XQC_MULTIPATH_10; args->quic_cfg.init_max_path_id = 2; args->quic_cfg.max_pkt_sz = 1200; + args->quic_cfg.extra_paths_num = 1; args->req_cfg.throttled_req = -1; @@ -1745,7 +1777,7 @@ xqc_demo_cli_parse_server_addr(char *url, xqc_demo_cli_net_config_t *cfg) /* set hint for hostname resolve */ struct addrinfo hints = {0}; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_family = AF_INET; //AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ @@ -1860,7 +1892,7 @@ void xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args) { int ch = 0; - while ((ch = getopt(argc, argv, "a:p:c:Ct:S:0m:A:D:l:L:k:K:U:u:dMoi:w:Ps:bZ:NQT:R:V:B:I:n:eEF:G:r:x:y:Y:f:")) != -1) { + while ((ch = getopt(argc, argv, "a:p:c:Ct:S:0m:A:D:l:L:k:K:U:u:dMoi:w:Ps:bZ:NQT:R:V:B:I:n:eEF:G:r:x:X:y:Y:f:")) != -1) { switch (ch) { /* server ip */ case 'a': @@ -2019,10 +2051,11 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args printf("option adding interface: %s\n", optarg); if (args->net_cfg.ifcnt < MAX_PATH_CNT) { strncpy(args->net_cfg.iflist[args->net_cfg.ifcnt++], optarg, strlen(optarg)); - } else { + } + /*} else { printf("too many interfaces (two at most)!\n"); exit(0); - } + }*/ break; case 'w': @@ -2081,6 +2114,12 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args args->quic_cfg.path_status_timer_threshold = atoi(optarg) * 1000; break; + case 'X': + printf("option create path numbers: %s\n", optarg); + args->quic_cfg.extra_paths_num = atoi(optarg); + args->quic_cfg.init_max_path_id = args->quic_cfg.extra_paths_num; + break; + case 'I': printf("option idle gap: %s\n", optarg); args->req_cfg.idle_gap = atoi(optarg); diff --git a/src/transport/xqc_conn.c b/src/transport/xqc_conn.c index ab3c189e..64d6c152 100644 --- a/src/transport/xqc_conn.c +++ b/src/transport/xqc_conn.c @@ -3790,10 +3790,10 @@ xqc_conn_update_flow_ctl_settings(xqc_connection_t *conn) } xqc_int_t -xqc_conn_add_path_cid_sets(xqc_connection_t *conn, uint32_t start, uint32_t end) +xqc_conn_add_path_cid_sets(xqc_connection_t *conn, uint64_t start, uint64_t end) { if (conn->enable_multipath) { - uint32_t path_id; + uint64_t path_id; xqc_int_t ret; /* add cid_set_inner for all paths */ for (path_id = start; path_id <= end; path_id++) { @@ -4623,7 +4623,7 @@ xqc_conn_get_available_path_id(xqc_connection_t *conn, uint64_t *path_id) /* principle: the next unused path ID has at least one unused DCID and one acked unused SCID */ xqc_cid_set_inner_t *scid_inner_set = xqc_get_next_unused_path_cid_set(&conn->scid_set); if (scid_inner_set) { - xqc_cid_set_inner_t *dcid_inner_set = xqc_get_path_cid_set(&conn->scid_set, scid_inner_set->path_id); + xqc_cid_set_inner_t *dcid_inner_set = xqc_get_path_cid_set(&conn->dcid_set, scid_inner_set->path_id); if (dcid_inner_set) { if (dcid_inner_set->unused_cnt > 0 && scid_inner_set->acked_unused > 0) { if (path_id) { diff --git a/src/transport/xqc_conn.h b/src/transport/xqc_conn.h index 73a8bef4..d1d91058 100644 --- a/src/transport/xqc_conn.h +++ b/src/transport/xqc_conn.h @@ -694,7 +694,7 @@ void xqc_path_send_packets(xqc_connection_t *conn, xqc_path_ctx_t *path, xqc_list_head_t *head, int congest, xqc_send_type_t send_type); xqc_int_t xqc_conn_try_to_enable_multipath(xqc_connection_t *conn); -xqc_int_t xqc_conn_add_path_cid_sets(xqc_connection_t *conn, uint32_t start, uint32_t end); +xqc_int_t xqc_conn_add_path_cid_sets(xqc_connection_t *conn, uint64_t start, uint64_t end); #endif /* _XQC_CONN_H_INCLUDED_ */ diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 63d74dca..066c8be2 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1911,11 +1911,11 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet conn->local_settings.active_connection_id_limit, path_id); if (ret != XQC_OK) { - xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_cid_set_insert_cid error|limit:%ui|unused:%i|used:%i|path:%ui|", + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_cid_set_insert_cid error|limit:%ui|unused:%i|used:%i|path:%ui|ret:%i|", conn->local_settings.active_connection_id_limit, xqc_cid_set_get_unused_cnt(&conn->dcid_set, path_id), xqc_cid_set_get_used_cnt(&conn->dcid_set, path_id), - path_id); + path_id, ret); return ret; } @@ -2069,11 +2069,17 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i return XQC_OK; } + uint64_t pre_max_path_id = conn->local_max_path_id; conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; + if (xqc_conn_add_path_cid_sets(conn, pre_max_path_id + 1, conn->local_max_path_id) != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, "|add_path_cid_sets_error|"); + return -XQC_EMALLOC; + } + ret = xqc_write_max_path_id_to_packet(conn, conn->local_max_path_id); if (ret != XQC_OK) { xqc_log(conn->log, XQC_LOG_ERROR, - "|xqc_process_path_blocked_frame error|"); + "|xqc_write_max_path_id_to_packet error|"); return ret; } From 3d68c714ff4f08547e94ff8937ab85414ccd6cdf Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 13:28:10 +0800 Subject: [PATCH 16/36] [+] add support for draft-11 error codes and cid rotation --- demo/demo_client.c | 91 +++++++++++++++++-- include/xquic/xqc_configure.h | 5 ++ include/xquic/xqc_errno.h | 6 ++ include/xquic/xquic.h | 7 +- src/transport/xqc_frame.c | 3 +- src/transport/xqc_multipath.c | 156 +++++++++++++++++++++++++++++++++ src/transport/xqc_multipath.h | 4 + src/transport/xqc_packet_out.c | 2 +- 8 files changed, 264 insertions(+), 10 deletions(-) diff --git a/demo/demo_client.c b/demo/demo_client.c index c5318070..b94d357c 100644 --- a/demo/demo_client.c +++ b/demo/demo_client.c @@ -191,6 +191,9 @@ typedef struct xqc_demo_cli_quic_config_s { uint8_t send_path_standby; xqc_msec_t path_status_timer_threshold; + xqc_msec_t path_cid_rotation; + xqc_msec_t path_cid_retirement; + uint64_t least_available_cid_count; uint64_t idle_timeout; @@ -420,6 +423,8 @@ typedef struct xqc_demo_cli_user_conn_s { struct event *ev_delay_req; struct event *ev_idle_restart; struct event *ev_close_path; + struct event *ev_cid_rotation; + struct event *ev_path_cid_retirement; struct event *ev_rebinding_p0; struct event *ev_rebinding_p1; @@ -431,6 +436,8 @@ typedef struct xqc_demo_cli_user_conn_s { xqc_msec_t path_status_time; xqc_msec_t path_status_timer_threshold; + int trigger_cid_rotation; + xqc_msec_t cid_rotation_timer_threshold; xqc_msec_t path_create_time; xqc_flag_t remove_path_flag; @@ -496,6 +503,11 @@ xqc_demo_cli_close_task(xqc_demo_cli_task_t *task) user_conn->ev_close_path = NULL; } + if (user_conn->ev_cid_rotation) { + event_del(user_conn->ev_cid_rotation); + user_conn->ev_cid_rotation = NULL; + } + if (user_conn->ev_rebinding_p0) { event_del(user_conn->ev_rebinding_p0); user_conn->ev_rebinding_p0 = NULL; @@ -887,6 +899,7 @@ xqc_demo_cli_conn_create_path(const xqc_cid_t *cid, void *conn_user_data) ret = xqc_demo_cli_init_user_path(user_conn, user_conn->total_path_cnt, path_id); if (ret < 0) { + printf("xqc_demo_cli_init_user_path fail: path_id %"PRIu64"\n", path_id); xqc_conn_close_path(ctx->engine, &(user_conn->cid), path_id); return; } @@ -1498,6 +1511,11 @@ xqc_demo_cli_idle_callback(int fd, short what, void *arg) user_conn->ev_close_path = NULL; } + if (user_conn->ev_cid_rotation) { + event_del(user_conn->ev_cid_rotation); + user_conn->ev_cid_rotation = NULL; + } + if (user_conn->ev_rebinding_p0) { event_del(user_conn->ev_rebinding_p0); user_conn->ev_rebinding_p0 = NULL; @@ -1570,6 +1588,39 @@ xqc_demo_cli_close_path_timeout(int fd, short what, void *arg) } } +static void +xqc_demo_cli_trigger_path_cid_rotation(int fd, short what, void *arg) +{ + xqc_demo_cli_user_conn_t *user_conn = (xqc_demo_cli_user_conn_t *) arg; + printf("xqc_demo_cli_cid_rotation: active path: %d\n", user_conn->active_path_cnt); + if (user_conn->active_path_cnt > 0) { + uint64_t path_id = 1; + printf("trigger cid rotation on path: path_id %"PRIu64"\n", path_id); + int ret = xqc_conn_trigger_cid_rotation_on_path(user_conn->ctx->engine, &(user_conn->cid), path_id); + if (ret != XQC_OK) { + printf("trigger cid rotation on path: path_id %"PRIu64" failed\n", path_id); + } else { + user_conn->trigger_cid_rotation = 1; + } + } +} + +static void +xqc_demo_cli_trigger_path_cid_retirment(int fd, short what, void *arg) +{ + xqc_demo_cli_user_conn_t *user_conn = (xqc_demo_cli_user_conn_t *) arg; + uint64_t path_id = 1; + + if (!user_conn->trigger_cid_rotation) { + printf("can't trigger cid retirement on path: path_id %"PRIu64" because the cid rotation failed\n", path_id); + return; + } + + printf("trigger cid retirement on path: path_id %"PRIu64"\n", path_id); + xqc_conn_trigger_cid_retirement_on_path(user_conn->ctx->engine, &(user_conn->cid), path_id); +} + + static void xqc_demo_cli_rebind_path0(int fd, short what, void *arg) { @@ -1892,18 +1943,12 @@ void xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args) { int ch = 0; - while ((ch = getopt(argc, argv, "a:p:c:Ct:S:0m:A:D:l:L:k:K:U:u:dMoi:w:Ps:bZ:NQT:R:V:B:I:n:eEF:G:r:x:X:y:Y:f:")) != -1) { + while ((ch = getopt(argc, argv, "a:p:c:Ct:S:0m:A:D:l:L:k:K:U:u:dMoi:w:Ps:bz:Z:NQT:R:V:B:I:n:eEF:g:G:r:x:X:y:Y:f:")) != -1) { switch (ch) { /* server ip */ case 'a': printf("option addr :%s\n", optarg); snprintf(args->net_cfg.server_addr, sizeof(args->net_cfg.server_addr), optarg); - - /*if (strlen(args->net_cfg.server_addr) != 0) { - args->net_cfg.addr_len = strlen(args->net_cfg.server_addr); - memcpy(&args->net_cfg.addr, args->net_cfg.server_addr, args->net_cfg.addr_len); - printf("using address %s from option -a\n", args->net_cfg.server_addr); - }*/ break; /* server port */ @@ -2114,6 +2159,16 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args args->quic_cfg.path_status_timer_threshold = atoi(optarg) * 1000; break; + case 'z': + printf("option multipath trigger cid rotation: %s ms\n", optarg); + args->quic_cfg.path_cid_rotation = atoi(optarg); + break; + + case 'g': + printf("option force a cid rotation after %s ms\n", optarg); + args->quic_cfg.path_cid_retirement = atoi(optarg); + break; + case 'X': printf("option create path numbers: %s\n", optarg); args->quic_cfg.extra_paths_num = atoi(optarg); @@ -2670,6 +2725,28 @@ xqc_demo_cli_start(xqc_demo_cli_user_conn_t *user_conn, xqc_demo_cli_client_args event_add(user_conn->ev_close_path, &tv); } + if (args->quic_cfg.path_cid_rotation) { + user_conn->ev_cid_rotation = event_new(user_conn->ctx->eb, -1, 0, + xqc_demo_cli_trigger_path_cid_rotation, + user_conn); + struct timeval tv = { + .tv_sec = args->quic_cfg.path_cid_rotation / 1000, + .tv_usec = (args->quic_cfg.path_cid_rotation % 1000) * 1000, + }; + event_add(user_conn->ev_cid_rotation, &tv); + } + + if (args->quic_cfg.path_cid_retirement) { + user_conn->ev_path_cid_retirement = event_new(user_conn->ctx->eb, -1, 0, + xqc_demo_cli_trigger_path_cid_retirment, + user_conn); + struct timeval tv = { + .tv_sec = args->quic_cfg.path_cid_retirement / 1000, + .tv_usec = (args->quic_cfg.path_cid_retirement % 1000) * 1000, + }; + event_add(user_conn->ev_path_cid_retirement, &tv); + } + if (args->net_cfg.rebind_p0) { user_conn->ev_rebinding_p0 = event_new(user_conn->ctx->eb, -1, 0, xqc_demo_cli_rebind_path0, diff --git a/include/xquic/xqc_configure.h b/include/xquic/xqc_configure.h index fa13e49b..2ef3e9d4 100644 --- a/include/xquic/xqc_configure.h +++ b/include/xquic/xqc_configure.h @@ -9,3 +9,8 @@ /* #undef XQC_ENABLE_MP_INTEROP */ /* #undef XQC_NO_PID_PACKET_PROCESS */ /* #undef XQC_PROTECT_POOL_MEM */ +/* #undef XQC_COMPAT_DUPLICATE */ +/* #undef XQC_ENABLE_FEC */ +/* #undef XQC_ENABLE_XOR */ +/* #undef XQC_ENABLE_RSC */ +/* #undef XQC_ENABLE_PKM */ diff --git a/include/xquic/xqc_errno.h b/include/xquic/xqc_errno.h index 894f1c9d..e4292deb 100644 --- a/include/xquic/xqc_errno.h +++ b/include/xquic/xqc_errno.h @@ -279,6 +279,12 @@ typedef enum { XQC_QPACK_ERR_MAX, } xqc_qpack_error_t; +typedef enum { + XQC_PATH_NO_ERROR = 0x0, + XQC_PATH_APPLICATION_ABANDON = 0x004150504142414E, /* Path abandon error code: APPLICATION_ABANDON */ + XQC_PATH_RESOURCE_LIMIT_REACHED = 0x0052534C494D4954, /* Path abandon error code: RESOURCE_LIMIT_REACHED */ +} xqc_multipath_error_t; + #define QPACK_ERR_START 900 static const int QPACK_ERR_CNT = XQC_QPACK_ERR_MAX - QPACK_ERR_START; diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index 198a79c9..5c946dcd 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -2141,7 +2141,12 @@ XQC_EXPORT_PUBLIC_API xqc_int_t xqc_path_get_local_addr(xqc_connection_t *conn, uint64_t path_id, struct sockaddr *addr, socklen_t addr_cap, socklen_t *local_addr_len); - + +XQC_EXPORT_PUBLIC_API +xqc_int_t xqc_conn_trigger_cid_rotation_on_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t path_id); + +XQC_EXPORT_PUBLIC_API +xqc_int_t xqc_conn_trigger_cid_retirement_on_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t path_id); /** * @brief load balance cid encryption. diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 066c8be2..b65239b4 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -1723,7 +1723,8 @@ xqc_process_path_abandon_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i } } - xqc_log(conn->log, XQC_LOG_DEBUG, "|path:%ui|state:%d|err_code:%ui|", path->path_id, path->path_state, error_code); + xqc_log(conn->log, XQC_LOG_DEBUG, "|path:%ui|state:%d|err_code:%ui|", path->path_id, path->path_state, + error_code); return XQC_OK; } diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index 804bb492..974f9198 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -139,6 +139,8 @@ xqc_path_create(xqc_connection_t *conn, xqc_cid_t *scid, xqc_cid_t *dcid, uint64 xqc_cid_copy(&(path->path_dcid), dcid); } + xqc_cid_copy(&path->path_last_dcid, &path->path_dcid); + xqc_cid_set_update_state(&conn->dcid_set, path_id, XQC_CID_SET_USED); xqc_cid_set_update_state(&conn->scid_set, path_id, XQC_CID_SET_USED); @@ -516,6 +518,7 @@ xqc_conn_close_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t closed return -XQC_EMP_NO_ACTIVE_PATH; } + path->path_err_code = XQC_PATH_APPLICATION_ABANDON; xqc_int_t ret = xqc_path_immediate_close(path); if (ret != XQC_OK) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_path_immediate_close error|%d|", ret); @@ -1488,4 +1491,157 @@ xqc_path_recent_loss_rate(xqc_path_ctx_t *path) } return xqc_max(loss_rate0, loss_rate1); +} + + +xqc_int_t +xqc_path_cid_rotate(xqc_path_ctx_t *path, uint64_t path_id) +{ + xqc_int_t ret = XQC_ERROR; + xqc_connection_t *conn = path->parent_conn; + xqc_cid_t new_dcid; + xqc_cid_inner_t *new_dcid_inner; + ret = xqc_get_unused_cid(&conn->dcid_set, &new_dcid, path_id); + + if (ret != XQC_OK) { + xqc_log(path->parent_conn->log, XQC_LOG_ERROR, "|xqc_get_unused_cid err|path_id:%ui|", path_id); + return -XQC_EMP_NO_AVAILABLE_CID_FOR_PATH; + } + + xqc_log(path->parent_conn->log, XQC_LOG_DEBUG, "|xqc_conn_trigger_cid_rotation_on_path|path_id:%ui|new_dcid:%s|old_dcid:%s|", + path_id, + xqc_dcid_str(conn->engine,&new_dcid), + xqc_scid_str(conn->engine,&path->path_dcid)); + + xqc_cid_copy(&path->path_last_dcid, &path->path_dcid); + xqc_cid_copy(&path->path_dcid, &new_dcid); + new_dcid_inner = xqc_cid_in_cid_set(&conn->dcid_set, &new_dcid, path_id); + xqc_cid_switch_to_next_state(&conn->dcid_set, new_dcid_inner, XQC_CID_USED, path_id); + + return XQC_OK; +} + + +xqc_int_t +xqc_conn_trigger_cid_rotation_on_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t path_id) +{ + xqc_connection_t *conn = NULL; + xqc_path_ctx_t *path = NULL; + + xqc_log(engine->log, XQC_LOG_DEBUG, "|scid:%s|path_id:%ui|", xqc_scid_str(engine, scid), path_id); + + conn = xqc_engine_conns_hash_find(engine, scid, 's'); + if (!conn) { + xqc_log(engine->log, XQC_LOG_ERROR, "|can not find connection|"); + return -XQC_ECONN_NFOUND; + } + if (conn->conn_state >= XQC_CONN_STATE_CLOSING) { + return -XQC_CLOSING; + } + + /* check mp-support */ + if (!conn->enable_multipath) { + xqc_log(engine->log, XQC_LOG_WARN, + "|Multipath is not supported in connection|%p|", conn); + return -XQC_EMP_NOT_SUPPORT_MP; + } + + /* abandon path */ + path = xqc_conn_find_path_by_path_id(conn, path_id); + if (path == NULL) { + xqc_log(engine->log, XQC_LOG_WARN, + "|path is not found by path_id in connection|%p|%ui|", + conn, path_id); + return -XQC_EMP_PATH_NOT_FOUND; + } + + xqc_int_t ret = xqc_path_cid_rotate(path, path_id); + if (ret != XQC_OK) { + xqc_log(engine->log, XQC_LOG_WARN, + "|xqc_path_cid_rotate error|scid:%s|path_id:%ui|", xqc_scid_str(engine, scid), path_id); + } + + return ret; +} + + +xqc_int_t +xqc_path_last_cid_retirement(xqc_path_ctx_t *path, uint64_t path_id) +{ + xqc_connection_t *conn = path->parent_conn; + xqc_engine_t *engine = conn->engine; + + xqc_int_t ret = XQC_ERROR; + if (path->path_last_dcid.cid_seq_num == path->path_dcid.cid_seq_num) { + xqc_log(path->parent_conn->log, XQC_LOG_ERROR, "|retiring the same dcid which path is still using|path_id:%ui|new_dcid:%s|old_dcid:%s|", path_id, + xqc_dcid_str(engine, &path->path_dcid), + xqc_scid_str(engine, &path->path_last_dcid)); + return XQC_ERROR; + } + + xqc_log(path->parent_conn->log, XQC_LOG_DEBUG, "|xqc_conn_trigger_cid_retirement_on_path|path_id:%ui|new_dcid:%s|old_dcid:%s|old_seq:%ui|", path_id, + xqc_dcid_str(engine, &path->path_dcid), + xqc_scid_str(engine, &path->path_last_dcid), + path->path_last_dcid.cid_seq_num); + + ret = xqc_write_mp_retire_conn_id_frame_to_packet(path->parent_conn, path->path_last_dcid.cid_seq_num, path_id); + if (ret != XQC_OK) { + xqc_log(path->parent_conn->log, XQC_LOG_ERROR, "|xqc_write_retire_conn_id_frame_to_packet error|"); + return ret; + } + + xqc_cid_inner_t *last_dcid = xqc_get_inner_cid_by_seq(&conn->dcid_set, path->path_last_dcid.cid_seq_num, path_id); + if (last_dcid == NULL) { + xqc_log(path->parent_conn->log, XQC_LOG_ERROR, "|can't get inner cid by seq|path_id:%ui|seq:%ui|", path_id, path->path_last_dcid.cid_seq_num); + return ret; + } + + xqc_cid_switch_to_next_state(&conn->dcid_set, last_dcid, XQC_CID_RETIRED, path_id); + + + return XQC_OK; +} + + +/* trigger the last dcid to be retired */ +xqc_int_t +xqc_conn_trigger_cid_retirement_on_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t path_id) +{ + xqc_connection_t *conn = NULL; + xqc_path_ctx_t *path = NULL; + + xqc_log(engine->log, XQC_LOG_DEBUG, "|scid:%s|path_id:%ui|", xqc_scid_str(engine, scid), path_id); + + conn = xqc_engine_conns_hash_find(engine, scid, 's'); + if (!conn) { + xqc_log(engine->log, XQC_LOG_ERROR, "|can not find connection|"); + return -XQC_ECONN_NFOUND; + } + if (conn->conn_state >= XQC_CONN_STATE_CLOSING) { + return -XQC_CLOSING; + } + + /* check mp-support */ + if (!conn->enable_multipath) { + xqc_log(engine->log, XQC_LOG_WARN, + "|Multipath is not supported in connection|%p|", conn); + return -XQC_EMP_NOT_SUPPORT_MP; + } + + /* abandon path */ + path = xqc_conn_find_path_by_path_id(conn, path_id); + if (path == NULL) { + xqc_log(engine->log, XQC_LOG_WARN, + "|path is not found by path_id in connection|%p|%ui|", + conn, path_id); + return -XQC_EMP_PATH_NOT_FOUND; + } + + xqc_int_t ret = xqc_path_last_cid_retirement(path, path_id); + if (ret != XQC_OK) { + xqc_log(engine->log, XQC_LOG_WARN, + "|xqc_path_last_cid_retirement error|scid:%s|path_id:%ui|", xqc_scid_str(engine, scid), path_id); + } + + return ret; } \ No newline at end of file diff --git a/src/transport/xqc_multipath.h b/src/transport/xqc_multipath.h index d387630b..b203b410 100644 --- a/src/transport/xqc_multipath.h +++ b/src/transport/xqc_multipath.h @@ -91,6 +91,9 @@ struct xqc_path_ctx_s { uint64_t path_id; /* path identifier */ xqc_cid_t path_scid; xqc_cid_t path_dcid; + xqc_cid_t path_last_dcid; + + xqc_multipath_error_t path_err_code; /* Path_address: 4-tuple */ unsigned char peer_addr[sizeof(struct sockaddr_in6)], @@ -255,6 +258,7 @@ double xqc_path_recent_loss_rate(xqc_path_ctx_t *path); double xqc_conn_recent_loss_rate(xqc_connection_t *conn); + #endif /* XQC_MULTIPATH_H */ diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 9ee37997..41832dd5 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1570,7 +1570,7 @@ xqc_write_path_abandon_frame_to_packet(xqc_connection_t *conn, xqc_path_ctx_t *p uint64_t path_id = path->path_id; - ret = xqc_gen_path_abandon_frame(conn, packet_out, path_id, 0); + ret = xqc_gen_path_abandon_frame(conn, packet_out, path_id, (uint64_t)path->path_err_code); if (ret < 0) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_path_abandon_frame error|%d|", ret); goto error; From 0ae0a78ebf508aa0e65ebd9e300d2ed91982bead Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 19:43:23 +0800 Subject: [PATCH 17/36] [=] remove unused code --- src/transport/xqc_cid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transport/xqc_cid.c b/src/transport/xqc_cid.c index f2bfe775..11a2850a 100644 --- a/src/transport/xqc_cid.c +++ b/src/transport/xqc_cid.c @@ -142,7 +142,6 @@ xqc_cid_set_inner_init(xqc_cid_set_inner_t *cid_set_inner) xqc_memzero(cid_set_inner, sizeof(xqc_cid_set_inner_t)); xqc_init_list_head(&cid_set_inner->cid_list); xqc_init_list_head(&cid_set_inner->next); - cid_set_inner->largest_retire_prior_to = 0; } void From e7935eb09c813db6b7cb3a34b3d64b8905c267b3 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 19:45:17 +0800 Subject: [PATCH 18/36] [=] remove unused code --- src/transport/xqc_multipath.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index 974f9198..f21e7bb8 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -1515,8 +1515,6 @@ xqc_path_cid_rotate(xqc_path_ctx_t *path, uint64_t path_id) xqc_cid_copy(&path->path_last_dcid, &path->path_dcid); xqc_cid_copy(&path->path_dcid, &new_dcid); - new_dcid_inner = xqc_cid_in_cid_set(&conn->dcid_set, &new_dcid, path_id); - xqc_cid_switch_to_next_state(&conn->dcid_set, new_dcid_inner, XQC_CID_USED, path_id); return XQC_OK; } From 2fd8e794ff4393306d694b75b46a85a2b50c9b8d Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:30:09 +0800 Subject: [PATCH 19/36] [+] add resource limit for max path id update --- src/transport/xqc_conn.c | 4 ++++ src/transport/xqc_conn.h | 1 + src/transport/xqc_frame.c | 16 ++++------------ src/transport/xqc_multipath.c | 32 ++++++++++++++++++++++++++++++++ src/transport/xqc_multipath.h | 2 ++ 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/transport/xqc_conn.c b/src/transport/xqc_conn.c index 64d6c152..d5ded67b 100644 --- a/src/transport/xqc_conn.c +++ b/src/transport/xqc_conn.c @@ -736,6 +736,10 @@ xqc_conn_create(xqc_engine_t *engine, xqc_cid_t *dcid, xqc_cid_t *scid, xc->conn_settings.init_max_path_id = XQC_DEFAULT_INIT_MAX_PATH_ID; } + if (xc->max_paths_count == 0) { + xc->max_paths_count = XQC_MAX_PATHS_COUNT; + } + if (xc->conn_settings.probing_pkt_out_size == 0) { xc->conn_settings.probing_pkt_out_size = engine->default_conn_settings.probing_pkt_out_size; } diff --git a/src/transport/xqc_conn.h b/src/transport/xqc_conn.h index d1d91058..f01874f0 100644 --- a/src/transport/xqc_conn.h +++ b/src/transport/xqc_conn.h @@ -373,6 +373,7 @@ struct xqc_connection_s { uint32_t create_path_count; uint32_t validated_path_count; uint32_t active_path_count; + uint64_t max_paths_count; uint64_t curr_max_path_id; uint64_t local_max_path_id; diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index b65239b4..1ca5bddd 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -2070,18 +2070,10 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i return XQC_OK; } - uint64_t pre_max_path_id = conn->local_max_path_id; - conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; - if (xqc_conn_add_path_cid_sets(conn, pre_max_path_id + 1, conn->local_max_path_id) != XQC_OK) { - xqc_log(conn->log, XQC_LOG_ERROR, "|add_path_cid_sets_error|"); - return -XQC_EMALLOC; - } - - ret = xqc_write_max_path_id_to_packet(conn, conn->local_max_path_id); - if (ret != XQC_OK) { - xqc_log(conn->log, XQC_LOG_ERROR, - "|xqc_write_max_path_id_to_packet error|"); - return ret; + if (xqc_conn_check_path_id_blocked(conn) /* check whether all path ids have been used */ + && (uint64_t)conn->create_path_count < conn->max_paths_count) /* check whether touched path resource limit */ + { + ret = xqc_conn_update_max_path_id(conn); } return ret; diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index f21e7bb8..a0577f50 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -1641,5 +1641,37 @@ xqc_conn_trigger_cid_retirement_on_path(xqc_engine_t *engine, const xqc_cid_t *s "|xqc_path_last_cid_retirement error|scid:%s|path_id:%ui|", xqc_scid_str(engine, scid), path_id); } + return ret; +} + +xqc_bool_t +xqc_conn_check_path_id_blocked(xqc_connection_t *conn) +{ + if (conn->create_path_count >= conn->local_max_path_id + 1) { + return XQC_TRUE; + } + + return XQC_FALSE; +} + +xqc_int_t +xqc_conn_update_max_path_id(xqc_connection_t *conn) +{ + xqc_int_t ret = XQC_OK; + uint64_t pre_max_path_id = conn->local_max_path_id; + conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; + conn->local_max_path_id = xqc_max(conn->local_max_path_id, conn->max_paths_count); + if (xqc_conn_add_path_cid_sets(conn, pre_max_path_id + 1, conn->local_max_path_id) != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, "|add_path_cid_sets_error|"); + return -XQC_EMALLOC; + } + + ret = xqc_write_max_path_id_to_packet(conn, conn->local_max_path_id); + if (ret != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|xqc_write_max_path_id_to_packet error|"); + return ret; + } + return ret; } \ No newline at end of file diff --git a/src/transport/xqc_multipath.h b/src/transport/xqc_multipath.h index b203b410..249743bb 100644 --- a/src/transport/xqc_multipath.h +++ b/src/transport/xqc_multipath.h @@ -258,6 +258,8 @@ double xqc_path_recent_loss_rate(xqc_path_ctx_t *path); double xqc_conn_recent_loss_rate(xqc_connection_t *conn); +xqc_bool_t xqc_conn_check_path_id_blocked(xqc_connection_t *conn); +xqc_int_t xqc_conn_update_max_path_id(xqc_connection_t *conn); #endif /* XQC_MULTIPATH_H */ From f16e2528bcf7de56a5fafa602936b7c0899797e3 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:44:43 +0800 Subject: [PATCH 20/36] [~] adjust return value and fix old bug of casting --- src/transport/xqc_cid.c | 2 +- src/transport/xqc_frame.c | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/transport/xqc_cid.c b/src/transport/xqc_cid.c index 11a2850a..a274b4c1 100644 --- a/src/transport/xqc_cid.c +++ b/src/transport/xqc_cid.c @@ -249,7 +249,7 @@ xqc_cid_set_get_largest_seq_or_rpt(xqc_cid_set_t *cid_set, uint64_t path_id) return inner_set->largest_scid_seq_num; } /* if the path id is larger than expected, should return 0 here */ - return 0; + return XQC_ERROR; } xqc_int_t diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 1ca5bddd..4ce9f1a7 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -789,7 +789,8 @@ xqc_process_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in { xqc_int_t ret = XQC_ERROR; xqc_cid_t new_conn_cid; - uint64_t retire_prior_to, curr_rpi; + uint64_t retire_prior_to = 0; + int64_t curr_rpi = 0; xqc_cid_inner_t *inner_cid; xqc_list_head_t *pos, *next; @@ -846,7 +847,7 @@ xqc_process_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in return XQC_OK; } - if (retire_prior_to > curr_rpi) { + if (retire_prior_to > (uint64_t)curr_rpi) { /* * Upon receipt of an increased Retire Prior To field, the peer MUST stop using the * corresponding connection IDs and retire them with RETIRE_CONNECTION_ID frames before @@ -918,7 +919,8 @@ xqc_int_t xqc_process_retire_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in) { xqc_int_t ret = XQC_ERROR; - uint64_t seq_num = 0, largest_scid_seq_num = 0; + uint64_t seq_num = 0; + int64_t largest_scid_seq_num = 0; ret = xqc_parse_retire_conn_id_frame(packet_in, &seq_num); if (ret != XQC_OK) { @@ -939,7 +941,7 @@ xqc_process_retire_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet return -XQC_EPROTO; } - if (seq_num > largest_scid_seq_num) { + if (seq_num > (uint64_t)largest_scid_seq_num) { /* * Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number * greater than any previously sent to the peer MUST be treated as a @@ -1782,8 +1784,8 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet { xqc_int_t ret = XQC_ERROR; xqc_cid_t new_conn_cid; - uint64_t retire_prior_to; - int64_t curr_rpi; + uint64_t retire_prior_to = 0; + int64_t curr_rpi = 0; xqc_cid_inner_t *inner_cid; xqc_list_head_t *pos, *next; @@ -1853,7 +1855,7 @@ xqc_process_mp_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet return XQC_OK; } - if (retire_prior_to > curr_rpi) { + if (retire_prior_to > (uint64_t)curr_rpi) { /* * Upon receipt of an increased Retire Prior To field, the peer MUST stop using the * corresponding connection IDs and retire them with RETIRE_CONNECTION_ID frames before @@ -1927,7 +1929,8 @@ xqc_int_t xqc_process_mp_retire_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in) { xqc_int_t ret = XQC_ERROR; - uint64_t seq_num = 0, largest_scid_seq_num = 0, path_id; + uint64_t seq_num = 0, path_id; + int64_t largest_scid_seq_num = 0; ret = xqc_parse_mp_retire_conn_id_frame(packet_in, &seq_num, &path_id); if (ret != XQC_OK) { @@ -1956,7 +1959,7 @@ xqc_process_mp_retire_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *pac return -XQC_EPROTO; } - if (seq_num > largest_scid_seq_num) { + if (seq_num > (uint64_t)largest_scid_seq_num) { /* * Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number * greater than any previously sent to the peer MUST be treated as a From 36b7cc55559cd09671f8d0b54edc2a98239c87e2 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:45:27 +0800 Subject: [PATCH 21/36] [=] delete unused comments --- src/transport/xqc_cid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/transport/xqc_cid.c b/src/transport/xqc_cid.c index a274b4c1..d9eea4b4 100644 --- a/src/transport/xqc_cid.c +++ b/src/transport/xqc_cid.c @@ -248,7 +248,6 @@ xqc_cid_set_get_largest_seq_or_rpt(xqc_cid_set_t *cid_set, uint64_t path_id) if (inner_set) { return inner_set->largest_scid_seq_num; } - /* if the path id is larger than expected, should return 0 here */ return XQC_ERROR; } From 3e6ca43f260e685ae638c218eb4285f52939e930 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:47:17 +0800 Subject: [PATCH 22/36] [=] revert unused code --- demo/demo_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/demo_client.c b/demo/demo_client.c index b94d357c..48627f2d 100644 --- a/demo/demo_client.c +++ b/demo/demo_client.c @@ -1828,7 +1828,7 @@ xqc_demo_cli_parse_server_addr(char *url, xqc_demo_cli_net_config_t *cfg) /* set hint for hostname resolve */ struct addrinfo hints = {0}; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; //AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6: set to AF_INET if only using IPv4 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ From 5d89d8b4a1a953a39513b32f05078dc42387df46 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:55:29 +0800 Subject: [PATCH 23/36] [=] add comments for new APIs. --- include/xquic/xquic.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index 5c946dcd..0158fdbd 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -2142,6 +2142,9 @@ xqc_int_t xqc_path_get_local_addr(xqc_connection_t *conn, uint64_t path_id, struct sockaddr *addr, socklen_t addr_cap, socklen_t *local_addr_len); +/* + * These 2 APIs below is only used for IETF interop tests. Please don't use them for formal logic! + * */ XQC_EXPORT_PUBLIC_API xqc_int_t xqc_conn_trigger_cid_rotation_on_path(xqc_engine_t *engine, const xqc_cid_t *scid, uint64_t path_id); From 666d3c2c51b914a5331e8dda3bd3e9329ec03771 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 20:58:34 +0800 Subject: [PATCH 24/36] [~] adjust resource limit --- src/transport/xqc_multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index a0577f50..fefa7170 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -1660,7 +1660,7 @@ xqc_conn_update_max_path_id(xqc_connection_t *conn) xqc_int_t ret = XQC_OK; uint64_t pre_max_path_id = conn->local_max_path_id; conn->local_max_path_id += (conn->local_max_path_id + 1) / 2; - conn->local_max_path_id = xqc_max(conn->local_max_path_id, conn->max_paths_count); + conn->local_max_path_id = xqc_min(conn->local_max_path_id, conn->max_paths_count); if (xqc_conn_add_path_cid_sets(conn, pre_max_path_id + 1, conn->local_max_path_id) != XQC_OK) { xqc_log(conn->log, XQC_LOG_ERROR, "|add_path_cid_sets_error|"); return -XQC_EMALLOC; From 7dbb547aac5b2ea11f0ef0cba98f6d42b055087b Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 21:16:19 +0800 Subject: [PATCH 25/36] [=] add log --- src/transport/xqc_frame.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 4ce9f1a7..72bc2a8c 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -2059,7 +2059,9 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i } xqc_log(conn->log, XQC_LOG_DEBUG, - "|max_path_id:%ui|pre_local_max_path_id:%ui|", max_path_id, conn->local_max_path_id); + "|max_path_id:%ui|pre_local_max_path_id:%ui|create_path_count:%ui|max_paths_count:%ui|", + max_path_id, conn->local_max_path_id, + conn->create_path_count, conn->max_paths_count); if (conn->local_max_path_id < max_path_id) { xqc_log(conn->log, XQC_LOG_ERROR, From f9a1eab87a93c3a2e71b34ca61369b539b9eed92 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 21:25:34 +0800 Subject: [PATCH 26/36] [~] changing to uint64_t --- src/transport/xqc_conn.h | 6 +++--- src/transport/xqc_frame.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transport/xqc_conn.h b/src/transport/xqc_conn.h index f01874f0..ad16da01 100644 --- a/src/transport/xqc_conn.h +++ b/src/transport/xqc_conn.h @@ -370,9 +370,9 @@ struct xqc_connection_s { xqc_path_ctx_t *conn_initial_path; xqc_list_head_t conn_paths_list; uint64_t validating_path_id; - uint32_t create_path_count; - uint32_t validated_path_count; - uint32_t active_path_count; + uint64_t create_path_count; + uint64_t validated_path_count; + uint64_t active_path_count; uint64_t max_paths_count; uint64_t curr_max_path_id; diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 72bc2a8c..66d23759 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -2076,7 +2076,7 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i } if (xqc_conn_check_path_id_blocked(conn) /* check whether all path ids have been used */ - && (uint64_t)conn->create_path_count < conn->max_paths_count) /* check whether touched path resource limit */ + && conn->create_path_count < conn->max_paths_count) /* check whether touched path resource limit */ { ret = xqc_conn_update_max_path_id(conn); } From d0abe05208ce88a1b00bcb37ad58ebdfb0fb459e Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 21:27:38 +0800 Subject: [PATCH 27/36] [+] changing log --- src/transport/xqc_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_conn.c b/src/transport/xqc_conn.c index d5ded67b..17d3f2e5 100644 --- a/src/transport/xqc_conn.c +++ b/src/transport/xqc_conn.c @@ -3234,7 +3234,7 @@ xqc_conn_info_print(xqc_connection_t *conn, xqc_conn_stats_t *conn_stats) init_cwnd = conn->conn_settings.cc_params.customize_on ? conn->conn_settings.cc_params.init_cwnd : 0; /* conn info */ - ret = snprintf(buff, buff_size, "%s,%u,%u,%u,%u,%u,%u," + ret = snprintf(buff, buff_size, "%s,%"PRIu64",%"PRIu64",%"PRIu64",%u,%u,%u," "%u,%u,%u,%u,%u,%u,%u,%"PRIu64",%"PRIu64",%"PRIu64",i%u," #ifdef XQC_ENABLE_FEC "%u,%u,%u,%u,%u,%u,%u," From aaf82bb2c5e29b18723dd38b6d4916d6a810faff Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Wed, 4 Dec 2024 21:38:36 +0800 Subject: [PATCH 28/36] [+] adjust check for max path ids --- src/transport/xqc_engine.c | 2 +- src/transport/xqc_multipath.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index b29d4301..40bbd0d2 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -742,7 +742,7 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) xqc_log(conn->log, XQC_LOG_DEBUG, "|create_path_count:%ui|remote_max_path_id:%ui|", conn->create_path_count, conn->remote_max_path_id); - if (conn->create_path_count == conn->remote_max_path_id + if (conn->create_path_count >= conn->remote_max_path_id + 1 && conn->conn_type == XQC_CONN_TYPE_CLIENT) { ret = xqc_write_path_blocked_to_packet(conn, conn->remote_max_path_id); diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index fefa7170..3227ca60 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -75,7 +75,7 @@ xqc_path_create(xqc_connection_t *conn, xqc_cid_t *scid, xqc_cid_t *dcid, uint64 { xqc_path_ctx_t *path = NULL; - if (conn->create_path_count > xqc_min(conn->local_max_path_id, conn->remote_max_path_id)) { + if (conn->create_path_count > xqc_min(conn->local_max_path_id, conn->remote_max_path_id) + 1) { xqc_log(conn->log, XQC_LOG_ERROR, "|too many paths|current maximum:%d|", XQC_MAX_PATHS_COUNT); return NULL; From 167bf7a74a2a7b56492063cee14db47b49caa421 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 18:08:10 +0800 Subject: [PATCH 29/36] [+] add support for draft-12 transport param and new frame type --- include/xquic/xquic.h | 1 + src/transport/xqc_frame.c | 10 +++++ src/transport/xqc_frame.h | 2 + src/transport/xqc_frame_parser.c | 60 ++++++++++++++++++++++++++++ src/transport/xqc_frame_parser.h | 4 ++ src/transport/xqc_multipath.c | 1 + src/transport/xqc_transport_params.c | 13 ++++++ src/transport/xqc_transport_params.h | 1 + 8 files changed, 92 insertions(+) diff --git a/include/xquic/xquic.h b/include/xquic/xquic.h index 0158fdbd..d87ef9a1 100644 --- a/include/xquic/xquic.h +++ b/include/xquic/xquic.h @@ -1248,6 +1248,7 @@ typedef enum { XQC_ERR_MULTIPATH_VERSION = 0x00, XQC_MULTIPATH_10 = 0x0a, XQC_MULTIPATH_11 = 0x0b, + XQC_MULTIPATH_12 = 0x0c, } xqc_multipath_version_t; typedef enum { diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 66d23759..2fe9cd3a 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -356,6 +356,16 @@ xqc_process_frames(xqc_connection_t *conn, xqc_packet_in_t *packet_in) if (conn->conn_settings.multipath_version >= XQC_MULTIPATH_11) { ret = xqc_process_path_blocked_frame(conn, packet_in); + } else { + xqc_log(conn->log, XQC_LOG_ERROR, "|mp_version error|v:%ud|f:%xL|", + conn->conn_settings.multipath_version, frame_type); + ret = -XQC_EMP_INVALID_MP_VERTION; + } + break; + case XQC_TRANS_FRAME_TYPE_PATH_CIDS_BLOCKED: + if (conn->conn_settings.multipath_version >= XQC_MULTIPATH_12) { + ret = xqc_process_path_blocked_frame(conn, packet_in); + } else { xqc_log(conn->log, XQC_LOG_ERROR, "|mp_version error|v:%ud|f:%xL|", conn->conn_settings.multipath_version, frame_type); diff --git a/src/transport/xqc_frame.h b/src/transport/xqc_frame.h index 10ca5b3b..40030c8a 100644 --- a/src/transport/xqc_frame.h +++ b/src/transport/xqc_frame.h @@ -37,6 +37,7 @@ typedef enum { XQC_FRAME_MP_RETIRE_CONNECTION_ID, XQC_FRAME_MAX_PATH_ID, XQC_FRAME_PATH_BLOCKED, + XQC_FRAME_PATH_CIDS_BLOCKED, XQC_FRAME_PATH_FROZEN, XQC_FRAME_DATAGRAM, XQC_FRAME_Extension, @@ -75,6 +76,7 @@ typedef enum { XQC_FRAME_BIT_MP_RETIRE_CONNECTION_ID = 1ULL << XQC_FRAME_MP_RETIRE_CONNECTION_ID, XQC_FRAME_BIT_MAX_PATH_ID = 1ULL << XQC_FRAME_MAX_PATH_ID, XQC_FRAME_BIT_PATH_BLOCKED = 1ULL << XQC_FRAME_PATH_BLOCKED, + XQC_FRAME_BIT_PATH_CIDS_BLOCKED = 1ULL << XQC_FRAME_PATH_CIDS_BLOCKED, XQC_FRAME_BIT_PATH_FROZEN = 1ULL << XQC_FRAME_PATH_FROZEN, XQC_FRAME_BIT_DATAGRAM = 1ULL << XQC_FRAME_DATAGRAM, XQC_FRAME_BIT_Extension = 1ULL << XQC_FRAME_Extension, diff --git a/src/transport/xqc_frame_parser.c b/src/transport/xqc_frame_parser.c index d250a264..8662f031 100644 --- a/src/transport/xqc_frame_parser.c +++ b/src/transport/xqc_frame_parser.c @@ -3018,5 +3018,65 @@ xqc_parse_path_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id) packet_in->pi_frame_types |= XQC_FRAME_BIT_PATH_BLOCKED; + return XQC_OK; +} + + + +/* + * + * PATH_CIDS_BLOCKED Frame { + * Type (i) = TBD-09 (experiments use 0x15228c0e), + * Path Identifier (i), + * } + * Figure 11: PATH_CIDS_BLOCKED Frame Format + * + * */ +ssize_t +xqc_gen_path_cids_blocked_frame(xqc_packet_out_t *packet_out, uint64_t path_id) +{ + unsigned char *dst_buf = packet_out->po_buf + packet_out->po_used_size; + const unsigned char *begin = dst_buf; + + /* write frame type */ + uint64_t frame_type = XQC_TRANS_FRAME_TYPE_PATH_CIDS_BLOCKED; + unsigned frame_type_bits = xqc_vint_get_2bit(frame_type); + xqc_vint_write(dst_buf, frame_type, frame_type_bits, xqc_vint_len(frame_type_bits)); + dst_buf += xqc_vint_len(frame_type_bits); + + unsigned max_paths_bits = xqc_vint_get_2bit(path_id); + xqc_vint_write(dst_buf, path_id, max_paths_bits, xqc_vint_len(max_paths_bits)); + dst_buf += xqc_vint_len(max_paths_bits); + + packet_out->po_frame_types |= XQC_FRAME_BIT_PATH_CIDS_BLOCKED; + + return dst_buf - begin; +} + +xqc_int_t +xqc_parse_path_cids_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *path_id) +{ + unsigned char *p = packet_in->pos; + const unsigned char *end = packet_in->last; + int vlen; + + /* frame type */ + uint64_t frame_type = 0; + vlen = xqc_vint_read(p, end, &frame_type); /* get frame_type */ + if (vlen < 0) { + return -XQC_EVINTREAD; + } + p += vlen; + + vlen = xqc_vint_read(p, end, path_id); + if (vlen < 0) { + return -XQC_EVINTREAD; + } + p += vlen; + + packet_in->pos = p; + + packet_in->pi_frame_types |= XQC_FRAME_BIT_PATH_CIDS_BLOCKED; + return XQC_OK; } \ No newline at end of file diff --git a/src/transport/xqc_frame_parser.h b/src/transport/xqc_frame_parser.h index 8281e01a..1a8375f6 100644 --- a/src/transport/xqc_frame_parser.h +++ b/src/transport/xqc_frame_parser.h @@ -25,6 +25,7 @@ #define XQC_TRANS_FRAME_TYPE_MP_RETIRE_CONN_ID 0x15228c0a #define XQC_TRANS_FRAME_TYPE_MAX_PATH_ID 0x15228c0c #define XQC_TRANS_FRAME_TYPE_PATH_BLOCKED 0x15228c0d +#define XQC_TRANS_FRAME_TYPE_PATH_CIDS_BLOCKED 0x15228c0e #define XQC_TRANS_FRAME_TYPE_MP_FROZEN 0x15228cff /** @@ -182,5 +183,8 @@ xqc_int_t xqc_parse_max_path_id_frame(xqc_packet_in_t *packet_in, uint64_t *max_ ssize_t xqc_gen_path_blocked_frame(xqc_packet_out_t *packet_out, uint64_t max_path_id); xqc_int_t xqc_parse_path_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *max_path_id); +ssize_t xqc_gen_path_cids_blocked_frame(xqc_packet_out_t *packet_out, uint64_t path_id); +xqc_int_t xqc_parse_path_cids_blocked_frame(xqc_packet_in_t *packet_in, uint64_t *path_id); + void xqc_try_process_fec_decode(xqc_connection_t *conn, xqc_int_t block_id); #endif /*_XQC_FRAME_PARSER_H_INCLUDED_*/ diff --git a/src/transport/xqc_multipath.c b/src/transport/xqc_multipath.c index 3227ca60..02ce60f2 100644 --- a/src/transport/xqc_multipath.c +++ b/src/transport/xqc_multipath.c @@ -416,6 +416,7 @@ xqc_conn_is_current_mp_version_supported(xqc_multipath_version_t mp_version) switch (mp_version) { case XQC_MULTIPATH_10: case XQC_MULTIPATH_11: + case XQC_MULTIPATH_12: ret = XQC_OK; break; default: diff --git a/src/transport/xqc_transport_params.c b/src/transport/xqc_transport_params.c index a3d5287e..16d6de92 100644 --- a/src/transport/xqc_transport_params.c +++ b/src/transport/xqc_transport_params.c @@ -167,6 +167,11 @@ xqc_transport_params_calc_length(const xqc_transport_params_t *params, len += xqc_put_varint_len(XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11) + xqc_put_varint_len(xqc_put_varint_len(params->init_max_path_id)) + xqc_put_varint_len(params->init_max_path_id); + + } else if (params->multipath_version == XQC_MULTIPATH_12) { + len += xqc_put_varint_len(XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V12) + + xqc_put_varint_len(xqc_put_varint_len(params->init_max_path_id)) + + xqc_put_varint_len(params->init_max_path_id); } } @@ -399,6 +404,9 @@ xqc_encode_transport_params(const xqc_transport_params_t *params, } else if (params->multipath_version == XQC_MULTIPATH_11) { p = xqc_put_varint_param(p, XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11, params->init_max_path_id); + + } else if (params->multipath_version == XQC_MULTIPATH_12) { + p = xqc_put_varint_param(p, XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V12, params->init_max_path_id); } } @@ -710,6 +718,11 @@ xqc_decode_enable_multipath(xqc_transport_params_t *params, xqc_transport_params params->multipath_version = XQC_MULTIPATH_11; XQC_DECODE_VINT_VALUE(¶ms->init_max_path_id, p, end); return XQC_OK; + } else if (param_type == XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V12) { + params->enable_multipath = 1; + params->multipath_version = XQC_MULTIPATH_12; + XQC_DECODE_VINT_VALUE(¶ms->init_max_path_id, p, end); + return XQC_OK; } return XQC_OK; } diff --git a/src/transport/xqc_transport_params.h b/src/transport/xqc_transport_params.h index 609d0dec..c39b14b9 100644 --- a/src/transport/xqc_transport_params.h +++ b/src/transport/xqc_transport_params.h @@ -88,6 +88,7 @@ typedef enum { /* multipath quic attributes */ XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V10 = 0x0f739bbc1b666d09, XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11 = 0x0f739bbc1b666d11, + XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V12 = 0x0f739bbc1b666d0c, /* google connection options */ XQC_TRANSPORT_PARAM_GOOGLE_CO = 0x3128, From 146b53b32f90c1fe21c712f3e685e0bbdb91d1b4 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 18:38:40 +0800 Subject: [PATCH 30/36] [+] add path cids blocked trigger logic. --- include/xquic/xqc_errno.h | 2 ++ src/transport/xqc_engine.c | 15 +++++++++++++-- src/transport/xqc_packet_out.c | 29 +++++++++++++++++++++++++++++ src/transport/xqc_packet_out.h | 2 ++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/include/xquic/xqc_errno.h b/include/xquic/xqc_errno.h index e4292deb..e229da56 100644 --- a/include/xquic/xqc_errno.h +++ b/include/xquic/xqc_errno.h @@ -283,6 +283,8 @@ typedef enum { XQC_PATH_NO_ERROR = 0x0, XQC_PATH_APPLICATION_ABANDON = 0x004150504142414E, /* Path abandon error code: APPLICATION_ABANDON */ XQC_PATH_RESOURCE_LIMIT_REACHED = 0x0052534C494D4954, /* Path abandon error code: RESOURCE_LIMIT_REACHED */ + XQC_PATH_UNSTABLE_INTERFACE = 0x00554e5f494e5446, /* Path abandon error code: UNSTABLE_INTERFACE */ + XQC_PATH_NO_CID_AVAILABLE = 0x004e4f5f4349445f, /* Path abandon error code: NO_CID_AVAILABLE */ } xqc_multipath_error_t; #define QPACK_ERR_START 900 diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index 40bbd0d2..75c0e961 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -651,7 +651,7 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) xqc_log(conn->log, XQC_LOG_DEBUG, "|conn:%p|state:%s|flag:%s|now:%ui|", conn, xqc_conn_state_2_str(conn->conn_state), xqc_conn_flag_2_str(conn, conn->conn_flag), now); - int ret; + int ret = 0, rc = 0; xqc_bool_t wait_scid, wait_dcid; xqc_conn_timer_expire(conn, now); @@ -733,11 +733,22 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) } if (conn->enable_multipath) { + ret = xqc_conn_get_available_path_id(conn, NULL); if ((conn->conn_flag & XQC_CONN_FLAG_MP_WAIT_MP_READY) - && xqc_conn_get_available_path_id(conn, NULL) == XQC_OK) + && ret == XQC_OK) { conn->conn_flag |= XQC_CONN_FLAG_MP_READY_NOTIFY; conn->conn_flag &= ~XQC_CONN_FLAG_MP_WAIT_MP_READY; + } else if (ret != XQC_OK) { + /* not enough cid for new path id */ + uint64_t path_id = conn->create_path_count; + xqc_cid_set_inner_t *dcid_inner_set = xqc_get_path_cid_set(&conn->dcid_set, path_id); + if (dcid_inner_set && dcid_inner_set->unused_cnt == 0) { + rc = xqc_write_path_cids_blocked_to_packet(conn, path_id); + if (rc) { + xqc_log(conn->log, XQC_LOG_WARN, "|xqc_write_path_cids_blocked_to_packet error|ret:%ui|", ret); + } + } } xqc_log(conn->log, XQC_LOG_DEBUG, "|create_path_count:%ui|remote_max_path_id:%ui|", diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 41832dd5..2f82d75a 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1839,6 +1839,35 @@ xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id) xqc_log(conn->log, XQC_LOG_DEBUG, "|max_path_id:%ui|", max_path_id); return XQC_OK; + error: + xqc_maybe_recycle_packet_out(packet_out, conn); + return -XQC_EWRITE_PKT; +} + + +int +xqc_write_path_cids_blocked_to_packet(xqc_connection_t *conn, uint64_t path_id) +{ + ssize_t ret = XQC_ERROR; + xqc_packet_out_t *packet_out; + xqc_log(conn->log, XQC_LOG_DEBUG, "|path blocked max_path_id:%ui|", path_id); + + packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); + if (packet_out == NULL) { + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); + return -XQC_EWRITE_PKT; + } + + ret = xqc_gen_path_cids_blocked_frame(packet_out, path_id); + if (ret < 0) { + xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_path_blocked_frame error|"); + goto error; + } + packet_out->po_used_size += ret; + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + xqc_log(conn->log, XQC_LOG_DEBUG, "|max_path_id:%ui|", path_id); + return XQC_OK; + error: xqc_maybe_recycle_packet_out(packet_out, conn); return -XQC_EWRITE_PKT; diff --git a/src/transport/xqc_packet_out.h b/src/transport/xqc_packet_out.h index 0168a85c..248a14f5 100644 --- a/src/transport/xqc_packet_out.h +++ b/src/transport/xqc_packet_out.h @@ -233,6 +233,8 @@ xqc_int_t xqc_write_mp_retire_conn_id_frame_to_packet(xqc_connection_t *conn, ui int xqc_write_max_path_id_to_packet(xqc_connection_t *conn, uint64_t max_path_id); int xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id); +int xqc_write_path_cids_blocked_to_packet(xqc_connection_t *conn, uint64_t path_id); + /** * @brief Get remained space size in packet out buff. * From fc7ca661180e34d448aca1d122d280e708824507 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 18:42:08 +0800 Subject: [PATCH 31/36] [+] add version restriction --- src/transport/xqc_packet_out.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 2f82d75a..69a5648b 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1848,6 +1848,13 @@ xqc_write_path_blocked_to_packet(xqc_connection_t *conn, uint64_t max_path_id) int xqc_write_path_cids_blocked_to_packet(xqc_connection_t *conn, uint64_t path_id) { + if (conn->conn_settings.multipath_version < XQC_MULTIPATH_12) { + /* old version, do nothing here */ + xqc_log(conn->log, XQC_LOG_DEBUG, "|xqc_write_path_cids_blocked_to_packet|old version:%ui|", + conn->conn_settings.multipath_version); + return XQC_OK; + } + ssize_t ret = XQC_ERROR; xqc_packet_out_t *packet_out; xqc_log(conn->log, XQC_LOG_DEBUG, "|path blocked max_path_id:%ui|", path_id); From 85f79d9d5f7768e742a27043c2d6f5e62fd28690 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 18:48:55 +0800 Subject: [PATCH 32/36] [+] add transport param decode type --- src/transport/xqc_transport_params.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transport/xqc_transport_params.c b/src/transport/xqc_transport_params.c index 16d6de92..79f1c9cd 100644 --- a/src/transport/xqc_transport_params.c +++ b/src/transport/xqc_transport_params.c @@ -916,6 +916,7 @@ xqc_trans_param_get_index(uint64_t param_type) case XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V10: case XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V11: + case XQC_TRANSPORT_PARAM_INIT_MAX_PATH_ID_V12: return XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_PARSER; case XQC_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE: From d6dfe4fd3b57afc99d8125caa0f048b380d48ccc Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 19:17:57 +0800 Subject: [PATCH 33/36] [+] add handshake complete check for sending frame --- src/transport/xqc_engine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index 75c0e961..6f0e87c0 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -739,7 +739,7 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) { conn->conn_flag |= XQC_CONN_FLAG_MP_READY_NOTIFY; conn->conn_flag &= ~XQC_CONN_FLAG_MP_WAIT_MP_READY; - } else if (ret != XQC_OK) { + } else if (ret != XQC_OK && xqc_conn_check_handshake_completed(conn)) { /* not enough cid for new path id */ uint64_t path_id = conn->create_path_count; xqc_cid_set_inner_t *dcid_inner_set = xqc_get_path_cid_set(&conn->dcid_set, path_id); From 38ce8e67571d2b529a32f930b5620e0e874e2502 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 19:32:58 +0800 Subject: [PATCH 34/36] [+] add path_cids_blocked frame process --- src/transport/xqc_frame.c | 46 ++++++++++++++++++++++++++++++++++++++- src/transport/xqc_frame.h | 1 + 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 2fe9cd3a..e6f4e641 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -364,7 +364,7 @@ xqc_process_frames(xqc_connection_t *conn, xqc_packet_in_t *packet_in) break; case XQC_TRANS_FRAME_TYPE_PATH_CIDS_BLOCKED: if (conn->conn_settings.multipath_version >= XQC_MULTIPATH_12) { - ret = xqc_process_path_blocked_frame(conn, packet_in); + ret = xqc_process_path_cids_blocked_frame(conn, packet_in); } else { xqc_log(conn->log, XQC_LOG_ERROR, "|mp_version error|v:%ud|f:%xL|", @@ -2095,6 +2095,50 @@ xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_i } +xqc_int_t +xqc_process_path_cids_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in) +{ + xqc_int_t ret = XQC_ERROR; + uint64_t path_id, new_max_path_id; + + ret = xqc_parse_path_cids_blocked_frame(packet_in, &path_id); + if (ret != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|xqc_process_max_paths_frame error|"); + return ret; + } + + xqc_log(conn->log, XQC_LOG_DEBUG, + "|path_id:%ui|pre_local_max_path_id:%ui|create_path_count:%ui|max_paths_count:%ui|", + path_id, conn->local_max_path_id, + conn->create_path_count, conn->max_paths_count); + + if (conn->local_max_path_id < path_id) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|invalid path cids blocked frame|path_id:%ui|", path_id); + return -XQC_EIGNORE_PKT; + } + + /* try to add one new cid for the path id */ + uint64_t unused_limit = 2; + xqc_cid_set_inner_t* inner_set = xqc_get_path_cid_set(&conn->scid_set, path_id); + if (inner_set + && (inner_set->unused_cnt + inner_set->used_cnt) < conn->remote_settings.active_connection_id_limit + && inner_set->unused_cnt < unused_limit) + { + ret = xqc_write_mp_new_conn_id_frame_to_packet(conn, 0, inner_set->path_id); + if (ret != XQC_OK) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|xqc_write_mp_new_conn_id_frame_to_packet error|path_id:%ui|", + inner_set->path_id); + return ret; + } + } + + return ret; +} + + #ifdef XQC_ENABLE_FEC uint32_t diff --git a/src/transport/xqc_frame.h b/src/transport/xqc_frame.h index 40030c8a..29778446 100644 --- a/src/transport/xqc_frame.h +++ b/src/transport/xqc_frame.h @@ -186,5 +186,6 @@ xqc_int_t xqc_process_max_path_id_frame(xqc_connection_t *conn, xqc_packet_in_t xqc_int_t xqc_process_path_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in); +xqc_int_t xqc_process_path_cids_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in); #endif /* _XQC_FRAME_H_INCLUDED_ */ From 0c381d4fd96dc8ce3587ca38226a312391e69223 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 19:47:11 +0800 Subject: [PATCH 35/36] [+] add logs for new frames --- src/transport/xqc_frame.c | 12 +++++++++--- src/transport/xqc_packet_out.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index e6f4e641..47182180 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -2108,10 +2108,17 @@ xqc_process_path_cids_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *pac return ret; } + xqc_cid_set_inner_t* inner_set = xqc_get_path_cid_set(&conn->scid_set, path_id); + uint64_t scid_unused_count = 0; + if (inner_set) { + scid_unused_count = inner_set->unused_cnt; + } + xqc_log(conn->log, XQC_LOG_DEBUG, - "|path_id:%ui|pre_local_max_path_id:%ui|create_path_count:%ui|max_paths_count:%ui|", + "|path_id:%ui|local_max_path_id:%ui|create_path_count:%ui|max_paths_count:%ui|scid_unused_count:%ui|", path_id, conn->local_max_path_id, - conn->create_path_count, conn->max_paths_count); + conn->create_path_count, conn->max_paths_count, + scid_unused_count); if (conn->local_max_path_id < path_id) { xqc_log(conn->log, XQC_LOG_ERROR, @@ -2121,7 +2128,6 @@ xqc_process_path_cids_blocked_frame(xqc_connection_t *conn, xqc_packet_in_t *pac /* try to add one new cid for the path id */ uint64_t unused_limit = 2; - xqc_cid_set_inner_t* inner_set = xqc_get_path_cid_set(&conn->scid_set, path_id); if (inner_set && (inner_set->unused_cnt + inner_set->used_cnt) < conn->remote_settings.active_connection_id_limit && inner_set->unused_cnt < unused_limit) diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 69a5648b..e3437a71 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -1857,7 +1857,7 @@ xqc_write_path_cids_blocked_to_packet(xqc_connection_t *conn, uint64_t path_id) ssize_t ret = XQC_ERROR; xqc_packet_out_t *packet_out; - xqc_log(conn->log, XQC_LOG_DEBUG, "|path blocked max_path_id:%ui|", path_id); + xqc_log(conn->log, XQC_LOG_DEBUG, "|path_id:%ui|", path_id); packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); if (packet_out == NULL) { From 1980c17f85ed9d33a40de17439fe95078c4fd2be Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 20:06:54 +0800 Subject: [PATCH 36/36] [+] add flag for state cids_blocked has been sent --- src/transport/xqc_cid.h | 1 + src/transport/xqc_engine.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/transport/xqc_cid.h b/src/transport/xqc_cid.h index 39dbdf98..6a389d44 100644 --- a/src/transport/xqc_cid.h +++ b/src/transport/xqc_cid.h @@ -50,6 +50,7 @@ typedef struct xqc_cid_set_inner_s { }; xqc_cid_set_state_t set_state; uint32_t acked_unused; + uint32_t cids_blocked_sent; } xqc_cid_set_inner_t; typedef struct xqc_cid_set_s { diff --git a/src/transport/xqc_engine.c b/src/transport/xqc_engine.c index 6f0e87c0..fbd4d62a 100644 --- a/src/transport/xqc_engine.c +++ b/src/transport/xqc_engine.c @@ -743,11 +743,12 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now) /* not enough cid for new path id */ uint64_t path_id = conn->create_path_count; xqc_cid_set_inner_t *dcid_inner_set = xqc_get_path_cid_set(&conn->dcid_set, path_id); - if (dcid_inner_set && dcid_inner_set->unused_cnt == 0) { + if (dcid_inner_set && dcid_inner_set->unused_cnt == 0 && !dcid_inner_set->cids_blocked_sent) { rc = xqc_write_path_cids_blocked_to_packet(conn, path_id); if (rc) { xqc_log(conn->log, XQC_LOG_WARN, "|xqc_write_path_cids_blocked_to_packet error|ret:%ui|", ret); } + dcid_inner_set->cids_blocked_sent = 1; } }