<a id="explanation-haproxy-route-tcp"></a>

# How haproxy-route-tcp works

The `haproxy-route-tcp` interface enables the `ingress-configurator` charm to manage
Layer 4 (TCP) load balancing and routing through the
[`haproxy`](https://charmhub.io/haproxy) charm. Unlike HTTP modes,
`haproxy-route-tcp` operates exclusively in **integrator TCP mode**, where
backend target addresses and port mappings are defined directly through charm
configuration rather than discovered via an `ingress` relation.

This interface is designed for TCP workloads where the backend is not a charmed application
or does not implement the `ingress` interface.

## Architecture

In TCP mode, `ingress-configurator` acts as a configuration translation layer for
Layer 4 traffic. The operator supplies backend IP addresses, port mappings, health
checks, and TLS parameters via charm configuration. `ingress-configurator` validates
this state and forwards the configuration over the `haproxy-route-tcp` relation.
HAProxy then opens the requested frontend listener ports and proxies raw TCP connections
to the backends.

## Traffic routing and port range mapping

The `tcp-port-mapping` option uses `frontend:backend` syntax:

- **Single port** (`<port>:<port>`): e.g. `"4000:20000"`
- **Port range** (`<start>-<end>:<start>-<end>`): e.g. `"4000-4005:20000-20005"`

#### NOTE
Single port mapping can also be configured using `tcp-backend-port` and `tcp-frontend-port`,
but these options are deprecated in favor of `tcp-port-mapping`.

## TLS and health checks

- **TLS termination and SNI**: Traffic can be decrypted at HAProxy before being sent to backends, or passed through. When TLS enforcement is active, SNI hostnames allow HAProxy to route encrypted TCP streams to the correct backend.
- **Layer 4 health checking**: HAProxy monitors backend availability before dispatching connections.
  Beyond simple TCP handshakes, HAProxy can perform generic send/expect string matching or utilize native protocol checks for databases.

## Constraints and limitations

- **Integrator mode only**: `haproxy-route-tcp` cannot be used with an `ingress` relation.
  The charm blocks if an `ingress` relation and `haproxy-route-tcp` are present simultaneously.
- **One route relation at a time**: The charm permits only one active route relation (`haproxy-route`, `haproxy-route-tcp`, or `gateway-route`).
- **No `cache-config` support**: The content-cache integration operates at Layer 7 and cannot be used alongside `haproxy-route-tcp`.
- **Substrate support**: `haproxy-route-tcp` is only supported on Machine substrates.
