mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
QUIC: enforce flow control on incoming STREAM and CRYPTO frames.
This commit is contained in:
parent
693e55a4b2
commit
d69471b81b
@ -2802,13 +2802,6 @@ ngx_quic_buffer_frame(ngx_connection_t *c, ngx_quic_frames_stream_t *fs,
|
||||
|
||||
/* frame start offset is in the future, buffer it */
|
||||
|
||||
/* check limit on total size used by all buffered frames, not actual data */
|
||||
if (NGX_QUIC_MAX_BUFFERED - fs->total < f->length) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
"quic ordered input buffer limit exceeded");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
dst = ngx_quic_alloc_frame(c, f->length);
|
||||
if (dst == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -2857,11 +2850,22 @@ static ngx_int_t
|
||||
ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
ngx_quic_frame_t *frame)
|
||||
{
|
||||
uint64_t last;
|
||||
ngx_quic_connection_t *qc;
|
||||
ngx_quic_crypto_frame_t *f;
|
||||
ngx_quic_frames_stream_t *fs;
|
||||
|
||||
qc = c->quic;
|
||||
fs = &qc->crypto[pkt->level];
|
||||
f = &frame->u.crypto;
|
||||
|
||||
/* no overflow since both values are 62-bit */
|
||||
last = f->offset + f->length;
|
||||
|
||||
if (last > fs->received && last - fs->received > NGX_QUIC_MAX_BUFFERED) {
|
||||
c->quic->error = NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_crypto_input,
|
||||
NULL);
|
||||
@ -2978,6 +2982,9 @@ static ngx_int_t
|
||||
ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
ngx_quic_frame_t *frame)
|
||||
{
|
||||
size_t window;
|
||||
uint64_t last;
|
||||
ngx_buf_t *b;
|
||||
ngx_pool_t *pool;
|
||||
ngx_connection_t *sc;
|
||||
ngx_quic_stream_t *sn;
|
||||
@ -2995,6 +3002,9 @@ ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* no overflow since both values are 62-bit */
|
||||
last = f->offset + f->length;
|
||||
|
||||
sn = ngx_quic_find_stream(&qc->streams.tree, f->stream_id);
|
||||
|
||||
if (sn == NULL) {
|
||||
@ -3010,17 +3020,19 @@ ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
|
||||
sc = sn->c;
|
||||
fs = &sn->fs;
|
||||
b = sn->b;
|
||||
window = b->end - b->last;
|
||||
|
||||
if (last > window) {
|
||||
c->quic->error = NGX_QUIC_ERR_FLOW_CONTROL_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_stream_input,
|
||||
sn)
|
||||
!= NGX_OK)
|
||||
{
|
||||
pool = sc->pool;
|
||||
|
||||
ngx_close_connection(sc);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sc->listening->handler(sc);
|
||||
@ -3029,9 +3041,25 @@ ngx_quic_handle_stream_frame(ngx_connection_t *c, ngx_quic_header_t *pkt,
|
||||
}
|
||||
|
||||
fs = &sn->fs;
|
||||
b = sn->b;
|
||||
window = (b->pos - b->start) + (b->end - b->last);
|
||||
|
||||
if (last > fs->received && last - fs->received > window) {
|
||||
c->quic->error = NGX_QUIC_ERR_FLOW_CONTROL_ERROR;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_stream_input,
|
||||
sn);
|
||||
|
||||
cleanup:
|
||||
|
||||
pool = sc->pool;
|
||||
|
||||
ngx_close_connection(sc);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user