Http-reuse always with usesrc clientip

Hi,
I’ve been trying a couple of things and either I am missing something in the docs or there seems to be a bug.

I downsized my configuration as much as possible:

global
 ssl-default-bind-options ssl-min-ver TLSv1.2
 log 127.0.0.1 local0 info
 log 127.0.0.1 local0
 daemon
 nbthread 2
 stats timeout 30
 log-send-hostname
 chroot /var/empty

#############
defaults
 timeout connect 10s
 timeout http-request 10s
 timeout client 900s
 timeout server 900s
 mode http
 log global
 option httplog
#############
###############################

backend backend1
 mode http
 no log
 http-reuse always

# source 0.0.0.0 usesrc clientip
 balance source
 server server1 192.168.2.10:80 enabled

frontend frontend1
 no log
 mode http
 bind 192.168.1.10:80 interface eth1 transparent

 default_backend backend1

This seems to be working absolutely fine as long as I don’t enable usesrc clientip in the backend:

user@testclient:~$ for a in {1..90}; do curl --interface 12.12.12.12 http://192.168.1.10 -m2 -H "Connection: keep-alive"; done
root@haproxy:/opt/haproxy# tcpdump -i any 'host 192.168.2.10 or host 12.12.12.12' and tcp[13]=2 -nnn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
12:06:41.636383 eth1  In  IP 12.12.12.12.55549 > 192.168.1.10.80: Flags [S]
12:06:41.637004 eth2  Out IP 192.168.2.1.51544 > 192.168.2.10.80: Flags [S]
12:06:41.645423 eth1  In  IP 12.12.12.12.59131 > 192.168.1.10.80: Flags [S]
12:06:41.653970 eth1  In  IP 12.12.12.12.49811 > 192.168.1.10.80: Flags [S]
12:06:41.662192 eth1  In  IP 12.12.12.12.41853 > 192.168.1.10.80: Flags [S]
12:06:41.670344 eth1  In  IP 12.12.12.12.37247 > 192.168.1.10.80: Flags [S]
12:06:41.678518 eth1  In  IP 12.12.12.12.36007 > 192.168.1.10.80: Flags [S]
12:06:41.686688 eth1  In  IP 12.12.12.12.55457 > 192.168.1.10.80: Flags [S]
12:06:41.694942 eth1  In  IP 12.12.12.12.44871 > 192.168.1.10.80: Flags [S]
12:06:41.703217 eth1  In  IP 12.12.12.12.57151 > 192.168.1.10.80: Flags [S]
12:06:41.711506 eth1  In  IP 12.12.12.12.37281 > 192.168.1.10.80: Flags [S]
[...]
91 packets captured
91 packets received by filter
0 packets dropped by kernel
root@haproxy:/opt/haproxy# 

I can see exactly one SYN sent out towards the server and that’s it. Exactly as per the expectation.

As soon as I change the backend configuration to use the original client IP for the serverside connection, when I start the loop on the client again, the tcpdump looks like this:

root@haproxy:/opt/haproxy# tcpdump -i any 'host 192.168.2.10 or host 12.12.12.12' and tcp[13]=2 -nnn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
12:12:09.627302 eth1  In  IP 12.12.12.12.54739 > 192.168.1.10.80: Flags [S]
12:12:09.628353 eth2  Out IP 12.12.12.12.53362 > 192.168.2.10.80: Flags [S]
12:12:09.636901 eth1  In  IP 12.12.12.12.42743 > 192.168.1.10.80: Flags [S]
12:12:09.637324 eth2  Out IP 12.12.12.12.53368 > 192.168.2.10.80: Flags [S]
12:12:09.645450 eth1  In  IP 12.12.12.12.58641 > 192.168.1.10.80: Flags [S]
12:12:09.645687 eth2  Out IP 12.12.12.12.53370 > 192.168.2.10.80: Flags [S]
12:12:09.653742 eth1  In  IP 12.12.12.12.37701 > 192.168.1.10.80: Flags [S]
12:12:09.654009 eth2  Out IP 12.12.12.12.53372 > 192.168.2.10.80: Flags [S]
12:12:09.662045 eth1  In  IP 12.12.12.12.43733 > 192.168.1.10.80: Flags [S]
12:12:09.662410 eth2  Out IP 12.12.12.12.53374 > 192.168.2.10.80: Flags [S]
12:12:09.670386 eth1  In  IP 12.12.12.12.57391 > 192.168.1.10.80: Flags [S]
12:12:09.670668 eth2  Out IP 12.12.12.12.53386 > 192.168.2.10.80: Flags [S]
12:12:09.678750 eth1  In  IP 12.12.12.12.38029 > 192.168.1.10.80: Flags [S]
12:12:09.679158 eth2  Out IP 12.12.12.12.53388 > 192.168.2.10.80: Flags [S]
12:12:09.687070 eth1  In  IP 12.12.12.12.40609 > 192.168.1.10.80: Flags [S]
12:12:09.687529 eth2  Out IP 12.12.12.12.53390 > 192.168.2.10.80: Flags [S]
12:12:09.695557 eth1  In  IP 12.12.12.12.60707 > 192.168.1.10.80: Flags [S]
12:12:09.695865 eth2  Out IP 12.12.12.12.53392 > 192.168.2.10.80: Flags [S]
12:12:09.703892 eth1  In  IP 12.12.12.12.41257 > 192.168.1.10.80: Flags [S]
12:12:09.704217 eth2  Out IP 12.12.12.12.53394 > 192.168.2.10.80: Flags [S]
12:12:09.712266 eth1  In  IP 12.12.12.12.44583 > 192.168.1.10.80: Flags [S]
12:12:09.712590 eth2  Out IP 12.12.12.12.53396 > 192.168.2.10.80: Flags [S]
12:12:09.720537 eth1  In  IP 12.12.12.12.54489 > 192.168.1.10.80: Flags [S]
12:12:09.720809 eth2  Out IP 12.12.12.12.53398 > 192.168.2.10.80: Flags [S]
12:12:09.728792 eth1  In  IP 12.12.12.12.45777 > 192.168.1.10.80: Flags [S]
12:12:09.729108 eth2  Out IP 12.12.12.12.53400 > 192.168.2.10.80: Flags [S]
12:12:09.737403 eth1  In  IP 12.12.12.12.41671 > 192.168.1.10.80: Flags [S]
[...]
180 packets captured
180 packets received by filter
0 packets dropped by kernel
root@haproxy:/opt/haproxy# 

The client gets correct responses, but there is one serverside connection per clientside connection, which was what I wanted to avoid using http-reuse always.

Can anybody else reproduce this? Am I misreading the documentation? Or is there some other parameter I have to add in order to make this work also for transparent mode?

EDIT:
sorry, forgot to mention the haproxy version used:

root@haproxy:/opt/haproxy# /opt/haproxy/haproxy.bin -v
HAProxy version 2.6.0-a1efc04 2022/05/31 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2027.
Known bugs: http://www.haproxy.org/bugs/bugs-2.6.0.html
Running on: Linux 5.10.0-13-amd64 #1 SMP Debian 5.10.106-1 (2022-03-17) x86_64

I also reproduced with other versions, but to be sure, I eventually tried 2.6.

Many thanks in advance,
Matt

Maybe I am misunderstanding you, but are you expecting from http reuse that there will be less connections?

There wouldnt be, http reuse is meant to lessen the cost of setting up new connections to the backend, by re-using idle connections when possible.

But I’m still a bit of a newbie on HAProxy, so don’t take my word for it. Check the manual perhaps, it’s really a good resource.