Skip to content

Commit 107eab1

Browse files
cherylsyclaude
andcommitted
[+] #827 extract xqc_conn_validate_0rtt_transport_params for direct unit testing
Extract the 8 parameter comparisons (RFC 9000 §7.4.1 + RFC 9221 max_datagram_frame_size) from the inline block inside xqc_conn_tls_transport_params_cb into a standalone function xqc_conn_validate_0rtt_transport_params(). This allows unit tests to exercise the validation logic directly without TLS state mocking, CID setup, or encode/decode round-trips. Rewrite the three 0-RTT param validation tests to call the new function directly, removing the production-code invasion (early_data_accepted_override in xqc_tls_t) that the previous approach required. Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>
1 parent 96155cf commit 107eab1

3 files changed

Lines changed: 133 additions & 208 deletions

File tree

src/transport/xqc_conn.c

Lines changed: 90 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -6069,6 +6069,93 @@ xqc_check_fec_trans_param(xqc_connection_t *conn, xqc_transport_params_t params)
60696069
}
60706070
}
60716071

6072+
/*
6073+
* RFC 9000 Section 7.4.1: validate that new transport parameters do not
6074+
* reduce MUST parameters below the remembered (0-RTT) values.
6075+
*
6076+
* Returns XQC_OK if all parameters are valid, or an error code
6077+
* (TRA_0RTT_TRANS_PARAMS_ERROR) if any MUST parameter was reduced.
6078+
*/
6079+
xqc_int_t
6080+
xqc_conn_validate_0rtt_transport_params(xqc_connection_t *conn,
6081+
const xqc_transport_params_t *params)
6082+
{
6083+
xqc_trans_settings_t *remembered = &conn->remote_settings;
6084+
6085+
if (params->initial_max_data < remembered->max_data) {
6086+
xqc_log(conn->log, XQC_LOG_ERROR,
6087+
"|0rtt_param_reduced|initial_max_data|"
6088+
"remembered:%ui|new:%ui|",
6089+
remembered->max_data, params->initial_max_data);
6090+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6091+
}
6092+
6093+
if (params->initial_max_stream_data_bidi_local < remembered->max_stream_data_bidi_local) {
6094+
xqc_log(conn->log, XQC_LOG_ERROR,
6095+
"|0rtt_param_reduced|initial_max_stream_data_bidi_local|"
6096+
"remembered:%ui|new:%ui|",
6097+
remembered->max_stream_data_bidi_local,
6098+
params->initial_max_stream_data_bidi_local);
6099+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6100+
}
6101+
6102+
if (params->initial_max_stream_data_bidi_remote < remembered->max_stream_data_bidi_remote) {
6103+
xqc_log(conn->log, XQC_LOG_ERROR,
6104+
"|0rtt_param_reduced|initial_max_stream_data_bidi_remote|"
6105+
"remembered:%ui|new:%ui|",
6106+
remembered->max_stream_data_bidi_remote,
6107+
params->initial_max_stream_data_bidi_remote);
6108+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6109+
}
6110+
6111+
if (params->initial_max_stream_data_uni < remembered->max_stream_data_uni) {
6112+
xqc_log(conn->log, XQC_LOG_ERROR,
6113+
"|0rtt_param_reduced|initial_max_stream_data_uni|"
6114+
"remembered:%ui|new:%ui|",
6115+
remembered->max_stream_data_uni,
6116+
params->initial_max_stream_data_uni);
6117+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6118+
}
6119+
6120+
if (params->initial_max_streams_bidi < remembered->max_streams_bidi) {
6121+
xqc_log(conn->log, XQC_LOG_ERROR,
6122+
"|0rtt_param_reduced|initial_max_streams_bidi|"
6123+
"remembered:%ui|new:%ui|",
6124+
remembered->max_streams_bidi,
6125+
params->initial_max_streams_bidi);
6126+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6127+
}
6128+
6129+
if (params->initial_max_streams_uni < remembered->max_streams_uni) {
6130+
xqc_log(conn->log, XQC_LOG_ERROR,
6131+
"|0rtt_param_reduced|initial_max_streams_uni|"
6132+
"remembered:%ui|new:%ui|",
6133+
remembered->max_streams_uni,
6134+
params->initial_max_streams_uni);
6135+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6136+
}
6137+
6138+
if (params->active_connection_id_limit < remembered->active_connection_id_limit) {
6139+
xqc_log(conn->log, XQC_LOG_ERROR,
6140+
"|0rtt_param_reduced|active_connection_id_limit|"
6141+
"remembered:%ui|new:%ui|",
6142+
remembered->active_connection_id_limit,
6143+
params->active_connection_id_limit);
6144+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6145+
}
6146+
6147+
if (params->max_datagram_frame_size < remembered->max_datagram_frame_size) {
6148+
xqc_log(conn->log, XQC_LOG_ERROR,
6149+
"|0rtt_param_reduced|max_datagram_frame_size|"
6150+
"remembered:%ui|new:%ui|",
6151+
remembered->max_datagram_frame_size,
6152+
params->max_datagram_frame_size);
6153+
return TRA_0RTT_TRANS_PARAMS_ERROR;
6154+
}
6155+
6156+
return XQC_OK;
6157+
}
6158+
60726159
void
60736160
xqc_conn_tls_transport_params_cb(const uint8_t *tp, size_t len, void *user_data)
60746161
{
@@ -6117,101 +6204,11 @@ xqc_conn_tls_transport_params_cb(const uint8_t *tp, size_t len, void *user_data)
61176204
&& (conn->conn_flag & XQC_CONN_FLAG_HAS_0RTT)
61186205
&& xqc_tls_is_early_data_accepted(conn->tls) == XQC_TLS_EARLY_DATA_ACCEPT)
61196206
{
6120-
xqc_trans_settings_t *remembered = &conn->remote_settings;
6121-
6122-
/*
6123-
* MUST parameters -- server MUST NOT reduce these after 0-RTT is
6124-
* accepted (RFC 9000 Section 7.4.1):
6125-
* - active_connection_id_limit
6126-
* - initial_max_data
6127-
* - initial_max_stream_data_bidi_local
6128-
* - initial_max_stream_data_bidi_remote
6129-
* - initial_max_stream_data_uni
6130-
* - initial_max_streams_bidi
6131-
* - initial_max_streams_uni
6132-
*/
6133-
if (params.initial_max_data < remembered->max_data) {
6134-
xqc_log(conn->log, XQC_LOG_ERROR,
6135-
"|0rtt_param_reduced|initial_max_data|"
6136-
"remembered:%ui|new:%ui|",
6137-
remembered->max_data, params.initial_max_data);
6138-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6139-
return;
6140-
}
6141-
6142-
if (params.initial_max_stream_data_bidi_local < remembered->max_stream_data_bidi_local) {
6143-
xqc_log(conn->log, XQC_LOG_ERROR,
6144-
"|0rtt_param_reduced|initial_max_stream_data_bidi_local|"
6145-
"remembered:%ui|new:%ui|",
6146-
remembered->max_stream_data_bidi_local,
6147-
params.initial_max_stream_data_bidi_local);
6148-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6149-
return;
6150-
}
6151-
6152-
if (params.initial_max_stream_data_bidi_remote < remembered->max_stream_data_bidi_remote) {
6153-
xqc_log(conn->log, XQC_LOG_ERROR,
6154-
"|0rtt_param_reduced|initial_max_stream_data_bidi_remote|"
6155-
"remembered:%ui|new:%ui|",
6156-
remembered->max_stream_data_bidi_remote,
6157-
params.initial_max_stream_data_bidi_remote);
6158-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6159-
return;
6160-
}
6161-
6162-
if (params.initial_max_stream_data_uni < remembered->max_stream_data_uni) {
6163-
xqc_log(conn->log, XQC_LOG_ERROR,
6164-
"|0rtt_param_reduced|initial_max_stream_data_uni|"
6165-
"remembered:%ui|new:%ui|",
6166-
remembered->max_stream_data_uni,
6167-
params.initial_max_stream_data_uni);
6168-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6169-
return;
6170-
}
6171-
6172-
if (params.initial_max_streams_bidi < remembered->max_streams_bidi) {
6173-
xqc_log(conn->log, XQC_LOG_ERROR,
6174-
"|0rtt_param_reduced|initial_max_streams_bidi|"
6175-
"remembered:%ui|new:%ui|",
6176-
remembered->max_streams_bidi,
6177-
params.initial_max_streams_bidi);
6178-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6179-
return;
6180-
}
6181-
6182-
if (params.initial_max_streams_uni < remembered->max_streams_uni) {
6183-
xqc_log(conn->log, XQC_LOG_ERROR,
6184-
"|0rtt_param_reduced|initial_max_streams_uni|"
6185-
"remembered:%ui|new:%ui|",
6186-
remembered->max_streams_uni,
6187-
params.initial_max_streams_uni);
6188-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6189-
return;
6190-
}
6191-
6192-
if (params.active_connection_id_limit < remembered->active_connection_id_limit) {
6193-
xqc_log(conn->log, XQC_LOG_ERROR,
6194-
"|0rtt_param_reduced|active_connection_id_limit|"
6195-
"remembered:%ui|new:%ui|",
6196-
remembered->active_connection_id_limit,
6197-
params.active_connection_id_limit);
6198-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6207+
ret = xqc_conn_validate_0rtt_transport_params(conn, &params);
6208+
if (ret != XQC_OK) {
6209+
XQC_CONN_ERR(conn, ret);
61996210
return;
62006211
}
6201-
6202-
}
6203-
6204-
/* check datagram parameter -- unconditional, not gated on early_data
6205-
* accepted. For non-0RTT connections remote_settings.max_datagram_frame_size
6206-
* is 0, so this is a no-op. */
6207-
if (params.max_datagram_frame_size < conn->remote_settings.max_datagram_frame_size) {
6208-
xqc_log(conn->log, XQC_LOG_ERROR,
6209-
"|0rtt_param_reduced|max_datagram_frame_size|"
6210-
"remembered:%ui|new:%ui|",
6211-
conn->remote_settings.max_datagram_frame_size,
6212-
params.max_datagram_frame_size);
6213-
XQC_CONN_ERR(conn, TRA_0RTT_TRANS_PARAMS_ERROR);
6214-
return;
62156212
}
62166213

62176214
/* set remote transport param */

src/transport/xqc_conn.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,4 +749,15 @@ void xqc_conn_set_init_idle_timeout(xqc_connection_t *conn, xqc_msec_t init_idle
749749
void xqc_conn_try_to_enable_pmtud(xqc_connection_t *conn);
750750

751751
xqc_int_t xqc_conn_server_accept(xqc_connection_t *c);
752+
753+
/*
754+
* RFC 9000 Section 7.4.1: validate that new transport parameters do not
755+
* reduce MUST parameters below the remembered (0-RTT) values.
756+
*
757+
* Returns XQC_OK if all parameters are valid, or TRA_0RTT_TRANS_PARAMS_ERROR
758+
* if any MUST parameter was reduced.
759+
*/
760+
xqc_int_t xqc_conn_validate_0rtt_transport_params(xqc_connection_t *conn,
761+
const xqc_transport_params_t *params);
762+
752763
#endif /* _XQC_CONN_H_INCLUDED_ */

0 commit comments

Comments
 (0)