src/event/quic/ngx_event_quic.c - nginx-1.31.7 nginx/ @ 939334eff

Global variables defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Nginx, Inc.
  3. */


  4. #include <ngx_config.h>
  5. #include <ngx_core.h>
  6. #include <ngx_event.h>
  7. #include <ngx_sha1.h>
  8. #include <ngx_event_quic_connection.h>


  9. static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c,
  10.     ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
  11. static ngx_int_t ngx_quic_handle_stateless_reset(ngx_connection_t *c,
  12.     ngx_quic_header_t *pkt);
  13. static void ngx_quic_input_handler(ngx_event_t *rev);
  14. static void ngx_quic_close_handler(ngx_event_t *ev);

  15. static ngx_int_t ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b,
  16.     ngx_quic_conf_t *conf);
  17. static ngx_int_t ngx_quic_handle_packet(ngx_connection_t *c,
  18.     ngx_quic_conf_t *conf, ngx_quic_header_t *pkt);
  19. static ngx_int_t ngx_quic_handle_payload(ngx_connection_t *c,
  20.     ngx_quic_header_t *pkt);
  21. static ngx_int_t ngx_quic_check_csid(ngx_quic_connection_t *qc,
  22.     ngx_quic_header_t *pkt);
  23. static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c,
  24.     ngx_quic_header_t *pkt);

  25. static void ngx_quic_push_handler(ngx_event_t *ev);


  26. ‌static ngx_core_module_t  ngx_quic_module_ctx = {
  27.     ngx_string("quic"),
  28.     NULL,
  29.     NULL
  30. };


  31. ‌ngx_module_t  ngx_quic_module = {
  32.     NGX_MODULE_V1,
  33.     &ngx_quic_module_ctx,                  /* module context */
  34.     NULL,                                  /* module directives */
  35.     NGX_CORE_MODULE,                       /* module type */
  36.     NULL,                                  /* init master */
  37.     NULL,                                  /* init module */
  38.     NULL,                                  /* init process */
  39.     NULL,                                  /* init thread */
  40.     NULL,                                  /* exit thread */
  41.     NULL,                                  /* exit process */
  42.     NULL,                                  /* exit master */
  43.     NGX_MODULE_V1_PADDING
  44. };


  45. #if (NGX_DEBUG)

  46. void
  47. ‌ngx_quic_connstate_dbg(ngx_connection_t *c)
  48. {
  49.     u_char                 *p, *last;
  50.     ngx_quic_connection_t  *qc;
  51.     u_char                  buf[NGX_MAX_ERROR_STR];

  52.     p = buf;
  53.     last = p + sizeof(buf);

  54.     qc = ngx_quic_get_connection(c);

  55.     p = ngx_slprintf(p, last, "state:");

  56.     if (qc) {

  57.         if (qc->error) {
  58.             p = ngx_slprintf(p, last, "%s", qc->error_app ? " app" : "");
  59.             p = ngx_slprintf(p, last, " error:%ui", qc->error);

  60.             if (qc->error_reason) {
  61.                 p = ngx_slprintf(p, last, " \"%s\"", qc->error_reason);
  62.             }
  63.         }

  64.         p = ngx_slprintf(p, last, "%s", qc->shutdown ? " shutdown" : "");
  65.         p = ngx_slprintf(p, last, "%s", qc->closing ? " closing" : "");
  66.         p = ngx_slprintf(p, last, "%s", qc->draining ? " draining" : "");
  67.         p = ngx_slprintf(p, last, "%s", qc->key_phase ? " kp" : "");

  68.     } else {
  69.         p = ngx_slprintf(p, last, " early");
  70.     }

  71.     if (c->read->timer_set) {
  72.         p = ngx_slprintf(p, last,
  73.                          qc && qc->send_timer_set ? " send:%M" : " read:%M",
  74.                          c->read->timer.key - ngx_current_msec);
  75.     }

  76.     if (qc) {

  77.         if (qc->push.timer_set) {
  78.             p = ngx_slprintf(p, last, " push:%M",
  79.                              qc->push.timer.key - ngx_current_msec);
  80.         }

  81.         if (qc->pto.timer_set) {
  82.             p = ngx_slprintf(p, last, " pto:%M",
  83.                              qc->pto.timer.key - ngx_current_msec);
  84.         }

  85.         if (qc->close.timer_set) {
  86.             p = ngx_slprintf(p, last, " close:%M",
  87.                              qc->close.timer.key - ngx_current_msec);
  88.         }
  89.     }

  90.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  91.                    "quic %*s", p - buf, buf);
  92. }

  93. #endif


  94. ngx_int_t
  95. ‌ngx_quic_apply_transport_params(ngx_connection_t *c, ngx_quic_tp_t *ctp)
  96. {
  97.     ngx_str_t               scid;
  98.     ngx_quic_connection_t  *qc;

  99.     qc = ngx_quic_get_connection(c);

  100.     scid.data = qc->path->cid->id;
  101.     scid.len = qc->path->cid->len;

  102.     if (scid.len != ctp->initial_scid.len
  103.         || ngx_memcmp(scid.data, ctp->initial_scid.data, scid.len) != 0)
  104.     {
  105.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  106.         qc->error_reason = "invalid initial_source_connection_id";

  107.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  108.                       "quic client initial_source_connection_id mismatch");
  109.         return NGX_ERROR;
  110.     }

  111.     if (ctp->max_udp_payload_size < NGX_QUIC_MIN_INITIAL_SIZE
  112.         || ctp->max_udp_payload_size > NGX_QUIC_MAX_UDP_PAYLOAD_SIZE)
  113.     {
  114.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  115.         qc->error_reason = "invalid maximum packet size";

  116.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  117.                       "quic maximum packet size is invalid");
  118.         return NGX_ERROR;
  119.     }

  120.     if (ctp->active_connection_id_limit < 2) {
  121.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  122.         qc->error_reason = "invalid active_connection_id_limit";

  123.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  124.                       "quic active_connection_id_limit is invalid");
  125.         return NGX_ERROR;
  126.     }

  127.     if (ctp->ack_delay_exponent > 20) {
  128.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  129.         qc->error_reason = "invalid ack_delay_exponent";

  130.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  131.                       "quic ack_delay_exponent is invalid");
  132.         return NGX_ERROR;
  133.     }

  134.     if (ctp->max_ack_delay >= 16384) {
  135.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  136.         qc->error_reason = "invalid max_ack_delay";

  137.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  138.                       "quic max_ack_delay is invalid");
  139.         return NGX_ERROR;
  140.     }

  141.     if (ctp->max_idle_timeout > 0
  142.         && ctp->max_idle_timeout < qc->tp.max_idle_timeout)
  143.     {
  144.         qc->tp.max_idle_timeout = ctp->max_idle_timeout;
  145.     }

  146.     qc->streams.server_max_streams_bidi = ctp->initial_max_streams_bidi;
  147.     qc->streams.server_max_streams_uni = ctp->initial_max_streams_uni;

  148.     ngx_memcpy(&qc->ctp, ctp, sizeof(ngx_quic_tp_t));

  149.     return NGX_OK;
  150. }


  151. void
  152. ‌ngx_quic_run(ngx_connection_t *c, ngx_quic_conf_t *conf)
  153. {
  154.     ngx_int_t               rc;
  155.     ngx_quic_connection_t  *qc;

  156.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic run");

  157.     rc = ngx_quic_handle_datagram(c, c->buffer, conf);
  158.     if (rc != NGX_OK) {
  159.         ngx_quic_close_connection(c, rc);
  160.         return;
  161.     }

  162.     /* quic connection is now created */
  163.     qc = ngx_quic_get_connection(c);

  164.     ngx_add_timer(c->read, qc->tp.max_idle_timeout);

  165.     if (!qc->streams.initialized) {
  166.         ngx_add_timer(&qc->close, qc->conf->handshake_timeout);
  167.     }

  168.     ngx_quic_connstate_dbg(c);

  169.     c->read->handler = ngx_quic_input_handler;

  170.     return;
  171. }


  172. static ngx_quic_connection_t *
  173. ‌ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
  174.     ngx_quic_header_t *pkt)
  175. {
  176.     ngx_uint_t              i;
  177.     ngx_quic_tp_t          *ctp;
  178.     ngx_quic_connection_t  *qc;

  179.     qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t));
  180.     if (qc == NULL) {
  181.         return NULL;
  182.     }

  183.     qc->keys = ngx_pcalloc(c->pool, sizeof(ngx_quic_keys_t));
  184.     if (qc->keys == NULL) {
  185.         return NULL;
  186.     }

  187.     qc->version = pkt->version;

  188.     ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel,
  189.                     ngx_quic_rbtree_insert_stream);

  190.     for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
  191.         ngx_queue_init(&qc->send_ctx[i].frames);
  192.         ngx_queue_init(&qc->send_ctx[i].sending);
  193.         ngx_queue_init(&qc->send_ctx[i].sent);
  194.         qc->send_ctx[i].largest_pn = NGX_QUIC_UNSET_PN;
  195.         qc->send_ctx[i].largest_ack = NGX_QUIC_UNSET_PN;
  196.         qc->send_ctx[i].largest_range = NGX_QUIC_UNSET_PN;
  197.         qc->send_ctx[i].pending_ack = NGX_QUIC_UNSET_PN;
  198.     }

  199.     qc->send_ctx[0].level = NGX_QUIC_ENCRYPTION_INITIAL;
  200.     qc->send_ctx[1].level = NGX_QUIC_ENCRYPTION_HANDSHAKE;
  201.     qc->send_ctx[2].level = NGX_QUIC_ENCRYPTION_APPLICATION;

  202.     ngx_queue_init(&qc->free_frames);

  203.     ngx_quic_init_rtt(qc);

  204.     qc->pto.log = c->log;
  205.     qc->pto.data = c;
  206.     qc->pto.handler = ngx_quic_pto_handler;

  207.     qc->push.log = c->log;
  208.     qc->push.data = c;
  209.     qc->push.handler = ngx_quic_push_handler;

  210.     qc->close.log = c->log;
  211.     qc->close.data = c;
  212.     qc->close.handler = ngx_quic_close_handler;

  213.     qc->path_validation.log = c->log;
  214.     qc->path_validation.data = c;
  215.     qc->path_validation.handler = ngx_quic_path_handler;

  216.     qc->key_update.log = c->log;
  217.     qc->key_update.data = c;
  218.     qc->key_update.handler = ngx_quic_keys_update;

  219.     qc->conf = conf;

  220.     if (ngx_quic_init_transport_params(&qc->tp, conf) != NGX_OK) {
  221.         return NULL;
  222.     }

  223.     ctp = &qc->ctp;

  224.     /* defaults to be used before actual client parameters are received */
  225.     ctp->max_udp_payload_size = NGX_QUIC_MAX_UDP_PAYLOAD_SIZE;
  226.     ctp->ack_delay_exponent = NGX_QUIC_DEFAULT_ACK_DELAY_EXPONENT;
  227.     ctp->max_ack_delay = NGX_QUIC_DEFAULT_MAX_ACK_DELAY;
  228.     ctp->active_connection_id_limit = 2;

  229.     ngx_queue_init(&qc->streams.uninitialized);
  230.     ngx_queue_init(&qc->streams.free);

  231.     qc->streams.recv_max_data = qc->tp.initial_max_data;
  232.     qc->streams.recv_window = qc->streams.recv_max_data;

  233.     qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni;
  234.     qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi;

  235.     qc->congestion.window = ngx_min(10 * NGX_QUIC_MIN_INITIAL_SIZE,
  236.                                     ngx_max(2 * NGX_QUIC_MIN_INITIAL_SIZE,
  237.                                             14720));
  238.     qc->congestion.ssthresh = (size_t) -1;
  239.     qc->congestion.mtu = NGX_QUIC_MIN_INITIAL_SIZE;
  240.     qc->congestion.recovery_start = ngx_current_msec - 1;

  241.     qc->max_frames = (conf->max_concurrent_streams_uni
  242.                       + conf->max_concurrent_streams_bidi)
  243.                      * conf->stream_buffer_size / 2000;
  244.     qc->max_frames = ngx_max(qc->max_frames, 10000);

  245.     if (pkt->validated && pkt->retried) {
  246.         qc->tp.retry_scid.len = pkt->dcid.len;
  247.         qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid);
  248.         if (qc->tp.retry_scid.data == NULL) {
  249.             return NULL;
  250.         }
  251.     }

  252.     if (ngx_quic_keys_set_initial_secret(qc->keys, &pkt->dcid, c->log)
  253.         != NGX_OK)
  254.     {
  255.         return NULL;
  256.     }

  257.     qc->validated = pkt->validated;

  258.     if (ngx_quic_open_sockets(c, qc, pkt) != NGX_OK) {
  259.         ngx_quic_keys_cleanup(qc->keys);
  260.         return NULL;
  261.     }

  262.     c->idle = 1;
  263.     ngx_reusable_connection(c, 1);

  264.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  265.                    "quic connection created");

  266.     return qc;
  267. }


  268. static ngx_int_t
  269. ‌ngx_quic_handle_stateless_reset(ngx_connection_t *c, ngx_quic_header_t *pkt)
  270. {
  271.     u_char                 *tail, ch;
  272.     ngx_uint_t              i;
  273.     ngx_queue_t            *q;
  274.     ngx_quic_client_id_t   *cid;
  275.     ngx_quic_connection_t  *qc;

  276.     qc = ngx_quic_get_connection(c);

  277.     /* A stateless reset uses an entire UDP datagram */
  278.     if (!pkt->first) {
  279.         return NGX_DECLINED;
  280.     }

  281.     tail = pkt->raw->last - NGX_QUIC_SR_TOKEN_LEN;

  282.     for (q = ngx_queue_head(&qc->client_ids);
  283.          q != ngx_queue_sentinel(&qc->client_ids);
  284.          q = ngx_queue_next(q))
  285.     {
  286.         cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);

  287.         if (cid->seqnum == 0 || !cid->used) {
  288.             /*
  289.              * No stateless reset token in initial connection id.
  290.              * Don't accept a token from an unused connection id.
  291.              */
  292.             continue;
  293.         }

  294.         /* constant time comparison */

  295.         for (ch = 0, i = 0; i < NGX_QUIC_SR_TOKEN_LEN; i++) {
  296.             ch |= tail[i] ^ cid->sr_token[i];
  297.         }

  298.         if (ch == 0) {
  299.             return NGX_OK;
  300.         }
  301.     }

  302.     return NGX_DECLINED;
  303. }


  304. static void
  305. ‌ngx_quic_input_handler(ngx_event_t *rev)
  306. {
  307.     ngx_int_t               rc;
  308.     ngx_buf_t              *b;
  309.     ngx_connection_t       *c;
  310.     ngx_quic_connection_t  *qc;

  311.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0, "quic input handler");

  312.     c = rev->data;
  313.     qc = ngx_quic_get_connection(c);

  314.     c->log->action = "handling quic input";

  315.     if (rev->timedout) {
  316.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  317.                       "quic client timed out");
  318.         ngx_quic_close_connection(c, NGX_DONE);
  319.         return;
  320.     }

  321.     if (c->close) {
  322.         c->close = 0;

  323.         if (!ngx_exiting || !qc->streams.initialized) {
  324.             qc->error = NGX_QUIC_ERR_NO_ERROR;
  325.             qc->error_reason = "graceful shutdown";
  326.             ngx_quic_close_connection(c, NGX_ERROR);
  327.             return;
  328.         }

  329.         if (!qc->closing && qc->conf->shutdown) {
  330.             qc->conf->shutdown(c);
  331.         }

  332.         return;
  333.     }

  334.     b = c->udp->buffer;
  335.     if (b == NULL) {
  336.         return;
  337.     }

  338.     rc = ngx_quic_handle_datagram(c, b, NULL);

  339.     if (rc == NGX_ERROR) {
  340.         ngx_quic_close_connection(c, NGX_ERROR);
  341.         return;
  342.     }

  343.     if (rc == NGX_DONE) {
  344.         return;
  345.     }

  346.     /* rc == NGX_OK */

  347.     qc->send_timer_set = 0;
  348.     ngx_add_timer(rev, qc->tp.max_idle_timeout);

  349.     ngx_quic_connstate_dbg(c);
  350. }


  351. void
  352. ‌ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc)
  353. {
  354.     ngx_uint_t              i;
  355.     ngx_pool_t             *pool;
  356.     ngx_quic_send_ctx_t    *ctx;
  357.     ngx_quic_connection_t  *qc;

  358.     qc = ngx_quic_get_connection(c);

  359.     if (qc == NULL) {
  360.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  361.                        "quic packet rejected rc:%i, cleanup connection", rc);
  362.         goto quic_done;
  363.     }

  364.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  365.                    "quic close %s rc:%i",
  366.                    qc->closing ? "resumed": "initiated", rc);

  367.     if (!qc->closing) {

  368.         /* drop packets from retransmit queues, no ack is expected */
  369.         for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
  370.             ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
  371.             ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
  372.         }

  373.         if (qc->close.timer_set) {
  374.             ngx_del_timer(&qc->close);
  375.         }

  376.         if (rc == NGX_DONE) {

  377.             /*
  378.              * RFC 9000, 10.1.  Idle Timeout
  379.              *
  380.              *  If a max_idle_timeout is specified by either endpoint in its
  381.              *  transport parameters (Section 18.2), the connection is silently
  382.              *  closed and its state is discarded when it remains idle
  383.              */

  384.             /* this case also handles some errors from ngx_quic_run() */

  385.             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  386.                            "quic close silent drain:%d timedout:%d",
  387.                            qc->draining, c->read->timedout);
  388.         } else {

  389.             /*
  390.              * RFC 9000, 10.2.  Immediate Close
  391.              *
  392.              *  An endpoint sends a CONNECTION_CLOSE frame (Section 19.19)
  393.              *  to terminate the connection immediately.
  394.              */

  395.             if (qc->error == 0 && rc == NGX_ERROR) {
  396.                 qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  397.                 qc->error_app = 0;
  398.             }

  399.             ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  400.                            "quic close immediate term:%d drain:%d "
  401.                            "%serror:%ui \"%s\"",
  402.                            rc == NGX_ERROR ? 1 : 0, qc->draining,
  403.                            qc->error_app ? "app " : "", qc->error,
  404.                            qc->error_reason ? qc->error_reason : "");

  405.             for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
  406.                 ctx = &qc->send_ctx[i];

  407.                 if (!ngx_quic_keys_available(qc->keys, ctx->level, 1)) {
  408.                     continue;
  409.                 }

  410.                 qc->error_level = ctx->level;
  411.                 (void) ngx_quic_send_cc(c);

  412.                 if (rc == NGX_OK) {
  413.                     ngx_add_timer(&qc->close, 3 * ngx_quic_pto(c, ctx));
  414.                 }
  415.             }
  416.         }

  417.         qc->closing = 1;
  418.     }

  419.     if (rc == NGX_ERROR && qc->close.timer_set) {
  420.         /* do not wait for timer in case of fatal error */
  421.         ngx_del_timer(&qc->close);
  422.     }

  423.     if (ngx_quic_close_streams(c, qc) == NGX_AGAIN) {
  424.         return;
  425.     }

  426.     if (qc->push.timer_set) {
  427.         ngx_del_timer(&qc->push);
  428.     }

  429.     if (qc->pto.timer_set) {
  430.         ngx_del_timer(&qc->pto);
  431.     }

  432.     if (qc->path_validation.timer_set) {
  433.         ngx_del_timer(&qc->path_validation);
  434.     }

  435.     if (qc->push.posted) {
  436.         ngx_delete_posted_event(&qc->push);
  437.     }

  438.     if (qc->key_update.posted) {
  439.         ngx_delete_posted_event(&qc->key_update);
  440.     }

  441.     if (qc->close.timer_set) {
  442.         return;
  443.     }

  444.     if (qc->close.posted) {
  445.         ngx_delete_posted_event(&qc->close);
  446.     }

  447.     ngx_quic_close_sockets(c);

  448.     ngx_quic_keys_cleanup(qc->keys);

  449.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic close completed");

  450.     /* may be tested from SSL callback during SSL shutdown */
  451.     c->udp = NULL;

  452. quic_done:

  453.     if (c->ssl) {
  454.         (void) ngx_ssl_shutdown(c);
  455.     }

  456.     if (c->read->timer_set) {
  457.         ngx_del_timer(c->read);
  458.     }

  459. #if (NGX_STAT_STUB)
  460.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  461. #endif

  462.     c->destroyed = 1;

  463.     pool = c->pool;

  464.     ngx_close_connection(c);

  465.     ngx_destroy_pool(pool);
  466. }


  467. void
  468. ‌ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
  469.     const char *reason)
  470. {
  471.     ngx_quic_connection_t  *qc;

  472.     qc = ngx_quic_get_connection(c);

  473.     if (qc->closing) {
  474.         return;
  475.     }

  476.     qc->error = err;
  477.     qc->error_reason = reason;
  478.     qc->error_app = 1;
  479.     qc->error_ftype = 0;

  480.     ngx_post_event(&qc->close, &ngx_posted_events);
  481. }


  482. void
  483. ‌ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err,
  484.     const char *reason)
  485. {
  486.     ngx_quic_connection_t  *qc;

  487.     qc = ngx_quic_get_connection(c);
  488.     qc->shutdown = 1;
  489.     qc->shutdown_code = err;
  490.     qc->shutdown_reason = reason;

  491.     ngx_quic_shutdown_quic(c);
  492. }


  493. static void
  494. ‌ngx_quic_close_handler(ngx_event_t *ev)
  495. {
  496.     ngx_connection_t  *c;

  497.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic close handler");

  498.     c = ev->data;

  499.     ngx_quic_close_connection(c, NGX_OK);
  500. }


  501. static ngx_int_t
  502. ‌ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b,
  503.     ngx_quic_conf_t *conf)
  504. {
  505.     size_t                  size;
  506.     u_char                 *p, *start;
  507.     ngx_int_t               rc;
  508.     ngx_uint_t              good;
  509.     ngx_quic_path_t        *path;
  510.     ngx_quic_header_t       pkt;
  511.     ngx_quic_connection_t  *qc;

  512.     good = 0;
  513.     path = NULL;

  514.     size = b->last - b->pos;

  515.     p = start = b->pos;

  516.     while (p < b->last) {

  517.         ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
  518.         pkt.raw = b;
  519.         pkt.data = p;
  520.         pkt.len = b->last - p;
  521.         pkt.log = c->log;
  522.         pkt.first = (p == start) ? 1 : 0;
  523.         pkt.path = path;
  524.         pkt.flags = p[0];
  525.         pkt.raw->pos++;

  526.         rc = ngx_quic_handle_packet(c, conf, &pkt);

  527. #if (NGX_DEBUG)
  528.         if (pkt.parsed) {
  529.             ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  530.                            "quic packet done rc:%i level:%s"
  531.                            " decr:%d pn:%L perr:%ui",
  532.                            rc, ngx_quic_level_name(pkt.level),
  533.                            pkt.decrypted, pkt.pn, pkt.error);
  534.         } else {
  535.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  536.                            "quic packet done rc:%i parse failed", rc);
  537.         }
  538. #endif

  539.         if (rc == NGX_ERROR || rc == NGX_DONE) {
  540.             return rc;
  541.         }

  542.         if (rc == NGX_OK) {
  543.             good = 1;
  544.         }

  545.         path = pkt.path; /* preserve packet path from 1st packet */

  546.         /* NGX_OK || NGX_DECLINED */

  547.         /*
  548.          * we get NGX_DECLINED when there are no keys [yet] available
  549.          * to decrypt packet.
  550.          * Instead of queueing it, we ignore it and rely on the sender's
  551.          * retransmission:
  552.          *
  553.          * RFC 9000, 12.2.  Coalescing Packets
  554.          *
  555.          * For example, if decryption fails (because the keys are
  556.          * not available or for any other reason), the receiver MAY either
  557.          * discard or buffer the packet for later processing and MUST
  558.          * attempt to process the remaining packets.
  559.          *
  560.          * We also skip packets that don't match connection state
  561.          * or cannot be parsed properly.
  562.          */

  563.         /* b->pos is at header end, adjust by actual packet length */
  564.         b->pos = pkt.data + pkt.len;

  565.         p = b->pos;
  566.     }

  567.     if (!good) {
  568.         return NGX_DONE;
  569.     }

  570.     qc = ngx_quic_get_connection(c);

  571.     if (qc) {
  572.         qc->received += size;

  573.         if ((uint64_t) (c->sent + qc->received) / 8 >
  574.             (qc->streams.sent + qc->streams.recv_last) + 1048576)
  575.         {
  576.             ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic flood detected");

  577.             qc->error = NGX_QUIC_ERR_NO_ERROR;
  578.             qc->error_reason = "QUIC flood detected";
  579.             return NGX_ERROR;
  580.         }
  581.     }

  582.     return NGX_OK;
  583. }


  584. static ngx_int_t
  585. ‌ngx_quic_handle_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
  586.     ngx_quic_header_t *pkt)
  587. {
  588.     ngx_int_t               rc;
  589.     ngx_quic_socket_t      *qsock;
  590.     ngx_quic_connection_t  *qc;

  591.     c->log->action = "parsing quic packet";

  592.     rc = ngx_quic_parse_packet(pkt);

  593.     if (rc == NGX_ERROR) {
  594.         return NGX_DECLINED;
  595.     }

  596.     pkt->parsed = 1;

  597.     c->log->action = "handling quic packet";

  598.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  599.                    "quic packet rx dcid len:%uz %xV",
  600.                    pkt->dcid.len, &pkt->dcid);

  601. #if (NGX_DEBUG)
  602.     if (pkt->level != NGX_QUIC_ENCRYPTION_APPLICATION) {
  603.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  604.                        "quic packet rx scid len:%uz %xV",
  605.                        pkt->scid.len, &pkt->scid);
  606.     }

  607.     if (pkt->level == NGX_QUIC_ENCRYPTION_INITIAL) {
  608.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  609.                        "quic address validation token len:%uz %xV",
  610.                        pkt->token.len, &pkt->token);
  611.     }
  612. #endif

  613.     qc = ngx_quic_get_connection(c);

  614.     if (qc) {

  615.         if (rc == NGX_ABORT) {
  616.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  617.                           "quic unsupported version: 0x%xD", pkt->version);
  618.             return NGX_DECLINED;
  619.         }

  620.         if (pkt->level != NGX_QUIC_ENCRYPTION_APPLICATION) {

  621.             if (pkt->version != qc->version) {
  622.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  623.                               "quic version mismatch: 0x%xD", pkt->version);
  624.                 return NGX_DECLINED;
  625.             }

  626.             if (pkt->first) {
  627.                 qsock = ngx_quic_get_socket(c);

  628.                 if (ngx_cmp_sockaddr(&qsock->sockaddr.sockaddr, qsock->socklen,
  629.                                      qc->path->sockaddr, qc->path->socklen, 1)
  630.                     != NGX_OK)
  631.                 {
  632.                     /* packet comes from unknown path, possibly migration */
  633.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  634.                                    "quic too early migration attempt");
  635.                     return NGX_DONE;
  636.                 }
  637.             }

  638.             if (ngx_quic_check_csid(qc, pkt) != NGX_OK) {
  639.                 return NGX_DECLINED;
  640.             }

  641.         }

  642.         rc = ngx_quic_handle_payload(c, pkt);

  643.         if (rc == NGX_DECLINED
  644.             && pkt->level == NGX_QUIC_ENCRYPTION_APPLICATION)
  645.         {
  646.             if (ngx_quic_handle_stateless_reset(c, pkt) == NGX_OK) {
  647.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  648.                               "quic stateless reset packet detected");

  649.                 qc->draining = 1;
  650.                 ngx_post_event(&qc->close, &ngx_posted_events);

  651.                 return NGX_OK;
  652.             }
  653.         }

  654.         return rc;
  655.     }

  656.     /* packet does not belong to a connection */

  657.     if (rc == NGX_ABORT) {
  658.         return ngx_quic_negotiate_version(c, pkt);
  659.     }

  660.     if (pkt->level == NGX_QUIC_ENCRYPTION_APPLICATION) {
  661.         return ngx_quic_send_stateless_reset(c, conf, pkt);
  662.     }

  663.     if (pkt->level != NGX_QUIC_ENCRYPTION_INITIAL) {
  664.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  665.                        "quic expected initial, got handshake");
  666.         return NGX_ERROR;
  667.     }

  668.     c->log->action = "handling initial packet";

  669.     if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
  670.         /* RFC 9000, 7.2.  Negotiating Connection IDs */
  671.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  672.                       "quic too short dcid in initial"
  673.                       " packet: len:%i", pkt->dcid.len);
  674.         return NGX_ERROR;
  675.     }

  676.     /* process retry and initialize connection IDs */

  677.     if (pkt->token.len) {

  678.         rc = ngx_quic_validate_token(c, conf->av_token_key, pkt);

  679.         if (rc == NGX_ERROR) {
  680.             /* internal error */
  681.             return NGX_ERROR;

  682.         } else if (rc == NGX_ABORT) {
  683.             /* token cannot be decrypted */
  684.             return ngx_quic_send_early_cc(c, pkt,
  685.                                           NGX_QUIC_ERR_INVALID_TOKEN,
  686.                                           "cannot decrypt token");
  687.         } else if (rc == NGX_DECLINED) {
  688.             /* token is invalid */

  689.             if (pkt->retried) {
  690.                 /* invalid address validation token */
  691.                 return ngx_quic_send_early_cc(c, pkt,
  692.                                           NGX_QUIC_ERR_INVALID_TOKEN,
  693.                                           "invalid address validation token");
  694.             } else if (conf->retry) {
  695.                 /* invalid NEW_TOKEN */
  696.                 return ngx_quic_send_retry(c, conf, pkt);
  697.             }
  698.         }

  699.         /* NGX_OK */

  700.     } else if (conf->retry) {
  701.         return ngx_quic_send_retry(c, conf, pkt);

  702.     } else {
  703.         pkt->odcid = pkt->dcid;
  704.     }

  705.     if (ngx_terminate || ngx_exiting) {
  706.         if (conf->retry) {
  707.             return ngx_quic_send_retry(c, conf, pkt);
  708.         }

  709.         return NGX_ERROR;
  710.     }

  711.     c->log->action = "creating quic connection";

  712.     qc = ngx_quic_new_connection(c, conf, pkt);
  713.     if (qc == NULL) {
  714.         return NGX_ERROR;
  715.     }

  716.     return ngx_quic_handle_payload(c, pkt);
  717. }


  718. static ngx_int_t
  719. ‌ngx_quic_handle_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
  720. {
  721.     ngx_int_t               rc;
  722.     ngx_quic_send_ctx_t    *ctx;
  723.     ngx_quic_connection_t  *qc;
  724.     static u_char           buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];

  725.     qc = ngx_quic_get_connection(c);

  726.     qc->error = 0;
  727.     qc->error_reason = NULL;

  728.     c->log->action = "decrypting packet";

  729.     if (!ngx_quic_keys_available(qc->keys, pkt->level, 0)) {
  730.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  731.                       "quic no %s keys, ignoring packet",
  732.                       ngx_quic_level_name(pkt->level));
  733.         return NGX_DECLINED;
  734.     }

  735. #if (NGX_QUIC_QUICTLS_API)
  736.     /* QuicTLS provides app read keys before completing handshake */

  737.     if (pkt->level == NGX_QUIC_ENCRYPTION_APPLICATION && !c->ssl->handshaked) {
  738.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  739.                       "quic no %s keys ready, ignoring packet",
  740.                       ngx_quic_level_name(pkt->level));
  741.         return NGX_DECLINED;
  742.     }
  743. #endif

  744.     pkt->keys = qc->keys;
  745.     pkt->key_phase = qc->key_phase;
  746.     pkt->plaintext = buf;

  747.     ctx = ngx_quic_get_send_ctx(qc, pkt->level);

  748.     rc = ngx_quic_decrypt(pkt, &ctx->largest_pn);
  749.     if (rc != NGX_OK) {
  750.         qc->error = pkt->error;
  751.         qc->error_reason = "failed to decrypt packet";
  752.         return rc;
  753.     }

  754.     pkt->decrypted = 1;

  755.     c->log->action = "handling decrypted packet";

  756.     if (pkt->path == NULL) {
  757.         rc = ngx_quic_set_path(c, pkt);
  758.         if (rc != NGX_OK) {
  759.             return rc;
  760.         }
  761.     }

  762.     if (c->ssl == NULL) {
  763.         if (ngx_quic_init_connection(c) != NGX_OK) {
  764.             return NGX_ERROR;
  765.         }
  766.     }

  767.     if (pkt->level == NGX_QUIC_ENCRYPTION_HANDSHAKE) {
  768.         /*
  769.          * RFC 9001, 4.9.1.  Discarding Initial Keys
  770.          *
  771.          * The successful use of Handshake packets indicates
  772.          * that no more Initial packets need to be exchanged
  773.          */
  774.         ngx_quic_discard_ctx(c, NGX_QUIC_ENCRYPTION_INITIAL);

  775.         if (!qc->path->validated) {
  776.             qc->path->validated = 1;
  777.             ngx_quic_path_dbg(c, "in handshake", qc->path);
  778.             ngx_post_event(&qc->push, &ngx_posted_events);
  779.         }
  780.     }

  781.     if (pkt->level == NGX_QUIC_ENCRYPTION_APPLICATION) {
  782.         /*
  783.          * RFC 9001, 4.9.3.  Discarding 0-RTT Keys
  784.          *
  785.          * After receiving a 1-RTT packet, servers MUST discard
  786.          * 0-RTT keys within a short time
  787.          */
  788.         ngx_quic_keys_discard(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA);
  789.     }

  790.     if (qc->closing) {
  791.         /*
  792.          * RFC 9000, 10.2.  Immediate Close
  793.          *
  794.          * ... delayed or reordered packets are properly discarded.
  795.          *
  796.          *  In the closing state, an endpoint retains only enough information
  797.          *  to generate a packet containing a CONNECTION_CLOSE frame and to
  798.          *  identify packets as belonging to the connection.
  799.          */

  800.         qc->error_level = pkt->level;
  801.         qc->error = NGX_QUIC_ERR_NO_ERROR;
  802.         qc->error_reason = "connection is closing, packet discarded";
  803.         qc->error_ftype = 0;
  804.         qc->error_app = 0;

  805.         return ngx_quic_send_cc(c);
  806.     }

  807.     pkt->received = ngx_current_msec;

  808.     c->log->action = "handling payload";

  809.     if (pkt->level != NGX_QUIC_ENCRYPTION_APPLICATION) {
  810.         return ngx_quic_handle_frames(c, pkt);
  811.     }

  812.     if (!pkt->key_update) {
  813.         return ngx_quic_handle_frames(c, pkt);
  814.     }

  815.     /* switch keys and generate next on Key Phase change */

  816.     qc->key_phase ^= 1;
  817.     ngx_quic_keys_switch(c, qc->keys);

  818.     rc = ngx_quic_handle_frames(c, pkt);
  819.     if (rc != NGX_OK) {
  820.         return rc;
  821.     }

  822.     ngx_post_event(&qc->key_update, &ngx_posted_events);

  823.     return NGX_OK;
  824. }


  825. void
  826. ‌ngx_quic_discard_ctx(ngx_connection_t *c, ngx_uint_t level)
  827. {
  828.     ngx_queue_t            *q;
  829.     ngx_quic_frame_t       *f;
  830.     ngx_quic_socket_t      *qsock;
  831.     ngx_quic_send_ctx_t    *ctx;
  832.     ngx_quic_connection_t  *qc;

  833.     qc = ngx_quic_get_connection(c);

  834.     if (!ngx_quic_keys_available(qc->keys, level, 0)
  835.         && !ngx_quic_keys_available(qc->keys, level, 1))
  836.     {
  837.         return;
  838.     }

  839.     ngx_quic_keys_discard(qc->keys, level);

  840.     qc->pto_count = 0;

  841.     ctx = ngx_quic_get_send_ctx(qc, level);

  842.     ngx_quic_free_buffer(c, &ctx->crypto);

  843.     while (!ngx_queue_empty(&ctx->sent)) {
  844.         q = ngx_queue_head(&ctx->sent);
  845.         ngx_queue_remove(q);

  846.         f = ngx_queue_data(q, ngx_quic_frame_t, queue);
  847.         ngx_quic_congestion_ack(c, f);
  848.         ngx_quic_free_frame(c, f);
  849.     }

  850.     while (!ngx_queue_empty(&ctx->frames)) {
  851.         q = ngx_queue_head(&ctx->frames);
  852.         ngx_queue_remove(q);

  853.         f = ngx_queue_data(q, ngx_quic_frame_t, queue);
  854.         ngx_quic_free_frame(c, f);
  855.     }

  856.     if (level == NGX_QUIC_ENCRYPTION_INITIAL) {
  857.         /* close temporary listener with initial dcid */
  858.         qsock = ngx_quic_find_socket(c, NGX_QUIC_UNSET_PN);
  859.         if (qsock) {
  860.             ngx_quic_close_socket(c, qsock);
  861.         }
  862.     }

  863.     ctx->send_ack = 0;

  864.     ngx_quic_set_lost_timer(c);
  865. }


  866. static ngx_int_t
  867. ‌ngx_quic_check_csid(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
  868. {
  869.     ngx_queue_t           *q;
  870.     ngx_quic_client_id_t  *cid;

  871.     for (q = ngx_queue_head(&qc->client_ids);
  872.          q != ngx_queue_sentinel(&qc->client_ids);
  873.          q = ngx_queue_next(q))
  874.     {
  875.         cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);

  876.         if (pkt->scid.len == cid->len
  877.             && ngx_memcmp(pkt->scid.data, cid->id, cid->len) == 0)
  878.         {
  879.             return NGX_OK;
  880.         }
  881.     }

  882.     ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid");
  883.     return NGX_ERROR;
  884. }


  885. static ngx_int_t
  886. ‌ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt)
  887. {
  888.     u_char                 *end, *p;
  889.     ssize_t                 len;
  890.     ngx_buf_t               buf;
  891.     ngx_uint_t              do_close, nonprobing;
  892.     ngx_chain_t             chain;
  893.     ngx_quic_frame_t        frame;
  894.     ngx_quic_connection_t  *qc;

  895.     qc = ngx_quic_get_connection(c);

  896.     p = pkt->payload.data;
  897.     end = p + pkt->payload.len;

  898.     do_close = 0;
  899.     nonprobing = 0;

  900.     while (p < end) {

  901.         c->log->action = "parsing frames";

  902.         ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
  903.         ngx_memzero(&buf, sizeof(ngx_buf_t));
  904.         buf.temporary = 1;

  905.         chain.buf = &buf;
  906.         chain.next = NULL;
  907.         frame.data = &chain;

  908.         len = ngx_quic_parse_frame(pkt, p, end, &frame);

  909.         if (len < 0) {
  910.             qc->error = pkt->error;
  911.             return NGX_ERROR;
  912.         }

  913.         ngx_quic_log_frame(c->log, &frame, 0);

  914.         c->log->action = "handling frames";

  915.         p += len;

  916.         switch (frame.type) {
  917.         /* probing frames */
  918.         case NGX_QUIC_FT_PADDING:
  919.         case NGX_QUIC_FT_PATH_CHALLENGE:
  920.         case NGX_QUIC_FT_PATH_RESPONSE:
  921.         case NGX_QUIC_FT_NEW_CONNECTION_ID:
  922.             break;

  923.         /* non-probing frames */
  924.         default:
  925.             nonprobing = 1;
  926.             break;
  927.         }

  928.         switch (frame.type) {

  929.         case NGX_QUIC_FT_ACK:
  930.             if (ngx_quic_handle_ack_frame(c, pkt, &frame) != NGX_OK) {
  931.                 return NGX_ERROR;
  932.             }

  933.             continue;

  934.         case NGX_QUIC_FT_PADDING:
  935.             /* no action required */
  936.             continue;

  937.         case NGX_QUIC_FT_CONNECTION_CLOSE:
  938.         case NGX_QUIC_FT_CONNECTION_CLOSE_APP:
  939.             do_close = 1;
  940.             continue;
  941.         }

  942.         /* got there with ack-eliciting packet */
  943.         pkt->need_ack = 1;

  944.         switch (frame.type) {

  945.         case NGX_QUIC_FT_CRYPTO:

  946.             if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) {
  947.                 return NGX_ERROR;
  948.             }

  949.             break;

  950.         case NGX_QUIC_FT_PING:
  951.             break;

  952.         case NGX_QUIC_FT_STREAM:

  953.             if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) {
  954.                 return NGX_ERROR;
  955.             }

  956.             break;

  957.         case NGX_QUIC_FT_MAX_DATA:

  958.             if (ngx_quic_handle_max_data_frame(c, &frame.u.max_data) != NGX_OK)
  959.             {
  960.                 return NGX_ERROR;
  961.             }

  962.             break;

  963.         case NGX_QUIC_FT_STREAMS_BLOCKED:
  964.         case NGX_QUIC_FT_STREAMS_BLOCKED2:

  965.             if (ngx_quic_handle_streams_blocked_frame(c, pkt,
  966.                                                       &frame.u.streams_blocked)
  967.                 != NGX_OK)
  968.             {
  969.                 return NGX_ERROR;
  970.             }

  971.             break;

  972.         case NGX_QUIC_FT_DATA_BLOCKED:

  973.             if (ngx_quic_handle_data_blocked_frame(c, pkt,
  974.                                                    &frame.u.data_blocked)
  975.                 != NGX_OK)
  976.             {
  977.                 return NGX_ERROR;
  978.             }

  979.             break;

  980.         case NGX_QUIC_FT_STREAM_DATA_BLOCKED:

  981.             if (ngx_quic_handle_stream_data_blocked_frame(c, pkt,
  982.                                                   &frame.u.stream_data_blocked)
  983.                 != NGX_OK)
  984.             {
  985.                 return NGX_ERROR;
  986.             }

  987.             break;

  988.         case NGX_QUIC_FT_MAX_STREAM_DATA:

  989.             if (ngx_quic_handle_max_stream_data_frame(c, pkt,
  990.                                                       &frame.u.max_stream_data)
  991.                 != NGX_OK)
  992.             {
  993.                 return NGX_ERROR;
  994.             }

  995.             break;

  996.         case NGX_QUIC_FT_RESET_STREAM:

  997.             if (ngx_quic_handle_reset_stream_frame(c, pkt,
  998.                                                    &frame.u.reset_stream)
  999.                 != NGX_OK)
  1000.             {
  1001.                 return NGX_ERROR;
  1002.             }

  1003.             break;

  1004.         case NGX_QUIC_FT_STOP_SENDING:

  1005.             if (ngx_quic_handle_stop_sending_frame(c, pkt,
  1006.                                                    &frame.u.stop_sending)
  1007.                 != NGX_OK)
  1008.             {
  1009.                 return NGX_ERROR;
  1010.             }

  1011.             break;

  1012.         case NGX_QUIC_FT_MAX_STREAMS:
  1013.         case NGX_QUIC_FT_MAX_STREAMS2:

  1014.             if (ngx_quic_handle_max_streams_frame(c, pkt, &frame.u.max_streams)
  1015.                 != NGX_OK)
  1016.             {
  1017.                 return NGX_ERROR;
  1018.             }

  1019.             break;

  1020.         case NGX_QUIC_FT_PATH_CHALLENGE:

  1021.             if (ngx_quic_handle_path_challenge_frame(c, pkt,
  1022.                                                      &frame.u.path_challenge)
  1023.                 != NGX_OK)
  1024.             {
  1025.                 return NGX_ERROR;
  1026.             }

  1027.             break;

  1028.         case NGX_QUIC_FT_PATH_RESPONSE:

  1029.             if (ngx_quic_handle_path_response_frame(c, &frame.u.path_response)
  1030.                 != NGX_OK)
  1031.             {
  1032.                 return NGX_ERROR;
  1033.             }

  1034.             break;

  1035.         case NGX_QUIC_FT_NEW_CONNECTION_ID:

  1036.             if (ngx_quic_handle_new_connection_id_frame(c, &frame.u.ncid)
  1037.                 != NGX_OK)
  1038.             {
  1039.                 return NGX_ERROR;
  1040.             }

  1041.             break;

  1042.         case NGX_QUIC_FT_RETIRE_CONNECTION_ID:

  1043.             if (ngx_quic_handle_retire_connection_id_frame(c,
  1044.                                                            &frame.u.retire_cid)
  1045.                 != NGX_OK)
  1046.             {
  1047.                 return NGX_ERROR;
  1048.             }

  1049.             break;

  1050.         default:
  1051.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1052.                            "quic missing frame handler");
  1053.             return NGX_ERROR;
  1054.         }
  1055.     }

  1056.     if (p != end) {
  1057.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1058.                       "quic trailing garbage in payload:%ui bytes", end - p);

  1059.         qc->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR;
  1060.         return NGX_ERROR;
  1061.     }

  1062.     if (do_close) {
  1063.         qc->draining = 1;
  1064.         ngx_post_event(&qc->close, &ngx_posted_events);
  1065.     }

  1066.     if (pkt->path != qc->path && nonprobing) {

  1067.         /*
  1068.          * RFC 9000, 9.2.  Initiating Connection Migration
  1069.          *
  1070.          * An endpoint can migrate a connection to a new local
  1071.          * address by sending packets containing non-probing frames
  1072.          * from that address.
  1073.          */
  1074.         if (ngx_quic_handle_migration(c, pkt) != NGX_OK) {
  1075.             return NGX_ERROR;
  1076.         }
  1077.     }

  1078.     if (ngx_quic_ack_packet(c, pkt) != NGX_OK) {
  1079.         return NGX_ERROR;
  1080.     }

  1081.     return NGX_OK;
  1082. }


  1083. static void
  1084. ‌ngx_quic_push_handler(ngx_event_t *ev)
  1085. {
  1086.     ngx_connection_t  *c;

  1087.     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "quic push handler");

  1088.     c = ev->data;

  1089.     if (ngx_quic_output(c) != NGX_OK) {
  1090.         ngx_quic_close_connection(c, NGX_ERROR);
  1091.         return;
  1092.     }

  1093.     ngx_quic_connstate_dbg(c);
  1094. }


  1095. void
  1096. ‌ngx_quic_shutdown_quic(ngx_connection_t *c)
  1097. {
  1098.     ngx_quic_connection_t  *qc;

  1099.     if (c->reusable) {
  1100.         qc = ngx_quic_get_connection(c);
  1101.         ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
  1102.     }
  1103. }


  1104. void
  1105. ‌ngx_quic_address_hash(struct sockaddr *sockaddr, socklen_t socklen,
  1106.     ngx_uint_t no_port, u_char *salt, size_t saltlen, u_char buf[20])
  1107. {
  1108.     size_t                len;
  1109.     u_char               *data;
  1110.     ngx_sha1_t            sha1;
  1111.     struct sockaddr_in   *sin;
  1112. #if (NGX_HAVE_INET6)
  1113.     struct sockaddr_in6  *sin6;
  1114. #endif

  1115.     len = (size_t) socklen;
  1116.     data = (u_char *) sockaddr;

  1117.     if (no_port) {
  1118.         switch (sockaddr->sa_family) {

  1119. #if (NGX_HAVE_INET6)
  1120.         case AF_INET6:
  1121.             sin6 = (struct sockaddr_in6 *) sockaddr;

  1122.             len = sizeof(struct in6_addr);
  1123.             data = sin6->sin6_addr.s6_addr;

  1124.             break;
  1125. #endif

  1126.         case AF_INET:
  1127.             sin = (struct sockaddr_in *) sockaddr;

  1128.             len = sizeof(in_addr_t);
  1129.             data = (u_char *) &sin->sin_addr;

  1130.             break;
  1131.         }
  1132.     }

  1133.     ngx_sha1_init(&sha1);
  1134.     ngx_sha1_update(&sha1, data, len);

  1135.     if (salt) {
  1136.         ngx_sha1_update(&sha1, salt, saltlen);
  1137.     }

  1138.     ngx_sha1_final(buf, &sha1);
  1139. }