Mercurial > hg > nginx
comparison src/event/ngx_event_quic.c @ 8476:f9fbeb4ee0de quic
QUIC: added limit of queued data.
The ngx_quic_queue_frame() functions puts a frame into send queue and
schedules a push timer to actually send data.
The patch adds tracking for data amount in the queue and sends data
immediately if amount of data exceeds limit.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Thu, 16 Jul 2020 15:02:38 +0300 |
parents | b276833111cf |
children | 031918df51c0 |
comparison
equal
deleted
inserted
replaced
8475:b276833111cf | 8476:f9fbeb4ee0de |
---|---|
71 uint64_t largest_ack; /* received from peer */ | 71 uint64_t largest_ack; /* received from peer */ |
72 uint64_t largest_pn; /* received from peer */ | 72 uint64_t largest_pn; /* received from peer */ |
73 | 73 |
74 ngx_queue_t frames; | 74 ngx_queue_t frames; |
75 ngx_queue_t sent; | 75 ngx_queue_t sent; |
76 | |
77 size_t frames_len; | |
76 } ngx_quic_send_ctx_t; | 78 } ngx_quic_send_ctx_t; |
77 | 79 |
78 | 80 |
79 struct ngx_quic_connection_s { | 81 struct ngx_quic_connection_s { |
80 ngx_str_t scid; | 82 ngx_str_t scid; |
3271 | 3273 |
3272 ctx = ngx_quic_get_send_ctx(qc, frame->level); | 3274 ctx = ngx_quic_get_send_ctx(qc, frame->level); |
3273 | 3275 |
3274 ngx_queue_insert_tail(&ctx->frames, &frame->queue); | 3276 ngx_queue_insert_tail(&ctx->frames, &frame->queue); |
3275 | 3277 |
3276 /* TODO: check PUSH flag on stream and call output */ | 3278 frame->len = ngx_quic_create_frame(NULL, frame); |
3277 | 3279 /* always succeeds */ |
3278 if (!qc->push.timer_set && !qc->closing) { | 3280 |
3279 ngx_add_timer(&qc->push, qc->tp.max_ack_delay); | 3281 ctx->frames_len += frame->len; |
3282 | |
3283 if (qc->closing) { | |
3284 return; | |
3285 } | |
3286 | |
3287 /* TODO: TCP_NODELAY analogue ? TCP_CORK and others... */ | |
3288 | |
3289 if (ctx->frames_len < NGX_QUIC_MIN_DATA_NODELAY) { | |
3290 if (!qc->push.timer_set) { | |
3291 ngx_add_timer(&qc->push, qc->tp.max_ack_delay); | |
3292 } | |
3293 | |
3294 } else { | |
3295 ngx_post_event(&qc->push, &ngx_posted_events); | |
3280 } | 3296 } |
3281 } | 3297 } |
3282 | 3298 |
3283 | 3299 |
3284 static ngx_int_t | 3300 static ngx_int_t |
3307 | 3323 |
3308 | 3324 |
3309 static ngx_int_t | 3325 static ngx_int_t |
3310 ngx_quic_output_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) | 3326 ngx_quic_output_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx) |
3311 { | 3327 { |
3312 size_t len, hlen, n; | 3328 size_t len, hlen; |
3313 ngx_uint_t need_ack; | 3329 ngx_uint_t need_ack; |
3314 ngx_queue_t *q, range; | 3330 ngx_queue_t *q, range; |
3315 ngx_quic_frame_t *f; | 3331 ngx_quic_frame_t *f; |
3316 ngx_quic_congestion_t *cg; | 3332 ngx_quic_congestion_t *cg; |
3317 ngx_quic_connection_t *qc; | 3333 ngx_quic_connection_t *qc; |
3338 | 3354 |
3339 do { | 3355 do { |
3340 /* process group of frames that fits into packet */ | 3356 /* process group of frames that fits into packet */ |
3341 f = ngx_queue_data(q, ngx_quic_frame_t, queue); | 3357 f = ngx_queue_data(q, ngx_quic_frame_t, queue); |
3342 | 3358 |
3343 n = ngx_quic_create_frame(NULL, f); | 3359 if (len && hlen + len + f->len > qc->ctp.max_udp_payload_size) { |
3344 | |
3345 if (len && hlen + len + n > qc->ctp.max_udp_payload_size) { | |
3346 break; | 3360 break; |
3347 } | 3361 } |
3348 | 3362 |
3349 if (f->need_ack) { | 3363 if (f->need_ack) { |
3350 need_ack = 1; | 3364 need_ack = 1; |
3351 } | 3365 } |
3352 | 3366 |
3353 if (need_ack && cg->in_flight + len + n > cg->window) { | 3367 if (need_ack && cg->in_flight + len + f->len > cg->window) { |
3354 break; | 3368 break; |
3355 } | 3369 } |
3356 | 3370 |
3357 q = ngx_queue_next(q); | 3371 q = ngx_queue_next(q); |
3358 | 3372 |
3359 f->first = ngx_current_msec; | 3373 f->first = ngx_current_msec; |
3360 | 3374 |
3361 ngx_queue_remove(&f->queue); | 3375 ngx_queue_remove(&f->queue); |
3362 ngx_queue_insert_tail(&range, &f->queue); | 3376 ngx_queue_insert_tail(&range, &f->queue); |
3363 | 3377 ctx->frames_len -= f->len; |
3364 len += n; | 3378 |
3379 len += f->len; | |
3365 | 3380 |
3366 } while (q != ngx_queue_sentinel(&ctx->frames)); | 3381 } while (q != ngx_queue_sentinel(&ctx->frames)); |
3367 | 3382 |
3368 if (ngx_queue_empty(&range)) { | 3383 if (ngx_queue_empty(&range)) { |
3369 break; | 3384 break; |
4269 | 4284 |
4270 | 4285 |
4271 static void | 4286 static void |
4272 ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f) | 4287 ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f) |
4273 { | 4288 { |
4274 ssize_t n; | |
4275 ngx_msec_t timer; | 4289 ngx_msec_t timer; |
4276 ngx_quic_congestion_t *cg; | 4290 ngx_quic_congestion_t *cg; |
4277 ngx_quic_connection_t *qc; | 4291 ngx_quic_connection_t *qc; |
4278 | 4292 |
4279 qc = c->quic; | 4293 qc = c->quic; |
4280 cg = &qc->congestion; | 4294 cg = &qc->congestion; |
4281 | 4295 |
4282 n = ngx_quic_create_frame(NULL, f); | 4296 cg->in_flight -= f->len; |
4283 | |
4284 cg->in_flight -= n; | |
4285 | 4297 |
4286 timer = f->last - cg->recovery_start; | 4298 timer = f->last - cg->recovery_start; |
4287 | 4299 |
4288 if ((ngx_msec_int_t) timer <= 0) { | 4300 if ((ngx_msec_int_t) timer <= 0) { |
4289 return; | 4301 return; |
4290 } | 4302 } |
4291 | 4303 |
4292 if (cg->window < cg->ssthresh) { | 4304 if (cg->window < cg->ssthresh) { |
4293 cg->window += n; | 4305 cg->window += f->len; |
4294 | 4306 |
4295 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | 4307 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
4296 "quic congestion slow start win:%uz, ss:%uz, if:%uz", | 4308 "quic congestion slow start win:%uz, ss:%uz, if:%uz", |
4297 cg->window, cg->ssthresh, cg->in_flight); | 4309 cg->window, cg->ssthresh, cg->in_flight); |
4298 | 4310 |
4299 } else { | 4311 } else { |
4300 cg->window += qc->tp.max_udp_payload_size * n / cg->window; | 4312 cg->window += qc->tp.max_udp_payload_size * f->len / cg->window; |
4301 | 4313 |
4302 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | 4314 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, |
4303 "quic congestion avoidance win:%uz, ss:%uz, if:%uz", | 4315 "quic congestion avoidance win:%uz, ss:%uz, if:%uz", |
4304 cg->window, cg->ssthresh, cg->in_flight); | 4316 cg->window, cg->ssthresh, cg->in_flight); |
4305 } | 4317 } |