aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2023-05-11 19:40:11 +0400
committerRoman Arutyunyan <arut@nginx.com>2023-05-11 19:40:11 +0400
commit885c4881915e28661f341b9ac3807afb84c8b779 (patch)
treea21dbe246654401b3815d8cff039c7f53254f36c /src
parenta4319bc496264f94ea8a85702d9b5b8098d9d18c (diff)
downloadnginx-885c4881915e28661f341b9ac3807afb84c8b779.tar.gz
nginx-885c4881915e28661f341b9ac3807afb84c8b779.zip
QUIC: keep stream sockaddr and addr_text constant.
HTTP and Stream variables $remote_addr and $binary_remote_addr rely on constant client address, particularly because they are cacheable. However, QUIC client may migrate to a new address. While there's no perfect way to handle this, the proposed solution is to copy client address to QUIC stream at stream creation. The change also fixes truncated $remote_addr if migration happened while the stream was active. The reason is addr_text string was copied to stream by value.
Diffstat (limited to 'src')
-rw-r--r--src/event/quic/ngx_event_quic_streams.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/event/quic/ngx_event_quic_streams.c b/src/event/quic/ngx_event_quic_streams.c
index ded94af87..6664dfd7b 100644
--- a/src/event/quic/ngx_event_quic_streams.c
+++ b/src/event/quic/ngx_event_quic_streams.c
@@ -637,10 +637,12 @@ ngx_quic_do_init_streams(ngx_connection_t *c)
static ngx_quic_stream_t *
ngx_quic_create_stream(ngx_connection_t *c, uint64_t id)
{
+ ngx_str_t addr_text;
ngx_log_t *log;
ngx_pool_t *pool;
ngx_uint_t reusable;
ngx_queue_t *q;
+ struct sockaddr *sockaddr;
ngx_connection_t *sc;
ngx_quic_stream_t *qs;
ngx_pool_cleanup_t *cln;
@@ -692,6 +694,31 @@ ngx_quic_create_stream(ngx_connection_t *c, uint64_t id)
*log = *c->log;
pool->log = log;
+ sockaddr = ngx_palloc(pool, c->socklen);
+ if (sockaddr == NULL) {
+ ngx_destroy_pool(pool);
+ ngx_queue_insert_tail(&qc->streams.free, &qs->queue);
+ return NULL;
+ }
+
+ ngx_memcpy(sockaddr, c->sockaddr, c->socklen);
+
+ if (c->addr_text.data) {
+ addr_text.data = ngx_pnalloc(pool, c->addr_text.len);
+ if (addr_text.data == NULL) {
+ ngx_destroy_pool(pool);
+ ngx_queue_insert_tail(&qc->streams.free, &qs->queue);
+ return NULL;
+ }
+
+ ngx_memcpy(addr_text.data, c->addr_text.data, c->addr_text.len);
+ addr_text.len = c->addr_text.len;
+
+ } else {
+ addr_text.len = 0;
+ addr_text.data = NULL;
+ }
+
reusable = c->reusable;
ngx_reusable_connection(c, 0);
@@ -710,10 +737,10 @@ ngx_quic_create_stream(ngx_connection_t *c, uint64_t id)
sc->type = SOCK_STREAM;
sc->pool = pool;
sc->ssl = c->ssl;
- sc->sockaddr = c->sockaddr;
+ sc->sockaddr = sockaddr;
sc->socklen = c->socklen;
sc->listening = c->listening;
- sc->addr_text = c->addr_text;
+ sc->addr_text = addr_text;
sc->local_sockaddr = c->local_sockaddr;
sc->local_socklen = c->local_socklen;
sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);