comparison src/event/quic/ngx_event_quic.c @ 8281:a346905c359f quic

QUIC: fixed stateless reset recognition and send. Previously, if an unexpected packet was received on an existing QUIC connection, stateless reset token was neither recognized nor sent.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 01 Feb 2021 14:46:36 +0300
parents 1c6343bd7933
children 0697294f79a4
comparison
equal deleted inserted replaced
8280:1c6343bd7933 8281:a346905c359f
259 ngx_quic_header_t *pkt); 259 ngx_quic_header_t *pkt);
260 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,
261 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);
262 static void ngx_quic_discard_ctx(ngx_connection_t *c, 262 static void ngx_quic_discard_ctx(ngx_connection_t *c,
263 enum ssl_encryption_level_t level); 263 enum ssl_encryption_level_t level);
264 static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, 264 static ngx_int_t ngx_quic_check_csid(ngx_quic_connection_t *qc,
265 ngx_quic_header_t *pkt); 265 ngx_quic_header_t *pkt);
266 static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c, 266 static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c,
267 ngx_quic_header_t *pkt); 267 ngx_quic_header_t *pkt);
268 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,
269 ngx_quic_header_t *pkt); 269 ngx_quic_header_t *pkt);
2248 "quic unsupported version: 0x%xD", pkt->version); 2248 "quic unsupported version: 0x%xD", pkt->version);
2249 return NGX_DECLINED; 2249 return NGX_DECLINED;
2250 } 2250 }
2251 2251
2252 if (pkt->level != ssl_encryption_application) { 2252 if (pkt->level != ssl_encryption_application) {
2253
2253 if (pkt->version != qc->version) { 2254 if (pkt->version != qc->version) {
2254 ngx_log_error(NGX_LOG_INFO, c->log, 0, 2255 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2255 "quic version mismatch: 0x%xD", pkt->version); 2256 "quic version mismatch: 0x%xD", pkt->version);
2256 return NGX_DECLINED; 2257 return NGX_DECLINED;
2257 } 2258 }
2258 } 2259
2259 2260 if (ngx_quic_check_csid(qc, pkt) != NGX_OK) {
2260 if (ngx_quic_check_peer(qc, pkt) != NGX_OK) { 2261 return NGX_DECLINED;
2261
2262 if (pkt->level == ssl_encryption_application) {
2263 if (ngx_quic_process_stateless_reset(c, pkt) == NGX_OK) {
2264 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2265 "quic stateless reset packet detected");
2266
2267 qc->draining = 1;
2268 ngx_quic_close_connection(c, NGX_OK);
2269
2270 return NGX_OK;
2271 }
2272
2273 return ngx_quic_send_stateless_reset(c, qc->conf, pkt);
2274 } 2262 }
2275 2263
2276 return NGX_DECLINED; 2264 } else {
2265
2266 if (ngx_quic_process_stateless_reset(c, pkt) == NGX_OK) {
2267 ngx_log_error(NGX_LOG_INFO, c->log, 0,
2268 "quic stateless reset packet detected");
2269
2270 qc->draining = 1;
2271 ngx_quic_close_connection(c, NGX_OK);
2272
2273 return NGX_OK;
2274 }
2277 } 2275 }
2278 2276
2279 return ngx_quic_process_payload(c, pkt); 2277 return ngx_quic_process_payload(c, pkt);
2280 } 2278 }
2281 2279
2581 ctx->send_ack = 0; 2579 ctx->send_ack = 0;
2582 } 2580 }
2583 2581
2584 2582
2585 static ngx_int_t 2583 static ngx_int_t
2586 ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt) 2584 ngx_quic_check_csid(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
2587 { 2585 {
2588 ngx_queue_t *q; 2586 ngx_queue_t *q;
2589 ngx_quic_client_id_t *cid; 2587 ngx_quic_client_id_t *cid;
2590
2591 if (pkt->level == ssl_encryption_application) {
2592 return NGX_OK;
2593 }
2594 2588
2595 for (q = ngx_queue_head(&qc->client_ids); 2589 for (q = ngx_queue_head(&qc->client_ids);
2596 q != ngx_queue_sentinel(&qc->client_ids); 2590 q != ngx_queue_sentinel(&qc->client_ids);
2597 q = ngx_queue_next(q)) 2591 q = ngx_queue_next(q))
2598 { 2592 {