On Wed, Jun 19, 2024 at 9:07 AM Ruediger Pluem <rpl...@apache.org> wrote:
>
> On 6/18/24 4:20 PM, yla...@apache.org wrote:
> >
> > +            /* Release the old conn address */
> > +            if (conn->address) {
> > +                /* conn->address->addr cannot be released while it's used 
> > by
> > +                 * conn->sock->remote_addr, thus if the old address is 
> > still
> > +                 * the one used at apr_socket_connect() time AND the socket
> > +                 * shouldn't be closed because the newly resolved address 
> > is
> > +                 * the same. In this case let's (re)attach the old address 
> > to
> > +                 * the socket lifetime (scpool), in any other case just 
> > release
> > +                 * it now.
> > +                 */
> > +                int addr_alive = 0,
> > +                    conn_alive = (conn->sock && conn->addr &&
> > +                                  proxy_addrs_equal(conn->addr, 
> > address->addr));
> > +                if (conn_alive) {
> > +                    apr_sockaddr_t *remote_addr = NULL;
> > +                    apr_socket_addr_get(&remote_addr, APR_REMOTE, 
> > conn->sock);
> > +                    addr_alive = (conn->addr == remote_addr);
>
> How can this ever be true? The remote_addr is always allocated from 
> conn->scpool. How can
> conn->addr ever be allocated from conn->scpool? I think it always gets 
> allocated from
> either a subpool of worker->cp->dns_pool, from conn->pool or from 
> conn->uds_pool.
>
> > +                }

All the complications[1] in this commit come from the fact that
apr_socket_connect(sock, addr) does a simple pointer copy of addr into
sock->remote_addr, which apr_socket_addr_get(APR_REMOTE) will return.
And in ap_proxy_connect_backend() we indeed do the same[2] as
apr_socket_connect(conn->sock, conn->addr).
So I think it does not matter which pool conn->addr was allocated
from[3] when apr_socket_connect() does a pointer copy?

[1] When a new conn->[address->]addr is determined and it's the same
address as the old one and we want to keep the socket open, we cannot
simply release the old conn->address without leaving a dangling
pointer in sock->remote_addr. That's why conn->[address->]addr is
reattached to conn->scpool to be cleaned up only when the socket is
closed.

[2] Well, not really the same because we'll walk all the
conn->addr[->next] to find one that works, so the conn->addr ==
remote_addr test should actually be a loop to find one of the
conn->addr[->next]. Will fix this!

[3] From worker_address_resolve() it's actually a subpool of
worker->cp->dns_pool since worker->s->is_address_reusable here.

Regards;
Yann.

Reply via email to