src/event/quic/ngx_event_quic.c - nginx source code

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_event_quic_connection.h>


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

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

  24. static void ngx_quic_push_handler(ngx_event_t *ev);


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


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


  44. #if (NGX_DEBUG)

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

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

  53.     qc = ngx_quic_get_connection(c);

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

  55.     if (qc) {

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

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

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

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

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

  75.     if (qc) {

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

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

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

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

  92. #endif


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

  98.     qc = ngx_quic_get_connection(c);

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

  101.     if (scid.len != ctp->initial_scid.len
  102.         || ngx_memcmp(scid.data, ctp->initial_scid.data, scid.len) != 0)
  103.     {
  104.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  105.                       "quic client initial_source_connection_id mismatch");
  106.         return NGX_ERROR;
  107.     }

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

  113.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  114.                       "quic maximum packet size is invalid");
  115.         return NGX_ERROR;
  116.     }

  117.     if (ctp->active_connection_id_limit < 2) {
  118.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  119.         qc->error_reason = "invalid active_connection_id_limit";

  120.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  121.                       "quic active_connection_id_limit is invalid");
  122.         return NGX_ERROR;
  123.     }

  124.     if (ctp->ack_delay_exponent > 20) {
  125.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  126.         qc->error_reason = "invalid ack_delay_exponent";

  127.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  128.                       "quic ack_delay_exponent is invalid");
  129.         return NGX_ERROR;
  130.     }

  131.     if (ctp->max_ack_delay >= 16384) {
  132.         qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR;
  133.         qc->error_reason = "invalid max_ack_delay";

  134.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  135.                       "quic max_ack_delay is invalid");
  136.         return NGX_ERROR;
  137.     }

  138.     if (ctp->max_idle_timeout > 0
  139.         && ctp->max_idle_timeout < qc->tp.max_idle_timeout)
  140.     {
  141.         qc->tp.max_idle_timeout = ctp->max_idle_timeout;
  142.     }

  143.     qc->streams.server_max_streams_bidi = ctp->initial_max_streams_bidi;
  144.     qc->streams.server_max_streams_uni = ctp->initial_max_streams_uni;

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

  146.     return NGX_OK;
  147. }


  148. void
  149. ngx_quic_run(ngx_connection_t *c, ngx_quic_conf_t *conf)
  150. {
  151.     ngx_int_t               rc;
  152.     ngx_quic_connection_t  *qc;

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

  154.     rc = ngx_quic_handle_datagram(c, c->buffer, conf);
  155.     if (rc != NGX_OK) {
  156.         ngx_quic_close_connection(c, rc);
  157.         return;
  158.     }

  159.     /* quic connection is now created */
  160.     qc = ngx_quic_get_connection(c);

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

  162.     if (!qc->streams.initialized) {
  163.         ngx_add_timer(&qc->close, qc->conf->handshake_timeout);
  164.     }

  165.     ngx_quic_connstate_dbg(c);

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

  167.     return;
  168. }


  169. static ngx_quic_connection_t *
  170. ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,
  171.     ngx_quic_header_t *pkt)
  172. {
  173.     ngx_uint_t              i;
  174.     ngx_quic_tp_t          *ctp;
  175.     ngx_quic_connection_t  *qc;

  176.     qc = ngx_pcalloc(c->pool, sizeof(ngx_quic_connection_t));
  177.     if (qc == NULL) {
  178.         return NULL;
  179.     }

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

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

  185.     ngx_rbtree_init(&qc->streams.tree, &qc->streams.sentinel,
  186.                     ngx_quic_rbtree_insert_stream);

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

  196.     qc->send_ctx[0].level = ssl_encryption_initial;
  197.     qc->send_ctx[1].level = ssl_encryption_handshake;
  198.     qc->send_ctx[2].level = ssl_encryption_application;

  199.     ngx_queue_init(&qc->free_frames);

  200.     ngx_quic_init_rtt(qc);

  201.     qc->pto.log = c->log;
  202.     qc->pto.data = c;
  203.     qc->pto.handler = ngx_quic_pto_handler;

  204.     qc->push.log = c->log;
  205.     qc->push.data = c;
  206.     qc->push.handler = ngx_quic_push_handler;

  207.     qc->close.log = c->log;
  208.     qc->close.data = c;
  209.     qc->close.handler = ngx_quic_close_handler;

  210.     qc->path_validation.log = c->log;
  211.     qc->path_validation.data = c;
  212.     qc->path_validation.handler = ngx_quic_path_handler;

  213.     qc->key_update.log = c->log;
  214.     qc->key_update.data = c;
  215.     qc->key_update.handler = ngx_quic_keys_update;

  216.     qc->conf = conf;

  217.     if (ngx_quic_init_transport_params(&qc->tp, conf) != NGX_OK) {
  218.         return NULL;
  219.     }

  220.     ctp = &qc->ctp;

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

  226.     ngx_queue_init(&qc->streams.uninitialized);
  227.     ngx_queue_init(&qc->streams.free);

  228.     qc->streams.recv_max_data = qc->tp.initial_max_data;
  229.     qc->streams.recv_window = qc->streams.recv_max_data;

  230.     qc->streams.client_max_streams_uni = qc->tp.initial_max_streams_uni;
  231.     qc->streams.client_max_streams_bidi = qc->tp.initial_max_streams_bidi;

  232.     qc->congestion.window = ngx_min(10 * qc->tp.max_udp_payload_size,
  233.                                     ngx_max(2 * qc->tp.max_udp_payload_size,
  234.                                             14720));
  235.     qc->congestion.ssthresh = (size_t) -1;
  236.     qc->congestion.recovery_start = ngx_current_msec;

  237.     if (pkt->validated && pkt->retried) {
  238.         qc->tp.retry_scid.len = pkt->dcid.len;
  239.         qc->tp.retry_scid.data = ngx_pstrdup(c->pool, &pkt->dcid);
  240.         if (qc->tp.retry_scid.data == NULL) {
  241.             return NULL;
  242.         }
  243.     }

  244.     if (ngx_quic_keys_set_initial_secret(qc->keys, &pkt->dcid, c->log)
  245.         != NGX_OK)
  246.     {
  247.         return NULL;
  248.     }

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

  250.     if (ngx_quic_open_sockets(c, qc, pkt) != NGX_OK) {
  251.         ngx_quic_keys_cleanup(qc->keys);
  252.         return NULL;
  253.     }

  254.     c->idle = 1;
  255.     ngx_reusable_connection(c, 1);

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

  258.     return qc;
  259. }


  260. static ngx_int_t
  261. ngx_quic_handle_stateless_reset(ngx_connection_t *c, ngx_quic_header_t *pkt)
  262. {
  263.     u_char                 *tail, ch;
  264.     ngx_uint_t              i;
  265.     ngx_queue_t            *q;
  266.     ngx_quic_client_id_t   *cid;
  267.     ngx_quic_connection_t  *qc;

  268.     qc = ngx_quic_get_connection(c);

  269.     /* A stateless reset uses an entire UDP datagram */
  270.     if (!pkt->first) {
  271.         return NGX_DECLINED;
  272.     }

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

  274.     for (q = ngx_queue_head(&qc->client_ids);
  275.          q != ngx_queue_sentinel(&qc->client_ids);
  276.          q = ngx_queue_next(q))
  277.     {
  278.         cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);

  279.         if (cid->seqnum == 0 || !cid->used) {
  280.             /*
  281.              * No stateless reset token in initial connection id.
  282.              * Don't accept a token from an unused connection id.
  283.              */
  284.             continue;
  285.         }

  286.         /* constant time comparison */

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

  290.         if (ch == 0) {
  291.             return NGX_OK;
  292.         }
  293.     }

  294.     return NGX_DECLINED;
  295. }


  296. static void
  297. ngx_quic_input_handler(ngx_event_t *rev)
  298. {
  299.     ngx_int_t               rc;
  300.     ngx_buf_t              *b;
  301.     ngx_connection_t       *c;
  302.     ngx_quic_connection_t  *qc;

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

  304.     c = rev->data;
  305.     qc = ngx_quic_get_connection(c);

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

  307.     if (rev->timedout) {
  308.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  309.                       "quic client timed out");
  310.         ngx_quic_close_connection(c, NGX_DONE);
  311.         return;
  312.     }

  313.     if (c->close) {
  314.         c->close = 0;

  315.         if (!ngx_exiting || !qc->streams.initialized) {
  316.             qc->error = NGX_QUIC_ERR_NO_ERROR;
  317.             qc->error_reason = "graceful shutdown";
  318.             ngx_quic_close_connection(c, NGX_ERROR);
  319.             return;
  320.         }

  321.         if (!qc->closing && qc->conf->shutdown) {
  322.             qc->conf->shutdown(c);
  323.         }

  324.         return;
  325.     }

  326.     b = c->udp->buffer;
  327.     if (b == NULL) {
  328.         return;
  329.     }

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

  331.     if (rc == NGX_ERROR) {
  332.         ngx_quic_close_connection(c, NGX_ERROR);
  333.         return;
  334.     }

  335.     if (rc == NGX_DONE) {
  336.         return;
  337.     }

  338.     /* rc == NGX_OK */

  339.     qc->send_timer_set = 0;
  340.     ngx_add_timer(rev, qc->tp.max_idle_timeout);

  341.     ngx_quic_connstate_dbg(c);
  342. }


  343. void
  344. ngx_quic_close_connection(ngx_connection_t *c, ngx_int_t rc)
  345. {
  346.     ngx_uint_t              i;
  347.     ngx_pool_t             *pool;
  348.     ngx_quic_send_ctx_t    *ctx;
  349.     ngx_quic_connection_t  *qc;

  350.     qc = ngx_quic_get_connection(c);

  351.     if (qc == NULL) {
  352.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  353.                        "quic packet rejected rc:%i, cleanup connection", rc);
  354.         goto quic_done;
  355.     }

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

  359.     if (!qc->closing) {

  360.         /* drop packets from retransmit queues, no ack is expected */
  361.         for (i = 0; i < NGX_QUIC_SEND_CTX_LAST; i++) {
  362.             ngx_quic_free_frames(c, &qc->send_ctx[i].frames);
  363.             ngx_quic_free_frames(c, &qc->send_ctx[i].sent);
  364.         }

  365.         if (qc->close.timer_set) {
  366.             ngx_del_timer(&qc->close);
  367.         }

  368.         if (rc == NGX_DONE) {

  369.             /*
  370.              * RFC 9000, 10.1.  Idle Timeout
  371.              *
  372.              *  If a max_idle_timeout is specified by either endpoint in its
  373.              *  transport parameters (Section 18.2), the connection is silently
  374.              *  closed and its state is discarded when it remains idle
  375.              */

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

  377.             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  378.                            "quic close silent drain:%d timedout:%d",
  379.                            qc->draining, c->read->timedout);
  380.         } else {

  381.             /*
  382.              * RFC 9000, 10.2.  Immediate Close
  383.              *
  384.              *  An endpoint sends a CONNECTION_CLOSE frame (Section 19.19)
  385.              *  to terminate the connection immediately.
  386.              */

  387.             if (qc->error == (ngx_uint_t) -1) {
  388.                 qc->error = NGX_QUIC_ERR_INTERNAL_ERROR;
  389.                 qc->error_app = 0;
  390.             }

  391.             ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  392.                            "quic close immediate term:%d drain:%d "
  393.                            "%serror:%ui \"%s\"",
  394.                            rc == NGX_ERROR ? 1 : 0, qc->draining,
  395.                            qc->error_app ? "app " : "", qc->error,
  396.                            qc->error_reason ? qc->error_reason : "");

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

  399.                 if (!ngx_quic_keys_available(qc->keys, ctx->level, 1)) {
  400.                     continue;
  401.                 }

  402.                 qc->error_level = ctx->level;
  403.                 (void) ngx_quic_send_cc(c);

  404.                 if (rc == NGX_OK) {
  405.                     ngx_add_timer(&qc->close, 3 * ngx_quic_pto(c, ctx));
  406.                 }
  407.             }
  408.         }

  409.         qc->closing = 1;
  410.     }

  411.     if (rc == NGX_ERROR && qc->close.timer_set) {
  412.         /* do not wait for timer in case of fatal error */
  413.         ngx_del_timer(&qc->close);
  414.     }

  415.     if (ngx_quic_close_streams(c, qc) == NGX_AGAIN) {
  416.         return;
  417.     }

  418.     if (qc->push.timer_set) {
  419.         ngx_del_timer(&qc->push);
  420.     }

  421.     if (qc->pto.timer_set) {
  422.         ngx_del_timer(&qc->pto);
  423.     }

  424.     if (qc->path_validation.timer_set) {
  425.         ngx_del_timer(&qc->path_validation);
  426.     }

  427.     if (qc->push.posted) {
  428.         ngx_delete_posted_event(&qc->push);
  429.     }

  430.     if (qc->key_update.posted) {
  431.         ngx_delete_posted_event(&qc->key_update);
  432.     }

  433.     if (qc->close.timer_set) {
  434.         return;
  435.     }

  436.     if (qc->close.posted) {
  437.         ngx_delete_posted_event(&qc->close);
  438.     }

  439.     ngx_quic_close_sockets(c);

  440.     ngx_quic_keys_cleanup(qc->keys);

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

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

  444. quic_done:

  445.     if (c->ssl) {
  446.         (void) ngx_ssl_shutdown(c);
  447.     }

  448.     if (c->read->timer_set) {
  449.         ngx_del_timer(c->read);
  450.     }

  451. #if (NGX_STAT_STUB)
  452.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  453. #endif

  454.     c->destroyed = 1;

  455.     pool = c->pool;

  456.     ngx_close_connection(c);

  457.     ngx_destroy_pool(pool);
  458. }


  459. void
  460. ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
  461.     const char *reason)
  462. {
  463.     ngx_quic_connection_t  *qc;

  464.     qc = ngx_quic_get_connection(c);

  465.     if (qc->closing) {
  466.         return;
  467.     }

  468.     qc->error = err;
  469.     qc->error_reason = reason;
  470.     qc->error_app = 1;
  471.     qc->error_ftype = 0;

  472.     ngx_post_event(&qc->close, &ngx_posted_events);
  473. }


  474. void
  475. ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err,
  476.     const char *reason)
  477. {
  478.     ngx_quic_connection_t  *qc;

  479.     qc = ngx_quic_get_connection(c);
  480.     qc->shutdown = 1;
  481.     qc->shutdown_code = err;
  482.     qc->shutdown_reason = reason;

  483.     ngx_quic_shutdown_quic(c);
  484. }


  485. static void
  486. ngx_quic_close_handler(ngx_event_t *ev)
  487. {
  488.     ngx_connection_t  *c;

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

  490.     c = ev->data;

  491.     ngx_quic_close_connection(c, NGX_OK);
  492. }


  493. static ngx_int_t
  494. ngx_quic_handle_datagram(ngx_connection_t *c, ngx_buf_t *b,
  495.     ngx_quic_conf_t *conf)
  496. {
  497.     size_t                  size;
  498.     u_char                 *p, *start;
  499.     ngx_int_t               rc;
  500.     ngx_uint_t              good;
  501.     ngx_quic_path_t        *path;
  502.     ngx_quic_header_t       pkt;
  503.     ngx_quic_connection_t  *qc;

  504.     good = 0;
  505.     path = NULL;

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

  507.     p = start = b->pos;

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

  509.         ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
  510.         pkt.raw = b;
  511.         pkt.data = p;
  512.         pkt.len = b->last - p;
  513.         pkt.log = c->log;
  514.         pkt.first = (p == start) ? 1 : 0;
  515.         pkt.path = path;
  516.         pkt.flags = p[0];
  517.         pkt.raw->pos++;

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

  519. #if (NGX_DEBUG)
  520.         if (pkt.parsed) {
  521.             ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
  522.                            "quic packet done rc:%i level:%s"
  523.                            " decr:%d pn:%L perr:%ui",
  524.                            rc, ngx_quic_level_name(pkt.level),
  525.                            pkt.decrypted, pkt.pn, pkt.error);
  526.         } else {
  527.             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  528.                            "quic packet done rc:%i parse failed", rc);
  529.         }
  530. #endif

  531.         if (rc == NGX_ERROR || rc == NGX_DONE) {
  532.             return rc;
  533.         }

  534.         if (rc == NGX_OK) {
  535.             good = 1;
  536.         }

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

  538.         /* NGX_OK || NGX_DECLINED */

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

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

  557.         p = b->pos;
  558.     }

  559.     if (!good) {
  560.         return NGX_DONE;
  561.     }

  562.     qc = ngx_quic_get_connection(c);

  563.     if (qc) {
  564.         qc->received += size;

  565.         if ((uint64_t) (c->sent + qc->received) / 8 >
  566.             (qc->streams.sent + qc->streams.recv_last) + 1048576)
  567.         {
  568.             ngx_log_error(NGX_LOG_INFO, c->log, 0, "quic flood detected");

  569.             qc->error = NGX_QUIC_ERR_NO_ERROR;
  570.             qc->error_reason = "QUIC flood detected";
  571.             return NGX_ERROR;
  572.         }
  573.     }

  574.     return NGX_OK;
  575. }


  576. static ngx_int_t
  577. ngx_quic_handle_packet(ngx_connection_t *c, ngx_quic_conf_t *conf,
  578.     ngx_quic_header_t *pkt)
  579. {
  580.     ngx_int_t               rc;
  581.     ngx_quic_socket_t      *qsock;
  582.     ngx_quic_connection_t  *qc;

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

  584.     rc = ngx_quic_parse_packet(pkt);

  585.     if (rc == NGX_ERROR) {
  586.         return NGX_DECLINED;
  587.     }

  588.     pkt->parsed = 1;

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

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

  593. #if (NGX_DEBUG)
  594.     if (pkt->level != ssl_encryption_application) {
  595.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  596.                        "quic packet rx scid len:%uz %xV",
  597.                        pkt->scid.len, &pkt->scid);
  598.     }

  599.     if (pkt->level == ssl_encryption_initial) {
  600.         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  601.                        "quic address validation token len:%uz %xV",
  602.                        pkt->token.len, &pkt->token);
  603.     }
  604. #endif

  605.     qc = ngx_quic_get_connection(c);

  606.     if (qc) {

  607.         if (rc == NGX_ABORT) {
  608.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  609.                           "quic unsupported version: 0x%xD", pkt->version);
  610.             return NGX_DECLINED;
  611.         }

  612.         if (pkt->level != ssl_encryption_application) {

  613.             if (pkt->version != qc->version) {
  614.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  615.                               "quic version mismatch: 0x%xD", pkt->version);
  616.                 return NGX_DECLINED;
  617.             }

  618.             if (pkt->first) {
  619.                 qsock = ngx_quic_get_socket(c);

  620.                 if (ngx_cmp_sockaddr(&qsock->sockaddr.sockaddr, qsock->socklen,
  621.                                      qc->path->sockaddr, qc->path->socklen, 1)
  622.                     != NGX_OK)
  623.                 {
  624.                     /* packet comes from unknown path, possibly migration */
  625.                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  626.                                    "quic too early migration attempt");
  627.                     return NGX_DONE;
  628.                 }
  629.             }

  630.             if (ngx_quic_check_csid(qc, pkt) != NGX_OK) {
  631.                 return NGX_DECLINED;
  632.             }

  633.         }

  634.         rc = ngx_quic_handle_payload(c, pkt);

  635.         if (rc == NGX_DECLINED && pkt->level == ssl_encryption_application) {
  636.             if (ngx_quic_handle_stateless_reset(c, pkt) == NGX_OK) {
  637.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  638.                               "quic stateless reset packet detected");

  639.                 qc->draining = 1;
  640.                 ngx_post_event(&qc->close, &ngx_posted_events);

  641.                 return NGX_OK;
  642.             }
  643.         }

  644.         return rc;
  645.     }

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

  647.     if (rc == NGX_ABORT) {
  648.         return ngx_quic_negotiate_version(c, pkt);
  649.     }

  650.     if (pkt->level == ssl_encryption_application) {
  651.         return ngx_quic_send_stateless_reset(c, conf, pkt);
  652.     }

  653.     if (pkt->level != ssl_encryption_initial) {
  654.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  655.                        "quic expected initial, got handshake");
  656.         return NGX_ERROR;
  657.     }

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

  659.     if (pkt->dcid.len < NGX_QUIC_CID_LEN_MIN) {
  660.         /* RFC 9000, 7.2.  Negotiating Connection IDs */
  661.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  662.                       "quic too short dcid in initial"
  663.                       " packet: len:%i", pkt->dcid.len);
  664.         return NGX_ERROR;
  665.     }

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

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

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

  669.         if (rc == NGX_ERROR) {
  670.             /* internal error */
  671.             return NGX_ERROR;

  672.         } else if (rc == NGX_ABORT) {
  673.             /* token cannot be decrypted */
  674.             return ngx_quic_send_early_cc(c, pkt,
  675.                                           NGX_QUIC_ERR_INVALID_TOKEN,
  676.                                           "cannot decrypt token");
  677.         } else if (rc == NGX_DECLINED) {
  678.             /* token is invalid */

  679.             if (pkt->retried) {
  680.                 /* invalid address validation token */
  681.                 return ngx_quic_send_early_cc(c, pkt,
  682.                                           NGX_QUIC_ERR_INVALID_TOKEN,
  683.                                           "invalid address validation token");
  684.             } else if (conf->retry) {
  685.                 /* invalid NEW_TOKEN */
  686.                 return ngx_quic_send_retry(c, conf, pkt);
  687.             }
  688.         }

  689.         /* NGX_OK */

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

  692.     } else {
  693.         pkt->odcid = pkt->dcid;
  694.     }

  695.     if (ngx_terminate || ngx_exiting) {
  696.         if (conf->retry) {
  697.             return ngx_quic_send_retry(c, conf, pkt);
  698.         }

  699.         return NGX_ERROR;
  700.     }

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

  702.     qc = ngx_quic_new_connection(c, conf, pkt);
  703.     if (qc == NULL) {
  704.         return NGX_ERROR;
  705.     }

  706.     return ngx_quic_handle_payload(c, pkt);
  707. }


  708. static ngx_int_t
  709. ngx_quic_handle_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
  710. {
  711.     ngx_int_t               rc;
  712.     ngx_quic_send_ctx_t    *ctx;
  713.     ngx_quic_connection_t  *qc;
  714.     static u_char           buf[NGX_QUIC_MAX_UDP_PAYLOAD_SIZE];

  715.     qc = ngx_quic_get_connection(c);

  716.     qc->error = (ngx_uint_t) -1;
  717.     qc->error_reason = 0;

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

  719.     if (!ngx_quic_keys_available(qc->keys, pkt->level, 0)) {
  720.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  721.                       "quic no %s keys, ignoring packet",
  722.                       ngx_quic_level_name(pkt->level));
  723.         return NGX_DECLINED;
  724.     }

  725. #if !defined (OPENSSL_IS_BORINGSSL)
  726.     /* OpenSSL provides read keys for an application level before it's ready */

  727.     if (pkt->level == ssl_encryption_application && !c->ssl->handshaked) {
  728.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  729.                       "quic no %s keys ready, ignoring packet",
  730.                       ngx_quic_level_name(pkt->level));
  731.         return NGX_DECLINED;
  732.     }
  733. #endif

  734.     pkt->keys = qc->keys;
  735.     pkt->key_phase = qc->key_phase;
  736.     pkt->plaintext = buf;

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

  738.     rc = ngx_quic_decrypt(pkt, &ctx->largest_pn);
  739.     if (rc != NGX_OK) {
  740.         qc->error = pkt->error;
  741.         qc->error_reason = "failed to decrypt packet";
  742.         return rc;
  743.     }

  744.     pkt->decrypted = 1;

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

  746.     if (pkt->path == NULL) {
  747.         rc = ngx_quic_set_path(c, pkt);
  748.         if (rc != NGX_OK) {
  749.             return rc;
  750.         }
  751.     }

  752.     if (c->ssl == NULL) {
  753.         if (ngx_quic_init_connection(c) != NGX_OK) {
  754.             return NGX_ERROR;
  755.         }
  756.     }

  757.     if (pkt->level == ssl_encryption_handshake) {
  758.         /*
  759.          * RFC 9001, 4.9.1.  Discarding Initial Keys
  760.          *
  761.          * The successful use of Handshake packets indicates
  762.          * that no more Initial packets need to be exchanged
  763.          */
  764.         ngx_quic_discard_ctx(c, ssl_encryption_initial);

  765.         if (!qc->path->validated) {
  766.             qc->path->validated = 1;
  767.             ngx_quic_path_dbg(c, "in handshake", qc->path);
  768.             ngx_post_event(&qc->push, &ngx_posted_events);
  769.         }
  770.     }

  771.     if (pkt->level == ssl_encryption_application) {
  772.         /*
  773.          * RFC 9001, 4.9.3.  Discarding 0-RTT Keys
  774.          *
  775.          * After receiving a 1-RTT packet, servers MUST discard
  776.          * 0-RTT keys within a short time
  777.          */
  778.         ngx_quic_discard_ctx(c, ssl_encryption_early_data);
  779.     }

  780.     if (qc->closing) {
  781.         /*
  782.          * RFC 9000, 10.2.  Immediate Close
  783.          *
  784.          * ... delayed or reordered packets are properly discarded.
  785.          *
  786.          *  In the closing state, an endpoint retains only enough information
  787.          *  to generate a packet containing a CONNECTION_CLOSE frame and to
  788.          *  identify packets as belonging to the connection.
  789.          */

  790.         qc->error_level = pkt->level;
  791.         qc->error = NGX_QUIC_ERR_NO_ERROR;
  792.         qc->error_reason = "connection is closing, packet discarded";
  793.         qc->error_ftype = 0;
  794.         qc->error_app = 0;

  795.         return ngx_quic_send_cc(c);
  796.     }

  797.     pkt->received = ngx_current_msec;

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

  799.     if (pkt->level != ssl_encryption_application) {
  800.         return ngx_quic_handle_frames(c, pkt);
  801.     }

  802.     if (!pkt->key_update) {
  803.         return ngx_quic_handle_frames(c, pkt);
  804.     }

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

  806.     qc->key_phase ^= 1;
  807.     ngx_quic_keys_switch(c, qc->keys);

  808.     rc = ngx_quic_handle_frames(c, pkt);
  809.     if (rc != NGX_OK) {
  810.         return rc;
  811.     }

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

  813.     return NGX_OK;
  814. }


  815. void
  816. ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level)
  817. {
  818.     ngx_queue_t            *q;
  819.     ngx_quic_frame_t       *f;
  820.     ngx_quic_socket_t      *qsock;
  821.     ngx_quic_send_ctx_t    *ctx;
  822.     ngx_quic_connection_t  *qc;

  823.     qc = ngx_quic_get_connection(c);

  824.     if (!ngx_quic_keys_available(qc->keys, level, 0)
  825.         && !ngx_quic_keys_available(qc->keys, level, 1))
  826.     {
  827.         return;
  828.     }

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

  830.     qc->pto_count = 0;

  831.     ctx = ngx_quic_get_send_ctx(qc, level);

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

  833.     while (!ngx_queue_empty(&ctx->sent)) {
  834.         q = ngx_queue_head(&ctx->sent);
  835.         ngx_queue_remove(q);

  836.         f = ngx_queue_data(q, ngx_quic_frame_t, queue);
  837.         ngx_quic_congestion_ack(c, f);
  838.         ngx_quic_free_frame(c, f);
  839.     }

  840.     while (!ngx_queue_empty(&ctx->frames)) {
  841.         q = ngx_queue_head(&ctx->frames);
  842.         ngx_queue_remove(q);

  843.         f = ngx_queue_data(q, ngx_quic_frame_t, queue);
  844.         ngx_quic_free_frame(c, f);
  845.     }

  846.     if (level == ssl_encryption_initial) {
  847.         /* close temporary listener with initial dcid */
  848.         qsock = ngx_quic_find_socket(c, NGX_QUIC_UNSET_PN);
  849.         if (qsock) {
  850.             ngx_quic_close_socket(c, qsock);
  851.         }
  852.     }

  853.     ctx->send_ack = 0;

  854.     ngx_quic_set_lost_timer(c);
  855. }


  856. static ngx_int_t
  857. ngx_quic_check_csid(ngx_quic_connection_t *qc, ngx_quic_header_t *pkt)
  858. {
  859.     ngx_queue_t           *q;
  860.     ngx_quic_client_id_t  *cid;

  861.     for (q = ngx_queue_head(&qc->client_ids);
  862.          q != ngx_queue_sentinel(&qc->client_ids);
  863.          q = ngx_queue_next(q))
  864.     {
  865.         cid = ngx_queue_data(q, ngx_quic_client_id_t, queue);

  866.         if (pkt->scid.len == cid->len
  867.             && ngx_memcmp(pkt->scid.data, cid->id, cid->len) == 0)
  868.         {
  869.             return NGX_OK;
  870.         }
  871.     }

  872.     ngx_log_error(NGX_LOG_INFO, pkt->log, 0, "quic unexpected quic scid");
  873.     return NGX_ERROR;
  874. }


  875. static ngx_int_t
  876. ngx_quic_handle_frames(ngx_connection_t *c, ngx_quic_header_t *pkt)
  877. {
  878.     u_char                 *end, *p;
  879.     ssize_t                 len;
  880.     ngx_buf_t               buf;
  881.     ngx_uint_t              do_close, nonprobing;
  882.     ngx_chain_t             chain;
  883.     ngx_quic_frame_t        frame;
  884.     ngx_quic_connection_t  *qc;

  885.     qc = ngx_quic_get_connection(c);

  886.     p = pkt->payload.data;
  887.     end = p + pkt->payload.len;

  888.     do_close = 0;
  889.     nonprobing = 0;

  890.     while (p < end) {

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

  892.         ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
  893.         ngx_memzero(&buf, sizeof(ngx_buf_t));
  894.         buf.temporary = 1;

  895.         chain.buf = &buf;
  896.         chain.next = NULL;
  897.         frame.data = &chain;

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

  899.         if (len < 0) {
  900.             qc->error = pkt->error;
  901.             return NGX_ERROR;
  902.         }

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

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

  905.         p += len;

  906.         switch (frame.type) {
  907.         /* probing frames */
  908.         case NGX_QUIC_FT_PADDING:
  909.         case NGX_QUIC_FT_PATH_CHALLENGE:
  910.         case NGX_QUIC_FT_PATH_RESPONSE:
  911.         case NGX_QUIC_FT_NEW_CONNECTION_ID:
  912.             break;

  913.         /* non-probing frames */
  914.         default:
  915.             nonprobing = 1;
  916.             break;
  917.         }

  918.         switch (frame.type) {

  919.         case NGX_QUIC_FT_ACK:
  920.             if (ngx_quic_handle_ack_frame(c, pkt, &frame) != NGX_OK) {
  921.                 return NGX_ERROR;
  922.             }

  923.             continue;

  924.         case NGX_QUIC_FT_PADDING:
  925.             /* no action required */
  926.             continue;

  927.         case NGX_QUIC_FT_CONNECTION_CLOSE:
  928.         case NGX_QUIC_FT_CONNECTION_CLOSE_APP:
  929.             do_close = 1;
  930.             continue;
  931.         }

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

  934.         switch (frame.type) {

  935.         case NGX_QUIC_FT_CRYPTO:

  936.             if (ngx_quic_handle_crypto_frame(c, pkt, &frame) != NGX_OK) {
  937.                 return NGX_ERROR;
  938.             }

  939.             break;

  940.         case NGX_QUIC_FT_PING:
  941.             break;

  942.         case NGX_QUIC_FT_STREAM:

  943.             if (ngx_quic_handle_stream_frame(c, pkt, &frame) != NGX_OK) {
  944.                 return NGX_ERROR;
  945.             }

  946.             break;

  947.         case NGX_QUIC_FT_MAX_DATA:

  948.             if (ngx_quic_handle_max_data_frame(c, &frame.u.max_data) != NGX_OK)
  949.             {
  950.                 return NGX_ERROR;
  951.             }

  952.             break;

  953.         case NGX_QUIC_FT_STREAMS_BLOCKED:
  954.         case NGX_QUIC_FT_STREAMS_BLOCKED2:

  955.             if (ngx_quic_handle_streams_blocked_frame(c, pkt,
  956.                                                       &frame.u.streams_blocked)
  957.                 != NGX_OK)
  958.             {
  959.                 return NGX_ERROR;
  960.             }

  961.             break;

  962.         case NGX_QUIC_FT_DATA_BLOCKED:

  963.             if (ngx_quic_handle_data_blocked_frame(c, pkt,
  964.                                                    &frame.u.data_blocked)
  965.                 != NGX_OK)
  966.             {
  967.                 return NGX_ERROR;
  968.             }

  969.             break;

  970.         case NGX_QUIC_FT_STREAM_DATA_BLOCKED:

  971.             if (ngx_quic_handle_stream_data_blocked_frame(c, pkt,
  972.                                                   &frame.u.stream_data_blocked)
  973.                 != NGX_OK)
  974.             {
  975.                 return NGX_ERROR;
  976.             }

  977.             break;

  978.         case NGX_QUIC_FT_MAX_STREAM_DATA:

  979.             if (ngx_quic_handle_max_stream_data_frame(c, pkt,
  980.                                                       &frame.u.max_stream_data)
  981.                 != NGX_OK)
  982.             {
  983.                 return NGX_ERROR;
  984.             }

  985.             break;

  986.         case NGX_QUIC_FT_RESET_STREAM:

  987.             if (ngx_quic_handle_reset_stream_frame(c, pkt,
  988.                                                    &frame.u.reset_stream)
  989.                 != NGX_OK)
  990.             {
  991.                 return NGX_ERROR;
  992.             }

  993.             break;

  994.         case NGX_QUIC_FT_STOP_SENDING:

  995.             if (ngx_quic_handle_stop_sending_frame(c, pkt,
  996.                                                    &frame.u.stop_sending)
  997.                 != NGX_OK)
  998.             {
  999.                 return NGX_ERROR;
  1000.             }

  1001.             break;

  1002.         case NGX_QUIC_FT_MAX_STREAMS:
  1003.         case NGX_QUIC_FT_MAX_STREAMS2:

  1004.             if (ngx_quic_handle_max_streams_frame(c, pkt, &frame.u.max_streams)
  1005.                 != NGX_OK)
  1006.             {
  1007.                 return NGX_ERROR;
  1008.             }

  1009.             break;

  1010.         case NGX_QUIC_FT_PATH_CHALLENGE:

  1011.             if (ngx_quic_handle_path_challenge_frame(c, pkt,
  1012.                                                      &frame.u.path_challenge)
  1013.                 != NGX_OK)
  1014.             {
  1015.                 return NGX_ERROR;
  1016.             }

  1017.             break;

  1018.         case NGX_QUIC_FT_PATH_RESPONSE:

  1019.             if (ngx_quic_handle_path_response_frame(c, &frame.u.path_response)
  1020.                 != NGX_OK)
  1021.             {
  1022.                 return NGX_ERROR;
  1023.             }

  1024.             break;

  1025.         case NGX_QUIC_FT_NEW_CONNECTION_ID:

  1026.             if (ngx_quic_handle_new_connection_id_frame(c, &frame.u.ncid)
  1027.                 != NGX_OK)
  1028.             {
  1029.                 return NGX_ERROR;
  1030.             }

  1031.             break;

  1032.         case NGX_QUIC_FT_RETIRE_CONNECTION_ID:

  1033.             if (ngx_quic_handle_retire_connection_id_frame(c,
  1034.                                                            &frame.u.retire_cid)
  1035.                 != NGX_OK)
  1036.             {
  1037.                 return NGX_ERROR;
  1038.             }

  1039.             break;

  1040.         default:
  1041.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  1042.                            "quic missing frame handler");
  1043.             return NGX_ERROR;
  1044.         }
  1045.     }

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

  1049.         qc->error = NGX_QUIC_ERR_FRAME_ENCODING_ERROR;
  1050.         return NGX_ERROR;
  1051.     }

  1052.     if (do_close) {
  1053.         qc->draining = 1;
  1054.         ngx_post_event(&qc->close, &ngx_posted_events);
  1055.     }

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

  1057.         /*
  1058.          * RFC 9000, 9.2.  Initiating Connection Migration
  1059.          *
  1060.          * An endpoint can migrate a connection to a new local
  1061.          * address by sending packets containing non-probing frames
  1062.          * from that address.
  1063.          */
  1064.         if (ngx_quic_handle_migration(c, pkt) != NGX_OK) {
  1065.             return NGX_ERROR;
  1066.         }
  1067.     }

  1068.     if (ngx_quic_ack_packet(c, pkt) != NGX_OK) {
  1069.         return NGX_ERROR;
  1070.     }

  1071.     return NGX_OK;
  1072. }


  1073. static void
  1074. ngx_quic_push_handler(ngx_event_t *ev)
  1075. {
  1076.     ngx_connection_t  *c;

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

  1078.     c = ev->data;

  1079.     if (ngx_quic_output(c) != NGX_OK) {
  1080.         ngx_quic_close_connection(c, NGX_ERROR);
  1081.         return;
  1082.     }

  1083.     ngx_quic_connstate_dbg(c);
  1084. }


  1085. void
  1086. ngx_quic_shutdown_quic(ngx_connection_t *c)
  1087. {
  1088.     ngx_quic_connection_t  *qc;

  1089.     if (c->reusable) {
  1090.         qc = ngx_quic_get_connection(c);
  1091.         ngx_quic_finalize_connection(c, qc->shutdown_code, qc->shutdown_reason);
  1092.     }
  1093. }