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
@@ -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;

@@ -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);
@@ -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;
@@ -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"
@@ -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':
@@ -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) {
11 changes: 10 additions & 1 deletion demo/demo_server.c
Original file line number Diff line number Diff line change
@@ -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;
@@ -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"
@@ -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':
@@ -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;
@@ -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);
6 changes: 6 additions & 0 deletions include/xquic/xquic.h
Original file line number Diff line number Diff line change
@@ -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;


22 changes: 17 additions & 5 deletions interop/run_endpoint.sh
Original file line number Diff line number Diff line change
@@ -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)
:
;;
*)
@@ -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
@@ -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

@@ -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"
@@ -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
@@ -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)
8 changes: 6 additions & 2 deletions src/tls/xqc_crypto.c
Original file line number Diff line number Diff line change
@@ -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) {
43 changes: 29 additions & 14 deletions src/transport/xqc_conn.c
Original file line number Diff line number Diff line change
@@ -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,
};


@@ -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;
@@ -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;
@@ -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 */
@@ -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;
}
1 change: 0 additions & 1 deletion src/transport/xqc_conn.h
Original file line number Diff line number Diff line change
@@ -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
@@ -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|");
2 changes: 1 addition & 1 deletion src/transport/xqc_frame_parser.c
Original file line number Diff line number Diff line change
@@ -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
@@ -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 */
1 change: 1 addition & 0 deletions src/transport/xqc_packet_parser.c
Original file line number Diff line number Diff line change
@@ -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;
}

6 changes: 3 additions & 3 deletions src/transport/xqc_send_ctl.c
Original file line number Diff line number Diff line change
@@ -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),
@@ -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);
2 changes: 1 addition & 1 deletion src/transport/xqc_transport_params.c
Original file line number Diff line number Diff line change
@@ -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: