This adds basic support for the HAProxy PROXY protocol V1 on MySQL frontend
client connections. This allows the true client IP to be seen in the output
of `SHOW FULL PROCESSLIST` in ProxySQL's admin frontend when the ProxySQL
servers sit behind a load balancer such as HAProxy or AWS classic ELBs with
the PROXY protocol feature enabled.
I believe this should resolve sysown#2497 (Support for proxy_protocol for proxysql behind aws load balancer).
The patch adds a Proxy_Protocol class which handles:
- parsing of PROXY protocol headers (only the V1 header supported for now)
- matching client IPs against a list of configured network CIDRs
A new option, `proxy_protocol_frontend_nets` (list of network CIDRs), is
introduced to allow the PROXY protocol feature to be selectively turned on for
specific subnets where e.g. load balancers are running. This is similar to how
the PROXY protocol is implemented in MariaDB.
This variable can be set either in the config file or via the ProxySQL Admin
interface. Configuration file example:
mysql_variables=
{
...
proxy_protocol_frontend_nets="10.42.0.0/28 127.10.0.0/16"
...
}
ProxySQL Admin interface example:
UPDATE global_variables
SET variable_value="192.168.42.0/24"
WHERE variable_name="mysql-proxy_protocol_frontend_nets";
LOAD MYSQL VARIABLES TO RUNTIME;
The network CIDRs are stored as a thread-local variable in the MySQL_Thread
class. It's only updated by MySQL_Thread::refresh_variables().
A new MySQL Data Stream state (DSS), `STATE_PROXY_PROTOCOL`, is introduced to
handle the initial parsing of the PROXY protocol header. Once this has
completed, the state is reset back to `STATE_SERVER_HANDSHAKE`.
The patch hooks into the MySQL_Thread's main loop where `accept()` is called
to handle incoming connections. Next, the actual parsing of the PROXY protocol
header is invoked from the `MySQL_Data_Stream::read_pkts()` method, which is
also called from MySQL_Thread's main loop (where incoming data is handled).
I've only tested this with a HAProxy configuration block like:
listen proxysql-with-proxy
bind *:6030
option tcp-check
mode tcp
timeout server 6h
timeout client 6h
balance roundrobin
server proxysql-backend-1 127.0.0.1:6033 check send-proxy
listen proxysql-without-proxy
bind *:6031
option tcp-check
mode tcp
timeout server 6h
timeout client 6h
balance roundrobin
server proxysql-backend-2 192.168.1.123:6033 check