From 8102e1a3eecefb524ca1b7e127c11c11dbaac623 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Mon, 15 Dec 2025 16:55:11 +0800 Subject: [PATCH 1/8] [+] Fix: Validate frame types in packets to prevent protocol violations --- src/transport/xqc_frame.c | 115 +++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index f7d52f25b..a0d884bc3 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -172,6 +172,111 @@ xqc_insert_stream_frame(xqc_connection_t *conn, xqc_stream_t *stream, xqc_stream } +static xqc_int_t +xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_in, uint64_t frame_type) +{ + /* + * RFC 9000 Section 12.4 Table 3: + * frame types that are permitted in each packet type. + */ + xqc_bool_t allowed, is_init, is_hsk, is_0rtt, is_1rtt; + if ((packet_in->pi_flag & XQC_PIF_FEC_RECOVERED) != 0) { + return XQC_OK; + } + xqc_pkt_type_t pkt_type = packet_in->pi_pkt.pkt_type; + if (pkt_type >= XQC_PTYPE_NUM) { + return XQC_OK; + } + is_init = (pkt_type == XQC_PTYPE_INIT); + is_hsk = (pkt_type == XQC_PTYPE_HSK); + is_0rtt = (pkt_type == XQC_PTYPE_0RTT); + is_1rtt = (pkt_type == XQC_PTYPE_SHORT_HEADER); + allowed = XQC_FALSE; + + if (frame_type > 0x1e) { + /* + * Validate known extension frames as well, to avoid accepting + * application/stateful frames in Initial/Handshake packets. + */ + switch (frame_type) { + case 0x30: /* DATAGRAM */ + case 0x31: /* DATAGRAM with length */ + case XQC_TRANS_FRAME_TYPE_MP_ACK0: + case XQC_TRANS_FRAME_TYPE_MP_ACK1: + case XQC_TRANS_FRAME_TYPE_MP_ABANDON: + case XQC_TRANS_FRAME_TYPE_MP_STANDBY: + case XQC_TRANS_FRAME_TYPE_MP_AVAILABLE: + case XQC_TRANS_FRAME_TYPE_MP_FROZEN: + case XQC_TRANS_FRAME_TYPE_MP_NEW_CONN_ID: + case XQC_TRANS_FRAME_TYPE_MP_RETIRE_CONN_ID: + case XQC_TRANS_FRAME_TYPE_MAX_PATH_ID: + case 0xfec5: /* FEC SID */ + case 0xfec6: /* FEC REPAIR SYMBOL */ + allowed = (is_0rtt || is_1rtt); + break; + case XQC_TRANS_FRAME_TYPE_ACK_EXT: + allowed = (is_init || is_hsk || is_1rtt); + break; + default: + return XQC_OK; + } + + if (!allowed) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|illegal frame in packet type|frame_type:%xL|pkt_type:%s|", + frame_type, xqc_pkt_type_2_str(pkt_type)); + XQC_CONN_ERR(conn, TRA_PROTOCOL_VIOLATION); + return -XQC_EPROTO; + } + + return XQC_OK; + } + + switch (frame_type) { + /* IH01 */ + case 0x00: /* PADDING */ + case 0x01: /* PING */ + case 0x1c: /* CONNECTION_CLOSE (transport) */ + case 0x1d: /* CONNECTION_CLOSE (application) */ + allowed = XQC_TRUE; + break; + + /* IH_1 */ + case 0x02: /* ACK */ + case 0x03: /* ACK (ECN) */ + case 0x06: /* CRYPTO */ + allowed = (is_init || is_hsk || is_1rtt); + break; + + /* ___1 */ + case 0x07: /* NEW_TOKEN */ + case 0x1b: /* PATH_RESPONSE */ + case 0x1e: /* HANDSHAKE_DONE */ + allowed = is_1rtt; + break; + + /* __01 */ + default: + if ((frame_type >= 0x04 && frame_type <= 0x05) /* RESET_STREAM, STOP_SENDING */ + || (frame_type >= 0x08 && frame_type <= 0x1a)) /* STREAM..PATH_CHALLENGE */ + { + allowed = (is_0rtt || is_1rtt); + } + break; + } + + if (!allowed) { + xqc_log(conn->log, XQC_LOG_ERROR, + "|illegal frame in packet type|frame_type:%xL|pkt_type:%s|", + frame_type, xqc_pkt_type_2_str(pkt_type)); + XQC_CONN_ERR(conn, TRA_PROTOCOL_VIOLATION); + return -XQC_EPROTO; + } + + return XQC_OK; +} + + xqc_int_t xqc_process_frames(xqc_connection_t *conn, xqc_packet_in_t *packet_in) { @@ -212,6 +317,11 @@ xqc_process_frames(xqc_connection_t *conn, xqc_packet_in_t *packet_in) xqc_log(conn->log, XQC_LOG_DEBUG, "|frame_type:%xL|", frame_type); + ret = xqc_validate_frame_type_in_pkt(conn, packet_in, frame_type); + if (ret != XQC_OK) { + return ret; + } + switch (frame_type) { case 0x00: @@ -447,8 +557,9 @@ xqc_process_stream_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in) xqc_stream_t *stream = NULL; xqc_stream_frame_t *stream_frame; - if (packet_in->pi_pkt.pkt_type == XQC_PTYPE_INIT - || packet_in->pi_pkt.pkt_type == XQC_PTYPE_HSK) + if ((packet_in->pi_flag & XQC_PIF_FEC_RECOVERED) == 0 + && (packet_in->pi_pkt.pkt_type == XQC_PTYPE_INIT + || packet_in->pi_pkt.pkt_type == XQC_PTYPE_HSK)) { xqc_log(conn->log, XQC_LOG_ERROR, "|illegal STREAM frame in %s packet, close with PROTOCOL_VIOLATION|", From 0a5a962e006bf7a1fc8864b0a7b13d35775151b6 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Wed, 17 Dec 2025 23:04:52 +0800 Subject: [PATCH 2/8] [+] Fix: Refactor frame type validation logic in packets for clarity and correctness --- src/transport/xqc_frame.c | 57 ++++++++++----------------------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index a0d884bc3..a9cd162b4 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -179,7 +179,7 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i * RFC 9000 Section 12.4 Table 3: * frame types that are permitted in each packet type. */ - xqc_bool_t allowed, is_init, is_hsk, is_0rtt, is_1rtt; + xqc_bool_t allowed, pkt_flag_init, pkt_flag_hsk, pkt_flag_0rtt, pkt_flag_1rtt; if ((packet_in->pi_flag & XQC_PIF_FEC_RECOVERED) != 0) { return XQC_OK; } @@ -187,48 +187,17 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i if (pkt_type >= XQC_PTYPE_NUM) { return XQC_OK; } - is_init = (pkt_type == XQC_PTYPE_INIT); - is_hsk = (pkt_type == XQC_PTYPE_HSK); - is_0rtt = (pkt_type == XQC_PTYPE_0RTT); - is_1rtt = (pkt_type == XQC_PTYPE_SHORT_HEADER); + pkt_flag_init = (pkt_type == XQC_PTYPE_INIT); + pkt_flag_hsk = (pkt_type == XQC_PTYPE_HSK); + pkt_flag_0rtt = (pkt_type == XQC_PTYPE_0RTT); + pkt_flag_1rtt = (pkt_type == XQC_PTYPE_SHORT_HEADER); allowed = XQC_FALSE; - if (frame_type > 0x1e) { - /* - * Validate known extension frames as well, to avoid accepting - * application/stateful frames in Initial/Handshake packets. - */ - switch (frame_type) { - case 0x30: /* DATAGRAM */ - case 0x31: /* DATAGRAM with length */ - case XQC_TRANS_FRAME_TYPE_MP_ACK0: - case XQC_TRANS_FRAME_TYPE_MP_ACK1: - case XQC_TRANS_FRAME_TYPE_MP_ABANDON: - case XQC_TRANS_FRAME_TYPE_MP_STANDBY: - case XQC_TRANS_FRAME_TYPE_MP_AVAILABLE: - case XQC_TRANS_FRAME_TYPE_MP_FROZEN: - case XQC_TRANS_FRAME_TYPE_MP_NEW_CONN_ID: - case XQC_TRANS_FRAME_TYPE_MP_RETIRE_CONN_ID: - case XQC_TRANS_FRAME_TYPE_MAX_PATH_ID: - case 0xfec5: /* FEC SID */ - case 0xfec6: /* FEC REPAIR SYMBOL */ - allowed = (is_0rtt || is_1rtt); - break; - case XQC_TRANS_FRAME_TYPE_ACK_EXT: - allowed = (is_init || is_hsk || is_1rtt); - break; - default: - return XQC_OK; - } - - if (!allowed) { - xqc_log(conn->log, XQC_LOG_ERROR, - "|illegal frame in packet type|frame_type:%xL|pkt_type:%s|", - frame_type, xqc_pkt_type_2_str(pkt_type)); - XQC_CONN_ERR(conn, TRA_PROTOCOL_VIOLATION); - return -XQC_EPROTO; - } + if (!pkt_flag_init && !pkt_flag_hsk && !pkt_flag_0rtt && !pkt_flag_1rtt) { + return XQC_OK; + } + if (frame_type > 0x1e) { return XQC_OK; } @@ -245,14 +214,14 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i case 0x02: /* ACK */ case 0x03: /* ACK (ECN) */ case 0x06: /* CRYPTO */ - allowed = (is_init || is_hsk || is_1rtt); + allowed = (pkt_flag_init || pkt_flag_hsk || pkt_flag_1rtt); break; /* ___1 */ case 0x07: /* NEW_TOKEN */ case 0x1b: /* PATH_RESPONSE */ case 0x1e: /* HANDSHAKE_DONE */ - allowed = is_1rtt; + allowed = pkt_flag_1rtt; break; /* __01 */ @@ -260,7 +229,9 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i if ((frame_type >= 0x04 && frame_type <= 0x05) /* RESET_STREAM, STOP_SENDING */ || (frame_type >= 0x08 && frame_type <= 0x1a)) /* STREAM..PATH_CHALLENGE */ { - allowed = (is_0rtt || is_1rtt); + allowed = (pkt_flag_0rtt || pkt_flag_1rtt); + } else { + return XQC_OK; } break; } From 8dea4f9c6807aff74ab0163476703b171ecf8ac0 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Thu, 18 Dec 2025 17:27:58 +0800 Subject: [PATCH 3/8] [+] Fix: Add packet type determination to follow QUIC RFC table 3 specification --- src/transport/xqc_packet_out.c | 55 ++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index b564cc947..be4d439d7 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -994,13 +994,36 @@ xqc_write_stream_data_blocked_to_packet(xqc_connection_t *conn, xqc_stream_id_t return -XQC_EWRITE_PKT; } +static xqc_pkt_type_t +xqc_get_pkt_type_for_app_data_frame(xqc_connection_t *conn, xqc_bool_t *buff_pkt) +{ + *buff_pkt = XQC_FALSE; + + if (conn->conn_flag & XQC_CONN_FLAG_CAN_SEND_1RTT) { + return XQC_PTYPE_SHORT_HEADER; + } + + if (conn->conn_type == XQC_CONN_TYPE_CLIENT + && conn->conn_state == XQC_CONN_STATE_CLIENT_INITIAL_SENT + && xqc_conn_is_ready_to_send_early_data(conn)) + { + conn->conn_flag |= XQC_CONN_FLAG_HAS_0RTT; + return XQC_PTYPE_0RTT; + } + + *buff_pkt = XQC_TRUE; + return XQC_PTYPE_SHORT_HEADER; +} + int xqc_write_streams_blocked_to_packet(xqc_connection_t *conn, uint64_t stream_limit, int bidirectional) { ssize_t ret; xqc_packet_out_t *packet_out; + xqc_bool_t buff_pkt = XQC_FALSE; + xqc_pkt_type_t pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); - packet_out = xqc_write_new_packet(conn, XQC_PTYPE_NUM); + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; @@ -1016,6 +1039,10 @@ xqc_write_streams_blocked_to_packet(xqc_connection_t *conn, uint64_t stream_limi xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + return XQC_OK; error: @@ -1057,6 +1084,20 @@ xqc_write_max_stream_data_to_packet(xqc_connection_t *conn, xqc_stream_id_t stre { ssize_t ret = XQC_OK; xqc_packet_out_t *packet_out; + xqc_bool_t buff_pkt = XQC_FALSE; + + if (pkt_type == XQC_PTYPE_NUM + || pkt_type == XQC_PTYPE_INIT + || pkt_type == XQC_PTYPE_HSK) + { + pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); + } + + if (pkt_type == XQC_PTYPE_SHORT_HEADER + && (conn->conn_flag & XQC_CONN_FLAG_CAN_SEND_1RTT) == 0) + { + buff_pkt = XQC_TRUE; + } packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { @@ -1074,6 +1115,10 @@ xqc_write_max_stream_data_to_packet(xqc_connection_t *conn, xqc_stream_id_t stre xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + return XQC_OK; error: @@ -1086,13 +1131,15 @@ xqc_write_max_streams_to_packet(xqc_connection_t *conn, uint64_t max_stream, int { ssize_t ret = XQC_ERROR; xqc_packet_out_t *packet_out; + xqc_bool_t buff_pkt = XQC_FALSE; + xqc_pkt_type_t pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); if (max_stream > XQC_MAX_STREAMS) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_max_streams_to_packet error|set max_stream:%ui", max_stream); return -XQC_EPARAM; } - packet_out = xqc_write_new_packet(conn, XQC_PTYPE_NUM); + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; @@ -1108,6 +1155,10 @@ xqc_write_max_streams_to_packet(xqc_connection_t *conn, uint64_t max_stream, int xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + xqc_log(conn->log, XQC_LOG_DEBUG, "|new_max_stream:%ui|", max_stream); return XQC_OK; From e8469ec5f51659ea104e08498f1084c438cee123 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Thu, 7 May 2026 20:58:48 +0800 Subject: [PATCH 4/8] [~] Fix: Enhance frame type validation and add tests for application connection close handling --- src/transport/xqc_frame.c | 44 +++++++--- src/transport/xqc_packet_out.c | 107 +++++++++++++++--------- tests/unittest/main.c | 6 +- tests/unittest/xqc_process_frame_test.c | 93 +++++++++++++++++++- tests/unittest/xqc_process_frame_test.h | 4 + 5 files changed, 199 insertions(+), 55 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index a9cd162b4..2ce252644 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -179,7 +179,9 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i * RFC 9000 Section 12.4 Table 3: * frame types that are permitted in each packet type. */ - xqc_bool_t allowed, pkt_flag_init, pkt_flag_hsk, pkt_flag_0rtt, pkt_flag_1rtt; + xqc_bool_t allowed = XQC_FALSE; + xqc_bool_t pkt_flag_init = XQC_FALSE, pkt_flag_hsk = XQC_FALSE; + xqc_bool_t pkt_flag_0rtt = XQC_FALSE, pkt_flag_1rtt = XQC_FALSE; if ((packet_in->pi_flag & XQC_PIF_FEC_RECOVERED) != 0) { return XQC_OK; } @@ -191,7 +193,6 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i pkt_flag_hsk = (pkt_type == XQC_PTYPE_HSK); pkt_flag_0rtt = (pkt_type == XQC_PTYPE_0RTT); pkt_flag_1rtt = (pkt_type == XQC_PTYPE_SHORT_HEADER); - allowed = XQC_FALSE; if (!pkt_flag_init && !pkt_flag_hsk && !pkt_flag_0rtt && !pkt_flag_1rtt) { return XQC_OK; @@ -206,7 +207,6 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i case 0x00: /* PADDING */ case 0x01: /* PING */ case 0x1c: /* CONNECTION_CLOSE (transport) */ - case 0x1d: /* CONNECTION_CLOSE (application) */ allowed = XQC_TRUE; break; @@ -225,21 +225,39 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i break; /* __01 */ - default: - if ((frame_type >= 0x04 && frame_type <= 0x05) /* RESET_STREAM, STOP_SENDING */ - || (frame_type >= 0x08 && frame_type <= 0x1a)) /* STREAM..PATH_CHALLENGE */ - { - allowed = (pkt_flag_0rtt || pkt_flag_1rtt); - } else { - return XQC_OK; - } + case 0x04: /* RESET_STREAM */ + case 0x05: /* STOP_SENDING */ + case 0x08: /* STREAM */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: /* MAX_DATA */ + case 0x11: /* MAX_STREAM_DATA */ + case 0x12: /* MAX_STREAMS */ + case 0x13: + case 0x14: /* DATA_BLOCKED */ + case 0x15: /* STREAM_DATA_BLOCKED */ + case 0x16: /* STREAMS_BLOCKED */ + case 0x17: + case 0x18: /* NEW_CONNECTION_ID */ + case 0x19: /* RETIRE_CONNECTION_ID */ + case 0x1a: /* PATH_CHALLENGE */ + case 0x1d: /* CONNECTION_CLOSE (application) */ + allowed = (pkt_flag_0rtt || pkt_flag_1rtt); break; + + default: + return XQC_OK; } if (!allowed) { xqc_log(conn->log, XQC_LOG_ERROR, - "|illegal frame in packet type|frame_type:%xL|pkt_type:%s|", - frame_type, xqc_pkt_type_2_str(pkt_type)); + "|illegal frame in packet type|frame_type:%xL|pkt_type:%s|pkt_num:%ui|", + frame_type, xqc_pkt_type_2_str(pkt_type), packet_in->pi_pkt.pkt_num); XQC_CONN_ERR(conn, TRA_PROTOCOL_VIOLATION); return -XQC_EPROTO; } diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index be4d439d7..dca726e44 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -789,13 +789,19 @@ xqc_write_conn_close_to_packet(xqc_connection_t *conn, uint64_t err_code) pkt_type = XQC_PTYPE_SHORT_HEADER; } + xqc_bool_t is_app = err_code >= H3_NO_ERROR; + if (is_app && (pkt_type == XQC_PTYPE_INIT || pkt_type == XQC_PTYPE_HSK)) { + is_app = XQC_FALSE; + err_code = TRA_APPLICATION_ERROR; + } + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; } - ret = xqc_gen_conn_close_frame(packet_out, err_code, err_code >= H3_NO_ERROR ? 1:0, 0); + ret = xqc_gen_conn_close_frame(packet_out, err_code, is_app, 0); if (ret < 0) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_gen_conn_close_frame error|"); goto error; @@ -935,13 +941,51 @@ xqc_write_stop_sending_to_packet(xqc_connection_t *conn, xqc_stream_t *stream, return -XQC_EWRITE_PKT; } + +static xqc_pkt_type_t +xqc_select_pkt_type_for_app_data_frame(xqc_connection_t *conn, + xqc_pkt_type_t requested_pkt_type, xqc_bool_t *buff_pkt) +{ + *buff_pkt = XQC_FALSE; + + if (requested_pkt_type == XQC_PTYPE_0RTT) { + return XQC_PTYPE_0RTT; + } + + if (conn->conn_flag & XQC_CONN_FLAG_CAN_SEND_1RTT) { + if (requested_pkt_type == XQC_PTYPE_SHORT_HEADER) { + return requested_pkt_type; + } + + return XQC_PTYPE_SHORT_HEADER; + } + + if (requested_pkt_type == XQC_PTYPE_SHORT_HEADER) { + *buff_pkt = XQC_TRUE; + return requested_pkt_type; + } + + if (conn->conn_type == XQC_CONN_TYPE_CLIENT + && conn->conn_state == XQC_CONN_STATE_CLIENT_INITIAL_SENT + && xqc_conn_is_ready_to_send_early_data(conn)) + { + conn->conn_flag |= XQC_CONN_FLAG_HAS_0RTT; + return XQC_PTYPE_0RTT; + } + + *buff_pkt = XQC_TRUE; + return XQC_PTYPE_SHORT_HEADER; +} + int xqc_write_data_blocked_to_packet(xqc_connection_t *conn, uint64_t data_limit) { ssize_t ret; xqc_packet_out_t *packet_out; + xqc_bool_t buff_pkt = XQC_FALSE; + xqc_pkt_type_t pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, XQC_PTYPE_NUM, &buff_pkt); - packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; @@ -958,6 +1002,10 @@ xqc_write_data_blocked_to_packet(xqc_connection_t *conn, uint64_t data_limit) /* we need to send this packet asap */ xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + return XQC_OK; error: @@ -970,7 +1018,10 @@ xqc_write_stream_data_blocked_to_packet(xqc_connection_t *conn, xqc_stream_id_t { ssize_t ret; xqc_packet_out_t *packet_out; - packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); + xqc_bool_t buff_pkt = XQC_FALSE; + xqc_pkt_type_t pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, XQC_PTYPE_NUM, &buff_pkt); + + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; @@ -987,6 +1038,10 @@ xqc_write_stream_data_blocked_to_packet(xqc_connection_t *conn, xqc_stream_id_t /* we need to send this packet asap */ xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + return XQC_OK; error: @@ -994,34 +1049,13 @@ xqc_write_stream_data_blocked_to_packet(xqc_connection_t *conn, xqc_stream_id_t return -XQC_EWRITE_PKT; } -static xqc_pkt_type_t -xqc_get_pkt_type_for_app_data_frame(xqc_connection_t *conn, xqc_bool_t *buff_pkt) -{ - *buff_pkt = XQC_FALSE; - - if (conn->conn_flag & XQC_CONN_FLAG_CAN_SEND_1RTT) { - return XQC_PTYPE_SHORT_HEADER; - } - - if (conn->conn_type == XQC_CONN_TYPE_CLIENT - && conn->conn_state == XQC_CONN_STATE_CLIENT_INITIAL_SENT - && xqc_conn_is_ready_to_send_early_data(conn)) - { - conn->conn_flag |= XQC_CONN_FLAG_HAS_0RTT; - return XQC_PTYPE_0RTT; - } - - *buff_pkt = XQC_TRUE; - return XQC_PTYPE_SHORT_HEADER; -} - int xqc_write_streams_blocked_to_packet(xqc_connection_t *conn, uint64_t stream_limit, int bidirectional) { ssize_t ret; xqc_packet_out_t *packet_out; xqc_bool_t buff_pkt = XQC_FALSE; - xqc_pkt_type_t pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); + xqc_pkt_type_t pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, XQC_PTYPE_NUM, &buff_pkt); packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { @@ -1055,8 +1089,10 @@ xqc_write_max_data_to_packet(xqc_connection_t *conn, uint64_t max_data) { ssize_t ret; xqc_packet_out_t *packet_out; + xqc_bool_t buff_pkt = XQC_FALSE; + xqc_pkt_type_t pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, XQC_PTYPE_NUM, &buff_pkt); - packet_out = xqc_write_new_packet(conn, XQC_PTYPE_SHORT_HEADER); + packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_new_packet error|"); return -XQC_EWRITE_PKT; @@ -1072,6 +1108,10 @@ xqc_write_max_data_to_packet(xqc_connection_t *conn, uint64_t max_data) xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); + if (buff_pkt) { + xqc_conn_buff_1rtt_packet(conn, packet_out); + } + return XQC_OK; error: @@ -1086,18 +1126,7 @@ xqc_write_max_stream_data_to_packet(xqc_connection_t *conn, xqc_stream_id_t stre xqc_packet_out_t *packet_out; xqc_bool_t buff_pkt = XQC_FALSE; - if (pkt_type == XQC_PTYPE_NUM - || pkt_type == XQC_PTYPE_INIT - || pkt_type == XQC_PTYPE_HSK) - { - pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); - } - - if (pkt_type == XQC_PTYPE_SHORT_HEADER - && (conn->conn_flag & XQC_CONN_FLAG_CAN_SEND_1RTT) == 0) - { - buff_pkt = XQC_TRUE; - } + pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, pkt_type, &buff_pkt); packet_out = xqc_write_new_packet(conn, pkt_type); if (packet_out == NULL) { @@ -1132,7 +1161,7 @@ xqc_write_max_streams_to_packet(xqc_connection_t *conn, uint64_t max_stream, int ssize_t ret = XQC_ERROR; xqc_packet_out_t *packet_out; xqc_bool_t buff_pkt = XQC_FALSE; - xqc_pkt_type_t pkt_type = xqc_get_pkt_type_for_app_data_frame(conn, &buff_pkt); + xqc_pkt_type_t pkt_type = xqc_select_pkt_type_for_app_data_frame(conn, XQC_PTYPE_NUM, &buff_pkt); if (max_stream > XQC_MAX_STREAMS) { xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_write_max_streams_to_packet error|set max_stream:%ui", max_stream); diff --git a/tests/unittest/main.c b/tests/unittest/main.c index 8c5b1404f..dc1cabe18 100644 --- a/tests/unittest/main.c +++ b/tests/unittest/main.c @@ -73,12 +73,14 @@ main() || !CU_add_test(pSuite, "xqc_test_cubic", xqc_test_cubic) || !CU_add_test(pSuite, "xqc_test_short_header_parse_cid", xqc_test_short_header_packet_parse_cid) || !CU_add_test(pSuite, "xqc_test_long_header_parse_cid", xqc_test_long_header_packet_parse_cid) - || !CU_add_test(pSuite, "xqc_test_empty_pkt", xqc_test_empty_pkt) - || !CU_add_test(pSuite, "xqc_test_engine_packet_process", xqc_test_engine_packet_process) || !CU_add_test(pSuite, "xqc_test_stream_frame", xqc_test_stream_frame) || !CU_add_test(pSuite, "xqc_test_process_frame", xqc_test_process_frame) + || !CU_add_test(pSuite, "xqc_test_handshake_app_conn_close_is_converted", xqc_test_handshake_app_conn_close_is_converted) + || !CU_add_test(pSuite, "xqc_test_1rtt_only_flow_control_frames_are_buffered", xqc_test_1rtt_only_flow_control_frames_are_buffered) || !CU_add_test(pSuite, "xqc_test_parse_padding_frame", xqc_test_parse_padding_frame) || !CU_add_test(pSuite, "xqc_test_large_ack_frame", xqc_test_large_ack_frame) + || !CU_add_test(pSuite, "xqc_test_empty_pkt", xqc_test_empty_pkt) + || !CU_add_test(pSuite, "xqc_test_engine_packet_process", xqc_test_engine_packet_process) || !CU_add_test(pSuite, "xqc_test_h3_frame", xqc_test_frame) || !CU_add_test(pSuite, "xqc_test_transport_params", xqc_test_transport_params) || !CU_add_test(pSuite, "xqc_test_tls", xqc_test_tls) diff --git a/tests/unittest/xqc_process_frame_test.c b/tests/unittest/xqc_process_frame_test.c index d2d5c00ba..a6a9ea6fc 100644 --- a/tests/unittest/xqc_process_frame_test.c +++ b/tests/unittest/xqc_process_frame_test.c @@ -7,12 +7,35 @@ #include "xqc_common_test.h" #include "src/transport/xqc_frame.h" #include "src/transport/xqc_packet_in.h" +#include "src/transport/xqc_packet_out.h" +#include "src/transport/xqc_send_queue.h" #include "src/common/utils/vint/xqc_variable_len_int.h" #include "src/transport/xqc_conn.h" char XQC_TEST_ILL_FRAME_1[] = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char XQC_TEST_ZERO_LEN_NEW_TOKEN_FRAME[] = {0x07, 0x00}; char XQC_TEST_STREAM_FRAME[] = {0x0a, 0x00, 0x01, 0x00}; +char XQC_TEST_APP_CONN_CLOSE_FRAME[] = {0x1d, 0x00, 0x00}; + + +static void +xqc_test_1rtt_only_frame_buffered(xqc_connection_t *conn) +{ + CU_ASSERT(xqc_list_empty(&conn->conn_send_queue->sndq_send_packets_high_pri)); + CU_ASSERT(!xqc_list_empty(&conn->conn_send_queue->sndq_buff_1rtt_packets)); +} + + +static xqc_packet_out_t * +xqc_test_first_high_pri_packet(xqc_connection_t *conn) +{ + if (xqc_list_empty(&conn->conn_send_queue->sndq_send_packets_high_pri)) { + return NULL; + } + + return xqc_list_entry(conn->conn_send_queue->sndq_send_packets_high_pri.next, + xqc_packet_out_t, po_list); +} void @@ -41,6 +64,74 @@ xqc_test_process_frame() CU_ASSERT(ret == -XQC_EPROTO); xqc_engine_destroy(conn->engine); + + conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + xqc_packet_in_t pi_app_conn_close_init; + memset(&pi_app_conn_close_init, 0, sizeof(xqc_packet_in_t)); + pi_app_conn_close_init.pi_pkt.pkt_type = XQC_PTYPE_INIT; + pi_app_conn_close_init.pos = XQC_TEST_APP_CONN_CLOSE_FRAME; + pi_app_conn_close_init.last = pi_app_conn_close_init.pos + sizeof(XQC_TEST_APP_CONN_CLOSE_FRAME); + ret = xqc_process_frames(conn, &pi_app_conn_close_init); + CU_ASSERT(ret == -XQC_EPROTO); + + xqc_engine_destroy(conn->engine); +} + + +void +xqc_test_handshake_app_conn_close_is_converted() +{ + xqc_connection_t *conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + int ret = xqc_write_conn_close_to_packet(conn, H3_NO_ERROR); + CU_ASSERT(ret == XQC_OK); + + xqc_packet_out_t *packet_out = xqc_test_first_high_pri_packet(conn); + CU_ASSERT(packet_out != NULL); + CU_ASSERT(packet_out->po_pkt.pkt_type == XQC_PTYPE_INIT); + CU_ASSERT(packet_out->po_payload < packet_out->po_buf + packet_out->po_used_size); + CU_ASSERT(*packet_out->po_payload == 0x1c); + + uint64_t err_code = 0; + ssize_t vlen = xqc_vint_read(packet_out->po_payload + 1, + packet_out->po_buf + packet_out->po_used_size, + &err_code); + CU_ASSERT(vlen > 0); + CU_ASSERT(err_code == TRA_APPLICATION_ERROR); + + xqc_engine_destroy(conn->engine); +} + + +void +xqc_test_1rtt_only_flow_control_frames_are_buffered() +{ + xqc_connection_t *conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + int ret = xqc_write_data_blocked_to_packet(conn, 1); + CU_ASSERT(ret == XQC_OK); + xqc_test_1rtt_only_frame_buffered(conn); + xqc_engine_destroy(conn->engine); + + conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + ret = xqc_write_stream_data_blocked_to_packet(conn, 0, 1); + CU_ASSERT(ret == XQC_OK); + xqc_test_1rtt_only_frame_buffered(conn); + xqc_engine_destroy(conn->engine); + + conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + ret = xqc_write_max_data_to_packet(conn, 1); + CU_ASSERT(ret == XQC_OK); + xqc_test_1rtt_only_frame_buffered(conn); + xqc_engine_destroy(conn->engine); } @@ -63,6 +154,7 @@ xqc_test_parse_padding_frame() char XQC_MIXED_PADDING_FRAME[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3F}; xqc_packet_in_t pi_padding_mix; memset(&pi_padding_mix, 0, sizeof(xqc_packet_in_t)); + pi_padding_mix.pi_pkt.pkt_type = XQC_PTYPE_SHORT_HEADER; pi_padding_mix.pos = XQC_MIXED_PADDING_FRAME; pi_padding_mix.last = pi_padding_mix.pos + sizeof(XQC_MIXED_PADDING_FRAME); ret = xqc_process_frames(conn, &pi_padding_mix); @@ -110,4 +202,3 @@ xqc_test_large_ack_frame() xqc_engine_destroy(conn->engine); } - diff --git a/tests/unittest/xqc_process_frame_test.h b/tests/unittest/xqc_process_frame_test.h index 496ee8fe0..9c7b60eb6 100644 --- a/tests/unittest/xqc_process_frame_test.h +++ b/tests/unittest/xqc_process_frame_test.h @@ -7,6 +7,10 @@ void xqc_test_process_frame(); +void xqc_test_handshake_app_conn_close_is_converted(); + +void xqc_test_1rtt_only_flow_control_frames_are_buffered(); + void xqc_test_parse_padding_frame(); void xqc_test_large_ack_frame(); From d8a997800c9d60dcfae59da1920897830cb94eae Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Fri, 29 May 2026 10:56:34 +0800 Subject: [PATCH 5/8] [~] Fix: Refine frame validation for RFC compliance --- src/transport/xqc_frame.c | 7 ++++- src/transport/xqc_packet_out.c | 34 +++++++++++---------- tests/unittest/xqc_process_frame_test.c | 40 ++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/transport/xqc_frame.c b/src/transport/xqc_frame.c index 2ce252644..50b0e742b 100644 --- a/src/transport/xqc_frame.c +++ b/src/transport/xqc_frame.c @@ -198,11 +198,16 @@ xqc_validate_frame_type_in_pkt(xqc_connection_t *conn, xqc_packet_in_t *packet_i return XQC_OK; } - if (frame_type > 0x1e) { + if (frame_type > 0x1e && frame_type != 0x30 && frame_type != 0x31) { return XQC_OK; } switch (frame_type) { + case 0x30: + case 0x31: + allowed = (pkt_flag_0rtt || pkt_flag_1rtt); + break; + /* IH01 */ case 0x00: /* PADDING */ case 0x01: /* PING */ diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index dca726e44..92f6d495c 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -790,9 +790,13 @@ xqc_write_conn_close_to_packet(xqc_connection_t *conn, uint64_t err_code) } xqc_bool_t is_app = err_code >= H3_NO_ERROR; - if (is_app && (pkt_type == XQC_PTYPE_INIT || pkt_type == XQC_PTYPE_HSK)) { - is_app = XQC_FALSE; - err_code = TRA_APPLICATION_ERROR; + if (pkt_type == XQC_PTYPE_INIT || pkt_type == XQC_PTYPE_HSK) { + if (err_code >= TRA_CRYPTO_ERROR_BASE && err_code <= TRA_CRYPTO_ERROR) { + is_app = XQC_FALSE; + } else if (is_app) { + is_app = XQC_FALSE; + err_code = TRA_APPLICATION_ERROR; + } } packet_out = xqc_write_new_packet(conn, pkt_type); @@ -1000,10 +1004,10 @@ xqc_write_data_blocked_to_packet(xqc_connection_t *conn, uint64_t data_limit) packet_out->po_used_size += ret; /* we need to send this packet asap */ - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } return XQC_OK; @@ -1036,10 +1040,10 @@ xqc_write_stream_data_blocked_to_packet(xqc_connection_t *conn, xqc_stream_id_t packet_out->po_used_size += ret; /* we need to send this packet asap */ - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } return XQC_OK; @@ -1071,10 +1075,10 @@ xqc_write_streams_blocked_to_packet(xqc_connection_t *conn, uint64_t stream_limi packet_out->po_used_size += ret; - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } return XQC_OK; @@ -1106,10 +1110,10 @@ xqc_write_max_data_to_packet(xqc_connection_t *conn, uint64_t max_data) packet_out->po_used_size += ret; - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } return XQC_OK; @@ -1142,10 +1146,10 @@ xqc_write_max_stream_data_to_packet(xqc_connection_t *conn, xqc_stream_id_t stre packet_out->po_used_size += ret; - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } return XQC_OK; @@ -1182,10 +1186,10 @@ xqc_write_max_streams_to_packet(xqc_connection_t *conn, uint64_t max_stream, int packet_out->po_used_size += ret; - xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); - if (buff_pkt) { xqc_conn_buff_1rtt_packet(conn, packet_out); + } else { + xqc_send_queue_move_to_high_pri(&packet_out->po_list, conn->conn_send_queue); } xqc_log(conn->log, XQC_LOG_DEBUG, "|new_max_stream:%ui|", max_stream); diff --git a/tests/unittest/xqc_process_frame_test.c b/tests/unittest/xqc_process_frame_test.c index a6a9ea6fc..9b6748c2e 100644 --- a/tests/unittest/xqc_process_frame_test.c +++ b/tests/unittest/xqc_process_frame_test.c @@ -16,6 +16,7 @@ char XQC_TEST_ILL_FRAME_1[] = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char XQC_TEST_ZERO_LEN_NEW_TOKEN_FRAME[] = {0x07, 0x00}; char XQC_TEST_STREAM_FRAME[] = {0x0a, 0x00, 0x01, 0x00}; char XQC_TEST_APP_CONN_CLOSE_FRAME[] = {0x1d, 0x00, 0x00}; +char XQC_TEST_DATAGRAM_FRAME[] = {0x30}; static void @@ -77,8 +78,20 @@ xqc_test_process_frame() CU_ASSERT(ret == -XQC_EPROTO); xqc_engine_destroy(conn->engine); -} + conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + xqc_packet_in_t pi_datagram_init; + memset(&pi_datagram_init, 0, sizeof(xqc_packet_in_t)); + pi_datagram_init.pi_pkt.pkt_type = XQC_PTYPE_INIT; + pi_datagram_init.pos = XQC_TEST_DATAGRAM_FRAME; + pi_datagram_init.last = pi_datagram_init.pos + sizeof(XQC_TEST_DATAGRAM_FRAME); + ret = xqc_process_frames(conn, &pi_datagram_init); + CU_ASSERT(ret == -XQC_EPROTO); + + xqc_engine_destroy(conn->engine); +} void xqc_test_handshake_app_conn_close_is_converted() @@ -86,7 +99,7 @@ xqc_test_handshake_app_conn_close_is_converted() xqc_connection_t *conn = test_engine_connect(); CU_ASSERT(conn != NULL); - int ret = xqc_write_conn_close_to_packet(conn, H3_NO_ERROR); + int ret = xqc_write_conn_close_to_packet(conn, TRA_CRYPTO_ERROR_BASE); CU_ASSERT(ret == XQC_OK); xqc_packet_out_t *packet_out = xqc_test_first_high_pri_packet(conn); @@ -100,6 +113,27 @@ xqc_test_handshake_app_conn_close_is_converted() packet_out->po_buf + packet_out->po_used_size, &err_code); CU_ASSERT(vlen > 0); + CU_ASSERT(err_code == TRA_CRYPTO_ERROR_BASE); + + xqc_engine_destroy(conn->engine); + + conn = test_engine_connect(); + CU_ASSERT(conn != NULL); + + ret = xqc_write_conn_close_to_packet(conn, H3_NO_ERROR); + CU_ASSERT(ret == XQC_OK); + + packet_out = xqc_test_first_high_pri_packet(conn); + CU_ASSERT(packet_out != NULL); + CU_ASSERT(packet_out->po_pkt.pkt_type == XQC_PTYPE_INIT); + CU_ASSERT(packet_out->po_payload < packet_out->po_buf + packet_out->po_used_size); + CU_ASSERT(*packet_out->po_payload == 0x1c); + + err_code = 0; + vlen = xqc_vint_read(packet_out->po_payload + 1, + packet_out->po_buf + packet_out->po_used_size, + &err_code); + CU_ASSERT(vlen > 0); CU_ASSERT(err_code == TRA_APPLICATION_ERROR); xqc_engine_destroy(conn->engine); @@ -134,7 +168,6 @@ xqc_test_1rtt_only_flow_control_frames_are_buffered() xqc_engine_destroy(conn->engine); } - void xqc_test_parse_padding_frame() { @@ -164,7 +197,6 @@ xqc_test_parse_padding_frame() xqc_engine_destroy(conn->engine); } - void xqc_test_large_ack_frame() { From 590f872fc652610a6e4fba259947815a23c133b9 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Fri, 29 May 2026 17:45:07 +0800 Subject: [PATCH 6/8] [~] Fix: Use dynamic crypto error range --- src/transport/xqc_packet_out.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transport/xqc_packet_out.c b/src/transport/xqc_packet_out.c index 92f6d495c..ba9ef354f 100644 --- a/src/transport/xqc_packet_out.c +++ b/src/transport/xqc_packet_out.c @@ -791,7 +791,7 @@ xqc_write_conn_close_to_packet(xqc_connection_t *conn, uint64_t err_code) xqc_bool_t is_app = err_code >= H3_NO_ERROR; if (pkt_type == XQC_PTYPE_INIT || pkt_type == XQC_PTYPE_HSK) { - if (err_code >= TRA_CRYPTO_ERROR_BASE && err_code <= TRA_CRYPTO_ERROR) { + if (err_code >= TRA_CRYPTO_ERROR_BASE && err_code <= TRA_CRYPTO_ERROR_BASE + 0xff) { is_app = XQC_FALSE; } else if (is_app) { is_app = XQC_FALSE; From 70abcd003d47bfaa1a144ff6e104958ebf6fb5ed Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Mon, 1 Jun 2026 15:53:31 +0800 Subject: [PATCH 7/8] [~] Fix: Restore merge-lost stream frame test helper and includes --- tests/unittest/xqc_process_frame_test.c | 26 +++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unittest/xqc_process_frame_test.c b/tests/unittest/xqc_process_frame_test.c index 5f15b6a3a..b6fac347e 100644 --- a/tests/unittest/xqc_process_frame_test.c +++ b/tests/unittest/xqc_process_frame_test.c @@ -6,11 +6,14 @@ #include "xqc_process_frame_test.h" #include "xqc_common_test.h" #include "src/transport/xqc_frame.h" +#include "src/transport/xqc_frame_parser.h" +#include "src/transport/xqc_packet.h" #include "src/transport/xqc_packet_in.h" #include "src/transport/xqc_packet_out.h" #include "src/transport/xqc_send_queue.h" #include "src/common/utils/vint/xqc_variable_len_int.h" #include "src/transport/xqc_conn.h" +#include "xquic/xqc_errno.h" char XQC_TEST_ILL_FRAME_1[] = {0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char XQC_TEST_ZERO_LEN_NEW_TOKEN_FRAME[] = {0x07, 0x00}; @@ -19,6 +22,29 @@ char XQC_TEST_APP_CONN_CLOSE_FRAME[] = {0x1d, 0x00, 0x00}; char XQC_TEST_DATAGRAM_FRAME[] = {0x30}; +static xqc_int_t +xqc_test_parse_stream_frame_inner(unsigned char *frame_buf, + size_t frame_buf_len, + xqc_stream_frame_t *frame, xqc_stream_id_t *stream_id, + xqc_connection_t **conn) +{ + xqc_packet_in_t pi; + + *conn = test_engine_connect(); + CU_ASSERT(*conn != NULL); + if (*conn == NULL) { + return XQC_ERROR; + } + + memset(&pi, 0, sizeof(pi)); + memset(frame, 0, sizeof(*frame)); + pi.pos = frame_buf; + pi.last = frame_buf + frame_buf_len; + + return xqc_parse_stream_frame(&pi, *conn, frame, stream_id); +} + + static void xqc_test_1rtt_only_frame_buffered(xqc_connection_t *conn) { From 480f9a1a287e7f8ae41a94d6028d5088d0d867a4 Mon Sep 17 00:00:00 2001 From: Sy03 <1370724210@qq.com> Date: Mon, 1 Jun 2026 17:53:41 +0800 Subject: [PATCH 8/8] [~] Fix: Set correct pkt_type in CID tests, avoid CRYPTO_ERROR collision in conn_close test --- tests/unittest/xqc_cid_test.c | 2 ++ tests/unittest/xqc_process_frame_test.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unittest/xqc_cid_test.c b/tests/unittest/xqc_cid_test.c index 8b38542bd..f4060ba6b 100644 --- a/tests/unittest/xqc_cid_test.c +++ b/tests/unittest/xqc_cid_test.c @@ -123,6 +123,7 @@ xqc_test_recv_retire_cid() 0x00, /* Sequence Number */}; xqc_packet_in_t packet_in; memset(&packet_in, 0, sizeof(xqc_packet_in_t)); + packet_in.pi_pkt.pkt_type = XQC_PTYPE_SHORT_HEADER; packet_in.pos = XQC_RETIRE_CID_FRAME; packet_in.last = packet_in.pos + sizeof(XQC_RETIRE_CID_FRAME); @@ -182,6 +183,7 @@ xqc_test_retire_cid_with_odcid_in_set() 0x00, /* Sequence Number */}; xqc_packet_in_t packet_in; memset(&packet_in, 0, sizeof(xqc_packet_in_t)); + packet_in.pi_pkt.pkt_type = XQC_PTYPE_SHORT_HEADER; packet_in.pos = XQC_RETIRE_CID_FRAME; packet_in.last = packet_in.pos + sizeof(XQC_RETIRE_CID_FRAME); diff --git a/tests/unittest/xqc_process_frame_test.c b/tests/unittest/xqc_process_frame_test.c index b6fac347e..1f230d879 100644 --- a/tests/unittest/xqc_process_frame_test.c +++ b/tests/unittest/xqc_process_frame_test.c @@ -146,7 +146,7 @@ xqc_test_handshake_app_conn_close_is_converted() conn = test_engine_connect(); CU_ASSERT(conn != NULL); - ret = xqc_write_conn_close_to_packet(conn, H3_NO_ERROR); + ret = xqc_write_conn_close_to_packet(conn, 0x200); CU_ASSERT(ret == XQC_OK); packet_out = xqc_test_first_high_pri_packet(conn);