From 167bf7a74a2a7b56492063cee14db47b49caa421 Mon Sep 17 00:00:00 2001 From: Yanmei-Liu Date: Tue, 28 Jan 2025 18:08:10 +0800 Subject: [PATCH] [+] 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,