mirror of
https://github.com/nginx/nginx.git
synced 2025-01-22 04:02:58 +08:00
QUIC: send PING frames on PTO expiration.
Two PING frames are sent per level that generate two UDP datagrams.
This commit is contained in:
parent
8084a829d0
commit
5d4e864e0d
@ -5099,6 +5099,10 @@ ngx_quic_output_packet(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
|
||||
f->plen = 0;
|
||||
|
||||
nframes++;
|
||||
|
||||
if (f->flush) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nframes == 0) {
|
||||
@ -5346,9 +5350,10 @@ static void
|
||||
ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_queue_t *q;
|
||||
ngx_msec_t now;
|
||||
ngx_queue_t *q, *next;
|
||||
ngx_connection_t *c;
|
||||
ngx_quic_frame_t *start;
|
||||
ngx_quic_frame_t *f;
|
||||
ngx_quic_send_ctx_t *ctx;
|
||||
ngx_quic_connection_t *qc;
|
||||
|
||||
@ -5356,8 +5361,7 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
|
||||
c = ev->data;
|
||||
qc = ngx_quic_get_connection(c);
|
||||
|
||||
qc->pto_count++;
|
||||
now = ngx_current_msec;
|
||||
|
||||
for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
|
||||
|
||||
@ -5368,21 +5372,79 @@ ngx_quic_pto_handler(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
q = ngx_queue_head(&ctx->sent);
|
||||
start = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
|
||||
if (start->pnum <= ctx->largest_ack
|
||||
if (f->pnum <= ctx->largest_ack
|
||||
&& ctx->largest_ack != NGX_QUIC_UNSET_PN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic pto pnum:%uL pto_count:%ui level:%d",
|
||||
start->pnum, qc->pto_count, start->level);
|
||||
if ((ngx_msec_int_t) (f->last + ngx_quic_pto(c, ctx) - now) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_quic_resend_frames(c, ctx);
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"quic pto %s pto_count:%ui",
|
||||
ngx_quic_level_name(ctx->level), qc->pto_count);
|
||||
|
||||
for (q = ngx_queue_head(&ctx->frames);
|
||||
q != ngx_queue_sentinel(&ctx->frames);
|
||||
/* void */)
|
||||
{
|
||||
next = ngx_queue_next(q);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
|
||||
if (f->type == NGX_QUIC_FT_PING) {
|
||||
ngx_queue_remove(q);
|
||||
ngx_quic_free_frame(c, f);
|
||||
}
|
||||
|
||||
q = next;
|
||||
}
|
||||
|
||||
for (q = ngx_queue_head(&ctx->sent);
|
||||
q != ngx_queue_sentinel(&ctx->sent);
|
||||
/* void */)
|
||||
{
|
||||
next = ngx_queue_next(q);
|
||||
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
|
||||
|
||||
if (f->type == NGX_QUIC_FT_PING) {
|
||||
ngx_quic_congestion_lost(c, f);
|
||||
ngx_queue_remove(q);
|
||||
ngx_quic_free_frame(c, f);
|
||||
}
|
||||
|
||||
q = next;
|
||||
}
|
||||
|
||||
/* enforce 2 udp datagrams */
|
||||
|
||||
f = ngx_quic_alloc_frame(c);
|
||||
if (f == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
f->level = ctx->level;
|
||||
f->type = NGX_QUIC_FT_PING;
|
||||
f->flush = 1;
|
||||
|
||||
ngx_quic_queue_frame(qc, f);
|
||||
|
||||
f = ngx_quic_alloc_frame(c);
|
||||
if (f == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
f->level = ctx->level;
|
||||
f->type = NGX_QUIC_FT_PING;
|
||||
|
||||
ngx_quic_queue_frame(qc, f);
|
||||
}
|
||||
|
||||
qc->pto_count++;
|
||||
|
||||
ngx_quic_connstate_dbg(c);
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ static size_t ngx_quic_create_short_header(ngx_quic_header_t *pkt, u_char *out,
|
||||
|
||||
static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt,
|
||||
ngx_uint_t frame_type);
|
||||
static size_t ngx_quic_create_ping(u_char *p);
|
||||
static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack,
|
||||
ngx_chain_t *ranges);
|
||||
static size_t ngx_quic_create_stop_sending(u_char *p,
|
||||
@ -1220,6 +1221,9 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
||||
f->need_ack = 1;
|
||||
|
||||
switch (f->type) {
|
||||
case NGX_QUIC_FT_PING:
|
||||
return ngx_quic_create_ping(p);
|
||||
|
||||
case NGX_QUIC_FT_ACK:
|
||||
f->need_ack = 0;
|
||||
return ngx_quic_create_ack(p, &f->u.ack, f->data);
|
||||
@ -1276,6 +1280,23 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_ping(u_char *p)
|
||||
{
|
||||
u_char *start;
|
||||
|
||||
if (p == NULL) {
|
||||
return ngx_quic_varint_len(NGX_QUIC_FT_PING);
|
||||
}
|
||||
|
||||
start = p;
|
||||
|
||||
ngx_quic_build_int(&p, NGX_QUIC_FT_PING);
|
||||
|
||||
return p - start;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack, ngx_chain_t *ranges)
|
||||
{
|
||||
|
@ -263,8 +263,8 @@ struct ngx_quic_frame_s {
|
||||
ngx_msec_t first;
|
||||
ngx_msec_t last;
|
||||
ssize_t len;
|
||||
ngx_uint_t need_ack;
|
||||
/* unsigned need_ack:1; */
|
||||
unsigned need_ack:1;
|
||||
unsigned flush:1;
|
||||
|
||||
ngx_chain_t *data;
|
||||
union {
|
||||
|
Loading…
Reference in New Issue
Block a user