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

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. ngx_int_t
  9. ngx_quic_open_sockets(ngx_connection_t *c, ngx_quic_connection_t *qc,
  10.     ngx_quic_header_t *pkt)
  11. {
  12.     ngx_quic_socket_t     *qsock, *tmp;
  13.     ngx_quic_client_id_t  *cid;

  14.     /*
  15.      * qc->path = NULL
  16.      *
  17.      * qc->nclient_ids = 0
  18.      * qc->nsockets = 0
  19.      * qc->max_retired_seqnum = 0
  20.      * qc->client_seqnum = 0
  21.      */

  22.     ngx_queue_init(&qc->sockets);
  23.     ngx_queue_init(&qc->free_sockets);

  24.     ngx_queue_init(&qc->paths);
  25.     ngx_queue_init(&qc->free_paths);

  26.     ngx_queue_init(&qc->client_ids);
  27.     ngx_queue_init(&qc->free_client_ids);

  28.     qc->tp.original_dcid.len = pkt->odcid.len;
  29.     qc->tp.original_dcid.data = ngx_pstrdup(c->pool, &pkt->odcid);
  30.     if (qc->tp.original_dcid.data == NULL) {
  31.         return NGX_ERROR;
  32.     }

  33.     /* socket to use for further processing (id auto-generated) */
  34.     qsock = ngx_quic_create_socket(c, qc);
  35.     if (qsock == NULL) {
  36.         return NGX_ERROR;
  37.     }

  38.     /* socket is listening at new server id */
  39.     if (ngx_quic_listen(c, qc, qsock) != NGX_OK) {
  40.         return NGX_ERROR;
  41.     }

  42.     qsock->used = 1;

  43.     qc->tp.initial_scid.len = qsock->sid.len;
  44.     qc->tp.initial_scid.data = ngx_pnalloc(c->pool, qsock->sid.len);
  45.     if (qc->tp.initial_scid.data == NULL) {
  46.         goto failed;
  47.     }
  48.     ngx_memcpy(qc->tp.initial_scid.data, qsock->sid.id, qsock->sid.len);

  49.     /* for all packets except first, this is set at udp layer */
  50.     c->udp = &qsock->udp;

  51.     /* ngx_quic_get_connection(c) macro is now usable */

  52.     /* we have a client identified by scid */
  53.     cid = ngx_quic_create_client_id(c, &pkt->scid, 0, NULL);
  54.     if (cid == NULL) {
  55.         goto failed;
  56.     }

  57.     /* path of the first packet is our initial active path */
  58.     qc->path = ngx_quic_new_path(c, c->sockaddr, c->socklen, cid);
  59.     if (qc->path == NULL) {
  60.         goto failed;
  61.     }

  62.     qc->path->tag = NGX_QUIC_PATH_ACTIVE;

  63.     if (pkt->validated) {
  64.         qc->path->validated = 1;
  65.     }

  66.     ngx_quic_path_dbg(c, "set active", qc->path);

  67.     tmp = ngx_pcalloc(c->pool, sizeof(ngx_quic_socket_t));
  68.     if (tmp == NULL) {
  69.         goto failed;
  70.     }

  71.     tmp->sid.seqnum = NGX_QUIC_UNSET_PN; /* temporary socket */

  72.     ngx_memcpy(tmp->sid.id, pkt->dcid.data, pkt->dcid.len);
  73.     tmp->sid.len = pkt->dcid.len;

  74.     if (ngx_quic_listen(c, qc, tmp) != NGX_OK) {
  75.         goto failed;
  76.     }

  77.     return NGX_OK;

  78. failed:

  79.     ngx_rbtree_delete(&c->listening->rbtree, &qsock->udp.node);
  80.     c->udp = NULL;

  81.     return NGX_ERROR;
  82. }


  83. ngx_quic_socket_t *
  84. ngx_quic_create_socket(ngx_connection_t *c, ngx_quic_connection_t *qc)
  85. {
  86.     ngx_queue_t        *q;
  87.     ngx_quic_socket_t  *sock;

  88.     if (!ngx_queue_empty(&qc->free_sockets)) {

  89.         q = ngx_queue_head(&qc->free_sockets);
  90.         sock = ngx_queue_data(q, ngx_quic_socket_t, queue);

  91.         ngx_queue_remove(&sock->queue);

  92.         ngx_memzero(sock, sizeof(ngx_quic_socket_t));

  93.     } else {

  94.         sock = ngx_pcalloc(c->pool, sizeof(ngx_quic_socket_t));
  95.         if (sock == NULL) {
  96.             return NULL;
  97.         }
  98.     }

  99.     sock->sid.len = NGX_QUIC_SERVER_CID_LEN;
  100.     if (ngx_quic_create_server_id(c, sock->sid.id) != NGX_OK) {
  101.         return NULL;
  102.     }

  103.     sock->sid.seqnum = qc->server_seqnum++;

  104.     return sock;
  105. }


  106. void
  107. ngx_quic_close_socket(ngx_connection_t *c, ngx_quic_socket_t *qsock)
  108. {
  109.     ngx_quic_connection_t  *qc;

  110.     qc = ngx_quic_get_connection(c);

  111.     ngx_queue_remove(&qsock->queue);
  112.     ngx_queue_insert_head(&qc->free_sockets, &qsock->queue);

  113.     ngx_rbtree_delete(&c->listening->rbtree, &qsock->udp.node);
  114.     qc->nsockets--;

  115.     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
  116.                    "quic socket seq:%L closed nsock:%ui",
  117.                    (int64_t) qsock->sid.seqnum, qc->nsockets);
  118. }


  119. ngx_int_t
  120. ngx_quic_listen(ngx_connection_t *c, ngx_quic_connection_t *qc,
  121.     ngx_quic_socket_t *qsock)
  122. {
  123.     ngx_str_t              id;
  124.     ngx_quic_server_id_t  *sid;

  125.     sid = &qsock->sid;

  126.     id.data = sid->id;
  127.     id.len = sid->len;

  128.     qsock->udp.connection = c;
  129.     qsock->udp.node.key = ngx_crc32_long(id.data, id.len);
  130.     qsock->udp.key = id;

  131.     ngx_rbtree_insert(&c->listening->rbtree, &qsock->udp.node);

  132.     ngx_queue_insert_tail(&qc->sockets, &qsock->queue);

  133.     qc->nsockets++;
  134.     qsock->quic = qc;

  135.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  136.                    "quic socket seq:%L listening at sid:%xV nsock:%ui",
  137.                    (int64_t) sid->seqnum, &id, qc->nsockets);

  138.     return NGX_OK;
  139. }


  140. void
  141. ngx_quic_close_sockets(ngx_connection_t *c)
  142. {
  143.     ngx_queue_t            *q;
  144.     ngx_quic_socket_t      *qsock;
  145.     ngx_quic_connection_t  *qc;

  146.     qc = ngx_quic_get_connection(c);

  147.     while (!ngx_queue_empty(&qc->sockets)) {
  148.         q = ngx_queue_head(&qc->sockets);
  149.         qsock = ngx_queue_data(q, ngx_quic_socket_t, queue);

  150.         ngx_quic_close_socket(c, qsock);
  151.     }
  152. }


  153. ngx_quic_socket_t *
  154. ngx_quic_find_socket(ngx_connection_t *c, uint64_t seqnum)
  155. {
  156.     ngx_queue_t            *q;
  157.     ngx_quic_socket_t      *qsock;
  158.     ngx_quic_connection_t  *qc;

  159.     qc = ngx_quic_get_connection(c);

  160.     for (q = ngx_queue_head(&qc->sockets);
  161.          q != ngx_queue_sentinel(&qc->sockets);
  162.          q = ngx_queue_next(q))
  163.     {
  164.         qsock = ngx_queue_data(q, ngx_quic_socket_t, queue);

  165.         if (qsock->sid.seqnum == seqnum) {
  166.             return qsock;
  167.         }
  168.     }

  169.     return NULL;
  170. }