comparison src/event/quic/ngx_event_quic_streams.c @ 9087:3bb003fcd682 quic

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.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 11 May 2023 19:40:11 +0400
parents cc3d24a9b76f
children
comparison
equal deleted inserted replaced
9086:cc3d24a9b76f 9087:3bb003fcd682
635 635
636 636
637 static ngx_quic_stream_t * 637 static ngx_quic_stream_t *
638 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id) 638 ngx_quic_create_stream(ngx_connection_t *c, uint64_t id)
639 { 639 {
640 ngx_str_t addr_text;
640 ngx_log_t *log; 641 ngx_log_t *log;
641 ngx_pool_t *pool; 642 ngx_pool_t *pool;
642 ngx_uint_t reusable; 643 ngx_uint_t reusable;
643 ngx_queue_t *q; 644 ngx_queue_t *q;
645 struct sockaddr *sockaddr;
644 ngx_connection_t *sc; 646 ngx_connection_t *sc;
645 ngx_quic_stream_t *qs; 647 ngx_quic_stream_t *qs;
646 ngx_pool_cleanup_t *cln; 648 ngx_pool_cleanup_t *cln;
647 ngx_quic_connection_t *qc; 649 ngx_quic_connection_t *qc;
648 650
689 return NULL; 691 return NULL;
690 } 692 }
691 693
692 *log = *c->log; 694 *log = *c->log;
693 pool->log = log; 695 pool->log = log;
696
697 sockaddr = ngx_palloc(pool, c->socklen);
698 if (sockaddr == NULL) {
699 ngx_destroy_pool(pool);
700 ngx_queue_insert_tail(&qc->streams.free, &qs->queue);
701 return NULL;
702 }
703
704 ngx_memcpy(sockaddr, c->sockaddr, c->socklen);
705
706 if (c->addr_text.data) {
707 addr_text.data = ngx_pnalloc(pool, c->addr_text.len);
708 if (addr_text.data == NULL) {
709 ngx_destroy_pool(pool);
710 ngx_queue_insert_tail(&qc->streams.free, &qs->queue);
711 return NULL;
712 }
713
714 ngx_memcpy(addr_text.data, c->addr_text.data, c->addr_text.len);
715 addr_text.len = c->addr_text.len;
716
717 } else {
718 addr_text.len = 0;
719 addr_text.data = NULL;
720 }
694 721
695 reusable = c->reusable; 722 reusable = c->reusable;
696 ngx_reusable_connection(c, 0); 723 ngx_reusable_connection(c, 0);
697 724
698 sc = ngx_get_connection(c->fd, log); 725 sc = ngx_get_connection(c->fd, log);
708 sc->quic = qs; 735 sc->quic = qs;
709 sc->shared = 1; 736 sc->shared = 1;
710 sc->type = SOCK_STREAM; 737 sc->type = SOCK_STREAM;
711 sc->pool = pool; 738 sc->pool = pool;
712 sc->ssl = c->ssl; 739 sc->ssl = c->ssl;
713 sc->sockaddr = c->sockaddr; 740 sc->sockaddr = sockaddr;
714 sc->socklen = c->socklen; 741 sc->socklen = c->socklen;
715 sc->listening = c->listening; 742 sc->listening = c->listening;
716 sc->addr_text = c->addr_text; 743 sc->addr_text = addr_text;
717 sc->local_sockaddr = c->local_sockaddr; 744 sc->local_sockaddr = c->local_sockaddr;
718 sc->local_socklen = c->local_socklen; 745 sc->local_socklen = c->local_socklen;
719 sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); 746 sc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
720 sc->start_time = c->start_time; 747 sc->start_time = c->start_time;
721 sc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED; 748 sc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;