# HG changeset patch # User Roman Arutyunyan # Date 1611826518 -10800 # Node ID 1c6343bd7933744518473cc9d0b6fbdaba729b3c # Parent dffb66fb783b1434bf778950ab92e18f16c01ea8 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 diff -r dffb66fb783b -r 1c6343bd7933 src/event/quic/ngx_event_quic.c --- a/src/event/quic/ngx_event_quic.c Fri Jan 29 15:53:47 2021 +0300 +++ b/src/event/quic/ngx_event_quic.c Thu Jan 28 12:35:18 2021 +0300 @@ -255,13 +255,15 @@ ngx_quic_conf_t *conf); static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); +static ngx_int_t ngx_quic_process_payload(ngx_connection_t *c, + ngx_quic_header_t *pkt); static ngx_int_t ngx_quic_send_early_cc(ngx_connection_t *c, ngx_quic_header_t *inpkt, ngx_uint_t err, const char *reason); static void ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level); static ngx_int_t ngx_quic_check_peer(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt); -static ngx_int_t ngx_quic_payload_handler(ngx_connection_t *c, +static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt); static ngx_int_t ngx_quic_ack_packet(ngx_connection_t *c, ngx_quic_header_t *pkt); @@ -2120,11 +2122,10 @@ static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf) { - u_char *p; - ngx_int_t rc; - ngx_uint_t good; - ngx_quic_header_t pkt; - ngx_quic_connection_t *qc; + u_char *p; + ngx_int_t rc; + ngx_uint_t good; + ngx_quic_header_t pkt; good = 0; @@ -2140,12 +2141,6 @@ pkt.flags = p[0]; pkt.raw->pos++; - qc = ngx_quic_get_connection(c); - if (qc) { - qc->error = 0; - qc->error_reason = 0; - } - rc = ngx_quic_process_packet(c, conf, &pkt); #if (NGX_DEBUG) @@ -2212,11 +2207,8 @@ ngx_quic_header_t *pkt) { ngx_int_t rc; - ngx_quic_send_ctx_t *ctx; ngx_quic_connection_t *qc; - static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; - c->log->action = "parsing quic packet"; rc = ngx_quic_parse_packet(pkt); @@ -2229,8 +2221,6 @@ c->log->action = "processing quic packet"; - qc = ngx_quic_get_connection(c); - ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic packet rx dcid len:%uz %xV", pkt->dcid.len, &pkt->dcid); @@ -2249,6 +2239,8 @@ } #endif + qc = ngx_quic_get_connection(c); + if (qc) { if (rc == NGX_ABORT) { @@ -2284,83 +2276,102 @@ return NGX_DECLINED; } - } else { - - if (rc == NGX_ABORT) { - return ngx_quic_negotiate_version(c, pkt); - } - - if (pkt->level == ssl_encryption_initial) { - c->log->action = "processing initial packet"; - - if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) { - /* 7.2. Negotiating Connection IDs */ - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "quic too short dcid in initial" - " packet: len:%i", pkt->dcid.len); - return NGX_ERROR; + return ngx_quic_process_payload(c, pkt); + } + + /* packet does not belong to a connection */ + + if (rc == NGX_ABORT) { + return ngx_quic_negotiate_version(c, pkt); + } + + if (pkt->level == ssl_encryption_application) { + return ngx_quic_send_stateless_reset(c, conf, pkt); + } + + if (pkt->level != ssl_encryption_initial) { + return NGX_ERROR; + } + + c->log->action = "processing initial packet"; + + if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) { + /* 7.2. Negotiating Connection IDs */ + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "quic too short dcid in initial" + " packet: len:%i", pkt->dcid.len); + return NGX_ERROR; + } + + /* process retry and initialize connection IDs */ + + if (pkt->token.len) { + + rc = ngx_quic_validate_token(c, conf->token_key, pkt); + + if (rc == NGX_ERROR) { + /* internal error */ + return NGX_ERROR; + + } else if (rc == NGX_ABORT) { + /* token cannot be decrypted */ + return ngx_quic_send_early_cc(c, pkt, + NGX_QUIC_ERR_INVALID_TOKEN, + "cannot decrypt token"); + } else if (rc == NGX_DECLINED) { + /* token is invalid */ + + if (pkt->retried) { + /* invalid Retry token */ + return ngx_quic_send_early_cc(c, pkt, + NGX_QUIC_ERR_INVALID_TOKEN, + "invalid token"); + } else if (conf->retry) { + /* invalid NEW_TOKEN */ + return ngx_quic_send_retry(c, conf, pkt); } - - /* process retry and initialize connection IDs */ - - if (pkt->token.len) { - - rc = ngx_quic_validate_token(c, conf->token_key, pkt); - - if (rc == NGX_ERROR) { - /* internal error */ - return NGX_ERROR; - - } else if (rc == NGX_ABORT) { - /* token cannot be decrypted */ - return ngx_quic_send_early_cc(c, pkt, - NGX_QUIC_ERR_INVALID_TOKEN, - "cannot decrypt token"); - } else if (rc == NGX_DECLINED) { - /* token is invalid */ - - if (pkt->retried) { - /* invalid Retry token */ - return ngx_quic_send_early_cc(c, pkt, - NGX_QUIC_ERR_INVALID_TOKEN, - "invalid token"); - } else if (conf->retry) { - /* invalid NEW_TOKEN */ - return ngx_quic_send_retry(c, conf, pkt); - } - } - - /* NGX_OK */ - - } else if (conf->retry) { - return ngx_quic_send_retry(c, conf, pkt); - - } else { - pkt->odcid = pkt->dcid; - } - - if (ngx_terminate || ngx_exiting) { - if (conf->retry) { - return ngx_quic_send_retry(c, conf, pkt); - } - - return NGX_ERROR; - } - - c->log->action = "creating quic connection"; - - qc = ngx_quic_new_connection(c, conf, pkt); - if (qc == NULL) { - return NGX_ERROR; - } - - } else if (pkt->level == ssl_encryption_application) { - return ngx_quic_send_stateless_reset(c, conf, pkt); - - } else { - return NGX_ERROR; - } - } + } + + /* NGX_OK */ + + } else if (conf->retry) { + return ngx_quic_send_retry(c, conf, pkt); + + } else { + pkt->odcid = pkt->dcid; + } + + if (ngx_terminate || ngx_exiting) { + if (conf->retry) { + return ngx_quic_send_retry(c, conf, pkt); + } + + return NGX_ERROR; + } + + c->log->action = "creating quic connection"; + + qc = ngx_quic_new_connection(c, conf, pkt); + if (qc == NULL) { + return NGX_ERROR; + } + + return ngx_quic_process_payload(c, pkt); +} + + +static ngx_int_t +ngx_quic_process_payload(ngx_connection_t *c, ngx_quic_header_t *pkt) +{ + ngx_int_t rc; + ngx_quic_send_ctx_t *ctx; + ngx_quic_connection_t *qc; + static u_char buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE]; + + qc = ngx_quic_get_connection(c); + + qc->error = 0; + qc->error_reason = 0; c->log->action = "decrypting packet"; @@ -2404,16 +2415,35 @@ } } + if (qc->closing) { + /* + * 10.1 Closing and Draining Connection States + * ... delayed or reordered packets are properly discarded. + * + * An endpoint retains only enough information to generate + * a packet containing a CONNECTION_CLOSE frame and to identify + * packets as belonging to the connection. + */ + + qc->error_level = pkt->level; + qc->error = NGX_QUIC_ERR_NO_ERROR; + qc->error_reason = "connection is closing, packet discarded"; + qc->error_ftype = 0; + qc->error_app = 0; + + return ngx_quic_send_cc(c); + } + pkt->received = ngx_current_msec; c->log->action = "handling payload"; if (pkt->level != ssl_encryption_application) { - return ngx_quic_payload_handler(c, pkt); + return ngx_quic_handle_frames(c, pkt); } if (!pkt->key_update) { - return ngx_quic_payload_handler(c, pkt); + return ngx_quic_handle_frames(c, pkt); } /* switch keys and generate next on Key Phase change */ @@ -2421,7 +2451,7 @@ qc->key_phase ^= 1; ngx_quic_keys_switch(c, qc->keys); - rc = ngx_quic_payload_handler(c, pkt); + rc = ngx_quic_handle_frames(c, pkt); if (rc != NGX_OK) { return rc; } @@ -2581,7 +2611,7 @@ static ngx_int_t -ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt) +ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt) { u_char *end, *p; ssize_t len; @@ -2593,25 +2623,6 @@ qc = ngx_quic_get_connection(c); - if (qc->closing) { - /* - * 10.1 Closing and Draining Connection States - * ... delayed or reordered packets are properly discarded. - * - * An endpoint retains only enough information to generate - * a packet containing a CONNECTION_CLOSE frame and to identify - * packets as belonging to the connection. - */ - - qc->error_level = pkt->level; - qc->error = NGX_QUIC_ERR_NO_ERROR; - qc->error_reason = "connection is closing, packet discarded"; - qc->error_ftype = 0; - qc->error_app = 0; - - return ngx_quic_send_cc(c); - } - p = pkt->payload.data; end = p + pkt->payload.len;