mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
Merge 9b1b2c4220
into ecb809305e
This commit is contained in:
commit
d5584fcdfd
@ -628,6 +628,12 @@ ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
|
|||||||
ngx_quic_queue_frame(qc, f);
|
ngx_quic_queue_frame(qc, f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NGX_QUIC_FT_DATA_BLOCKED:
|
||||||
|
if (qc->streams.send_max_data == f->u.data_blocked.limit) {
|
||||||
|
ngx_queue_insert_tail(&ctx->frames, &f->queue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case NGX_QUIC_FT_STREAM:
|
case NGX_QUIC_FT_STREAM:
|
||||||
qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
|
qs = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ typedef struct {
|
|||||||
uint64_t client_streams_uni;
|
uint64_t client_streams_uni;
|
||||||
uint64_t client_streams_bidi;
|
uint64_t client_streams_bidi;
|
||||||
|
|
||||||
ngx_uint_t initialized;
|
unsigned initialized:1;
|
||||||
/* unsigned initialized:1; */
|
unsigned flow_control_blocked:1;
|
||||||
} ngx_quic_streams_t;
|
} ngx_quic_streams_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1054,6 +1054,30 @@ ngx_quic_stream_flush(ngx_quic_stream_t *qs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0 && !last) {
|
if (len == 0 && !last) {
|
||||||
|
/*
|
||||||
|
* RFC 9000, 4.1. Data Flow Control
|
||||||
|
*
|
||||||
|
* A sender SHOULD send a STREAM_DATA_BLOCKED or DATA_BLOCKED frame to
|
||||||
|
* indicate to the receiver that it has data to write but is blocked by
|
||||||
|
* flow control limits.
|
||||||
|
*/
|
||||||
|
if (qc->streams.send_max_data == qc->streams.send_offset
|
||||||
|
&& !qc->streams.flow_control_blocked)
|
||||||
|
{
|
||||||
|
qc->streams.flow_control_blocked = 1;
|
||||||
|
|
||||||
|
frame = ngx_quic_alloc_frame(pc);
|
||||||
|
if (frame == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->level = ssl_encryption_application;
|
||||||
|
frame->type = NGX_QUIC_FT_DATA_BLOCKED;
|
||||||
|
frame->u.data_blocked.limit = qc->streams.send_max_data;
|
||||||
|
|
||||||
|
ngx_quic_queue_frame(qc, frame);
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1344,6 +1368,8 @@ ngx_quic_handle_max_data_frame(ngx_connection_t *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
qc->streams.send_max_data = f->max_data;
|
qc->streams.send_max_data = f->max_data;
|
||||||
|
qc->streams.flow_control_blocked = 0;
|
||||||
|
|
||||||
node = ngx_rbtree_min(tree->root, tree->sentinel);
|
node = ngx_rbtree_min(tree->root, tree->sentinel);
|
||||||
|
|
||||||
while (node && qc->streams.send_offset < qc->streams.send_max_data) {
|
while (node && qc->streams.send_offset < qc->streams.send_max_data) {
|
||||||
|
@ -118,6 +118,8 @@ static size_t ngx_quic_create_max_stream_data(u_char *p,
|
|||||||
ngx_quic_max_stream_data_frame_t *ms);
|
ngx_quic_max_stream_data_frame_t *ms);
|
||||||
static size_t ngx_quic_create_max_data(u_char *p,
|
static size_t ngx_quic_create_max_data(u_char *p,
|
||||||
ngx_quic_max_data_frame_t *md);
|
ngx_quic_max_data_frame_t *md);
|
||||||
|
static size_t ngx_quic_create_data_blocked(u_char *p,
|
||||||
|
ngx_quic_data_blocked_frame_t *db);
|
||||||
static size_t ngx_quic_create_path_challenge(u_char *p,
|
static size_t ngx_quic_create_path_challenge(u_char *p,
|
||||||
ngx_quic_path_challenge_frame_t *pc);
|
ngx_quic_path_challenge_frame_t *pc);
|
||||||
static size_t ngx_quic_create_path_response(u_char *p,
|
static size_t ngx_quic_create_path_response(u_char *p,
|
||||||
@ -1328,6 +1330,9 @@ ngx_quic_create_frame(u_char *p, ngx_quic_frame_t *f)
|
|||||||
case NGX_QUIC_FT_MAX_DATA:
|
case NGX_QUIC_FT_MAX_DATA:
|
||||||
return ngx_quic_create_max_data(p, &f->u.max_data);
|
return ngx_quic_create_max_data(p, &f->u.max_data);
|
||||||
|
|
||||||
|
case NGX_QUIC_FT_DATA_BLOCKED:
|
||||||
|
return ngx_quic_create_data_blocked(p, &f->u.data_blocked);
|
||||||
|
|
||||||
case NGX_QUIC_FT_PATH_CHALLENGE:
|
case NGX_QUIC_FT_PATH_CHALLENGE:
|
||||||
return ngx_quic_create_path_challenge(p, &f->u.path_challenge);
|
return ngx_quic_create_path_challenge(p, &f->u.path_challenge);
|
||||||
|
|
||||||
@ -1889,6 +1894,27 @@ ngx_quic_create_max_data(u_char *p, ngx_quic_max_data_frame_t *md)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
ngx_quic_create_data_blocked(u_char *p, ngx_quic_data_blocked_frame_t *db)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
u_char *start;
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
len = ngx_quic_varint_len(NGX_QUIC_FT_DATA_BLOCKED);
|
||||||
|
len += ngx_quic_varint_len(db->limit);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = p;
|
||||||
|
|
||||||
|
ngx_quic_build_int(&p, NGX_QUIC_FT_DATA_BLOCKED);
|
||||||
|
ngx_quic_build_int(&p, db->limit);
|
||||||
|
|
||||||
|
return p - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ngx_quic_create_path_challenge(u_char *p, ngx_quic_path_challenge_frame_t *pc)
|
ngx_quic_create_path_challenge(u_char *p, ngx_quic_path_challenge_frame_t *pc)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user