]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: rhttp: fix incorrect dst/dst_port values
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 31 Mar 2025 15:57:35 +0000 (17:57 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 2 Apr 2025 12:57:40 +0000 (14:57 +0200)
With a @rhttp server, connect is not possible, transfer is only possible
via idle connection reuse. The server does not have any network address.

Thus, it is unnecessary to allocate the stream destination address prior
to connection reuse. This patch adjusts this by fixing
alloc_dst_address() to take this into account.

Prior to this patch, alloc_dst_address() would incorrectly assimilate a
@rhttp server with a transparent proxy mode. Thus stream destination
address would be copied from the destination address. Connection adress
would then be rewrote with this incorrect value. This did not impact
connect or reuse as destination addr is only used in idle conn hash
calculation for transparent servers. However, it causes incorrect values
for dst/dst_port samples.

This should be backported up to 2.9.

src/backend.c

index a753a0ef4f2d19f0d76d8e3df96ccdfd4be06ae7..eab4ea6a185e419b8d4ec104291bbbe90895e9dd 100644 (file)
@@ -858,13 +858,14 @@ out_ok:
        return err;
 }
 
-/* Allocate an address for the destination endpoint
- * The address is taken from the currently assigned server, or from the
- * dispatch or transparent address.
+/* Allocate <*ss> address unless already set. Address is then set to the
+ * destination endpoint of <srv> server, or via <s> from a dispatch or
+ * transparent address.
  *
- * Returns SRV_STATUS_OK on success. Does nothing if the address was
- * already set.
- * On error, no address is allocated and SRV_STATUS_INTERNAL is returned.
+ * Note that no address is allocated if server relies on reverse HTTP.
+ *
+ * Returns SRV_STATUS_OK on success, or if already already set. Else an error
+ * code is returned and <*ss> is not allocated.
  */
 static int alloc_dst_address(struct sockaddr_storage **ss,
                              struct server *srv, struct stream *s)
@@ -874,6 +875,11 @@ static int alloc_dst_address(struct sockaddr_storage **ss,
        if (*ss)
                return SRV_STATUS_OK;
 
+       if (srv && (srv->flags & SRV_F_RHTTP)) {
+               /* For reverse HTTP, destination address is unknown. */
+               return SRV_STATUS_OK;
+       }
+
        if ((s->flags & SF_DIRECT) || (s->be->lbprm.algo & BE_LB_KIND)) {
                /* A server is necessarily known for this stream */
                if (!(s->flags & SF_ASSIGNED))
@@ -1888,7 +1894,8 @@ skip_reuse:
                return SF_ERR_RESOURCE;
 
        /* copy the target address into the connection */
-       *srv_conn->dst = *s->scb->dst;
+       if (s->scb->dst)
+               *srv_conn->dst = *s->scb->dst;
 
        /* Copy network namespace from client connection */
        srv_conn->proxy_netns = cli_conn ? cli_conn->proxy_netns : NULL;