summaryrefslogtreecommitdiffhomepage
path: root/src/event/ngx_event_udp.c
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2022-04-20 16:01:17 +0400
committerRoman Arutyunyan <arut@nginx.com>2022-04-20 16:01:17 +0400
commit9d81ef744cdaacf1e52bcaec4224d375af5ba59b (patch)
treedb3f8a9fc1381a2c848d934fd1c7f9bbaf1a9dca /src/event/ngx_event_udp.c
parentc24c27bb074b571fc9e9d75e19be31b83c69c253 (diff)
downloadnginx-9d81ef744cdaacf1e52bcaec4224d375af5ba59b.tar.gz
nginx-9d81ef744cdaacf1e52bcaec4224d375af5ba59b.tar.bz2
QUIC: separate UDP framework for QUIC.
Previously, QUIC used the existing UDP framework, which was created for UDP in Stream. However the way QUIC connections are created and looked up is different from the way UDP connections in Stream are created and looked up. Now these two implementations are decoupled.
Diffstat (limited to 'src/event/ngx_event_udp.c')
-rw-r--r--src/event/ngx_event_udp.c173
1 files changed, 59 insertions, 114 deletions
diff --git a/src/event/ngx_event_udp.c b/src/event/ngx_event_udp.c
index 1053fa0ac..a7fa38aa8 100644
--- a/src/event/ngx_event_udp.c
+++ b/src/event/ngx_event_udp.c
@@ -15,27 +15,25 @@
static void ngx_close_accepted_udp_connection(ngx_connection_t *c);
static ssize_t ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf,
size_t size);
-static ngx_int_t ngx_create_udp_connection(ngx_connection_t *c);
+static ngx_int_t ngx_insert_udp_connection(ngx_connection_t *c);
static ngx_connection_t *ngx_lookup_udp_connection(ngx_listening_t *ls,
- ngx_str_t *key, struct sockaddr *local_sockaddr, socklen_t local_socklen);
+ struct sockaddr *sockaddr, socklen_t socklen,
+ struct sockaddr *local_sockaddr, socklen_t local_socklen);
void
ngx_event_recvmsg(ngx_event_t *ev)
{
- size_t len;
ssize_t n;
- ngx_str_t key;
ngx_buf_t buf;
ngx_log_t *log;
ngx_err_t err;
- socklen_t local_socklen;
+ socklen_t socklen, local_socklen;
ngx_event_t *rev, *wev;
struct iovec iov[1];
struct msghdr msg;
ngx_sockaddr_t sa, lsa;
- ngx_udp_dgram_t dgram;
- struct sockaddr *local_sockaddr;
+ struct sockaddr *sockaddr, *local_sockaddr;
ngx_listening_t *ls;
ngx_event_conf_t *ecf;
ngx_connection_t *c, *lc;
@@ -110,21 +108,21 @@ ngx_event_recvmsg(ngx_event_t *ev)
}
#endif
- dgram.sockaddr = msg.msg_name;
- dgram.socklen = msg.msg_namelen;
+ sockaddr = msg.msg_name;
+ socklen = msg.msg_namelen;
- if (dgram.socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
- dgram.socklen = sizeof(ngx_sockaddr_t);
+ if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+ socklen = sizeof(ngx_sockaddr_t);
}
- if (dgram.socklen == 0) {
+ if (socklen == 0) {
/*
* on Linux recvmsg() returns zero msg_namelen
* when receiving packets from unbound AF_UNIX sockets
*/
- dgram.socklen = sizeof(struct sockaddr);
+ socklen = sizeof(struct sockaddr);
ngx_memzero(&sa, sizeof(struct sockaddr));
sa.sockaddr.sa_family = ls->sockaddr->sa_family;
}
@@ -152,35 +150,8 @@ ngx_event_recvmsg(ngx_event_t *ev)
#endif
- key.data = (u_char *) dgram.sockaddr;
- key.len = dgram.socklen;
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (dgram.sockaddr->sa_family == AF_UNIX) {
- struct sockaddr_un *saun = (struct sockaddr_un *) dgram.sockaddr;
-
- if (dgram.socklen <= (socklen_t) offsetof(struct sockaddr_un,
- sun_path)
- || saun->sun_path[0] == '\0')
- {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "unbound unix socket");
- key.len = 0;
- }
- }
-
-#endif
-
-#if (NGX_QUIC)
- if (ls->quic) {
- if (ngx_quic_get_packet_dcid(ev->log, buffer, n, &key) != NGX_OK) {
- goto next;
- }
- }
-#endif
-
- c = ngx_lookup_udp_connection(ls, &key, local_sockaddr, local_socklen);
+ c = ngx_lookup_udp_connection(ls, sockaddr, socklen, local_sockaddr,
+ local_socklen);
if (c) {
@@ -202,14 +173,10 @@ ngx_event_recvmsg(ngx_event_t *ev)
buf.pos = buffer;
buf.last = buffer + n;
- buf.start = buf.pos;
- buf.end = buffer + sizeof(buffer);
rev = c->read;
- dgram.buffer = &buf;
-
- c->udp->dgram = &dgram;
+ c->udp->buffer = &buf;
rev->ready = 1;
rev->active = 0;
@@ -217,7 +184,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
rev->handler(rev);
if (c->udp) {
- c->udp->dgram = NULL;
+ c->udp->buffer = NULL;
}
rev->ready = 0;
@@ -240,7 +207,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
c->shared = 1;
c->type = SOCK_DGRAM;
- c->socklen = dgram.socklen;
+ c->socklen = socklen;
#if (NGX_STAT_STUB)
(void) ngx_atomic_fetch_add(ngx_stat_active, 1);
@@ -252,21 +219,13 @@ ngx_event_recvmsg(ngx_event_t *ev)
return;
}
- len = dgram.socklen;
-
-#if (NGX_QUIC)
- if (ls->quic) {
- len = NGX_SOCKADDRLEN;
- }
-#endif
-
- c->sockaddr = ngx_palloc(c->pool, len);
+ c->sockaddr = ngx_palloc(c->pool, socklen);
if (c->sockaddr == NULL) {
ngx_close_accepted_udp_connection(c);
return;
}
- ngx_memcpy(c->sockaddr, dgram.sockaddr, dgram.socklen);
+ ngx_memcpy(c->sockaddr, sockaddr, socklen);
log = ngx_palloc(c->pool, sizeof(ngx_log_t));
if (log == NULL) {
@@ -369,7 +328,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
}
#endif
- if (ngx_create_udp_connection(c) != NGX_OK) {
+ if (ngx_insert_udp_connection(c) != NGX_OK) {
ngx_close_accepted_udp_connection(c);
return;
}
@@ -412,17 +371,17 @@ ngx_udp_shared_recv(ngx_connection_t *c, u_char *buf, size_t size)
ssize_t n;
ngx_buf_t *b;
- if (c->udp == NULL || c->udp->dgram == NULL) {
+ if (c->udp == NULL || c->udp->buffer == NULL) {
return NGX_AGAIN;
}
- b = c->udp->dgram->buffer;
+ b = c->udp->buffer;
n = ngx_min(b->last - b->pos, (ssize_t) size);
ngx_memcpy(buf, b->pos, n);
- c->udp->dgram = NULL;
+ c->udp->buffer = NULL;
c->read->ready = 0;
c->read->active = 1;
@@ -458,8 +417,8 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
udpt = (ngx_udp_connection_t *) temp;
ct = udpt->connection;
- rc = ngx_memn2cmp(udp->key.data, udpt->key.data,
- udp->key.len, udpt->key.len);
+ rc = ngx_cmp_sockaddr(c->sockaddr, c->socklen,
+ ct->sockaddr, ct->socklen, 1);
if (rc == 0 && c->listening->wildcard) {
rc = ngx_cmp_sockaddr(c->local_sockaddr, c->local_socklen,
@@ -485,18 +444,12 @@ ngx_udp_rbtree_insert_value(ngx_rbtree_node_t *temp,
static ngx_int_t
-ngx_create_udp_connection(ngx_connection_t *c)
+ngx_insert_udp_connection(ngx_connection_t *c)
{
- ngx_str_t key;
+ uint32_t hash;
ngx_pool_cleanup_t *cln;
ngx_udp_connection_t *udp;
-#if (NGX_QUIC)
- if (c->listening->quic) {
- return NGX_OK;
- }
-#endif
-
if (c->udp) {
return NGX_OK;
}
@@ -506,34 +459,10 @@ ngx_create_udp_connection(ngx_connection_t *c)
return NGX_ERROR;
}
- cln = ngx_pool_cleanup_add(c->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->data = c;
- cln->handler = ngx_delete_udp_connection;
-
- key.data = (u_char *) c->sockaddr;
- key.len = c->socklen;
-
- ngx_insert_udp_connection(c, udp, &key);
-
- c->udp = udp;
-
- return NGX_OK;
-}
-
-
-void
-ngx_insert_udp_connection(ngx_connection_t *c, ngx_udp_connection_t *udp,
- ngx_str_t *key)
-{
- uint32_t hash;
+ udp->connection = c;
ngx_crc32_init(hash);
-
- ngx_crc32_update(&hash, key->data, key->len);
+ ngx_crc32_update(&hash, (u_char *) c->sockaddr, c->socklen);
if (c->listening->wildcard) {
ngx_crc32_update(&hash, (u_char *) c->local_sockaddr, c->local_socklen);
@@ -541,11 +470,21 @@ ngx_insert_udp_connection(ngx_connection_t *c, ngx_udp_connection_t *udp,
ngx_crc32_final(hash);
- udp->connection = c;
- udp->key = *key;
udp->node.key = hash;
+ cln = ngx_pool_cleanup_add(c->pool, 0);
+ if (cln == NULL) {
+ return NGX_ERROR;
+ }
+
+ cln->data = c;
+ cln->handler = ngx_delete_udp_connection;
+
ngx_rbtree_insert(&c->listening->rbtree, &udp->node);
+
+ c->udp = udp;
+
+ return NGX_OK;
}
@@ -565,8 +504,8 @@ ngx_delete_udp_connection(void *data)
static ngx_connection_t *
-ngx_lookup_udp_connection(ngx_listening_t *ls, ngx_str_t *key,
- struct sockaddr *local_sockaddr, socklen_t local_socklen)
+ngx_lookup_udp_connection(ngx_listening_t *ls, struct sockaddr *sockaddr,
+ socklen_t socklen, struct sockaddr *local_sockaddr, socklen_t local_socklen)
{
uint32_t hash;
ngx_int_t rc;
@@ -574,15 +513,27 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, ngx_str_t *key,
ngx_rbtree_node_t *node, *sentinel;
ngx_udp_connection_t *udp;
- if (key->len == 0) {
- return NULL;
+#if (NGX_HAVE_UNIX_DOMAIN)
+
+ if (sockaddr->sa_family == AF_UNIX) {
+ struct sockaddr_un *saun = (struct sockaddr_un *) sockaddr;
+
+ if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path)
+ || saun->sun_path[0] == '\0')
+ {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
+ "unbound unix socket");
+ return NULL;
+ }
}
+#endif
+
node = ls->rbtree.root;
sentinel = ls->rbtree.sentinel;
ngx_crc32_init(hash);
- ngx_crc32_update(&hash, key->data, key->len);
+ ngx_crc32_update(&hash, (u_char *) sockaddr, socklen);
if (ls->wildcard) {
ngx_crc32_update(&hash, (u_char *) local_sockaddr, local_socklen);
@@ -608,7 +559,8 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, ngx_str_t *key,
c = udp->connection;
- rc = ngx_memn2cmp(key->data, udp->key.data, key->len, udp->key.len);
+ rc = ngx_cmp_sockaddr(sockaddr, socklen,
+ c->sockaddr, c->socklen, 1);
if (rc == 0 && ls->wildcard) {
rc = ngx_cmp_sockaddr(local_sockaddr, local_socklen,
@@ -616,13 +568,6 @@ ngx_lookup_udp_connection(ngx_listening_t *ls, ngx_str_t *key,
}
if (rc == 0) {
-
-#if (NGX_QUIC)
- if (ls->quic && c->udp != udp) {
- c->udp = udp;
- }
-#endif
-
return c;
}