comparison src/event/ngx_event_quic.c @ 8148:93be5658a250 quic

QUIC: reverted previous 3 commits. Changes were intended for the test repository.
author Vladimir Homutov <vl@nginx.com>
date Mon, 19 Oct 2020 10:32:53 +0300
parents 018baa412c0d
children 44991d728899
comparison
equal deleted inserted replaced
8147:018baa412c0d 8148:93be5658a250
91 */ 91 */
92 typedef struct { 92 typedef struct {
93 ngx_quic_secret_t client_secret; 93 ngx_quic_secret_t client_secret;
94 ngx_quic_secret_t server_secret; 94 ngx_quic_secret_t server_secret;
95 95
96 enum ssl_encryption_level_t level;
97
98 uint64_t pnum; /* to be sent */ 96 uint64_t pnum; /* to be sent */
99 uint64_t largest_ack; /* received from peer */ 97 uint64_t largest_ack; /* received from peer */
100 uint64_t largest_pn; /* received from peer */ 98 uint64_t largest_pn; /* received from peer */
101 99
102 ngx_queue_t frames; 100 ngx_queue_t frames;
103 ngx_queue_t sent; 101 ngx_queue_t sent;
104
105 uint64_t largest_range;
106 uint64_t first_range;
107 ngx_uint_t nranges;
108 ngx_quic_ack_range_t ranges[NGX_QUIC_MAX_RANGES];
109 struct timeval ack_received;
110 ngx_uint_t send_ack; /* unsigned send_ack:1 */
111 } ngx_quic_send_ctx_t; 102 } ngx_quic_send_ctx_t;
112 103
113 104
114 struct ngx_quic_connection_s { 105 struct ngx_quic_connection_s {
115 ngx_str_t scid; /* initial client ID */ 106 ngx_str_t scid; /* initial client ID */
237 enum ssl_encryption_level_t level); 228 enum ssl_encryption_level_t level);
238 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, 229 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc,
239 ngx_quic_header_t *pkt); 230 ngx_quic_header_t *pkt);
240 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, 231 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c,
241 ngx_quic_header_t *pkt); 232 ngx_quic_header_t *pkt);
242 static ngx_int_t ngx_quic_ack_packet(ngx_connection_t *c, 233 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt);
243 ngx_quic_header_t *pkt);
244 static ngx_int_t ngx_quic_send_ack_range(ngx_connection_t *c,
245 ngx_quic_send_ctx_t *ctx, uint64_t smallest, uint64_t largest);
246 static void ngx_quic_drop_ack_ranges(ngx_connection_t *c,
247 ngx_quic_send_ctx_t *ctx, uint64_t pn);
248 static ngx_int_t ngx_quic_send_ack(ngx_connection_t *c,
249 ngx_quic_send_ctx_t *ctx);
250 static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c, 234 static ngx_int_t ngx_quic_ack_delay(ngx_connection_t *c,
251 struct timeval *received, enum ssl_encryption_level_t level); 235 struct timeval *received, enum ssl_encryption_level_t level);
252 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c); 236 static ngx_int_t ngx_quic_send_cc(ngx_connection_t *c);
253 static ngx_int_t ngx_quic_send_new_token(ngx_connection_t *c); 237 static ngx_int_t ngx_quic_send_new_token(ngx_connection_t *c);
254 238
699 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { 683 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
700 ngx_queue_init(&qc->send_ctx[i].frames); 684 ngx_queue_init(&qc->send_ctx[i].frames);
701 ngx_queue_init(&qc->send_ctx[i].sent); 685 ngx_queue_init(&qc->send_ctx[i].sent);
702 qc->send_ctx[i].largest_pn = (uint64_t) -1; 686 qc->send_ctx[i].largest_pn = (uint64_t) -1;
703 qc->send_ctx[i].largest_ack = (uint64_t) -1; 687 qc->send_ctx[i].largest_ack = (uint64_t) -1;
704 qc->send_ctx[i].largest_range = (uint64_t) -1; 688 }
705 }
706
707 qc->send_ctx[0].level = ssl_encryption_initial;
708 qc->send_ctx[1].level = ssl_encryption_handshake;
709 qc->send_ctx[2].level = ssl_encryption_application;
710 689
711 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) { 690 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
712 ngx_queue_init(&qc->crypto[i].frames); 691 ngx_queue_init(&qc->crypto[i].frames);
713 } 692 }
714 693
1993 1972
1994 f = ngx_queue_data(q, ngx_quic_frame_t, queue); 1973 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
1995 ngx_quic_congestion_ack(c, f); 1974 ngx_quic_congestion_ack(c, f);
1996 ngx_quic_free_frame(c, f); 1975 ngx_quic_free_frame(c, f);
1997 } 1976 }
1998
1999 ctx->send_ack = 0;
2000 } 1977 }
2001 1978
2002 1979
2003 static ngx_int_t 1980 static ngx_int_t
2004 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) 1981 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
2130 } 2107 }
2131 2108
2132 /* got there with ack-eliciting packet */ 2109 /* got there with ack-eliciting packet */
2133 2110
2134 if (!ack_sent) { 2111 if (!ack_sent) {
2135 if (ngx_quic_ack_packet(c, pkt) != NGX_OK) { 2112 if (ngx_quic_send_ack(c, pkt) != NGX_OK) {
2136 return NGX_ERROR; 2113 return NGX_ERROR;
2137 } 2114 }
2138 2115
2139 ack_sent = 1; 2116 ack_sent = 1;
2140 } 2117 }
2295 return NGX_OK; 2272 return NGX_OK;
2296 } 2273 }
2297 2274
2298 2275
2299 static ngx_int_t 2276 static ngx_int_t
2300 ngx_quic_ack_packet(ngx_connection_t *c, ngx_quic_header_t *pkt) 2277 ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_header_t *pkt)
2301 {
2302 uint64_t base, largest, smallest, gs, ge, gap, range, pn;
2303 ngx_uint_t i, j, nr;
2304 ngx_quic_send_ctx_t *ctx;
2305 ngx_quic_ack_range_t *r;
2306
2307 c->log->action = "preparing ack";
2308
2309 ctx = ngx_quic_get_send_ctx(c->quic, pkt->level);
2310
2311 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
2312 "ngx_quic_ack_packet pn %uL largest %uL nranges %ui",
2313 pkt->pn, ctx->largest_range, ctx->nranges);
2314
2315 if (!ctx->send_ack) {
2316 ngx_post_event(&c->quic->push, &ngx_posted_events);
2317 }
2318
2319 ctx->send_ack = 1;
2320
2321 base = ctx->largest_range;
2322 pn = pkt->pn;
2323
2324 if (base == (uint64_t) -1) {
2325 ctx->largest_range = pn;
2326 ctx->ack_received = pkt->received;
2327 return NGX_OK;
2328 }
2329
2330 if (base == pn) {
2331 return NGX_OK;
2332 }
2333
2334 largest = base;
2335 smallest = largest - ctx->first_range;
2336
2337 if (pn > base) {
2338 ctx->largest_range = pn;
2339 ctx->ack_received = pkt->received;
2340
2341 if (pn - base == 1) {
2342 ctx->first_range++;
2343 return NGX_OK;
2344
2345 } else {
2346 /* new gap in front of current largest */
2347 gap = pn - base - 2;
2348 range = ctx->first_range;
2349
2350 ctx->first_range = 0;
2351 i = 0;
2352
2353 goto insert;
2354 }
2355 }
2356
2357 /* pn < base, perform lookup in existing ranges */
2358
2359 if (pn >= smallest && pn <= largest) {
2360 return NGX_OK;
2361 }
2362
2363 #if (NGX_SUPPRESS_WARN)
2364 r = NULL;
2365 #endif
2366
2367 for (i = 0; i < ctx->nranges; i++) {
2368 r = &ctx->ranges[i];
2369
2370 ge = smallest - 1;
2371 gs = ge - r->gap;
2372
2373 if (pn >= gs && pn <= ge) {
2374
2375 if (gs == ge) {
2376 /* gap size is exactly one packet, now filled */
2377
2378 /* data moves to previous range, current is removed */
2379
2380 if (i == 0) {
2381 ctx->first_range += r->range + 2;
2382
2383 } else {
2384 ctx->ranges[i - 1].range += r->range + 2;
2385 }
2386
2387 nr = ctx->nranges - i - 1;
2388 if (nr) {
2389 ngx_memmove(&ctx->ranges[i], &ctx->ranges[i + 1],
2390 sizeof(ngx_quic_ack_range_t) * nr);
2391 }
2392
2393 ctx->nranges--;
2394
2395 } else if (pn == gs) {
2396 /* current gap shrinks from tail (current range grows) */
2397 r->gap--;
2398 r->range++;
2399
2400 } else if (pn == ge) {
2401 /* current gap shrinks from head (previous range grows) */
2402 r->gap--;
2403
2404 if (i == 0) {
2405 ctx->first_range++;
2406
2407 } else {
2408 ctx->ranges[i - 1].range++;
2409 }
2410
2411 } else {
2412 /* current gap is split into two parts */
2413
2414 r->gap = pn - gs - 1;
2415 gap = ge - pn - 1;
2416 range = 0;
2417
2418 goto insert;
2419 }
2420
2421 return NGX_OK;
2422 }
2423
2424 largest = smallest - r->gap - 2;
2425 smallest = largest - r->range;
2426
2427 if (pn >= smallest && pn <= largest) {
2428 /* this packet number is already known */
2429 return NGX_OK;
2430 }
2431
2432 }
2433
2434 if (pn == smallest - 1) {
2435 /* extend first or last range */
2436
2437 if (i == 0) {
2438 ctx->first_range++;
2439
2440 } else {
2441 r->range++;
2442 }
2443
2444 return NGX_OK;
2445 }
2446
2447 /* nothing found, add new range at the tail */
2448
2449 if (ctx->nranges == NGX_QUIC_MAX_RANGES) {
2450 /* packet is too old to keep it */
2451 return ngx_quic_send_ack_range(c, ctx, pn, pn);
2452 }
2453
2454 gap = smallest - 2 - pn;
2455 range = 0;
2456
2457 insert:
2458
2459 nr = ctx->nranges - i;
2460
2461 if (ctx->nranges == NGX_QUIC_MAX_RANGES) {
2462 /* last range is dropped and reused for newer data */
2463
2464 for (j = i; j < ctx->nranges; j++) {
2465 largest = smallest - ctx->ranges[j].gap - 2;
2466 smallest = largest - ctx->ranges[j].range;
2467 }
2468
2469 if (ngx_quic_send_ack_range(c, ctx, smallest, largest) != NGX_OK) {
2470 return NGX_ERROR;
2471 }
2472
2473 nr--;
2474
2475 } else {
2476 ctx->nranges++;
2477 }
2478
2479 ngx_memmove(&ctx->ranges[i + 1], &ctx->ranges[i],
2480 sizeof(ngx_quic_ack_range_t) * nr);
2481
2482 ctx->ranges[i].gap = gap;
2483 ctx->ranges[i].range = range;
2484
2485 return NGX_OK;
2486 }
2487
2488
2489 static ngx_int_t
2490 ngx_quic_send_ack_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
2491 uint64_t smallest, uint64_t largest)
2492 { 2278 {
2493 ngx_quic_frame_t *frame; 2279 ngx_quic_frame_t *frame;
2280
2281 c->log->action = "generating acknowledgment";
2282
2283 /* every ACK-eliciting packet is acknowledged, TODO ACK Ranges */
2494 2284
2495 frame = ngx_quic_alloc_frame(c, 0); 2285 frame = ngx_quic_alloc_frame(c, 0);
2496 if (frame == NULL) { 2286 if (frame == NULL) {
2497 return NGX_ERROR; 2287 return NGX_ERROR;
2498 } 2288 }
2499 2289
2500 frame->level = ctx->level; 2290 frame->level = (pkt->level == ssl_encryption_early_data)
2291 ? ssl_encryption_application
2292 : pkt->level;
2293
2501 frame->type = NGX_QUIC_FT_ACK; 2294 frame->type = NGX_QUIC_FT_ACK;
2502 frame->u.ack.largest = largest; 2295 frame->u.ack.largest = pkt->pn;
2503 frame->u.ack.delay = 0; 2296 frame->u.ack.delay = ngx_quic_ack_delay(c, &pkt->received, frame->level);
2504 frame->u.ack.range_count = 0; 2297
2505 frame->u.ack.first_range = largest - smallest; 2298 ngx_sprintf(frame->info, "ACK for PN=%uL from frame handler level=%d",
2506 2299 pkt->pn, frame->level);
2507 ngx_sprintf(frame->info, "ACK for PN=%uL..%uL 0 ranges level=%d",
2508 largest, smallest, frame->level);
2509
2510 return NGX_OK;
2511 }
2512
2513
2514 static void
2515 ngx_quic_drop_ack_ranges(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
2516 uint64_t pn)
2517 {
2518 uint64_t base;
2519 ngx_uint_t i, smallest, largest;
2520 ngx_quic_ack_range_t *r;
2521
2522 base = ctx->largest_range;
2523
2524 if (base == (uint64_t) -1) {
2525 return;
2526 }
2527
2528 largest = base;
2529 smallest = largest - ctx->first_range;
2530
2531 if (pn >= largest) {
2532 ctx->largest_range = (uint64_t) - 1;
2533 ctx->first_range = 0;
2534 ctx->nranges = 0;
2535 return;
2536 }
2537
2538 if (pn >= smallest) {
2539 ctx->first_range = largest - pn - 1;
2540 ctx->nranges = 0;
2541 return;
2542 }
2543
2544 for (i = 0; i < ctx->nranges; i++) {
2545 r = &ctx->ranges[i];
2546 largest = smallest - r->gap - 2;
2547 smallest = largest - r->range;
2548 if (pn >= largest) {
2549 ctx->nranges = i;
2550 return;
2551 }
2552 if (pn >= smallest) {
2553 r->range = largest - pn - 1;
2554 ctx->nranges = i + 1;
2555 return;
2556 }
2557 }
2558 }
2559
2560
2561 static ngx_int_t
2562 ngx_quic_send_ack(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
2563 {
2564 size_t ranges_len;
2565 ngx_quic_frame_t *frame;
2566
2567 ranges_len = sizeof(ngx_quic_ack_range_t) * ctx->nranges;
2568
2569 frame = ngx_quic_alloc_frame(c, ranges_len);
2570 if (frame == NULL) {
2571 return NGX_ERROR;
2572 }
2573
2574 ngx_memcpy(frame->data, ctx->ranges, ranges_len);
2575
2576 frame->level = ctx->level;
2577 frame->type = NGX_QUIC_FT_ACK;
2578 frame->u.ack.largest = ctx->largest_range;
2579 frame->u.ack.delay = ngx_quic_ack_delay(c, &ctx->ack_received, ctx->level);
2580 frame->u.ack.range_count = ctx->nranges;
2581 frame->u.ack.first_range = ctx->first_range;
2582 frame->u.ack.ranges_start = frame->data;
2583 frame->u.ack.ranges_end = frame->data + ranges_len;
2584
2585 ngx_sprintf(frame->info, "ACK for PN=%uL %ui ranges level=%d",
2586 ctx->largest_range, ctx->nranges, frame->level);
2587
2588 ngx_quic_queue_frame(c->quic, frame); 2300 ngx_quic_queue_frame(c->quic, frame);
2589
2590 ctx->send_ack = 0;
2591 2301
2592 return NGX_OK; 2302 return NGX_OK;
2593 } 2303 }
2594 2304
2595 2305
2826 q = ngx_queue_prev(q); 2536 q = ngx_queue_prev(q);
2827 2537
2828 if (f->pnum >= min && f->pnum <= max) { 2538 if (f->pnum >= min && f->pnum <= max) {
2829 ngx_quic_congestion_ack(c, f); 2539 ngx_quic_congestion_ack(c, f);
2830 2540
2831 switch (f->type) { 2541 ngx_quic_handle_stream_ack(c, f);
2832 case NGX_QUIC_FT_ACK:
2833 ngx_quic_drop_ack_ranges(c, ctx, f->u.ack.largest);
2834 break;
2835
2836 case NGX_QUIC_FT_STREAM0:
2837 case NGX_QUIC_FT_STREAM1:
2838 case NGX_QUIC_FT_STREAM2:
2839 case NGX_QUIC_FT_STREAM3:
2840 case NGX_QUIC_FT_STREAM4:
2841 case NGX_QUIC_FT_STREAM5:
2842 case NGX_QUIC_FT_STREAM6:
2843 case NGX_QUIC_FT_STREAM7:
2844 ngx_quic_handle_stream_ack(c, f);
2845 break;
2846 }
2847 2542
2848 if (f->pnum > found_num || !found) { 2543 if (f->pnum > found_num || !found) {
2849 *send_time = f->last; 2544 *send_time = f->last;
2850 found_num = f->pnum; 2545 found_num = f->pnum;
2851 } 2546 }
2962 { 2657 {
2963 uint64_t sent, unacked; 2658 uint64_t sent, unacked;
2964 ngx_event_t *wev; 2659 ngx_event_t *wev;
2965 ngx_quic_stream_t *sn; 2660 ngx_quic_stream_t *sn;
2966 ngx_quic_connection_t *qc; 2661 ngx_quic_connection_t *qc;
2662
2663 if (f->type < NGX_QUIC_FT_STREAM0 || f->type > NGX_QUIC_FT_STREAM7) {
2664 return;
2665 }
2967 2666
2968 qc = c->quic; 2667 qc = c->quic;
2969 2668
2970 sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id); 2669 sn = ngx_quic_find_stream(&qc->streams.tree, f->u.stream.stream_id);
2971 if (sn == NULL) { 2670 if (sn == NULL) {
4011 3710
4012 static ngx_int_t 3711 static ngx_int_t
4013 ngx_quic_output(ngx_connection_t *c) 3712 ngx_quic_output(ngx_connection_t *c)
4014 { 3713 {
4015 ngx_uint_t i; 3714 ngx_uint_t i;
4016 ngx_quic_send_ctx_t *ctx;
4017 ngx_quic_connection_t *qc; 3715 ngx_quic_connection_t *qc;
4018 3716
4019 c->log->action = "sending frames"; 3717 c->log->action = "sending frames";
4020 3718
4021 qc = c->quic; 3719 qc = c->quic;
4022 3720
4023 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) { 3721 for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
4024 3722 if (ngx_quic_output_frames(c, &qc->send_ctx[i]) != NGX_OK) {
4025 ctx = &qc->send_ctx[i];
4026
4027 if (ctx->send_ack) {
4028 if (ngx_quic_send_ack(c, ctx) != NGX_OK) {
4029 return NGX_ERROR;
4030 }
4031 }
4032
4033 if (ngx_quic_output_frames(c, ctx) != NGX_OK) {
4034 return NGX_ERROR; 3723 return NGX_ERROR;
4035 } 3724 }
4036 } 3725 }
4037 3726
4038 if (!qc->send_timer_set && !qc->closing) { 3727 if (!qc->send_timer_set && !qc->closing) {
4066 3755
4067 /* all frames in same send_ctx share same level */ 3756 /* all frames in same send_ctx share same level */
4068 hlen = (f->level == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER 3757 hlen = (f->level == ssl_encryption_application) ? NGX_QUIC_MAX_SHORT_HEADER
4069 : NGX_QUIC_MAX_LONG_HEADER; 3758 : NGX_QUIC_MAX_LONG_HEADER;
4070 hlen += EVP_GCM_TLS_TAG_LEN; 3759 hlen += EVP_GCM_TLS_TAG_LEN;
4071 hlen -= NGX_QUIC_MAX_CID_LEN - qc->scid.len;
4072 3760
4073 do { 3761 do {
4074 len = 0; 3762 len = 0;
4075 need_ack = 0; 3763 need_ack = 0;
4076 ngx_queue_init(&range); 3764 ngx_queue_init(&range);
4096 * Prior to validation, endpoints are limited in what they 3784 * Prior to validation, endpoints are limited in what they
4097 * are able to send. During the handshake, a server cannot 3785 * are able to send. During the handshake, a server cannot
4098 * send more than three times the data it receives; 3786 * send more than three times the data it receives;
4099 */ 3787 */
4100 3788
4101 if (((c->sent + hlen + len + f->len) / 3) > qc->received) { 3789 if (((c->sent + len + f->len) / 3) > qc->received) {
4102 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 3790 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
4103 "quic hit amplification limit" 3791 "quic hit amplification limit"
4104 " received %uz sent %O", 3792 " received %uz sent %O",
4105 qc->received, c->sent); 3793 qc->received, c->sent);
4106 break; 3794 break;