QUIC: optimized connection frame threshold.

Previosly the threshold was hardcoded at 10000.  This value is too low for
high BDP networks.  For example, if all frames are STREAM frames, and MTU
is 1500, the upper limit for congestion window would be roughly 15M
(10000 * 1500).  With 100ms RTT it's just a 1.2Gbps network (15M * 10 * 8).
In reality, the limit is even lower because of other frame types.  Also,
the number of frames that could be used simultaneously depends on the total
amount of data buffered in all server streams, and client flow control.

The change sets frame threshold based on max concurrent streams and stream
buffer size, the product of which is the maximum number of in-flight stream
data in all server streams at any moment.  The value is divided by 2000 to
account for a typical MTU 1500 and the fact that not all frames are STREAM
frames.
This commit is contained in:
Roman Arutyunyan 2025-04-04 17:39:05 +04:00 committed by Roman Arutyunyan
parent f9a7e7cc11
commit 2fb32ff24d
3 changed files with 6 additions and 1 deletions

View File

@ -315,6 +315,10 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE; qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE;
qc->congestion.recovery_start = ngx_current_msec - 1; qc->congestion.recovery_start = ngx_current_msec - 1;
qc->max_frames = (conf->max_concurrent_streams_uni
+ conf->max_concurrent_streams_bidi)
* conf->stream_buffer_size / 2000;
if (pkt->validated && pkt->retried) { if (pkt->validated && pkt->retried) {
qc->tp.retry_scid.len = pkt->dcid.len; qc->tp.retry_scid.len = pkt->dcid.len;
qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid); qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid);

View File

@ -261,6 +261,7 @@ struct ngx_quic_connection_s {
ngx_buf_t *free_shadow_bufs; ngx_buf_t *free_shadow_bufs;
ngx_uint_t nframes; ngx_uint_t nframes;
ngx_uint_t max_frames;
#ifdef NGX_QUIC_DEBUG_ALLOC #ifdef NGX_QUIC_DEBUG_ALLOC
ngx_uint_t nbufs; ngx_uint_t nbufs;
ngx_uint_t nshadowbufs; ngx_uint_t nshadowbufs;

View File

@ -214,7 +214,7 @@ ngx_quic_alloc_frame(ngx_connection_t *c)
"quic reuse frame n:%ui", qc->nframes); "quic reuse frame n:%ui", qc->nframes);
#endif #endif
} else if (qc->nframes < 10000) { } else if (qc->nframes < qc->max_frames) {
frame = ngx_palloc(c->pool, sizeof(ngx_quic_frame_t)); frame = ngx_palloc(c->pool, sizeof(ngx_quic_frame_t));
if (frame == NULL) { if (frame == NULL) {
return NULL; return NULL;