On 6/19/24 12:00 PM, Yann Ylavic wrote:
> 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.

As far as I read the code it does not.

https://github.com/apache/apr/blob/b0a08c76ceacc2308d7cf1d5a7bb3c9b4665a432/network_io/unix/sockets.c#L423-L433

We copy the data (sa, salen family and port) not a pointer.

> 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.

As said I don't see a dangling pointer because I don't read a pointer copy from 
the code.

> 
> [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.
> 

Regards

Rüdiger

Reply via email to