Load balance TCP sessions based on packet

I am setting up Haproxy in tcp mode. Back end will be set of servers that acts as hub server for set of clients. Since hub server maintains session, load balancer need to route packets to specific server where session is originated. I can manipulate TCP packet and add session data in it.
Based on my understanding of Haproxy configuration, this is not possible with default settings.
What will be the correct place to intercept TCP packet to decode the session data and route to correct backend server

A TCP connection on the frontend will always have a 1:1 relation to a TCP connection on the backend, it doesn’t work any other way, so during a TCP session there are no issues.

Only when the connection is closed and later re-established would you then, due to round-robin load-balancing, likely hit a different backend server.

If you need to address the latter case, e.g. a client needs to stick to the same server even when a new TCP connection is established, then you could stick to the source IP:

  • either by hashing (balance source)
  • or by saving the source IP address in stick tables

If you cannot use the source IP to stick the server to a backend, then it is entirely depended on the actual protocol used on top of TCP. The client would need to send a identifier in the first packet, haproxy would have to intercept that and decide which backend server the identifier belongs to, before any backend server connection is established.

In other words, any protocol that doesn’t provide a identifier in the first packet from the client, or any protocol where the server sends data first, will not be compatible with this approach, and a full application aware connection broker / proxy would be necessary.

For me, clients need to stick to same server even when new TCP connection is established and even , more than one client need to stick to the same server since these clients are collaborating via the server.
I am trying to modify haproxy code to handle this scenario and trying to follow same logic that you mentioned ( intercept the first packet and decide backend server). My question is where in haproxy code this should be done? I am going through assign-server method in backend.c. The request attribute in proxy structure contain the packet data is my understanding right?


So some clients (which collaborate) should be going to server A. Some other clients (which collaborate) should be going to server B, etc. Is that what you want?

How would you know which clients collaborate which each other at the load-balancing level and how would you handle the case when one client of server A needs to collaborate with server B?

I have not yet understood what you really want to achieve and how.

Some things are possible without modifying the source code. Other things won’t ever be possible in haproxy, even if you modify the code. Whatever the case, I have only contributed small code changes to haproxy so I certainly won’t be able to help you modifying the source code.

Hi All,

I was watching this thread and had a few questions on the topic.

I am also setting up TCP load balancing. Specifically RTMP.

If I have backend server A and server B, and I use “stick tables”. Assuming customer A is assigned to server A and customer B is assigned to server B.

Customer A disconnects, and reconnects, they will go back to A (assuming their stick table entry has not expired).

What if I put server A in “DRAIN” mode, and customer A disconnects and reconnects. I am assuming that customer A will go back to server A since they are in the stick table – the DRAIN just means to ignore this server for new connections coming in (e.g. customer C).