comparison src/event/quic/ngx_event_quic.c @ 8698:9ed95726b99b quic

QUIC: send PING frames on PTO expiration. Two PING frames are sent per level that generate two UDP datagrams.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 12 Feb 2021 14:51:53 +0300
parents faa3201ff351
children ba9e34c03968
comparison
equal deleted inserted replaced
8697:faa3201ff351 8698:9ed95726b99b
5097 f->first = now; 5097 f->first = now;
5098 f->last = now; 5098 f->last = now;
5099 f->plen = 0; 5099 f->plen = 0;
5100 5100
5101 nframes++; 5101 nframes++;
5102
5103 if (f->flush) {
5104 break;
5105 }
5102 } 5106 }
5103 5107
5104 if (nframes == 0) { 5108 if (nframes == 0) {
5105 return 0; 5109 return 0;
5106 } 5110 }
5344 5348
5345 static void 5349 static void
5346 ngx_quic_pto_handler(ngx_event_t *ev) 5350 ngx_quic_pto_handler(ngx_event_t *ev)
5347 { 5351 {
5348 ngx_uint_t i; 5352 ngx_uint_t i;
5349 ngx_queue_t *q; 5353 ngx_msec_t now;
5354 ngx_queue_t *q, *next;
5350 ngx_connection_t *c; 5355 ngx_connection_t *c;
5351 ngx_quic_frame_t *start; 5356 ngx_quic_frame_t *f;
5352 ngx_quic_send_ctx_t *ctx; 5357 ngx_quic_send_ctx_t *ctx;
5353 ngx_quic_connection_t *qc; 5358 ngx_quic_connection_t *qc;
5354 5359
5355 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic pto timer"); 5360 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic pto timer");
5356 5361
5357 c = ev->data; 5362 c = ev->data;
5358 qc = ngx_quic_get_connection(c); 5363 qc = ngx_quic_get_connection(c);
5359 5364 now = ngx_current_msec;
5360 qc->pto_count++;
5361 5365
5362 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { 5366 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
5363 5367
5364 ctx = &qc->send_ctx[i]; 5368 ctx = &qc->send_ctx[i];
5365 5369
5366 if (ngx_queue_empty(&ctx->sent)) { 5370 if (ngx_queue_empty(&ctx->sent)) {
5367 continue; 5371 continue;
5368 } 5372 }
5369 5373
5370 q = ngx_queue_head(&ctx->sent); 5374 q = ngx_queue_head(&ctx->sent);
5371 start = ngx_queue_data(q, ngx_quic_frame_t, queue); 5375 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
5372 5376
5373 if (start->pnum <= ctx->largest_ack 5377 if (f->pnum <= ctx->largest_ack
5374 && ctx->largest_ack != NGX_QUIC_UNSET_PN) 5378 && ctx->largest_ack != NGX_QUIC_UNSET_PN)
5375 { 5379 {
5376 continue; 5380 continue;
5377 } 5381 }
5378 5382
5379 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, 5383 if ((ngx_msec_int_t) (f->last + ngx_quic_pto(c, ctx) - now) > 0) {
5380 "quic pto pnum:%uL pto_count:%ui level:%d", 5384 continue;
5381 start->pnum, qc->pto_count, start->level); 5385 }
5382 5386
5383 ngx_quic_resend_frames(c, ctx); 5387 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
5384 } 5388 "quic pto %s pto_count:%ui",
5389 ngx_quic_level_name(ctx->level), qc->pto_count);
5390
5391 for (q = ngx_queue_head(&ctx->frames);
5392 q != ngx_queue_sentinel(&ctx->frames);
5393 /* void */)
5394 {
5395 next = ngx_queue_next(q);
5396 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
5397
5398 if (f->type == NGX_QUIC_FT_PING) {
5399 ngx_queue_remove(q);
5400 ngx_quic_free_frame(c, f);
5401 }
5402
5403 q = next;
5404 }
5405
5406 for (q = ngx_queue_head(&ctx->sent);
5407 q != ngx_queue_sentinel(&ctx->sent);
5408 /* void */)
5409 {
5410 next = ngx_queue_next(q);
5411 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
5412
5413 if (f->type == NGX_QUIC_FT_PING) {
5414 ngx_quic_congestion_lost(c, f);
5415 ngx_queue_remove(q);
5416 ngx_quic_free_frame(c, f);
5417 }
5418
5419 q = next;
5420 }
5421
5422 /* enforce 2 udp datagrams */
5423
5424 f = ngx_quic_alloc_frame(c);
5425 if (f == NULL) {
5426 break;
5427 }
5428
5429 f->level = ctx->level;
5430 f->type = NGX_QUIC_FT_PING;
5431 f->flush = 1;
5432
5433 ngx_quic_queue_frame(qc, f);
5434
5435 f = ngx_quic_alloc_frame(c);
5436 if (f == NULL) {
5437 break;
5438 }
5439
5440 f->level = ctx->level;
5441 f->type = NGX_QUIC_FT_PING;
5442
5443 ngx_quic_queue_frame(qc, f);
5444 }
5445
5446 qc->pto_count++;
5385 5447
5386 ngx_quic_connstate_dbg(c); 5448 ngx_quic_connstate_dbg(c);
5387 } 5449 }
5388 5450
5389 5451