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

support standard stateless reset #313

Merged
merged 1 commit into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ if (XQC_ENABLE_EVENT_LOG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DXQC_ENABLE_EVENT_LOG ")
endif()

if(XQC_COMPAT_GENERATE_SR_PKT)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DXQC_COMPAT_GENERATE_SR_PKT")
endif()


if(ANDROID)
set(DYMAMIC_LINK_OPTION
${DYMAMIC_LINK_OPTION}
Expand Down
3 changes: 2 additions & 1 deletion demo/demo_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,8 @@ xqc_demo_cli_socket_read_handler(xqc_demo_cli_user_conn_t *user_conn)
if (xqc_engine_packet_process(user_conn->ctx->engine, packet_buf, recv_size,
(struct sockaddr *)(&user_conn->local_addr),
user_conn->local_addrlen, (struct sockaddr *)(&addr),
addr_len, (xqc_msec_t)recv_time, user_conn) != XQC_OK)
addr_len, (xqc_msec_t)recv_time,
user_conn) != XQC_OK)
{
return;
}
Expand Down
13 changes: 9 additions & 4 deletions include/xquic/xqc_http3.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ typedef int (*xqc_h3_request_notify_pt)(xqc_h3_request_t *h3_request, void *h3s_
typedef int (*xqc_h3_request_read_notify_pt)(xqc_h3_request_t *h3_request,
xqc_request_notify_flag_t flag, void *h3s_user_data);

typedef void (*xqc_h3_request_closing_notify_pt)(xqc_h3_request_t *h3_request,
xqc_int_t err, void *h3s_user_data);

/**
* @brief encode flags of http headers
Expand Down Expand Up @@ -304,16 +306,19 @@ typedef struct xqc_h3_conn_callbacks_s {
typedef struct xqc_h3_request_callbacks_s {
/* request creation notify. it will be triggered after a request was created, and is required
for server, optional for client */
xqc_h3_request_notify_pt h3_request_create_notify;
xqc_h3_request_notify_pt h3_request_create_notify;

/* request close notify. which will be triggered after a request was closed */
xqc_h3_request_notify_pt h3_request_close_notify;
xqc_h3_request_notify_pt h3_request_close_notify;

/* request read notify callback. which will be triggered after received http headers or body */
xqc_h3_request_read_notify_pt h3_request_read_notify;
xqc_h3_request_read_notify_pt h3_request_read_notify;

/* request write notify callback. when triggered, users can continue to send headers or body */
xqc_h3_request_notify_pt h3_request_write_notify;
xqc_h3_request_notify_pt h3_request_write_notify;

/* request closing notify callback, will be triggered when request is closing */
xqc_h3_request_closing_notify_pt h3_request_closing_notify;

} xqc_h3_request_callbacks_t;

Expand Down
28 changes: 24 additions & 4 deletions include/xquic/xquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,19 @@ typedef ssize_t (*xqc_send_mmsg_ex_pt)(uint64_t path_id,
typedef xqc_int_t (*xqc_stream_notify_pt)(xqc_stream_t *stream,
void *strm_user_data);

/**
* @brief stream closing callback function, this will be triggered when some
* error on a stream happens.
*
* @param stream QUIC stream handler
* @param err_code error code
* @param strm_user_data stream level user_data, which was the parameter of xqc_stream_create set by
* client, or the parameter of xqc_stream_set_user_data set by server
* @return 0 for success, -1 for failure
*/
typedef void (*xqc_stream_closing_notify_pt)(xqc_stream_t *stream,
xqc_int_t err_code, void *strm_user_data);

/**
* @brief the callback API to notify application that there is a datagram to be read
*
Expand Down Expand Up @@ -708,23 +721,23 @@ typedef struct xqc_stream_callbacks_s {
* this will be triggered when QUIC stream data is ready for read. application layer could read
* data when xqc_stream_recv interface.
*/
xqc_stream_notify_pt stream_read_notify;
xqc_stream_notify_pt stream_read_notify;

/**
* stream write callback function. REQUIRED for both client and server
*
* when sending data with xqc_stream_send, xquic might be blocked or send part of the data. if
* this callback function is triggered, applications can continue to send the rest data.
*/
xqc_stream_notify_pt stream_write_notify;
xqc_stream_notify_pt stream_write_notify;

/**
* stream create callback function. REQUIRED for server, OPTIONAL for client.
*
* this will be triggered when QUIC stream is created. applications can create its own stream
* context in this callback function.
*/
xqc_stream_notify_pt stream_create_notify;
xqc_stream_notify_pt stream_create_notify;

/**
* stream close callback function. REQUIRED for both server and client.
Expand All @@ -733,7 +746,14 @@ typedef struct xqc_stream_callbacks_s {
* sending or receiving RESET_STREAM frame after 3 times of PTO, or when connection is closed.
* Applications can free the context which was created in stream_create_notify here.
*/
xqc_stream_notify_pt stream_close_notify;
xqc_stream_notify_pt stream_close_notify;

/**
* @brief stream reset callback function. OPTIONAL for both server and client
*
* this function will be triggered when a RESET_STREAM frame is received.
*/
xqc_stream_closing_notify_pt stream_closing_notify;

} xqc_stream_callbacks_t;

