[PATCH 2 of 4] Common tree insert function for QUIC and UDP connections

Maxim Dounin mdounin at mdounin.ru
Thu May 18 21:30:05 UTC 2023


Hello!

On Sun, May 14, 2023 at 05:38:53PM +0400, Roman Arutyunyan wrote:

> # HG changeset patch
> # User Roman Arutyunyan <arut at nginx.com>
> # Date 1684053011 -14400
> #      Sun May 14 12:30:11 2023 +0400
> # Branch quic
> # Node ID adcc6d8acfd47c1344b121fceeb94fbcc3f8b5c0
> # Parent  113e2438dbd40a6c5a2627ed98707c1418a10fd5
> Common tree insert function for QUIC and UDP connections.
> 
> Previously, ngx_udp_rbtree_insert_value() was used for plain UDP and
> ngx_quic_rbtree_insert_value() was used for QUIC.  Because of this it was
> impossible to initialize connection tree in ngx_create_listening() since
> this function is not aware what kind of listening it creates.
> 
> Now ngx_udp_rbtree_insert_value() is used for both QUIC and UDP.  To make
> is possible, a generic key field is added to ngx_udp_connection_t.  It keeps
> client address for UDP and connection ID for QUIC.
> 
> diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
> --- a/src/core/ngx_connection.c
> +++ b/src/core/ngx_connection.c
> @@ -72,6 +72,10 @@ ngx_create_listening(ngx_conf_t *cf, str
>  
>      ngx_memcpy(ls->addr_text.data, text, len);
>  
> +#if !(NGX_WIN32)
> +    ngx_rbtree_init(&ls->rbtree, &ls->sentinel, ngx_udp_rbtree_insert_value);
> +#endif
> +
>      ls->fd = (ngx_socket_t) -1;
>      ls->type = SOCK_STREAM;
>  
> diff --git a/src/event/ngx_event_udp.c b/src/event/ngx_event_udp.c
> --- a/src/event/ngx_event_udp.c
> +++ b/src/event/ngx_event_udp.c
> @@ -417,8 +417,8 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_n
>              udpt = (ngx_udp_connection_t *) temp;
>              ct = udpt->connection;
>  
> -            rc = ngx_cmp_sockaddr(c->sockaddr, c->socklen,
> -                                  ct->sockaddr, ct->socklen, 1);
> +            rc = ngx_memn2cmp(udp->key.data, udpt->key.data,
> +                              udp->key.len, udpt->key.len);
>  
>              if (rc == 0 && c->listening->wildcard) {
>                  rc = ngx_cmp_sockaddr(c->local_sockaddr, c->local_socklen,
> @@ -471,6 +471,8 @@ ngx_insert_udp_connection(ngx_connection
>      ngx_crc32_final(hash);
>  
>      udp->node.key = hash;
> +    udp->key.data = (u_char *) c->sockaddr;
> +    udp->key.len = c->socklen;
>  
>      cln = ngx_pool_cleanup_add(c->pool, 0);
>      if (cln == NULL) {
> diff --git a/src/event/ngx_event_udp.h b/src/event/ngx_event_udp.h
> --- a/src/event/ngx_event_udp.h
> +++ b/src/event/ngx_event_udp.h
> @@ -27,6 +27,7 @@ struct ngx_udp_connection_s {
>      ngx_rbtree_node_t   node;
>      ngx_connection_t   *connection;
>      ngx_buf_t          *buffer;
> +    ngx_str_t           key;
>  };
>  
>  
> diff --git a/src/event/quic/ngx_event_quic.h b/src/event/quic/ngx_event_quic.h
> --- a/src/event/quic/ngx_event_quic.h
> +++ b/src/event/quic/ngx_event_quic.h
> @@ -111,8 +111,6 @@ struct ngx_quic_stream_s {
>  
>  
>  void ngx_quic_recvmsg(ngx_event_t *ev);
> -void ngx_quic_rbtree_insert_value(ngx_rbtree_node_t *temp,
> -    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
>  void ngx_quic_run(ngx_connection_t *c, ngx_quic_conf_t *conf);
>  ngx_connection_t *ngx_quic_open_stream(ngx_connection_t *c, ngx_uint_t bidi);
>  void ngx_quic_finalize_connection(ngx_connection_t *c, ngx_uint_t err,
> diff --git a/src/event/quic/ngx_event_quic_socket.c b/src/event/quic/ngx_event_quic_socket.c
> --- a/src/event/quic/ngx_event_quic_socket.c
> +++ b/src/event/quic/ngx_event_quic_socket.c
> @@ -179,6 +179,7 @@ ngx_quic_listen(ngx_connection_t *c, ngx
>  
>      qsock->udp.connection = c;
>      qsock->udp.node.key = ngx_crc32_long(id.data, id.len);
> +    qsock->udp.key = id;
>  
>      ngx_rbtree_insert(&c->listening->rbtree, &qsock->udp.node);
>  
> diff --git a/src/event/quic/ngx_event_quic_udp.c b/src/event/quic/ngx_event_quic_udp.c
> --- a/src/event/quic/ngx_event_quic_udp.c
> +++ b/src/event/quic/ngx_event_quic_udp.c
> @@ -365,59 +365,6 @@ ngx_quic_close_accepted_connection(ngx_c
>  }
>  
>  
> -void
> -ngx_quic_rbtree_insert_value(ngx_rbtree_node_t *temp,
> -    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
> -{
> -    ngx_int_t            rc;
> -    ngx_connection_t    *c, *ct;
> -    ngx_rbtree_node_t  **p;
> -    ngx_quic_socket_t   *qsock, *qsockt;
> -
> -    for ( ;; ) {
> -
> -        if (node->key < temp->key) {
> -
> -            p = &temp->left;
> -
> -        } else if (node->key > temp->key) {
> -
> -            p = &temp->right;
> -
> -        } else { /* node->key == temp->key */
> -
> -            qsock = (ngx_quic_socket_t *) node;
> -            c = qsock->udp.connection;
> -
> -            qsockt = (ngx_quic_socket_t *) temp;
> -            ct = qsockt->udp.connection;
> -
> -            rc = ngx_memn2cmp(qsock->sid.id, qsockt->sid.id,
> -                              qsock->sid.len, qsockt->sid.len);
> -
> -            if (rc == 0 && c->listening->wildcard) {
> -                rc = ngx_cmp_sockaddr(c->local_sockaddr, c->local_socklen,
> -                                      ct->local_sockaddr, ct->local_socklen, 1);
> -            }
> -
> -            p = (rc < 0) ? &temp->left : &temp->right;
> -        }
> -
> -        if (*p == sentinel) {
> -            break;
> -        }
> -
> -        temp = *p;
> -    }
> -
> -    *p = node;
> -    node->parent = temp;
> -    node->left = sentinel;
> -    node->right = sentinel;
> -    ngx_rbt_red(node);
> -}
> -
> -
>  static ngx_connection_t *
>  ngx_quic_lookup_connection(ngx_listening_t *ls, ngx_str_t *key,
>      struct sockaddr *local_sockaddr, socklen_t local_socklen)
> diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
> --- a/src/http/ngx_http.c
> +++ b/src/http/ngx_http.c
> @@ -1883,14 +1883,7 @@ ngx_http_add_listening(ngx_conf_t *cf, n
>      ls->wildcard = addr->opt.wildcard;
>  
>  #if (NGX_HTTP_V3)
> -
>      ls->quic = addr->opt.quic;
> -
> -    if (ls->quic) {
> -        ngx_rbtree_init(&ls->rbtree, &ls->sentinel,
> -                        ngx_quic_rbtree_insert_value);
> -    }
> -
>  #endif
>  
>      return ls;
> diff --git a/src/stream/ngx_stream.c b/src/stream/ngx_stream.c
> --- a/src/stream/ngx_stream.c
> +++ b/src/stream/ngx_stream.c
> @@ -518,11 +518,6 @@ ngx_stream_optimize_servers(ngx_conf_t *
>              ls->reuseport = addr[i].opt.reuseport;
>  #endif
>  
> -#if !(NGX_WIN32)
> -            ngx_rbtree_init(&ls->rbtree, &ls->sentinel,
> -                            ngx_udp_rbtree_insert_value);
> -#endif
> -
>              stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t));
>              if (stport == NULL) {
>                  return NGX_CONF_ERROR;

Looks good.

-- 
Maxim Dounin
http://mdounin.ru/


More information about the nginx-devel mailing list