aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2021-01-28 12:35:18 +0300
committerRoman Arutyunyan <arut@nginx.com>2021-01-28 12:35:18 +0300
commitfef33604662c4722a2bf0d682f4a0526eb20a692 (patch)
tree93f8656d6fa9734fa425cad4aab74543a8a410ce /src
parent89dda20510bf7dac952a2dc0b5f29deba376e25f (diff)
downloadnginx-fef33604662c4722a2bf0d682f4a0526eb20a692.tar.gz
nginx-fef33604662c4722a2bf0d682f4a0526eb20a692.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/event/quic/ngx_event_quic.c203
1 files changed, 107 insertions, 96 deletions
diff --git a/src/event/quic/ngx_event_quic.c b/src/event/quic/ngx_event_quic.c
index 52397bcf5..742950b6c 100644
--- a/src/event/quic/ngx_event_quic.c
+++ b/src/event/quic/ngx_event_quic.c
@@ -255,13 +255,15 @@ static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b,
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 @@ ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc)
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 @@ ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b, ngx_quic_conf_t *conf)
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_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
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 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
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 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
}
#endif
+ qc = ngx_quic_get_connection(c);
+
if (qc) {
if (rc == NGX_ABORT) {
@@ -2284,84 +2276,103 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
return NGX_DECLINED;
}
- } else {
+ return ngx_quic_process_payload(c, pkt);
+ }
- if (rc == NGX_ABORT) {
- return ngx_quic_negotiate_version(c, pkt);
- }
+ /* packet does not belong to a connection */
- if (pkt->level == ssl_encryption_initial) {
- c->log->action = "processing initial packet";
+ if (rc == NGX_ABORT) {
+ return ngx_quic_negotiate_version(c, pkt);
+ }
- 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;
- }
+ if (pkt->level == ssl_encryption_application) {
+ return ngx_quic_send_stateless_reset(c, conf, pkt);
+ }
- /* process retry and initialize connection IDs */
+ if (pkt->level != ssl_encryption_initial) {
+ return NGX_ERROR;
+ }
- if (pkt->token.len) {
+ c->log->action = "processing initial packet";
- rc = ngx_quic_validate_token(c, conf->token_key, pkt);
+ 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;
+ }
- if (rc == NGX_ERROR) {
- /* internal error */
- return NGX_ERROR;
+ /* process retry and initialize connection IDs */
- } 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->token.len) {
- 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);
- }
- }
+ rc = ngx_quic_validate_token(c, conf->token_key, pkt);
- /* NGX_OK */
+ 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);
-
- } else {
- pkt->odcid = pkt->dcid;
}
+ }
- if (ngx_terminate || ngx_exiting) {
- if (conf->retry) {
- return ngx_quic_send_retry(c, conf, pkt);
- }
+ /* NGX_OK */
- return NGX_ERROR;
- }
+ } else if (conf->retry) {
+ return ngx_quic_send_retry(c, conf, pkt);
- c->log->action = "creating quic connection";
+ } else {
+ pkt->odcid = pkt->dcid;
+ }
- qc = ngx_quic_new_connection(c, conf, pkt);
- if (qc == NULL) {
- return NGX_ERROR;
- }
+ if (ngx_terminate || ngx_exiting) {
+ if (conf->retry) {
+ return ngx_quic_send_retry(c, conf, pkt);
+ }
- } else if (pkt->level == ssl_encryption_application) {
- return ngx_quic_send_stateless_reset(c, conf, pkt);
+ return NGX_ERROR;
+ }
- } else {
- 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";
if (!ngx_quic_keys_available(qc->keys, pkt->level)) {
@@ -2404,16 +2415,35 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
}
}
+ 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 @@ ngx_quic_process_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
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 @@ 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, 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 @@ ngx_quic_payload_handler(ngx_connection_t *c, ngx_quic_header_t *pkt)
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;