Skip to content

Commit

Permalink
[+] release version 1.7.2 (#415)
Browse files Browse the repository at this point in the history
* [+] release version 1.7.2

* Update src/transport/xqc_send_ctl.c

* Update src/transport/xqc_send_ctl.c

---------

Co-authored-by: Yanmei Liu <healing4d@gmail.com>
  • Loading branch information
cherylsy and Yanmei-Liu committed Apr 25, 2024
1 parent b691b6e commit 1b6717f
Show file tree
Hide file tree
Showing 21 changed files with 408 additions and 68 deletions.
4 changes: 2 additions & 2 deletions demo/demo_client.c
Expand Up @@ -1268,10 +1268,10 @@ xqc_demo_cli_h3_request_close_notify(xqc_h3_request_t *h3_request, void *user_da
xqc_request_stats_t stats;
stats = xqc_h3_request_get_stats(h3_request);
printf("send_body_size:%zu, recv_body_size:%zu, send_header_size:%zu, recv_header_size:%zu, "
"recv_fin:%d, err:%d, rate_limit:%"PRIu64", mp_state:%d, early_data:%d, avail_send_weight:%.3lf, avail_recv_weight:%.3lf\n",
"recv_fin:%d, err:%d, rate_limit:%"PRIu64", mp_state:%d, early_data:%d, avail_send_weight:%.3lf, avail_recv_weight:%.3lf, cwnd_blk:%"PRIu64"\n",
stats.send_body_size, stats.recv_body_size, stats.send_header_size, stats.recv_header_size,
user_stream->recv_fin, stats.stream_err, stats.rate_limit, stats.mp_state, stats.early_data_state,
stats.mp_default_path_send_weight, stats.mp_default_path_recv_weight);
stats.mp_default_path_send_weight, stats.mp_default_path_recv_weight, stats.cwnd_blocked_ms);

printf("\033[33m[H3-req] send_bytes:%zu, recv_bytes:%zu, path_info:%s\n\033[0m",
stats.send_body_size + stats.send_header_size,
Expand Down
4 changes: 3 additions & 1 deletion demo/demo_server.c
Expand Up @@ -724,6 +724,9 @@ int
xqc_demo_svr_h3_request_close_notify(xqc_h3_request_t *h3_request, void *strm_user_data)
{
DEBUG;
xqc_request_stats_t stats = xqc_h3_request_get_stats(h3_request);
printf("cwnd_blocked:%"PRIu64"\n", stats.cwnd_blocked_ms);

xqc_demo_svr_user_stream_t *user_stream = (xqc_demo_svr_user_stream_t*)strm_user_data;
xqc_demo_svr_close_user_stream_resource(user_stream);
free(user_stream);
Expand Down Expand Up @@ -757,7 +760,6 @@ xqc_demo_svr_request_send_body(xqc_demo_svr_user_stream_t *user_stream, char *da
if (ret == -XQC_EAGAIN) {
ret = 0;
}

return ret;
}

Expand Down
17 changes: 16 additions & 1 deletion include/xquic/xqc_http3.h
Expand Up @@ -114,7 +114,7 @@ typedef struct xqc_http_headers_s {
} xqc_http_headers_t;


#define XQC_STREAM_INFO_LEN 100
#define XQC_STREAM_INFO_LEN 128

/**
* @brief request statistics structure
Expand Down Expand Up @@ -165,6 +165,21 @@ typedef struct xqc_request_stats_s {
uint8_t early_data_state;

char stream_info[XQC_STREAM_INFO_LEN];

xqc_usec_t stream_fst_fin_snd_time;

/**
* @brief how long the request was blocked by congestion control (ms)
*/
xqc_msec_t cwnd_blocked_ms;
/**
* @brief the number of packet has been retransmitted
*/
uint32_t retrans_cnt;

xqc_usec_t stream_fst_pkt_snd_time;
xqc_usec_t stream_fst_pkt_rcv_time;

} xqc_request_stats_t;

/**
Expand Down
77 changes: 63 additions & 14 deletions src/http3/xqc_h3_request.c
Expand Up @@ -59,7 +59,10 @@ xqc_h3_request_destroy(xqc_h3_request_t *h3_request)
"|rcvd_bdy_sz:%uz|snd_bdy_sz:%uz|rcvd_hdr_sz:%uz|snd_hdr_sz:%uz"
"|create:%ui|blkd:%ui|nblkd:%ui|hdr_b:%ui|hdr_e:%ui|bdy_b:%ui|fin:%ui|recv_end:%ui"
"|hrd_send:%ui|bdy_send:%ui|fin_send:%ui|fin_ack:%ui|last_send:%ui|last_recv:%ui"
"|mp_state:%d|path_info:%s|comp_hdr_s:%uz|comp_hdr_r:%uz|",
"|mp_state:%d|path_info:%s|comp_hdr_s:%uz|comp_hdr_r:%uz|fst_fin_snd:%ui|"
"sched_blk:%ud|sched_blk_time:%ui|"
"cwnd_blk:%ud|cwnd_blk_time:%ui|"
"pacing_blk:%ud|pacing_blk_time:%ui|begin_state:%s|end_state:%s|",
h3s->stream_id, stats.stream_close_msg ? stats.stream_close_msg : "",
stats.stream_err, stats.recv_body_size, stats.send_body_size,
stats.recv_header_size, stats.send_header_size,
Expand All @@ -78,7 +81,16 @@ xqc_h3_request_destroy(xqc_h3_request_t *h3_request)
xqc_calc_delay(h3_request->h3_stream->h3c->conn->conn_last_send_time, create_time),
xqc_calc_delay(h3_request->h3_stream->h3c->conn->conn_last_recv_time, create_time),
stats.mp_state, stats.stream_info, stats.send_hdr_compressed,
stats.recv_hdr_compressed);
stats.recv_hdr_compressed,
xqc_calc_delay(stats.stream_fst_fin_snd_time, create_time),
h3_request->sched_cwnd_blk_cnt,
h3_request->sched_cwnd_blk_duration / 1000,
h3_request->send_cwnd_blk_cnt,
h3_request->send_cwnd_blk_duration/ 1000,
h3_request->send_pacing_blk_cnt,
h3_request->send_pacing_blk_duration / 1000,
h3s->begin_trans_state,
h3s->end_trans_state);

if (h3_request->request_if->h3_request_close_notify) {
h3_request->request_if->h3_request_close_notify(h3_request, h3_request->user_data);
Expand Down Expand Up @@ -168,6 +180,37 @@ xqc_h3_request_create_inner(xqc_h3_conn_t *h3_conn, xqc_h3_stream_t *h3_stream,
return h3_request;
}

void
xqc_h3_request_encode_rtts(xqc_h3_request_t *h3r, char *buff, size_t buff_size)
{
xqc_h3_stream_t *h3_stream = h3r->h3_stream;
size_t cursor = 0;
int ret, i;

for (int i = 0; i < XQC_MAX_PATHS_COUNT; ++i) {
if ((h3_stream->paths_info[i].path_send_bytes > 0)
|| (h3_stream->paths_info[i].path_recv_bytes > 0))
{
ret = snprintf(buff + cursor, buff_size - cursor,
"%"PRIu64"-", h3_stream->paths_info[i].path_srtt / 1000);
cursor += ret;

if (cursor >= buff_size) {
break;
}
}
}

cursor = xqc_min(cursor, buff_size);
for (i = cursor - 1; i >= 0; i--) {
if (buff[i] == '-') {
buff[i] = '\0';
break;
}
}
buff[buff_size - 1] = '\0';
}

void
xqc_stream_info_print(xqc_h3_stream_t *h3_stream, xqc_request_stats_t *stats)
{
Expand All @@ -189,9 +232,10 @@ xqc_stream_info_print(xqc_h3_stream_t *h3_stream, xqc_request_stats_t *stats)

xqc_conn_encode_mp_settings(h3c->conn, mp_settings, XQC_MP_SETTINGS_STR_LEN);

ret = snprintf(buff, buff_size, "(%d,%"PRIu64",%s,%"PRIu64",%"PRIu64")#",
ret = snprintf(buff, buff_size, "(%d,%"PRIu64",%s,%"PRIu64",%"PRIu64",%"PRIu64",%u)#",
flag, h3_stream->recv_rate_limit, mp_settings,
h3_stream->send_offset, h3_stream->recv_offset);
h3_stream->send_offset, h3_stream->recv_offset,
stats->cwnd_blocked_ms, stats->retrans_cnt);

cursor += ret;

Expand Down Expand Up @@ -256,6 +300,9 @@ xqc_h3_request_get_stats(xqc_h3_request_t *h3_request)
xqc_request_stats_t stats;
xqc_memzero(&stats, sizeof(stats));

/* try to update stats */
xqc_h3_stream_update_stats(h3_request->h3_stream);

uint64_t conn_err = h3_request->h3_stream->h3c->conn->conn_err;
stats.recv_body_size = h3_request->body_recvd;
stats.send_body_size = h3_request->body_sent;
Expand All @@ -273,18 +320,17 @@ xqc_h3_request_get_stats(xqc_h3_request_t *h3_request)
stats.h3r_header_send_time = h3_request->h3r_header_send_time;
stats.h3r_body_send_time = h3_request->h3r_body_send_time;
stats.stream_fin_send_time = h3_request->stream_fin_send_time;
stats.stream_fst_fin_snd_time = h3_request->stream_fst_fin_snd_time;
stats.stream_fin_ack_time = h3_request->stream_fin_ack_time;
stats.stream_close_msg = h3_request->stream_close_msg;
stats.send_hdr_compressed = h3_request->compressed_header_sent;
stats.recv_hdr_compressed = h3_request->compressed_header_recvd;
stats.rate_limit = h3_request->h3_stream->recv_rate_limit;

/* try to update early data state */
if (h3_request->h3_stream->stream) {
xqc_h3_stream_update_early_data_state(h3_request->h3_stream);
}

stats.cwnd_blocked_ms = (h3_request->sched_cwnd_blk_duration + h3_request->send_cwnd_blk_duration) / 1000;
stats.early_data_state = h3_request->h3_stream->early_data_state;
stats.retrans_cnt = h3_request->retrans_pkt_cnt;
stats.stream_fst_pkt_snd_time = h3_request->stream_fst_pkt_snd_time;
stats.stream_fst_pkt_rcv_time = h3_request->stream_fst_pkt_rcv_time;

xqc_h3_stream_get_path_info(h3_request->h3_stream);
xqc_request_path_metrics_print(h3_request->h3_stream->h3c->conn,
Expand All @@ -299,8 +345,11 @@ xqc_h3_request_stats_print(xqc_h3_request_t *h3_request, char *str, size_t size)
{
xqc_request_stats_t stats = xqc_h3_request_get_stats(h3_request);
xqc_usec_t create_time = h3_request->h3r_begin_time;
char rtt_str[32] = {0};
xqc_h3_request_encode_rtts(h3_request, rtt_str, 32);
return snprintf(str, size, "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64
",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64,
",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",cc:%"PRIu64
",rtx:%u,rtt:%s",
h3_request->h3_stream->stream_id,
xqc_calc_delay(stats.h3r_header_begin_time, create_time) / 1000,
xqc_calc_delay(stats.h3r_header_end_time, create_time) / 1000,
Expand All @@ -310,7 +359,8 @@ xqc_h3_request_stats_print(xqc_h3_request_t *h3_request, char *str, size_t size)
xqc_calc_delay(stats.h3r_header_send_time, create_time) / 1000,
xqc_calc_delay(stats.h3r_body_send_time, create_time) / 1000,
xqc_calc_delay(stats.stream_fin_send_time, create_time) / 1000,
xqc_calc_delay(stats.stream_fin_ack_time, create_time) / 1000);
xqc_calc_delay(stats.stream_fin_ack_time, create_time) / 1000,
stats.cwnd_blocked_ms, stats.retrans_cnt, rtt_str);
}

void
Expand Down Expand Up @@ -384,7 +434,6 @@ xqc_h3_request_copy_header(xqc_http_header_t *dst, xqc_http_header_t *src, xqc_v
return XQC_OK;
}


ssize_t
xqc_h3_request_send_headers(xqc_h3_request_t *h3_request, xqc_http_headers_t *headers, uint8_t fin)
{
Expand Down Expand Up @@ -634,7 +683,7 @@ xqc_h3_request_on_recv_header(xqc_h3_request_t *h3r)
/* notify data before trailer headers*/
ret = xqc_h3_request_on_recv_body(h3r);
if (ret != XQC_OK) {
xqc_log(h3r->h3_stream->log, XQC_LOG_ERROR, "|xqc_h3_request_on_recv_body error|%d|", ret);
xqc_log(h3r->h3_stream->log, XQC_LOG_ERROR, "|recv body error|%d|", ret);
return ret;
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/http3/xqc_h3_request.h
Expand Up @@ -61,8 +61,20 @@ typedef struct xqc_h3_request_s {
xqc_usec_t h3r_body_send_time;
xqc_usec_t stream_fin_send_time;
xqc_usec_t stream_fin_ack_time;
xqc_usec_t stream_fst_fin_snd_time;
xqc_usec_t stream_fst_pkt_snd_time;
xqc_usec_t stream_fst_pkt_rcv_time;
const char *stream_close_msg;

uint32_t sched_cwnd_blk_cnt;
uint32_t send_cwnd_blk_cnt;
uint32_t send_pacing_blk_cnt;
xqc_usec_t sched_cwnd_blk_duration;
xqc_usec_t send_cwnd_blk_duration;
xqc_usec_t send_pacing_blk_duration;

uint32_t retrans_pkt_cnt;

} xqc_h3_request_t;

xqc_h3_request_t *xqc_h3_request_create_inner(xqc_h3_conn_t *h3_conn, xqc_h3_stream_t *h3_stream,
Expand Down
49 changes: 39 additions & 10 deletions src/http3/xqc_h3_stream.c
Expand Up @@ -1643,9 +1643,7 @@ xqc_h3_stream_process_data(xqc_stream_t *stream, xqc_h3_stream_t *h3s, xqc_bool_
if (h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
/* only request stream will be blocked */
xqc_h3_request_stream_fin(h3s->h3r);
h3s->send_offset = h3s->stream->stream_send_offset;
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;
xqc_h3_stream_update_early_data_state(h3s);
xqc_h3_stream_update_stats(h3s);
}
}

Expand Down Expand Up @@ -1882,10 +1880,42 @@ xqc_h3_stream_read_notify(xqc_stream_t *stream, void *user_data)
}

void
xqc_h3_stream_update_early_data_state(xqc_h3_stream_t *h3s)
xqc_h3_stream_update_stats(xqc_h3_stream_t *h3s)
{
if (h3s->stream == NULL) {
return;
}

if (h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
h3s->h3r->stream_fin_send_time = h3s->stream->stream_stats.local_fin_snd_time;
h3s->h3r->stream_fst_fin_snd_time = h3s->stream->stream_stats.local_fst_fin_snd_time;
h3s->h3r->stream_fin_ack_time = h3s->stream->stream_stats.first_fin_ack_time;
h3s->h3r->send_cwnd_blk_cnt = h3s->stream->stream_stats.send_cwnd_blk_cnt;
h3s->h3r->sched_cwnd_blk_cnt = h3s->stream->stream_stats.sched_cwnd_blk_cnt;
h3s->h3r->send_pacing_blk_cnt = h3s->stream->stream_stats.send_pacing_blk_cnt;
h3s->h3r->send_cwnd_blk_duration = h3s->stream->stream_stats.send_cwnd_blk_duration;
h3s->h3r->sched_cwnd_blk_duration = h3s->stream->stream_stats.sched_cwnd_blk_duration;
h3s->h3r->send_pacing_blk_duration = h3s->stream->stream_stats.send_pacing_blk_duration;
h3s->h3r->retrans_pkt_cnt = h3s->stream->stream_stats.retrans_pkt_cnt;
h3s->h3r->stream_fst_pkt_snd_time = h3s->stream->stream_stats.first_snd_time;
h3s->h3r->stream_fst_pkt_rcv_time = h3s->stream->stream_stats.first_rcv_time;
}

h3s->send_offset = h3s->stream->stream_send_offset;
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;

if (h3s->h3c == NULL) {
return;
}

xqc_connection_t *conn = xqc_h3_conn_get_xqc_conn(h3s->h3c);

if (conn == NULL) {
return;
}

if (h3s->stream->stream_flag & XQC_STREAM_FLAG_HAS_0RTT) {
if (h3s->h3c->conn->conn_flag & XQC_CONN_FLAG_0RTT_OK) {
if (conn->conn_flag & XQC_CONN_FLAG_0RTT_OK) {
h3s->early_data_state = 1;

} else {
Expand All @@ -1909,19 +1939,18 @@ xqc_h3_stream_close_notify(xqc_stream_t *stream, void *user_data)
xqc_h3_stream_get_path_info(h3s);

if (h3s->h3r && h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
h3s->h3r->stream_fin_send_time = h3s->stream->stream_stats.local_fin_snd_time;
h3s->h3r->stream_fin_ack_time = h3s->stream->stream_stats.first_fin_ack_time;
h3s->h3r->stream_close_msg = h3s->stream->stream_close_msg;
h3s->send_offset = h3s->stream->stream_send_offset;
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;
xqc_h3_stream_update_early_data_state(h3s);
xqc_h3_stream_update_stats(h3s);
}

if (h3s->h3_ext_bs && h3s->type == XQC_H3_STREAM_TYPE_BYTESTEAM) {
//TODO: record stats info
xqc_h3_ext_bytestream_save_stats_from_stream(h3s->h3_ext_bs, h3s->stream);
}

xqc_memcpy(h3s->begin_trans_state, stream->begin_trans_state, XQC_STREAM_TRANSPORT_STATE_SZ);
xqc_memcpy(h3s->end_trans_state, stream->end_trans_state, XQC_STREAM_TRANSPORT_STATE_SZ);

h3s->stream = NULL; /* stream closed, MUST NOT use it any more */

/*
Expand Down
6 changes: 5 additions & 1 deletion src/http3/xqc_h3_stream.h
Expand Up @@ -9,6 +9,7 @@
#include "src/http3/xqc_h3_defs.h"
#include "src/http3/qpack/xqc_qpack.h"
#include "src/http3/frame/xqc_h3_frame.h"
#include "src/transport/xqc_stream.h"

typedef struct xqc_h3_conn_s xqc_h3_conn_t;
typedef struct xqc_h3_stream_s xqc_h3_stream_t;
Expand Down Expand Up @@ -153,13 +154,16 @@ typedef struct xqc_h3_stream_s {

uint8_t early_data_state;

char begin_trans_state[XQC_STREAM_TRANSPORT_STATE_SZ];
char end_trans_state[XQC_STREAM_TRANSPORT_STATE_SZ];

} xqc_h3_stream_t;


/* transport layer callback hook */
extern const xqc_stream_callbacks_t h3_stream_callbacks;

void xqc_h3_stream_update_early_data_state(xqc_h3_stream_t *h3s);
void xqc_h3_stream_update_stats(xqc_h3_stream_t *h3s);

xqc_h3_stream_t *xqc_h3_stream_create(xqc_h3_conn_t *h3c, xqc_stream_t *stream,
xqc_h3_stream_type_t type, void *user_data);
Expand Down
2 changes: 1 addition & 1 deletion src/transport/scheduler/xqc_scheduler_common.c
Expand Up @@ -10,7 +10,7 @@ xqc_scheduler_check_path_can_send(xqc_path_ctx_t *path, xqc_packet_out_t *packet
uint32_t schedule_bytes = path->path_schedule_bytes;

/* normal packets in send list will be blocked by cc */
if (check_cwnd && (!xqc_send_packet_cwnd_allows(send_ctl, packet_out, schedule_bytes)))
if (check_cwnd && (!xqc_send_packet_cwnd_allows(send_ctl, packet_out, schedule_bytes, 0)))
{
xqc_log(send_ctl->ctl_conn->log, XQC_LOG_DEBUG, "|path:%ui|blocked by cwnd|", path->path_id);
return XQC_FALSE;
Expand Down

0 comments on commit 1b6717f

Please sign in to comment.