Expand Down
4 changes: 4 additions & 0 deletions include/xquic/xquic_typedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,14 @@ typedef uint8_t xqc_bool_t;
/* restrictions of key length in lb cid encryption */
#define XQC_LB_CID_KEY_LEN 16

/* length of stateless reset token */
#define XQC_STATELESS_RESET_TOKENLEN 16

typedef struct xqc_cid_s {
uint8_t cid_len;
uint8_t cid_buf[XQC_MAX_CID_LEN];
uint64_t cid_seq_num;
uint8_t sr_token[XQC_STATELESS_RESET_TOKENLEN];
} xqc_cid_t;

typedef enum xqc_log_level_s {
Expand Down
37 changes: 34 additions & 3 deletions scripts/case_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1367,8 +1367,8 @@ killall test_server
sleep 1
clear_log
echo -e "stateless reset...\c"
./test_client -l d -x 41 -1 > stdlog
result=`grep "receive reset, enter draining" clog`
./test_client -l d -x 41 -1 -t 5 > stdlog
result=`grep "|====>|receive stateless reset" clog`
cloing_notify=`grep "conn closing: 641" stdlog`
if [ -n "$result" ] && [ -n "$cloing_notify" ]; then
echo ">>>>>>>> pass:1"
Expand All @@ -1379,6 +1379,21 @@ else
fi


clear_log
echo -e "stateless reset during hsk...\c"
./test_client -l d -t 5 -x 45 -1 -s 100 -G > stdlog
result=`grep "|====>|receive stateless reset" clog`
cloing_notify=`grep "conn closing: 641" stdlog`
svr_hsk=`grep "handshake_time:0" slog`
if [ -n "$result" ] && [ -n "$cloing_notify" ] && [ -n "$svr_hsk" ]; then
echo ">>>>>>>> pass:1"
case_print_result "stateless_reset_during_hsk" "pass"
else
echo ">>>>>>>> pass:0"
case_print_result "stateless_reset_during_hsk" "fail"
exit
fi

killall test_server
./test_server -l d -e -M > /dev/null &
sleep 1
Expand Down Expand Up @@ -1611,7 +1626,7 @@ if [ -f xqc_token ]; then
rm -f xqc_token
fi
if [ -f stdlog ]; then
. rm -f stdlog
rm -f stdlog
fi
./test_server -l d -Q 9000 > /dev/null &
sleep 1
Expand Down Expand Up @@ -3596,4 +3611,20 @@ fi
rm -rf tp_localhost test_session xqc_token
killall test_server

clear_log
echo -e "request_closing_notify...\c"
./test_server -l d -x 14 > /dev/null &
sleep 1
./test_client -l d >> stdlog
res=`grep "request closing notify triggered" stdlog`
if [ -n "$res" ]; then
echo ">>>>>>>> pass:1"
case_print_result "request_closing_notify" "pass"
else
echo ">>>>>>>> pass:0"
case_print_result "request_closing_notify" "fail"
fi

killall test_server

cd -
1 change: 1 addition & 0 deletions scripts/xquic.lds
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ XQUIC_VERS_1.0 {
xqc_h3_conn_get_errno;
xqc_h3_conn_get_ssl;
xqc_h3_conn_set_user_data;
xqc_h3_conn_get_user_data;
xqc_h3_conn_get_peer_addr;
xqc_h3_conn_get_local_addr;
xqc_h3_conn_is_ready_to_send_early_data;
Expand Down
2 changes: 2 additions & 0 deletions src/common/xqc_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ xqc_log_type_2_level(xqc_log_type_t type)
case TRA_DATAGRAMS_SENT:
case TRA_DATAGRAMS_RECEIVED:
case TRA_STREAM_STATE_UPDATED:
case TRA_STATELESS_RESET:
case REC_METRICS_UPDATED:
case REC_PARAMETERS_SET:
case REC_CONGESTION_STATE_UPDATED:
Expand Down Expand Up @@ -139,6 +140,7 @@ xqc_log_type_str(xqc_log_type_t type)
[TRA_STREAM_STATE_UPDATED] = "stream_state_updated",
[TRA_FRAMES_PROCESSED] = "frames_processed",
[TRA_DATA_MOVED] = "data_moved",
[TRA_STATELESS_RESET] = "stateless_reset",
[REC_PARAMETERS_SET] = "rec_parameters_set",
[REC_METRICS_UPDATED] = "rec_metrics_updated",
[REC_CONGESTION_STATE_UPDATED] = "congestion_state_updated",
Expand Down
1 change: 1 addition & 0 deletions src/common/xqc_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ typedef enum {
TRA_STREAM_STATE_UPDATED,
TRA_FRAMES_PROCESSED,
TRA_DATA_MOVED,
TRA_STATELESS_RESET,

/* recovery event */
REC_PARAMETERS_SET,
Expand Down
16 changes: 12 additions & 4 deletions src/common/xqc_log_event_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,14 @@ xqc_log_TRA_FRAMES_PROCESSED_callback(xqc_log_t *log, const char *func, ...)
va_end(args);
}


void
xqc_log_TRA_STATELESS_RESET_callback(xqc_log_t *log, const char *func, xqc_connection_t *conn)
{
xqc_log_implement(log, TRA_DATAGRAMS_SENT, func, "|stateless reset|cid:%s",
log->scid);
}

void
xqc_log_REC_PARAMETERS_SET_callback(xqc_log_t *log, const char *func, xqc_send_ctl_t *send_ctl)
{
Expand Down Expand Up @@ -504,7 +512,7 @@ xqc_log_HTTP_STREAM_TYPE_SET_callback(xqc_log_t *log, const char *func, xqc_h3_s
{
xqc_log_implement(log, HTTP_STREAM_TYPE_SET, func,
"|%s|stream_id:%ui|stream_type:%d|",
local == XQC_LOG_LOCAL_EVENT ? "local" : "remote", h3_stream->stream->stream_id, h3_stream->type);
local == XQC_LOG_LOCAL_EVENT ? "local" : "remote", h3_stream->stream_id, h3_stream->type);
}

void
Expand All @@ -514,7 +522,7 @@ xqc_log_HTTP_FRAME_CREATED_callback(xqc_log_t *log, const char *func, ...)
va_list args;
va_start(args, func);
xqc_h3_stream_t *h3_stream = va_arg(args, xqc_h3_stream_t*);
xqc_stream_id_t stream_id = h3_stream->stream->stream_id;
xqc_stream_id_t stream_id = h3_stream->stream_id;
xqc_h3_frm_type_t type = va_arg(args, xqc_h3_frm_type_t);
switch (type) {
case XQC_H3_FRM_DATA: {
Expand Down Expand Up @@ -574,7 +582,7 @@ void
xqc_log_HTTP_FRAME_PARSED_callback(xqc_log_t *log, const char *func, xqc_h3_stream_t *h3_stream)
{
xqc_h3_frame_t *frame = &h3_stream->pctx.frame_pctx.frame;
xqc_stream_id_t stream_id = h3_stream->stream->stream_id;
xqc_stream_id_t stream_id = h3_stream->stream_id;
switch (frame->type) {
case XQC_H3_FRM_DATA:
case XQC_H3_FRM_HEADERS:
Expand Down Expand Up @@ -621,7 +629,7 @@ void
xqc_log_QPACK_STREAM_STATE_UPDATED_callback(xqc_log_t *log, const char *func, xqc_h3_stream_t *h3_stream)
{
xqc_log_implement(log, QPACK_STREAM_STATE_UPDATED, func,
"|stream_id:%ui|%s|", h3_stream->stream->stream_id,
"|stream_id:%ui|%s|", h3_stream->stream_id,
h3_stream->flags & XQC_HTTP3_STREAM_FLAG_QPACK_DECODE_BLOCKED ? "blocked" : "unblocked");
}

Expand Down
2 changes: 2 additions & 0 deletions src/common/xqc_log_event_callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ void xqc_log_TRA_STREAM_STATE_UPDATED_callback(xqc_log_t *log, const char *func,

void xqc_log_TRA_FRAMES_PROCESSED_callback(xqc_log_t *log, const char *func, ...);

void xqc_log_TRA_STATELESS_RESET_callback(xqc_log_t *log, const char *func, xqc_connection_t *c);

void xqc_log_REC_PARAMETERS_SET_callback(xqc_log_t *log, const char *func, xqc_send_ctl_t *send_ctl);

void xqc_log_REC_METRICS_UPDATED_callback(xqc_log_t *log, const char *func, xqc_send_ctl_t *send_ctl);
Expand Down
9 changes: 9 additions & 0 deletions src/http3/xqc_h3_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,15 @@ xqc_h3_request_end(xqc_h3_request_t *h3r)
XQC_H3_REQUEST_RECORD_TIME(h3r->h3r_end_time);
}

void
xqc_h3_request_closing(xqc_h3_request_t *h3r, xqc_int_t err)
{
if (h3r->request_if->h3_request_closing_notify) {
h3r->request_if->h3_request_closing_notify(h3r, err, h3r->user_data);
}
}


#define XQC_PRIORITY_URGENCY "u="
#define XQC_PRIORITY_URGENCY_LEN 2

Expand Down
1 change: 1 addition & 0 deletions src/http3/xqc_h3_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,6 @@ void xqc_h3_request_on_body_send(xqc_h3_request_t *h3r);
void xqc_h3_request_stream_fin(xqc_h3_request_t *h3r);
void xqc_h3_request_begin(xqc_h3_request_t *h3r);
void xqc_h3_request_end(xqc_h3_request_t *h3r);
void xqc_h3_request_closing(xqc_h3_request_t *h3r, xqc_int_t err);

#endif /* _XQC_H3_REQUEST_H_INCLUDED_ */
26 changes: 23 additions & 3 deletions src/http3/xqc_h3_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1883,13 +1883,33 @@ xqc_h3_stream_close_notify(xqc_stream_t *stream, void *user_data)
}


void
xqc_h3_stream_closing_notify(xqc_stream_t *stream,
xqc_int_t err_code, void *strm_user_data)
{
xqc_h3_stream_t *h3s;

h3s = (xqc_h3_stream_t *)strm_user_data;
if (NULL == h3s) {
return;
}

/* only http3 request shall be notified */
if (h3s->type == XQC_H3_STREAM_TYPE_REQUEST
&& h3s->h3r)
{
xqc_h3_request_closing(h3s->h3r, err_code);
}
}

/**
* transport callback
*/
const xqc_stream_callbacks_t h3_stream_callbacks = {
.stream_write_notify = xqc_h3_stream_write_notify,
.stream_read_notify = xqc_h3_stream_read_notify,
.stream_close_notify = xqc_h3_stream_close_notify,
.stream_write_notify = xqc_h3_stream_write_notify,
.stream_read_notify = xqc_h3_stream_read_notify,
.stream_close_notify = xqc_h3_stream_close_notify,
.stream_closing_notify = xqc_h3_stream_closing_notify,
};


Expand Down
12 changes: 11 additions & 1 deletion src/transport/xqc_cid.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ xqc_cid_copy(xqc_cid_t *dst, xqc_cid_t *src)
dst->cid_len = src->cid_len;
xqc_memcpy(dst->cid_buf, src->cid_buf, dst->cid_len);
dst->cid_seq_num = src->cid_seq_num;
xqc_memcpy(dst->sr_token, src->sr_token, XQC_STATELESS_RESET_TOKENLEN);
}

void
Expand All @@ -83,6 +84,7 @@ xqc_cid_set(xqc_cid_t *cid, const unsigned char *data, uint8_t len)

static unsigned char g_scid_buf[XQC_MAX_CID_LEN * 2 + 1];
static unsigned char g_dcid_buf[XQC_MAX_CID_LEN * 2 + 1];
static unsigned char g_sr_token_buf[XQC_STATELESS_RESET_TOKENLEN * 2 + 1];

unsigned char *
xqc_dcid_str(const xqc_cid_t *dcid)
Expand All @@ -100,6 +102,14 @@ xqc_scid_str(const xqc_cid_t *scid)
return g_scid_buf;
}

unsigned char *
xqc_sr_token_str(const char *sr_token)
{
xqc_hex_dump(g_sr_token_buf, sr_token, XQC_STATELESS_RESET_TOKENLEN);
g_sr_token_buf[XQC_STATELESS_RESET_TOKENLEN * 2] = '\0';
return g_sr_token_buf;
}

unsigned char *
xqc_dcid_str_by_scid(xqc_engine_t *engine, const xqc_cid_t *scid)
{
Expand Down Expand Up @@ -160,7 +170,7 @@ xqc_destroy_cid_set(xqc_cid_set_t *cid_set)
xqc_int_t
xqc_cid_set_insert_cid(xqc_cid_set_t *cid_set, xqc_cid_t *cid, xqc_cid_state_t state, uint64_t limit)
{
if (cid_set->unused_cnt + cid_set->used_cnt >= limit) {
if (cid_set->unused_cnt + cid_set->used_cnt > limit) {
return -XQC_EACTIVE_CID_LIMIT;
}

Expand Down
3 changes: 3 additions & 0 deletions src/transport/xqc_cid.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,8 @@ xqc_cid_inner_t *xqc_cid_in_cid_set(const xqc_cid_set_t *cid_set, xqc_cid_t *cid
xqc_int_t xqc_cid_switch_to_next_state(xqc_cid_set_t *cid_set, xqc_cid_inner_t *cid, xqc_cid_state_t state);
xqc_int_t xqc_get_unused_cid(xqc_cid_set_t *cid_set, xqc_cid_t *cid);


unsigned char *xqc_sr_token_str(const char *sr_token);

#endif /* _XQC_CID_H_INCLUDED_ */

Loading