comparison src/event/quic/ngx_event_quic.c @ 8687:1c6343bd7933 quic

QUIC: refactored packet processing. - split ngx_quic_process_packet() in two functions with the second one called ngx_quic_process_payload() in charge of decrypring and handling the payload - renamed ngx_quic_payload_handler() to ngx_quic_handle_frames() - moved error cleanup from ngx_quic_input() to ngx_quic_process_payload() - moved handling closed connection from ngx_quic_handle_frames() to ngx_quic_process_payload() - minor fixes
author Roman Arutyunyan <arut@nginx.com>
date Thu, 28 Jan 2021 12:35:18 +0300
parents dffb66fb783b
children a346905c359f
comparison
equal deleted inserted replaced
8686:dffb66fb783b 8687:1c6343bd7933
253 253
254 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, 254 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b,
255 ngx_quic_conf_t *conf); 255 ngx_quic_conf_t *conf);
256 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, 256 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c,
257 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); 257 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
258 static ngx_int_t ngx_quic_process_payload(ngx_connection_t *c,
259 ngx_quic_header_t *pkt);
258 static ngx_int_t ngx_quic_send_early_cc(ngx_connection_t *c, 260 static ngx_int_t ngx_quic_send_early_cc(ngx_connection_t *c,
259 ngx_quic_header_t *inpkt, ngx_uint_t err, const char *reason); 261 ngx_quic_header_t *inpkt, ngx_uint_t err, const char *reason);
260 static void ngx_quic_discard_ctx(ngx_connection_t *c, 262 static void ngx_quic_discard_ctx(ngx_connection_t *c,
261 enum ssl_encryption_level_t level); 263 enum ssl_encryption_level_t level);
262 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, 264 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc,
263 ngx_quic_header_t *pkt); 265 ngx_quic_header_t *pkt);
264 static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, 266 static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c,
265 ngx_quic_header_t *pkt); 267 ngx_quic_header_t *pkt);
266 static ngx_int_t ngx_quic_ack_packet(ngx_connection_t *c, 268 static ngx_int_t ngx_quic_ack_packet(ngx_connection_t *c,
267 ngx_quic_header_t *pkt); 269 ngx_quic_header_t *pkt);
268 static ngx_int_t ngx_quic_send_ack_range(ngx_connection_t *c, 270 static ngx_int_t ngx_quic_send_ack_range(ngx_connection_t *c,
269 ngx_quic_send_ctx_t *ctx, uint64_t smallest, uint64_t largest); 271 ngx_quic_send_ctx_t *ctx, uint64_t smallest, uint64_t largest);
2118 2120
2119 2121
2120 static ngx_int_t 2122 static ngx_int_t
2121 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf) 2123 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
2122 { 2124 {
2123 u_char *p; 2125 u_char *p;
2124 ngx_int_t rc; 2126 ngx_int_t rc;
2125 ngx_uint_t good; 2127 ngx_uint_t good;
2126 ngx_quic_header_t pkt; 2128 ngx_quic_header_t pkt;
2127 ngx_quic_connection_t *qc;
2128 2129
2129 good = 0; 2130 good = 0;
2130 2131
2131 p = b->pos; 2132 p = b->pos;
2132 2133
2137 pkt.data = p; 2138 pkt.data = p;
2138 pkt.len = b->last - p; 2139 pkt.len = b->last - p;
2139 pkt.log = c->log; 2140 pkt.log = c->log;
2140 pkt.flags = p[0]; 2141 pkt.flags = p[0];
2141 pkt.raw->pos++; 2142 pkt.raw->pos++;
2142
2143 qc = ngx_quic_get_connection(c);
2144 if (qc) {
2145 qc->error = 0;
2146 qc->error_reason = 0;
2147 }
2148 2143
2149 rc = ngx_quic_process_packet(c, conf, &pkt); 2144 rc = ngx_quic_process_packet(c, conf, &pkt);
2150 2145
2151 #if (NGX_DEBUG) 2146 #if (NGX_DEBUG)
2152 if (pkt.parsed) { 2147 if (pkt.parsed) {
2210 static ngx_int_t 2205 static ngx_int_t
2211 ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf, 2206 ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
2212 ngx_quic_header_t *pkt) 2207 ngx_quic_header_t *pkt)
2213 { 2208 {
2214 ngx_int_t rc; 2209 ngx_int_t rc;
2215 ngx_quic_send_ctx_t *ctx;
2216 ngx_quic_connection_t *qc; 2210 ngx_quic_connection_t *qc;
2217
2218 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2219 2211
2220 c->log->action = "parsing quic packet"; 2212 c->log->action = "parsing quic packet";
2221 2213
2222 rc = ngx_quic_parse_packet(pkt); 2214 rc = ngx_quic_parse_packet(pkt);
2223 2215
2226 } 2218 }
2227 2219
2228 pkt->parsed = 1; 2220 pkt->parsed = 1;
2229 2221
2230 c->log->action = "processing quic packet"; 2222 c->log->action = "processing quic packet";
2231
2232 qc = ngx_quic_get_connection(c);
2233 2223
2234 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 2224 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
2235 "quic packet rx dcid len:%uz %xV", 2225 "quic packet rx dcid len:%uz %xV",
2236 pkt->dcid.len, &pkt->dcid); 2226 pkt->dcid.len, &pkt->dcid);
2237 2227
2246 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, 2236 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
2247 "quic token len:%uz %xV", 2237 "quic token len:%uz %xV",
2248 pkt->token.len, &pkt->token); 2238 pkt->token.len, &pkt->token);
2249 } 2239 }
2250 #endif 2240 #endif
2241
2242 qc = ngx_quic_get_connection(c);
2251 2243
2252 if (qc) { 2244 if (qc) {
2253 2245
2254 if (rc == NGX_ABORT) { 2246 if (rc == NGX_ABORT) {
2255 ngx_log_error(NGX_LOG_INFO, c->log, 0, 2247 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2282 } 2274 }
2283 2275
2284 return NGX_DECLINED; 2276 return NGX_DECLINED;
2285 } 2277 }
2286 2278
2279 return ngx_quic_process_payload(c, pkt);
2280 }
2281
2282 /* packet does not belong to a connection */
2283
2284 if (rc == NGX_ABORT) {
2285 return ngx_quic_negotiate_version(c, pkt);
2286 }
2287
2288 if (pkt->level == ssl_encryption_application) {
2289 return ngx_quic_send_stateless_reset(c, conf, pkt);
2290 }
2291
2292 if (pkt->level != ssl_encryption_initial) {
2293 return NGX_ERROR;
2294 }
2295
2296 c->log->action = "processing initial packet";
2297
2298 if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
2299 /* 7.2. Negotiating Connection IDs */
2300 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2301 "quic too short dcid in initial"
2302 " packet: len:%i", pkt->dcid.len);
2303 return NGX_ERROR;
2304 }
2305
2306 /* process retry and initialize connection IDs */
2307
2308 if (pkt->token.len) {
2309
2310 rc = ngx_quic_validate_token(c, conf->token_key, pkt);
2311
2312 if (rc == NGX_ERROR) {
2313 /* internal error */
2314 return NGX_ERROR;
2315
2316 } else if (rc == NGX_ABORT) {
2317 /* token cannot be decrypted */
2318 return ngx_quic_send_early_cc(c, pkt,
2319 NGX_QUIC_ERR_INVALID_TOKEN,
2320 "cannot decrypt token");
2321 } else if (rc == NGX_DECLINED) {
2322 /* token is invalid */
2323
2324 if (pkt->retried) {
2325 /* invalid Retry token */
2326 return ngx_quic_send_early_cc(c, pkt,
2327 NGX_QUIC_ERR_INVALID_TOKEN,
2328 "invalid token");
2329 } else if (conf->retry) {
2330 /* invalid NEW_TOKEN */
2331 return ngx_quic_send_retry(c, conf, pkt);
2332 }
2333 }
2334
2335 /* NGX_OK */
2336
2337 } else if (conf->retry) {
2338 return ngx_quic_send_retry(c, conf, pkt);
2339
2287 } else { 2340 } else {
2288 2341 pkt->odcid = pkt->dcid;
2289 if (rc == NGX_ABORT) { 2342 }
2290 return ngx_quic_negotiate_version(c, pkt); 2343
2291 } 2344 if (ngx_terminate || ngx_exiting) {
2292 2345 if (conf->retry) {
2293 if (pkt->level == ssl_encryption_initial) { 2346 return ngx_quic_send_retry(c, conf, pkt);
2294 c->log->action = "processing initial packet"; 2347 }
2295 2348
2296 if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) { 2349 return NGX_ERROR;
2297 /* 7.2. Negotiating Connection IDs */ 2350 }
2298 ngx_log_error(NGX_LOG_INFO, c->log, 0, 2351
2299 "quic too short dcid in initial" 2352 c->log->action = "creating quic connection";
2300 " packet: len:%i", pkt->dcid.len); 2353
2301 return NGX_ERROR; 2354 qc = ngx_quic_new_connection(c, conf, pkt);
2302 } 2355 if (qc == NULL) {
2303 2356 return NGX_ERROR;
2304 /* process retry and initialize connection IDs */ 2357 }
2305 2358
2306 if (pkt->token.len) { 2359 return ngx_quic_process_payload(c, pkt);
2307 2360 }
2308 rc = ngx_quic_validate_token(c, conf->token_key, pkt); 2361
2309 2362
2310 if (rc == NGX_ERROR) { 2363 static ngx_int_t
2311 /* internal error */ 2364 ngx_quic_process_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
2312 return NGX_ERROR; 2365 {
2313 2366 ngx_int_t rc;
2314 } else if (rc == NGX_ABORT) { 2367 ngx_quic_send_ctx_t *ctx;
2315 /* token cannot be decrypted */ 2368 ngx_quic_connection_t *qc;
2316 return ngx_quic_send_early_cc(c, pkt, 2369 static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2317 NGX_QUIC_ERR_INVALID_TOKEN, 2370
2318 "cannot decrypt token"); 2371 qc = ngx_quic_get_connection(c);
2319 } else if (rc == NGX_DECLINED) { 2372
2320 /* token is invalid */ 2373 qc->error = 0;
2321 2374 qc->error_reason = 0;
2322 if (pkt->retried) {
2323 /* invalid Retry token */
2324 return ngx_quic_send_early_cc(c, pkt,
2325 NGX_QUIC_ERR_INVALID_TOKEN,
2326 "invalid token");
2327 } else if (conf->retry) {
2328 /* invalid NEW_TOKEN */
2329 return ngx_quic_send_retry(c, conf, pkt);
2330 }
2331 }
2332
2333 /* NGX_OK */
2334
2335 } else if (conf->retry) {
2336 return ngx_quic_send_retry(c, conf, pkt);
2337
2338 } else {
2339 pkt->odcid = pkt->dcid;
2340 }
2341
2342 if (ngx_terminate || ngx_exiting) {
2343 if (conf->retry) {
2344 return ngx_quic_send_retry(c, conf, pkt);
2345 }
2346
2347 return NGX_ERROR;
2348 }
2349
2350 c->log->action = "creating quic connection";
2351
2352 qc = ngx_quic_new_connection(c, conf, pkt);
2353 if (qc == NULL) {
2354 return NGX_ERROR;
2355 }
2356
2357 } else if (pkt->level == ssl_encryption_application) {
2358 return ngx_quic_send_stateless_reset(c, conf, pkt);
2359
2360 } else {
2361 return NGX_ERROR;
2362 }
2363 }
2364 2375
2365 c->log->action = "decrypting packet"; 2376 c->log->action = "decrypting packet";
2366 2377
2367 if (!ngx_quic_keys_available(qc->keys, pkt->level)) { 2378 if (!ngx_quic_keys_available(qc->keys, pkt->level)) {
2368 ngx_log_error(NGX_LOG_INFO, c->log, 0, 2379 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2401 if (qc->validated == 0) { 2412 if (qc->validated == 0) {
2402 qc->validated = 1; 2413 qc->validated = 1;
2403 ngx_post_event(&qc->push, &ngx_posted_events); 2414 ngx_post_event(&qc->push, &ngx_posted_events);
2404 } 2415 }
2405 } 2416 }
2406
2407 pkt->received = ngx_current_msec;
2408
2409 c->log->action = "handling payload";
2410
2411 if (pkt->level != ssl_encryption_application) {
2412 return ngx_quic_payload_handler(c, pkt);
2413 }
2414
2415 if (!pkt->key_update) {
2416 return ngx_quic_payload_handler(c, pkt);
2417 }
2418
2419 /* switch keys and generate next on Key Phase change */
2420
2421 qc->key_phase ^= 1;
2422 ngx_quic_keys_switch(c, qc->keys);
2423
2424 rc = ngx_quic_payload_handler(c, pkt);
2425 if (rc != NGX_OK) {
2426 return rc;
2427 }
2428
2429 return ngx_quic_keys_update(c, qc->keys);
2430 }
2431
2432
2433 static ngx_int_t
2434 ngx_quic_send_early_cc(ngx_connection_t *c, ngx_quic_header_t *inpkt,
2435 ngx_uint_t err, const char *reason)
2436 {
2437 ssize_t len;
2438 ngx_str_t res;
2439 ngx_quic_frame_t frame;
2440 ngx_quic_header_t pkt;
2441
2442 static u_char src[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2443 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2444
2445 ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
2446 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
2447
2448 frame.level = inpkt->level;
2449 frame.type = NGX_QUIC_FT_CONNECTION_CLOSE;
2450 frame.u.close.error_code = err;
2451
2452 frame.u.close.reason.data = (u_char *) reason;
2453 frame.u.close.reason.len = ngx_strlen(reason);
2454
2455 len = ngx_quic_create_frame(NULL, &frame);
2456 if (len > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) {
2457 return NGX_ERROR;
2458 }
2459
2460 ngx_quic_log_frame(c->log, &frame, 1);
2461
2462 len = ngx_quic_create_frame(src, &frame);
2463 if (len == -1) {
2464 return NGX_ERROR;
2465 }
2466
2467 pkt.keys = ngx_quic_keys_new(c->pool);
2468 if (pkt.keys == NULL) {
2469 return NGX_ERROR;
2470 }
2471
2472 if (ngx_quic_keys_set_initial_secret(c->pool, pkt.keys, &inpkt->dcid)
2473 != NGX_OK)
2474 {
2475 return NGX_ERROR;
2476 }
2477
2478 pkt.flags = NGX_QUIC_PKT_FIXED_BIT | NGX_QUIC_PKT_LONG
2479 | NGX_QUIC_PKT_INITIAL;
2480
2481 pkt.num_len = 1;
2482 /*
2483 * pkt.num = 0;
2484 * pkt.trunc = 0;
2485 */
2486
2487 pkt.version = inpkt->version;
2488 pkt.log = c->log;
2489 pkt.level = inpkt->level;
2490 pkt.dcid = inpkt->scid;
2491 pkt.scid = inpkt->dcid;
2492 pkt.payload.data = src;
2493 pkt.payload.len = len;
2494
2495 res.data = dst;
2496
2497 if (ngx_quic_encrypt(&pkt, &res) != NGX_OK) {
2498 return NGX_ERROR;
2499 }
2500
2501 if (ngx_quic_send(c, res.data, res.len) == NGX_ERROR) {
2502 return NGX_ERROR;
2503 }
2504
2505 return NGX_OK;
2506 }
2507
2508
2509 static void
2510 ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
2511 {
2512 ngx_queue_t *q;
2513 ngx_quic_frame_t *f;
2514 ngx_quic_send_ctx_t *ctx;
2515 ngx_quic_connection_t *qc;
2516
2517 qc = ngx_quic_get_connection(c);
2518
2519 if (!ngx_quic_keys_available(qc->keys, level)) {
2520 return;
2521 }
2522
2523 ngx_quic_keys_discard(qc->keys, level);
2524
2525 qc->pto_count = 0;
2526
2527 ctx = ngx_quic_get_send_ctx(qc, level);
2528
2529 while (!ngx_queue_empty(&ctx->sent)) {
2530 q = ngx_queue_head(&ctx->sent);
2531 ngx_queue_remove(q);
2532
2533 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
2534 ngx_quic_congestion_ack(c, f);
2535 ngx_quic_free_frame(c, f);
2536 }
2537
2538 while (!ngx_queue_empty(&ctx->frames)) {
2539 q = ngx_queue_head(&ctx->frames);
2540 ngx_queue_remove(q);
2541
2542 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
2543 ngx_quic_congestion_ack(c, f);
2544 ngx_quic_free_frame(c, f);
2545 }
2546
2547 if (level == ssl_encryption_initial) {
2548 ngx_quic_clear_temp_server_ids(c);
2549 }
2550
2551 ctx->send_ack = 0;
2552 }
2553
2554
2555 static ngx_int_t
2556 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
2557 {
2558 ngx_queue_t *q;
2559 ngx_quic_client_id_t *cid;
2560
2561 if (pkt->level == ssl_encryption_application) {
2562 return NGX_OK;
2563 }
2564
2565 for (q = ngx_queue_head(&qc->client_ids);
2566 q != ngx_queue_sentinel(&qc->client_ids);
2567 q = ngx_queue_next(q))
2568 {
2569 cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);
2570
2571 if (pkt->scid.len == cid->len
2572 && ngx_memcmp(pkt->scid.data, cid->id, cid->len) == 0)
2573 {
2574 return NGX_OK;
2575 }
2576 }
2577
2578 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid");
2579 return NGX_ERROR;
2580 }
2581
2582
2583 static ngx_int_t
2584 ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
2585 {
2586 u_char *end, *p;
2587 ssize_t len;
2588 ngx_buf_t buf;
2589 ngx_uint_t do_close;
2590 ngx_chain_t chain;
2591 ngx_quic_frame_t frame;
2592 ngx_quic_connection_t *qc;
2593
2594 qc = ngx_quic_get_connection(c);
2595 2417
2596 if (qc->closing) { 2418 if (qc->closing) {
2597 /* 2419 /*
2598 * 10.1 Closing and Draining Connection States 2420 * 10.1 Closing and Draining Connection States
2599 * ... delayed or reordered packets are properly discarded. 2421 * ... delayed or reordered packets are properly discarded.
2609 qc->error_ftype = 0; 2431 qc->error_ftype = 0;
2610 qc->error_app = 0; 2432 qc->error_app = 0;
2611 2433
2612 return ngx_quic_send_cc(c); 2434 return ngx_quic_send_cc(c);
2613 } 2435 }
2436
2437 pkt->received = ngx_current_msec;
2438
2439 c->log->action = "handling payload";
2440
2441 if (pkt->level != ssl_encryption_application) {
2442 return ngx_quic_handle_frames(c, pkt);
2443 }
2444
2445 if (!pkt->key_update) {
2446 return ngx_quic_handle_frames(c, pkt);
2447 }
2448
2449 /* switch keys and generate next on Key Phase change */
2450
2451 qc->key_phase ^= 1;
2452 ngx_quic_keys_switch(c, qc->keys);
2453
2454 rc = ngx_quic_handle_frames(c, pkt);
2455 if (rc != NGX_OK) {
2456 return rc;
2457 }
2458
2459 return ngx_quic_keys_update(c, qc->keys);
2460 }
2461
2462
2463 static ngx_int_t
2464 ngx_quic_send_early_cc(ngx_connection_t *c, ngx_quic_header_t *inpkt,
2465 ngx_uint_t err, const char *reason)
2466 {
2467 ssize_t len;
2468 ngx_str_t res;
2469 ngx_quic_frame_t frame;
2470 ngx_quic_header_t pkt;
2471
2472 static u_char src[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2473 static u_char dst[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];
2474
2475 ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
2476 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
2477
2478 frame.level = inpkt->level;
2479 frame.type = NGX_QUIC_FT_CONNECTION_CLOSE;
2480 frame.u.close.error_code = err;
2481
2482 frame.u.close.reason.data = (u_char *) reason;
2483 frame.u.close.reason.len = ngx_strlen(reason);
2484
2485 len = ngx_quic_create_frame(NULL, &frame);
2486 if (len > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE) {
2487 return NGX_ERROR;
2488 }
2489
2490 ngx_quic_log_frame(c->log, &frame, 1);
2491
2492 len = ngx_quic_create_frame(src, &frame);
2493 if (len == -1) {
2494 return NGX_ERROR;
2495 }
2496
2497 pkt.keys = ngx_quic_keys_new(c->pool);
2498 if (pkt.keys == NULL) {
2499 return NGX_ERROR;
2500 }
2501
2502 if (ngx_quic_keys_set_initial_secret(c->pool, pkt.keys, &inpkt->dcid)
2503 != NGX_OK)
2504 {
2505 return NGX_ERROR;
2506 }
2507
2508 pkt.flags = NGX_QUIC_PKT_FIXED_BIT | NGX_QUIC_PKT_LONG
2509 | NGX_QUIC_PKT_INITIAL;
2510
2511 pkt.num_len = 1;
2512 /*
2513 * pkt.num = 0;
2514 * pkt.trunc = 0;
2515 */
2516
2517 pkt.version = inpkt->version;
2518 pkt.log = c->log;
2519 pkt.level = inpkt->level;
2520 pkt.dcid = inpkt->scid;
2521 pkt.scid = inpkt->dcid;
2522 pkt.payload.data = src;
2523 pkt.payload.len = len;
2524
2525 res.data = dst;
2526
2527 if (ngx_quic_encrypt(&pkt, &res) != NGX_OK) {
2528 return NGX_ERROR;
2529 }
2530
2531 if (ngx_quic_send(c, res.data, res.len) == NGX_ERROR) {
2532 return NGX_ERROR;
2533 }
2534
2535 return NGX_OK;
2536 }
2537
2538
2539 static void
2540 ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
2541 {
2542 ngx_queue_t *q;
2543 ngx_quic_frame_t *f;
2544 ngx_quic_send_ctx_t *ctx;
2545 ngx_quic_connection_t *qc;
2546
2547 qc = ngx_quic_get_connection(c);
2548
2549 if (!ngx_quic_keys_available(qc->keys, level)) {
2550 return;
2551 }
2552
2553 ngx_quic_keys_discard(qc->keys, level);
2554
2555 qc->pto_count = 0;
2556
2557 ctx = ngx_quic_get_send_ctx(qc, level);
2558
2559 while (!ngx_queue_empty(&ctx->sent)) {
2560 q = ngx_queue_head(&ctx->sent);
2561 ngx_queue_remove(q);
2562
2563 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
2564 ngx_quic_congestion_ack(c, f);
2565 ngx_quic_free_frame(c, f);
2566 }
2567
2568 while (!ngx_queue_empty(&ctx->frames)) {
2569 q = ngx_queue_head(&ctx->frames);
2570 ngx_queue_remove(q);
2571
2572 f = ngx_queue_data(q, ngx_quic_frame_t, queue);
2573 ngx_quic_congestion_ack(c, f);
2574 ngx_quic_free_frame(c, f);
2575 }
2576
2577 if (level == ssl_encryption_initial) {
2578 ngx_quic_clear_temp_server_ids(c);
2579 }
2580
2581 ctx->send_ack = 0;
2582 }
2583
2584
2585 static ngx_int_t
2586 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
2587 {
2588 ngx_queue_t *q;
2589 ngx_quic_client_id_t *cid;
2590
2591 if (pkt->level == ssl_encryption_application) {
2592 return NGX_OK;
2593 }
2594
2595 for (q = ngx_queue_head(&qc->client_ids);
2596 q != ngx_queue_sentinel(&qc->client_ids);
2597 q = ngx_queue_next(q))
2598 {
2599 cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);
2600
2601 if (pkt->scid.len == cid->len
2602 && ngx_memcmp(pkt->scid.data, cid->id, cid->len) == 0)
2603 {
2604 return NGX_OK;
2605 }
2606 }
2607
2608 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid");
2609 return NGX_ERROR;
2610 }
2611
2612
2613 static ngx_int_t
2614 ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt)
2615 {
2616 u_char *end, *p;
2617 ssize_t len;
2618 ngx_buf_t buf;
2619 ngx_uint_t do_close;
2620 ngx_chain_t chain;
2621 ngx_quic_frame_t frame;
2622 ngx_quic_connection_t *qc;
2623
2624 qc = ngx_quic_get_connection(c);
2614 2625
2615 p = pkt->payload.data; 2626 p = pkt->payload.data;
2616 end = p + pkt->payload.len; 2627 end = p + pkt->payload.len;
2617 2628
2618 do_close = 0; 2629 do_close = 0;