Skip to content

Commit 1b6717f

Browse files
cherylsyYanmei-Liu
andauthored
[+] release version 1.7.2 (#415)
* [+] release version 1.7.2 * Update src/transport/xqc_send_ctl.c * Update src/transport/xqc_send_ctl.c --------- Co-authored-by: Yanmei Liu <[email protected]>
1 parent b691b6e commit 1b6717f

21 files changed

+408
-68
lines changed

demo/demo_client.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1268,10 +1268,10 @@ xqc_demo_cli_h3_request_close_notify(xqc_h3_request_t *h3_request, void *user_da
12681268
xqc_request_stats_t stats;
12691269
stats = xqc_h3_request_get_stats(h3_request);
12701270
printf("send_body_size:%zu, recv_body_size:%zu, send_header_size:%zu, recv_header_size:%zu, "
1271-
"recv_fin:%d, err:%d, rate_limit:%"PRIu64", mp_state:%d, early_data:%d, avail_send_weight:%.3lf, avail_recv_weight:%.3lf\n",
1271+
"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",
12721272
stats.send_body_size, stats.recv_body_size, stats.send_header_size, stats.recv_header_size,
12731273
user_stream->recv_fin, stats.stream_err, stats.rate_limit, stats.mp_state, stats.early_data_state,
1274-
stats.mp_default_path_send_weight, stats.mp_default_path_recv_weight);
1274+
stats.mp_default_path_send_weight, stats.mp_default_path_recv_weight, stats.cwnd_blocked_ms);
12751275

12761276
printf("\033[33m[H3-req] send_bytes:%zu, recv_bytes:%zu, path_info:%s\n\033[0m",
12771277
stats.send_body_size + stats.send_header_size,

demo/demo_server.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,9 @@ int
724724
xqc_demo_svr_h3_request_close_notify(xqc_h3_request_t *h3_request, void *strm_user_data)
725725
{
726726
DEBUG;
727+
xqc_request_stats_t stats = xqc_h3_request_get_stats(h3_request);
728+
printf("cwnd_blocked:%"PRIu64"\n", stats.cwnd_blocked_ms);
729+
727730
xqc_demo_svr_user_stream_t *user_stream = (xqc_demo_svr_user_stream_t*)strm_user_data;
728731
xqc_demo_svr_close_user_stream_resource(user_stream);
729732
free(user_stream);
@@ -757,7 +760,6 @@ xqc_demo_svr_request_send_body(xqc_demo_svr_user_stream_t *user_stream, char *da
757760
if (ret == -XQC_EAGAIN) {
758761
ret = 0;
759762
}
760-
761763
return ret;
762764
}
763765

include/xquic/xqc_http3.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ typedef struct xqc_http_headers_s {
114114
} xqc_http_headers_t;
115115

116116

117-
#define XQC_STREAM_INFO_LEN 100
117+
#define XQC_STREAM_INFO_LEN 128
118118

119119
/**
120120
* @brief request statistics structure
@@ -165,6 +165,21 @@ typedef struct xqc_request_stats_s {
165165
uint8_t early_data_state;
166166

167167
char stream_info[XQC_STREAM_INFO_LEN];
168+
169+
xqc_usec_t stream_fst_fin_snd_time;
170+
171+
/**
172+
* @brief how long the request was blocked by congestion control (ms)
173+
*/
174+
xqc_msec_t cwnd_blocked_ms;
175+
/**
176+
* @brief the number of packet has been retransmitted
177+
*/
178+
uint32_t retrans_cnt;
179+
180+
xqc_usec_t stream_fst_pkt_snd_time;
181+
xqc_usec_t stream_fst_pkt_rcv_time;
182+
168183
} xqc_request_stats_t;
169184

170185
/**

src/http3/xqc_h3_request.c

+63-14
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ xqc_h3_request_destroy(xqc_h3_request_t *h3_request)
5959
"|rcvd_bdy_sz:%uz|snd_bdy_sz:%uz|rcvd_hdr_sz:%uz|snd_hdr_sz:%uz"
6060
"|create:%ui|blkd:%ui|nblkd:%ui|hdr_b:%ui|hdr_e:%ui|bdy_b:%ui|fin:%ui|recv_end:%ui"
6161
"|hrd_send:%ui|bdy_send:%ui|fin_send:%ui|fin_ack:%ui|last_send:%ui|last_recv:%ui"
62-
"|mp_state:%d|path_info:%s|comp_hdr_s:%uz|comp_hdr_r:%uz|",
62+
"|mp_state:%d|path_info:%s|comp_hdr_s:%uz|comp_hdr_r:%uz|fst_fin_snd:%ui|"
63+
"sched_blk:%ud|sched_blk_time:%ui|"
64+
"cwnd_blk:%ud|cwnd_blk_time:%ui|"
65+
"pacing_blk:%ud|pacing_blk_time:%ui|begin_state:%s|end_state:%s|",
6366
h3s->stream_id, stats.stream_close_msg ? stats.stream_close_msg : "",
6467
stats.stream_err, stats.recv_body_size, stats.send_body_size,
6568
stats.recv_header_size, stats.send_header_size,
@@ -78,7 +81,16 @@ xqc_h3_request_destroy(xqc_h3_request_t *h3_request)
7881
xqc_calc_delay(h3_request->h3_stream->h3c->conn->conn_last_send_time, create_time),
7982
xqc_calc_delay(h3_request->h3_stream->h3c->conn->conn_last_recv_time, create_time),
8083
stats.mp_state, stats.stream_info, stats.send_hdr_compressed,
81-
stats.recv_hdr_compressed);
84+
stats.recv_hdr_compressed,
85+
xqc_calc_delay(stats.stream_fst_fin_snd_time, create_time),
86+
h3_request->sched_cwnd_blk_cnt,
87+
h3_request->sched_cwnd_blk_duration / 1000,
88+
h3_request->send_cwnd_blk_cnt,
89+
h3_request->send_cwnd_blk_duration/ 1000,
90+
h3_request->send_pacing_blk_cnt,
91+
h3_request->send_pacing_blk_duration / 1000,
92+
h3s->begin_trans_state,
93+
h3s->end_trans_state);
8294

8395
if (h3_request->request_if->h3_request_close_notify) {
8496
h3_request->request_if->h3_request_close_notify(h3_request, h3_request->user_data);
@@ -168,6 +180,37 @@ xqc_h3_request_create_inner(xqc_h3_conn_t *h3_conn, xqc_h3_stream_t *h3_stream,
168180
return h3_request;
169181
}
170182

183+
void
184+
xqc_h3_request_encode_rtts(xqc_h3_request_t *h3r, char *buff, size_t buff_size)
185+
{
186+
xqc_h3_stream_t *h3_stream = h3r->h3_stream;
187+
size_t cursor = 0;
188+
int ret, i;
189+
190+
for (int i = 0; i < XQC_MAX_PATHS_COUNT; ++i) {
191+
if ((h3_stream->paths_info[i].path_send_bytes > 0)
192+
|| (h3_stream->paths_info[i].path_recv_bytes > 0))
193+
{
194+
ret = snprintf(buff + cursor, buff_size - cursor,
195+
"%"PRIu64"-", h3_stream->paths_info[i].path_srtt / 1000);
196+
cursor += ret;
197+
198+
if (cursor >= buff_size) {
199+
break;
200+
}
201+
}
202+
}
203+
204+
cursor = xqc_min(cursor, buff_size);
205+
for (i = cursor - 1; i >= 0; i--) {
206+
if (buff[i] == '-') {
207+
buff[i] = '\0';
208+
break;
209+
}
210+
}
211+
buff[buff_size - 1] = '\0';
212+
}
213+
171214
void
172215
xqc_stream_info_print(xqc_h3_stream_t *h3_stream, xqc_request_stats_t *stats)
173216
{
@@ -189,9 +232,10 @@ xqc_stream_info_print(xqc_h3_stream_t *h3_stream, xqc_request_stats_t *stats)
189232

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

192-
ret = snprintf(buff, buff_size, "(%d,%"PRIu64",%s,%"PRIu64",%"PRIu64")#",
235+
ret = snprintf(buff, buff_size, "(%d,%"PRIu64",%s,%"PRIu64",%"PRIu64",%"PRIu64",%u)#",
193236
flag, h3_stream->recv_rate_limit, mp_settings,
194-
h3_stream->send_offset, h3_stream->recv_offset);
237+
h3_stream->send_offset, h3_stream->recv_offset,
238+
stats->cwnd_blocked_ms, stats->retrans_cnt);
195239

196240
cursor += ret;
197241

@@ -256,6 +300,9 @@ xqc_h3_request_get_stats(xqc_h3_request_t *h3_request)
256300
xqc_request_stats_t stats;
257301
xqc_memzero(&stats, sizeof(stats));
258302

303+
/* try to update stats */
304+
xqc_h3_stream_update_stats(h3_request->h3_stream);
305+
259306
uint64_t conn_err = h3_request->h3_stream->h3c->conn->conn_err;
260307
stats.recv_body_size = h3_request->body_recvd;
261308
stats.send_body_size = h3_request->body_sent;
@@ -273,18 +320,17 @@ xqc_h3_request_get_stats(xqc_h3_request_t *h3_request)
273320
stats.h3r_header_send_time = h3_request->h3r_header_send_time;
274321
stats.h3r_body_send_time = h3_request->h3r_body_send_time;
275322
stats.stream_fin_send_time = h3_request->stream_fin_send_time;
323+
stats.stream_fst_fin_snd_time = h3_request->stream_fst_fin_snd_time;
276324
stats.stream_fin_ack_time = h3_request->stream_fin_ack_time;
277325
stats.stream_close_msg = h3_request->stream_close_msg;
278326
stats.send_hdr_compressed = h3_request->compressed_header_sent;
279327
stats.recv_hdr_compressed = h3_request->compressed_header_recvd;
280328
stats.rate_limit = h3_request->h3_stream->recv_rate_limit;
281-
282-
/* try to update early data state */
283-
if (h3_request->h3_stream->stream) {
284-
xqc_h3_stream_update_early_data_state(h3_request->h3_stream);
285-
}
286-
329+
stats.cwnd_blocked_ms = (h3_request->sched_cwnd_blk_duration + h3_request->send_cwnd_blk_duration) / 1000;
287330
stats.early_data_state = h3_request->h3_stream->early_data_state;
331+
stats.retrans_cnt = h3_request->retrans_pkt_cnt;
332+
stats.stream_fst_pkt_snd_time = h3_request->stream_fst_pkt_snd_time;
333+
stats.stream_fst_pkt_rcv_time = h3_request->stream_fst_pkt_rcv_time;
288334

289335
xqc_h3_stream_get_path_info(h3_request->h3_stream);
290336
xqc_request_path_metrics_print(h3_request->h3_stream->h3c->conn,
@@ -299,8 +345,11 @@ xqc_h3_request_stats_print(xqc_h3_request_t *h3_request, char *str, size_t size)
299345
{
300346
xqc_request_stats_t stats = xqc_h3_request_get_stats(h3_request);
301347
xqc_usec_t create_time = h3_request->h3r_begin_time;
348+
char rtt_str[32] = {0};
349+
xqc_h3_request_encode_rtts(h3_request, rtt_str, 32);
302350
return snprintf(str, size, "%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64
303-
",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64,
351+
",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",%"PRIu64",cc:%"PRIu64
352+
",rtx:%u,rtt:%s",
304353
h3_request->h3_stream->stream_id,
305354
xqc_calc_delay(stats.h3r_header_begin_time, create_time) / 1000,
306355
xqc_calc_delay(stats.h3r_header_end_time, create_time) / 1000,
@@ -310,7 +359,8 @@ xqc_h3_request_stats_print(xqc_h3_request_t *h3_request, char *str, size_t size)
310359
xqc_calc_delay(stats.h3r_header_send_time, create_time) / 1000,
311360
xqc_calc_delay(stats.h3r_body_send_time, create_time) / 1000,
312361
xqc_calc_delay(stats.stream_fin_send_time, create_time) / 1000,
313-
xqc_calc_delay(stats.stream_fin_ack_time, create_time) / 1000);
362+
xqc_calc_delay(stats.stream_fin_ack_time, create_time) / 1000,
363+
stats.cwnd_blocked_ms, stats.retrans_cnt, rtt_str);
314364
}
315365

316366
void
@@ -384,7 +434,6 @@ xqc_h3_request_copy_header(xqc_http_header_t *dst, xqc_http_header_t *src, xqc_v
384434
return XQC_OK;
385435
}
386436

387-
388437
ssize_t
389438
xqc_h3_request_send_headers(xqc_h3_request_t *h3_request, xqc_http_headers_t *headers, uint8_t fin)
390439
{
@@ -634,7 +683,7 @@ xqc_h3_request_on_recv_header(xqc_h3_request_t *h3r)
634683
/* notify data before trailer headers*/
635684
ret = xqc_h3_request_on_recv_body(h3r);
636685
if (ret != XQC_OK) {
637-
xqc_log(h3r->h3_stream->log, XQC_LOG_ERROR, "|xqc_h3_request_on_recv_body error|%d|", ret);
686+
xqc_log(h3r->h3_stream->log, XQC_LOG_ERROR, "|recv body error|%d|", ret);
638687
return ret;
639688
}
640689
}

src/http3/xqc_h3_request.h

+12
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,20 @@ typedef struct xqc_h3_request_s {
6161
xqc_usec_t h3r_body_send_time;
6262
xqc_usec_t stream_fin_send_time;
6363
xqc_usec_t stream_fin_ack_time;
64+
xqc_usec_t stream_fst_fin_snd_time;
65+
xqc_usec_t stream_fst_pkt_snd_time;
66+
xqc_usec_t stream_fst_pkt_rcv_time;
6467
const char *stream_close_msg;
6568

69+
uint32_t sched_cwnd_blk_cnt;
70+
uint32_t send_cwnd_blk_cnt;
71+
uint32_t send_pacing_blk_cnt;
72+
xqc_usec_t sched_cwnd_blk_duration;
73+
xqc_usec_t send_cwnd_blk_duration;
74+
xqc_usec_t send_pacing_blk_duration;
75+
76+
uint32_t retrans_pkt_cnt;
77+
6678
} xqc_h3_request_t;
6779

6880
xqc_h3_request_t *xqc_h3_request_create_inner(xqc_h3_conn_t *h3_conn, xqc_h3_stream_t *h3_stream,

src/http3/xqc_h3_stream.c

+39-10
Original file line numberDiff line numberDiff line change
@@ -1643,9 +1643,7 @@ xqc_h3_stream_process_data(xqc_stream_t *stream, xqc_h3_stream_t *h3s, xqc_bool_
16431643
if (h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
16441644
/* only request stream will be blocked */
16451645
xqc_h3_request_stream_fin(h3s->h3r);
1646-
h3s->send_offset = h3s->stream->stream_send_offset;
1647-
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;
1648-
xqc_h3_stream_update_early_data_state(h3s);
1646+
xqc_h3_stream_update_stats(h3s);
16491647
}
16501648
}
16511649

@@ -1882,10 +1880,42 @@ xqc_h3_stream_read_notify(xqc_stream_t *stream, void *user_data)
18821880
}
18831881

18841882
void
1885-
xqc_h3_stream_update_early_data_state(xqc_h3_stream_t *h3s)
1883+
xqc_h3_stream_update_stats(xqc_h3_stream_t *h3s)
18861884
{
1885+
if (h3s->stream == NULL) {
1886+
return;
1887+
}
1888+
1889+
if (h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
1890+
h3s->h3r->stream_fin_send_time = h3s->stream->stream_stats.local_fin_snd_time;
1891+
h3s->h3r->stream_fst_fin_snd_time = h3s->stream->stream_stats.local_fst_fin_snd_time;
1892+
h3s->h3r->stream_fin_ack_time = h3s->stream->stream_stats.first_fin_ack_time;
1893+
h3s->h3r->send_cwnd_blk_cnt = h3s->stream->stream_stats.send_cwnd_blk_cnt;
1894+
h3s->h3r->sched_cwnd_blk_cnt = h3s->stream->stream_stats.sched_cwnd_blk_cnt;
1895+
h3s->h3r->send_pacing_blk_cnt = h3s->stream->stream_stats.send_pacing_blk_cnt;
1896+
h3s->h3r->send_cwnd_blk_duration = h3s->stream->stream_stats.send_cwnd_blk_duration;
1897+
h3s->h3r->sched_cwnd_blk_duration = h3s->stream->stream_stats.sched_cwnd_blk_duration;
1898+
h3s->h3r->send_pacing_blk_duration = h3s->stream->stream_stats.send_pacing_blk_duration;
1899+
h3s->h3r->retrans_pkt_cnt = h3s->stream->stream_stats.retrans_pkt_cnt;
1900+
h3s->h3r->stream_fst_pkt_snd_time = h3s->stream->stream_stats.first_snd_time;
1901+
h3s->h3r->stream_fst_pkt_rcv_time = h3s->stream->stream_stats.first_rcv_time;
1902+
}
1903+
1904+
h3s->send_offset = h3s->stream->stream_send_offset;
1905+
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;
1906+
1907+
if (h3s->h3c == NULL) {
1908+
return;
1909+
}
1910+
1911+
xqc_connection_t *conn = xqc_h3_conn_get_xqc_conn(h3s->h3c);
1912+
1913+
if (conn == NULL) {
1914+
return;
1915+
}
1916+
18871917
if (h3s->stream->stream_flag & XQC_STREAM_FLAG_HAS_0RTT) {
1888-
if (h3s->h3c->conn->conn_flag & XQC_CONN_FLAG_0RTT_OK) {
1918+
if (conn->conn_flag & XQC_CONN_FLAG_0RTT_OK) {
18891919
h3s->early_data_state = 1;
18901920

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

19111941
if (h3s->h3r && h3s->type == XQC_H3_STREAM_TYPE_REQUEST) {
1912-
h3s->h3r->stream_fin_send_time = h3s->stream->stream_stats.local_fin_snd_time;
1913-
h3s->h3r->stream_fin_ack_time = h3s->stream->stream_stats.first_fin_ack_time;
19141942
h3s->h3r->stream_close_msg = h3s->stream->stream_close_msg;
1915-
h3s->send_offset = h3s->stream->stream_send_offset;
1916-
h3s->recv_offset = h3s->stream->stream_data_in.merged_offset_end;
1917-
xqc_h3_stream_update_early_data_state(h3s);
1943+
xqc_h3_stream_update_stats(h3s);
19181944
}
19191945

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

1951+
xqc_memcpy(h3s->begin_trans_state, stream->begin_trans_state, XQC_STREAM_TRANSPORT_STATE_SZ);
1952+
xqc_memcpy(h3s->end_trans_state, stream->end_trans_state, XQC_STREAM_TRANSPORT_STATE_SZ);
1953+
19251954
h3s->stream = NULL; /* stream closed, MUST NOT use it any more */
19261955

19271956
/*

src/http3/xqc_h3_stream.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "src/http3/xqc_h3_defs.h"
1010
#include "src/http3/qpack/xqc_qpack.h"
1111
#include "src/http3/frame/xqc_h3_frame.h"
12+
#include "src/transport/xqc_stream.h"
1213

1314
typedef struct xqc_h3_conn_s xqc_h3_conn_t;
1415
typedef struct xqc_h3_stream_s xqc_h3_stream_t;
@@ -153,13 +154,16 @@ typedef struct xqc_h3_stream_s {
153154

154155
uint8_t early_data_state;
155156

157+
char begin_trans_state[XQC_STREAM_TRANSPORT_STATE_SZ];
158+
char end_trans_state[XQC_STREAM_TRANSPORT_STATE_SZ];
159+
156160
} xqc_h3_stream_t;
157161

158162

159163
/* transport layer callback hook */
160164
extern const xqc_stream_callbacks_t h3_stream_callbacks;
161165

162-
void xqc_h3_stream_update_early_data_state(xqc_h3_stream_t *h3s);
166+
void xqc_h3_stream_update_stats(xqc_h3_stream_t *h3s);
163167

164168
xqc_h3_stream_t *xqc_h3_stream_create(xqc_h3_conn_t *h3c, xqc_stream_t *stream,
165169
xqc_h3_stream_type_t type, void *user_data);

src/transport/scheduler/xqc_scheduler_common.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ xqc_scheduler_check_path_can_send(xqc_path_ctx_t *path, xqc_packet_out_t *packet
1010
uint32_t schedule_bytes = path->path_schedule_bytes;
1111

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

0 commit comments

Comments
 (0)