Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic_transport.c @ 8098:d0d3fc0697a0 quic
QUIC: packet processing refactoring.
All packet header parsing is now performed by ngx_quic_parse_packet()
function, located in the ngx_quic_transport.c file.
The packet processing is centralized in the ngx_quic_process_packet()
function which decides if the packet should be accepted, ignored or
connection should be closed, depending on the connection state.
As a result of refactoring, behavior has changed in some places:
- minimal size of Initial packet is now always tested
- connection IDs are always tested in existing connections
- old keys are discarded on encryption level switch
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 30 Sep 2020 15:14:09 +0300 |
parents | a89a58c642ef |
children | b31c02454539 |
comparison
equal
deleted
inserted
replaced
8097:a89a58c642ef | 8098:d0d3fc0697a0 |
---|---|
64 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value); | 64 static u_char *ngx_quic_read_uint32(u_char *pos, u_char *end, uint32_t *value); |
65 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, | 65 static u_char *ngx_quic_read_bytes(u_char *pos, u_char *end, size_t len, |
66 u_char **out); | 66 u_char **out); |
67 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, | 67 static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, |
68 u_char *dst); | 68 u_char *dst); |
69 | |
70 static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt); | |
71 static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt, | |
72 size_t dcid_len); | |
73 static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt); | |
74 static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt); | |
69 | 75 |
70 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, | 76 static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, |
71 ngx_uint_t frame_type); | 77 ngx_uint_t frame_type); |
72 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); | 78 static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); |
73 static size_t ngx_quic_create_stop_sending(u_char *p, | 79 static size_t ngx_quic_create_stop_sending(u_char *p, |
243 return (u_char *) ngx_quic_errors[error_code]; | 249 return (u_char *) ngx_quic_errors[error_code]; |
244 } | 250 } |
245 | 251 |
246 | 252 |
247 ngx_int_t | 253 ngx_int_t |
254 ngx_quic_parse_packet(ngx_quic_header_t *pkt) | |
255 { | |
256 if (!ngx_quic_long_pkt(pkt->flags)) { | |
257 pkt->level = ssl_encryption_application; | |
258 | |
259 return ngx_quic_parse_short_header(pkt, NGX_QUIC_SERVER_CID_LEN); | |
260 } | |
261 | |
262 if (ngx_quic_parse_long_header(pkt) != NGX_OK) { | |
263 return NGX_DECLINED; | |
264 } | |
265 | |
266 if (pkt->version != NGX_QUIC_VERSION) { | |
267 return NGX_ABORT; | |
268 } | |
269 | |
270 if (ngx_quic_pkt_in(pkt->flags)) { | |
271 | |
272 if (pkt->len < NGX_QUIC_MIN_INITIAL_SIZE) { | |
273 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
274 "quic UDP datagram is too small for initial packet"); | |
275 return NGX_DECLINED; | |
276 } | |
277 | |
278 pkt->level = ssl_encryption_initial; | |
279 | |
280 return ngx_quic_parse_initial_header(pkt); | |
281 } | |
282 | |
283 if (ngx_quic_pkt_hs(pkt->flags)) { | |
284 pkt->level = ssl_encryption_handshake; | |
285 | |
286 } else if (ngx_quic_pkt_zrtt(pkt->flags)) { | |
287 pkt->level = ssl_encryption_early_data; | |
288 | |
289 } else { | |
290 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | |
291 "quic unknown long packet type"); | |
292 return NGX_DECLINED; | |
293 } | |
294 | |
295 return ngx_quic_parse_handshake_header(pkt); | |
296 } | |
297 | |
298 | |
299 static ngx_int_t | |
248 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) | 300 ngx_quic_parse_long_header(ngx_quic_header_t *pkt) |
249 { | 301 { |
250 u_char *p, *end; | 302 u_char *p, *end; |
251 uint8_t idlen; | 303 uint8_t idlen; |
252 | 304 |
454 | 506 |
455 return p - out; | 507 return p - out; |
456 } | 508 } |
457 | 509 |
458 | 510 |
459 ngx_int_t | 511 static ngx_int_t |
460 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, ngx_str_t *dcid) | 512 ngx_quic_parse_short_header(ngx_quic_header_t *pkt, size_t dcid_len) |
461 { | 513 { |
462 u_char *p, *end; | 514 u_char *p, *end; |
463 | 515 |
464 p = pkt->raw->pos; | 516 p = pkt->raw->pos; |
465 end = pkt->data + pkt->len; | 517 end = pkt->data + pkt->len; |
470 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { | 522 if (!(pkt->flags & NGX_QUIC_PKT_FIXED_BIT)) { |
471 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); | 523 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic fixed bit is not set"); |
472 return NGX_ERROR; | 524 return NGX_ERROR; |
473 } | 525 } |
474 | 526 |
475 if (ngx_memcmp(p, dcid->data, dcid->len) != 0) { | 527 pkt->dcid.len = dcid_len; |
476 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "unexpected quic dcid"); | 528 |
477 return NGX_ERROR; | 529 p = ngx_quic_read_bytes(p, end, dcid_len, &pkt->dcid.data); |
478 } | |
479 | |
480 pkt->dcid.len = dcid->len; | |
481 | |
482 p = ngx_quic_read_bytes(p, end, dcid->len, &pkt->dcid.data); | |
483 if (p == NULL) { | 530 if (p == NULL) { |
484 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, | 531 ngx_log_error(NGX_LOG_INFO, pkt->log, 0, |
485 "quic packet is too small to read dcid"); | 532 "quic packet is too small to read dcid"); |
486 return NGX_ERROR; | 533 return NGX_ERROR; |
487 } | 534 } |
490 | 537 |
491 return NGX_OK; | 538 return NGX_OK; |
492 } | 539 } |
493 | 540 |
494 | 541 |
495 ngx_int_t | 542 static ngx_int_t |
496 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) | 543 ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) |
497 { | 544 { |
498 u_char *p, *end; | 545 u_char *p, *end; |
499 uint64_t varint; | 546 uint64_t varint; |
500 | 547 |
546 | 593 |
547 return NGX_OK; | 594 return NGX_OK; |
548 } | 595 } |
549 | 596 |
550 | 597 |
551 ngx_int_t | 598 static ngx_int_t |
552 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) | 599 ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) |
553 { | 600 { |
554 u_char *p, *end; | 601 u_char *p, *end; |
555 uint64_t plen; | 602 uint64_t plen; |
556 | 603 |