Mercurial > hg > nginx-quic
diff 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 |
line wrap: on
line diff
--- a/src/event/ngx_event_quic_transport.c +++ b/src/event/ngx_event_quic_transport.c @@ -67,6 +67,12 @@ static u_char *ngx_quic_read_bytes(u_cha static u_char *ngx_quic_copy_bytes(u_char *pos, u_char *end, size_t len, u_char *dst); +static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt); +static ngx_int_t ngx_quic_parse_short_header(ngx_quic_header_t *pkt, + size_t dcid_len); +static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt); +static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt); + static ngx_int_t ngx_quic_frame_allowed(ngx_quic_header_t *pkt, ngx_uint_t frame_type); static size_t ngx_quic_create_ack(u_char *p, ngx_quic_ack_frame_t *ack); @@ -245,6 +251,52 @@ ngx_quic_error_text(uint64_t error_code) ngx_int_t +ngx_quic_parse_packet(ngx_quic_header_t *pkt) +{ + if (!ngx_quic_long_pkt(pkt->flags)) { + pkt->level = ssl_encryption_application; + + return ngx_quic_parse_short_header(pkt, NGX_QUIC_SERVER_CID_LEN); + } + + if (ngx_quic_parse_long_header(pkt) != NGX_OK) { + return NGX_DECLINED; + } + + if (pkt->version != NGX_QUIC_VERSION) { + return NGX_ABORT; + } + + if (ngx_quic_pkt_in(pkt->flags)) { + + if (pkt->len < NGX_QUIC_MIN_INITIAL_SIZE) { + ngx_log_error(NGX_LOG_INFO, pkt->log, 0, + "quic UDP datagram is too small for initial packet"); + return NGX_DECLINED; + } + + pkt->level = ssl_encryption_initial; + + return ngx_quic_parse_initial_header(pkt); + } + + if (ngx_quic_pkt_hs(pkt->flags)) { + pkt->level = ssl_encryption_handshake; + + } else if (ngx_quic_pkt_zrtt(pkt->flags)) { + pkt->level = ssl_encryption_early_data; + + } else { + ngx_log_error(NGX_LOG_INFO, pkt->log, 0, + "quic unknown long packet type"); + return NGX_DECLINED; + } + + return ngx_quic_parse_handshake_header(pkt); +} + + +static ngx_int_t ngx_quic_parse_long_header(ngx_quic_header_t *pkt) { u_char *p, *end; @@ -456,8 +508,8 @@ ngx_quic_create_retry_itag(ngx_quic_head } -ngx_int_t -ngx_quic_parse_short_header(ngx_quic_header_t *pkt, ngx_str_t *dcid) +static ngx_int_t +ngx_quic_parse_short_header(ngx_quic_header_t *pkt, size_t dcid_len) { u_char *p, *end; @@ -472,14 +524,9 @@ ngx_quic_parse_short_header(ngx_quic_hea return NGX_ERROR; } - if (ngx_memcmp(p, dcid->data, dcid->len) != 0) { - ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "unexpected quic dcid"); - return NGX_ERROR; - } + pkt->dcid.len = dcid_len; - pkt->dcid.len = dcid->len; - - p = ngx_quic_read_bytes(p, end, dcid->len, &pkt->dcid.data); + p = ngx_quic_read_bytes(p, end, dcid_len, &pkt->dcid.data); if (p == NULL) { ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic packet is too small to read dcid"); @@ -492,7 +539,7 @@ ngx_quic_parse_short_header(ngx_quic_hea } -ngx_int_t +static ngx_int_t ngx_quic_parse_initial_header(ngx_quic_header_t *pkt) { u_char *p, *end; @@ -548,7 +595,7 @@ ngx_quic_parse_initial_header(ngx_quic_h } -ngx_int_t +static ngx_int_t ngx_quic_parse_handshake_header(ngx_quic_header_t *pkt) { u_char *p, *end;