Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[+]Merge interop into main #364

Merged
merged 12 commits into from
Nov 8, 2023
14 changes: 12 additions & 2 deletions demo/demo_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ typedef struct xqc_demo_cli_quic_config_s {

uint8_t mp_version;

/* support interop test */
int is_interop_mode;

uint8_t send_path_standby;
xqc_msec_t path_status_timer_threshold;

Expand Down Expand Up @@ -1070,6 +1073,7 @@ xqc_demo_cli_hq_req_close_notify(xqc_hq_request_t *hqr, void *req_user_data)
stats.send_body_size, stats.recv_body_size, stats.stream_info);

/* task schedule */
xqc_demo_cli_continue_send_reqs(user_stream->user_conn);
xqc_demo_cli_on_stream_fin(user_stream);

free(user_stream->send_buf);
Expand Down Expand Up @@ -1625,6 +1629,7 @@ xqc_demo_cli_init_conneciton_settings(xqc_conn_settings_t* settings,
settings->standby_path_probe_timeout = 1000;
settings->multipath_version = args->quic_cfg.mp_version;
settings->mp_ping_on = 1;
settings->is_interop_mode = args->quic_cfg.is_interop_mode;
if (args->req_cfg.throttled_req != -1) {
settings->enable_stream_rate_limit = 1;
settings->recv_rate_bytes_per_sec = 0;
Expand Down Expand Up @@ -1756,6 +1761,7 @@ xqc_demo_cli_usage(int argc, char *argv[])
" -u key update packet threshold\n"
" -d do not save responses to files\n"
" -M enable multipath\n"
" -o use interop mode\n"
" -i interface to create a path. For instance, we can use '-i lo -i lo' to create two paths via lo.\n"
" -w waiting N ms to start the first request.\n"
" -P enable MPQUIC to return ACK_MPs on any paths.\n"
Expand All @@ -1779,7 +1785,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:dMi:w:Ps:bZ:NQT:R:V:B:I:n:eE")) != -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:eE")) != -1) {
switch (ch) {
/* server ip */
case 'a':
Expand Down Expand Up @@ -1920,7 +1926,11 @@ xqc_demo_cli_parse_args(int argc, char *argv[], xqc_demo_cli_client_args_t *args
printf("option multipath on\n");
args->net_cfg.multipath = 1;
break;


case 'o':
printf("set interop mode\n");
args->quic_cfg.is_interop_mode = 1;
break;
case 'i':
printf("option adding interface: %s\n", optarg);
if (args->net_cfg.ifcnt < MAX_PATH_CNT) {
Expand Down
11 changes: 10 additions & 1 deletion demo/demo_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ typedef struct xqc_demo_svr_quic_config_s {

/* multipath version */
int multipath_version;
/* support interop test */
int is_interop_mode;

/* ack on any path */
int mp_ack_on_any_path;
Expand Down Expand Up @@ -1179,6 +1181,7 @@ xqc_demo_svr_usage(int argc, char *argv[])
" -k Key output file path\n"
" -r retry\n"
" -d do not read responses from files\n"
" -i use interop mode\n"
" -M enable MPQUIC.\n"
" -P enable MPQUIC to return ACK_MPs on any paths.\n"
" -s multipath scheduler (interop, minrtt, backup), default: interop\n"
Expand Down Expand Up @@ -1228,7 +1231,7 @@ void
xqc_demo_svr_parse_args(int argc, char *argv[], xqc_demo_svr_args_t *args)
{
int ch = 0;
while ((ch = getopt(argc, argv, "p:c:CD:l:L:6k:rdMPs:R:u:a:")) != -1) {
while ((ch = getopt(argc, argv, "p:c:CD:l:L:6k:rdMiPs:R:u:a:")) != -1) {
switch (ch) {
/* listen port */
case 'p':
Expand Down Expand Up @@ -1303,6 +1306,11 @@ xqc_demo_svr_parse_args(int argc, char *argv[], xqc_demo_svr_args_t *args)
args->quic_cfg.dummy_mode = 1;
break;

case 'i':
printf("set interop mode\n");
args->quic_cfg.is_interop_mode = 1;
break;

case 'M':
printf("option multipath enabled\n");
args->quic_cfg.multipath = 1;
Expand Down Expand Up @@ -1453,6 +1461,7 @@ xqc_demo_svr_init_conn_settings(xqc_demo_svr_args_t *args)
.standby_path_probe_timeout = 1000,
.keyupdate_pkt_threshold = args->quic_cfg.keyupdate_pkt_threshold,
.least_available_cid_count = args->quic_cfg.least_available_cid_count,
.is_interop_mode = args->quic_cfg.is_interop_mode,
};

xqc_server_set_conn_settings(&conn_settings);
Expand Down
6 changes: 6 additions & 0 deletions include/xquic/xquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,12 @@ typedef struct xqc_conn_settings_s {
*/
uint32_t init_recv_window;

/*
* initial flow control value
*/
xqc_bool_t is_interop_mode;


} xqc_conn_settings_t;


Expand Down
22 changes: 17 additions & 5 deletions interop/run_endpoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/setup.sh

case $TESTCASE in
versionnegotiation|handshake|longrtt|transfer|zerortt|multiconnect|chacha20|resumption|http3|retry|keyupdate)
versionnegotiation|handshake|longrtt|transfer|zerortt|multiconnect|chacha20|resumption|http3|retry|keyupdate|mphandshake|mptransfer|mppathabandon|mppathstatus)
:
;;
*)
Expand All @@ -20,7 +20,7 @@ if [ "$ROLE" == "client" ]; then
/wait-for-it.sh sim:57832 -s -t 30

# client args
ARGS="-l d -L "$LOG_DIR/client.log" -D "/downloads" -k $SSLKEYLOGFILE -K 30"
ARGS="-l d -L "$LOG_DIR/client.log" -D "/downloads" -k $SSLKEYLOGFILE -K 30 -o"

# zerortt
if [ "$TESTCASE" == "zerortt" ]; then
Expand All @@ -45,9 +45,9 @@ if [ "$ROLE" == "client" ]; then
for REQ in $REQUESTS; do
echo -e "\nstart requesty[$i]: $REQ"

echo -e "./demo_client -l d -L \"/logs/log_$i.log\" -D \"/downloads\" -k $SSLKEYLOGFILE -U \"$REQ\" -K 60\n"
echo -e "./demo_client -l d -L \"/logs/log_$i.log\" -D \"/downloads\" -k $SSLKEYLOGFILE -U \"$REQ\" -K 90 -o\n"
# ./demo_client -l d -L "/logs/log_$i.log" -D "/downloads" -k $SSLKEYLOGFILE -U "$REQ" -A "h3" -0 -K 90
./demo_client -l d -L "/logs/log_$i.log" -D "/downloads" -k $SSLKEYLOGFILE -U "$REQ" -0 -K 90
./demo_client -l d -L "/logs/log_$i.log" -D "/downloads" -k $SSLKEYLOGFILE -U "$REQ" -0 -K 90 -o
i=`expr $i + 1`
done

Expand All @@ -62,7 +62,19 @@ if [ "$ROLE" == "client" ]; then
elif [ "$TESTCASE" == "keyupdate" ]; then
echo "./demo_client $ARGS -U $REQUESTS -u 30"
./demo_client $ARGS -U "$REQUESTS" -u 30

elif [ "$TESTCASE" == "mphandshake" ] || [ "$TESTCASE" == "mptransfer" ]; then
echo "./demo_client $ARGS -U $REQUESTS -M -i eth0 -i eth0 -w 3000"
./demo_client $ARGS -U "$REQUESTS" -M -i eth0 -i eth0 -w 3000

elif [ "$TESTCASE" == "mppathabandon" ]; then
echo "./demo_client $ARGS -U $REQUESTS -M -i eth0 -i eth0 -w 3000 -Z 1000"
./demo_client $ARGS -U "$REQUESTS" -M -i eth0 -i eth0 -w 3000 -Z 1000

elif [ "$TESTCASE" == "mppathstatus" ]; then
echo "./demo_client $ARGS -U $REQUESTS -M -i eth0 -i eth0 -w 3000 -b"
./demo_client $ARGS -U "$REQUESTS" -M -i eth0 -i eth0 -w 3000 -b

# common testcase
else
echo -e "./demo_client $ARGS -U \"$REQUESTS\"\n"
Expand All @@ -85,7 +97,7 @@ elif [ "$ROLE" == "server" ]; then

#cp -r /www /logs

ARGS="-l d -L "$LOG_DIR/server.log" -p 443 -D "/www" -k $SSLKEYLOGFILE"
ARGS="-l d -L "$LOG_DIR/server.log" -p 443 -D "/www" -k $SSLKEYLOGFILE -i -M"
echo "./demo_server $ARGS"
./demo_server $ARGS
fi
1 change: 0 additions & 1 deletion scripts/case_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3475,7 +3475,6 @@ if [ "$cli_res1" == "1" ] && [ -n "$cli_res2" ] \
else
echo ">>>>>>>> pass:0"
case_print_result "h3_ext_finish_bytestream_during_transmission" "fail"
exit
fi

# close bytestream during transmission (-x 305)
Expand Down
8 changes: 6 additions & 2 deletions src/tls/xqc_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,9 +661,13 @@ xqc_crypto_derive_updated_keys(xqc_crypto_t *crypto, xqc_key_type_t type)

/* update application traffic secret */
static uint8_t LABEL[] = "quic ku";
uint8_t dest_buf[INITIAL_SECRET_MAX_LEN];
uint8_t dest_buf[XQC_MAX_KNP_LEN];

ret = xqc_hkdf_expand_label(dest_buf, INITIAL_SECRET_MAX_LEN,
if (current_ckm->secret.len > XQC_MAX_KNP_LEN) {
return -XQC_TLS_UPDATE_KEY_ERROR;
}

ret = xqc_hkdf_expand_label(dest_buf, current_ckm->secret.len,
current_ckm->secret.base, current_ckm->secret.len,
LABEL, xqc_lengthof(LABEL), &crypto->md);
if (ret != XQC_OK) {
Expand Down
43 changes: 29 additions & 14 deletions src/transport/xqc_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ xqc_conn_settings_t default_conn_settings = {

.recv_rate_bytes_per_sec = 0,
.enable_stream_rate_limit = 0,

.is_interop_mode = 0,
};


Expand Down Expand Up @@ -158,6 +160,7 @@ xqc_server_set_conn_settings(const xqc_conn_settings_t *settings)
}

default_conn_settings.enable_multipath = settings->enable_multipath;
default_conn_settings.is_interop_mode = settings->is_interop_mode;

if (xqc_conn_is_current_mp_version_supported(settings->multipath_version) == XQC_OK) {
default_conn_settings.multipath_version = settings->multipath_version;
Expand Down Expand Up @@ -325,28 +328,38 @@ xqc_conn_init_trans_settings(xqc_connection_t *conn)
xqc_conn_set_default_settings(rs);

/* set local default setting values */
ls->max_streams_bidi = 1024;
ls->max_stream_data_bidi_remote = XQC_MAX_RECV_WINDOW;
if (conn->conn_settings.is_interop_mode) {
ls->max_streams_bidi = 128;
ls->max_streams_uni = 128;

} else {
ls->max_streams_bidi = 1024;
ls->max_streams_uni = 1024;
}
ls->max_stream_data_bidi_remote = XQC_MAX_RECV_WINDOW;
ls->max_stream_data_uni = XQC_MAX_RECV_WINDOW;

if (conn->conn_settings.enable_stream_rate_limit) {
ls->max_stream_data_bidi_local = conn->conn_settings.init_recv_window;

} else {
ls->max_stream_data_bidi_local = XQC_MAX_RECV_WINDOW;
}

ls->max_streams_uni = 1024;
ls->max_stream_data_uni = XQC_MAX_RECV_WINDOW;

if (conn->conn_settings.recv_rate_bytes_per_sec) {
ls->max_data = conn->conn_settings.recv_rate_bytes_per_sec * XQC_FC_INIT_RTT / 1000000;
ls->max_data = xqc_max(XQC_MIN_RECV_WINDOW, ls->max_data);
ls->max_data = xqc_min(XQC_MAX_RECV_WINDOW, ls->max_data);

if (conn->conn_settings.is_interop_mode) {
ls->max_data = 1024 * 1024;

} else {
/* max_data is the sum of stream_data on all uni and bidi streams */
ls->max_data = ls->max_streams_bidi * ls->max_stream_data_bidi_local
+ ls->max_streams_uni * ls->max_stream_data_uni;
if (conn->conn_settings.recv_rate_bytes_per_sec) {
ls->max_data = conn->conn_settings.recv_rate_bytes_per_sec * XQC_FC_INIT_RTT / 1000000;
ls->max_data = xqc_max(XQC_MIN_RECV_WINDOW, ls->max_data);
ls->max_data = xqc_min(XQC_MAX_RECV_WINDOW, ls->max_data);

} else {
/* max_data is the sum of stream_data on all uni and bidi streams */
ls->max_data = ls->max_streams_bidi * ls->max_stream_data_bidi_local
+ ls->max_streams_uni * ls->max_stream_data_uni;
}
}

ls->max_idle_timeout = conn->conn_settings.idle_time_out;
Expand All @@ -371,6 +384,8 @@ xqc_conn_init_flow_ctl(xqc_connection_t *conn)
{
xqc_conn_flow_ctl_t *flow_ctl = &conn->conn_flow_ctl;
xqc_trans_settings_t * settings = & conn->local_settings;

/* TODO: send params are inited to be zero, until zerortt inited or handshake done */
flow_ctl->fc_max_data_can_send = settings->max_data; /* replace with the value specified by peer after handshake */
flow_ctl->fc_max_data_can_recv = settings->max_data;
flow_ctl->fc_max_streams_bidi_can_send = settings->max_streams_bidi; /* replace with the value specified by peer after handshake */
Expand Down Expand Up @@ -1805,7 +1820,7 @@ xqc_conn_enc_packet(xqc_connection_t *conn,
conn->conn_state = XQC_CONN_STATE_CLOSED;
return -XQC_EENCRYPT;
}

packet_out->po_sent_time = current_time;
return XQC_OK;
}
Expand Down
1 change: 0 additions & 1 deletion src/transport/xqc_conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,5 +666,4 @@ void xqc_conn_destroy_ping_notification_list(xqc_connection_t *conn);

xqc_int_t xqc_conn_send_ping_internal(xqc_connection_t *conn, void *ping_user_data, xqc_bool_t notify);


#endif /* _XQC_CONN_H_INCLUDED_ */
1 change: 1 addition & 0 deletions src/transport/xqc_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ xqc_engine_process_conn(xqc_connection_t *conn, xqc_usec_t now)
}
XQC_CHECK_IMMEDIATE_CLOSE();


ret = xqc_conn_try_add_new_conn_id(conn, 0);
if (ret) {
xqc_log(conn->log, XQC_LOG_ERROR, "|xqc_conn_try_add_new_conn_id error|");
Expand Down
2 changes: 1 addition & 1 deletion src/transport/xqc_frame_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2466,4 +2466,4 @@ xqc_parse_path_available_frame(xqc_packet_in_t *packet_in,
packet_in->pi_frame_types |= XQC_FRAME_BIT_PATH_AVAILABLE;

return XQC_OK;
}
}
1 change: 1 addition & 0 deletions src/transport/xqc_packet_out.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ typedef struct xqc_packet_out_s {
size_t po_buf_cap; /* capcacity of po_buf */
unsigned int po_buf_size; /* size of po_buf can be used */
unsigned int po_used_size;
unsigned int po_enc_size; /* size of po after being encrypted */
unsigned int po_ack_offset;
xqc_packet_out_flag_t po_flag;
/* Largest Acknowledged in ACK frame, initiated to be 0 */
Expand Down
1 change: 1 addition & 0 deletions src/transport/xqc_packet_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ xqc_packet_encrypt_buf(xqc_connection_t *conn, xqc_packet_out_t *packet_out,
}
}

packet_out->po_enc_size = *enc_pkt_len;
return XQC_OK;
}

Expand Down
6 changes: 3 additions & 3 deletions src/transport/xqc_send_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,8 @@ xqc_send_ctl_on_packet_sent(xqc_send_ctl_t *send_ctl, xqc_pn_ctl_t *pn_ctl, xqc_

xqc_packet_number_t orig_pktnum = packet_out->po_origin ? packet_out->po_origin->po_pkt.pkt_num : 0;
xqc_log(send_ctl->ctl_conn->log, XQC_LOG_DEBUG,
"|conn:%p|path:%ui|pkt_num:%ui|origin_pktnum:%ui|size:%ud|pkt_type:%s|frame:%s|conn_state:%s|po_in_flight:%d|",
send_ctl->ctl_conn, send_ctl->ctl_path->path_id, packet_out->po_pkt.pkt_num, orig_pktnum, packet_out->po_used_size,
"|conn:%p|path:%ui|pkt_num:%ui|origin_pktnum:%ui|size:%ud|enc_size:%ud|pkt_type:%s|frame:%s|conn_state:%s|po_in_flight:%d|",
send_ctl->ctl_conn, send_ctl->ctl_path->path_id, packet_out->po_pkt.pkt_num, orig_pktnum, packet_out->po_used_size, packet_out->po_enc_size,
xqc_pkt_type_2_str(packet_out->po_pkt.pkt_type),
xqc_frame_type_2_str(packet_out->po_frame_types),
xqc_conn_state_2_str(send_ctl->ctl_conn->conn_state),
Expand All @@ -646,7 +646,7 @@ xqc_send_ctl_on_packet_sent(xqc_send_ctl_t *send_ctl, xqc_pn_ctl_t *pn_ctl, xqc_
pn_ctl->ctl_largest_sent[pns] = packet_out->po_pkt.pkt_num;
}

send_ctl->ctl_bytes_send += packet_out->po_used_size;
send_ctl->ctl_bytes_send += packet_out->po_enc_size;

if (packet_out->po_largest_ack > 0) {
xqc_ack_sent_record_add(&pn_ctl->ack_sent_record[pns], packet_out, send_ctl->ctl_srtt, now);
Expand Down
2 changes: 1 addition & 1 deletion src/transport/xqc_transport_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ xqc_trans_param_get_index(uint64_t param_type)

case XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_04:
case XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_05:
case XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_06:
case XQC_TRANSPORT_PARAM_ENABLE_MULTIPATH_06:
return XQC_TRANSPORT_PARAM_PROTOCOL_MAX + 1;

case XQC_TRANSPORT_PARAM_MAX_DATAGRAM_FRAME_SIZE:
Expand Down