Merge pull request #13 from heil/master
haproxy: import from packages, add myself as the maintainer
This commit is contained in:
commit
e5dd5abf15
5 changed files with 699 additions and 0 deletions
62
net/haproxy/Makefile
Normal file
62
net/haproxy/Makefile
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2009-2014 Thomas Heil <heil@terminal-consulting.de>
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=haproxy
|
||||||
|
PKG_VERSION:=1.4.25
|
||||||
|
PKG_RELEASE:=01
|
||||||
|
|
||||||
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
|
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.4/src
|
||||||
|
PKG_MD5SUM:=74b5ec1f0f9b4d148c8083bcfb512ccd
|
||||||
|
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
|
||||||
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/haproxy
|
||||||
|
SUBMENU:=Web Servers/Proxies
|
||||||
|
SECTION:=net
|
||||||
|
CATEGORY:=Network
|
||||||
|
TITLE:=The Reliable, High Performance TCP/HTTP Load Balancer
|
||||||
|
URL:=http://haproxy.1wt.eu/
|
||||||
|
DEPENDS:=+libpcre +libltdl
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/haproxy/conffiles
|
||||||
|
/etc/haproxy.cfg
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/haproxy/description
|
||||||
|
Open source High Performance TCP/HTTP Load Balancer
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(MAKE) TARGET=linux2628 -C $(PKG_BUILD_DIR) \
|
||||||
|
DESTDIR="$(PKG_INSTALL_DIR)" \
|
||||||
|
CC="$(TARGET_CC)" \
|
||||||
|
CFLAGS="$(TARGET_CFLAGS)" \
|
||||||
|
LD="$(TARGET_CC)" \
|
||||||
|
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||||
|
SMALL_OPTS="-DBUFSIZE=16384 -DMAXREWRITE=8192 -DSYSTEM_MAXCONN=65530" USE_LINUX_TPROXY=1 USE_LINUX_SPLICE=1 \
|
||||||
|
VERSION="$(PKG_VERSION)-patch$(PKG_RELEASE)" \
|
||||||
|
all install
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/haproxy/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/sbin
|
||||||
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/haproxy $(1)/usr/sbin/
|
||||||
|
$(INSTALL_DIR) $(1)/etc
|
||||||
|
$(INSTALL_CONF) ./files/haproxy.cfg $(1)/etc/
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/haproxy.init $(1)/etc/init.d/haproxy
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/net
|
||||||
|
$(INSTALL_BIN) ./files/haproxy.hotplug $(1)/etc/hotplug.d/net/90-haproxy
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,haproxy))
|
100
net/haproxy/files/haproxy.cfg
Normal file
100
net/haproxy/files/haproxy.cfg
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# Example configuration file for HAProxy 1.3, refer to the url below for
|
||||||
|
# a full documentation and examples for configuration:
|
||||||
|
# http://haproxy.1wt.eu/download/1.3/doc/configuration.txt
|
||||||
|
|
||||||
|
|
||||||
|
# Global parameters
|
||||||
|
global
|
||||||
|
|
||||||
|
# Log events to a remote syslog server at given address using the
|
||||||
|
# specified facility and verbosity level. Multiple log options
|
||||||
|
# are allowed.
|
||||||
|
#log 10.0.0.1 daemon info
|
||||||
|
|
||||||
|
# Specifiy the maximum number of allowed connections.
|
||||||
|
maxconn 32000
|
||||||
|
|
||||||
|
# Raise the ulimit for the maximum allowed number of open socket
|
||||||
|
# descriptors per process. This is usually at least twice the
|
||||||
|
# number of allowed connections (maxconn * 2 + nb_servers + 1) .
|
||||||
|
ulimit-n 65535
|
||||||
|
|
||||||
|
# Drop privileges (setuid, setgid), default is "root" on OpenWrt.
|
||||||
|
uid 0
|
||||||
|
gid 0
|
||||||
|
|
||||||
|
# Perform chroot into the specified directory.
|
||||||
|
#chroot /var/run/haproxy/
|
||||||
|
|
||||||
|
# Daemonize on startup
|
||||||
|
daemon
|
||||||
|
|
||||||
|
nosplice
|
||||||
|
# Enable debugging
|
||||||
|
#debug
|
||||||
|
|
||||||
|
# Spawn given number of processes and distribute load among them,
|
||||||
|
# used for multi-core environments or to circumvent per-process
|
||||||
|
# limits like number of open file descriptors. Default is 1.
|
||||||
|
#nbproc 2
|
||||||
|
|
||||||
|
|
||||||
|
# Example HTTP proxy listener
|
||||||
|
listen my_http_proxy
|
||||||
|
|
||||||
|
# Bind to port 81 and 444 on all interfaces (0.0.0.0)
|
||||||
|
bind :81,:444
|
||||||
|
|
||||||
|
# We're proxying HTTP here...
|
||||||
|
mode http
|
||||||
|
|
||||||
|
# Simple HTTP round robin over two servers using the specified
|
||||||
|
# source ip 192.168.1.1 .
|
||||||
|
balance roundrobin
|
||||||
|
server server01 192.168.1.10:80 source 192.168.1.1
|
||||||
|
server server02 192.168.1.20:80 source 192.168.1.1
|
||||||
|
|
||||||
|
# Serve an internal statistics page on /stats:
|
||||||
|
stats enable
|
||||||
|
stats uri /stats
|
||||||
|
|
||||||
|
# Enable HTTP basic auth for the statistics:
|
||||||
|
stats realm HA_Stats
|
||||||
|
stats auth username:password
|
||||||
|
|
||||||
|
|
||||||
|
# Example SMTP proxy listener
|
||||||
|
listen my_smtp_proxy
|
||||||
|
|
||||||
|
# Disable this instance without commenting out the section.
|
||||||
|
disabled
|
||||||
|
|
||||||
|
# Bind to port 26 and 588 on localhost
|
||||||
|
bind 127.0.0.1:26,127.0.0.1:588
|
||||||
|
|
||||||
|
# This is a TCP proxy
|
||||||
|
mode tcp
|
||||||
|
|
||||||
|
# Round robin load balancing over two servers on port 123 forcing
|
||||||
|
# the address 192.168.1.1 and port 25 as source.
|
||||||
|
balance roundrobin
|
||||||
|
#use next line for transparent proxy, so the servers can see the
|
||||||
|
#original ip-address and remove source keyword in server definition
|
||||||
|
#source 0.0.0.0 usesrc clientip
|
||||||
|
server server01 192.168.1.10:123 source 192.168.1.1:25
|
||||||
|
server server02 192.168.1.20:123 source 192.168.1.1:25
|
||||||
|
|
||||||
|
|
||||||
|
# Special health check listener for integration with external load
|
||||||
|
# balancers.
|
||||||
|
listen local_health_check
|
||||||
|
|
||||||
|
# Listen on port 60000
|
||||||
|
bind :60000
|
||||||
|
|
||||||
|
# This is a health check
|
||||||
|
mode health
|
||||||
|
|
||||||
|
# Enable HTTP-style responses: "HTTP/1.0 200 OK"
|
||||||
|
# else just print "OK".
|
||||||
|
#option httpchk
|
8
net/haproxy/files/haproxy.hotplug
Normal file
8
net/haproxy/files/haproxy.hotplug
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$ACTION" = add ]; then
|
||||||
|
|
||||||
|
/etc/init.d/haproxy enabled && \
|
||||||
|
/etc/init.d/haproxy start
|
||||||
|
fi
|
||||||
|
|
23
net/haproxy/files/haproxy.init
Normal file
23
net/haproxy/files/haproxy.init
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
# Copyright (C) 2009-2010 OpenWrt.org
|
||||||
|
|
||||||
|
START=99
|
||||||
|
STOP=80
|
||||||
|
|
||||||
|
SERVICE_USE_PID=1
|
||||||
|
|
||||||
|
HAPROXY_BIN="/usr/sbin/haproxy"
|
||||||
|
HAPROXY_CONFIG="/etc/haproxy.cfg"
|
||||||
|
HAPROXY_PID="/var/run/haproxy.pid"
|
||||||
|
|
||||||
|
start() {
|
||||||
|
service_start $HAPROXY_BIN -q -D -f "$HAPROXY_CONFIG" -p "$HAPROXY_PID"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
service_stop $HAPROXY_BIN
|
||||||
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
$HAPROXY_BIN -D -q -f $HAPROXY_CONFIG -p $HAPROXY_PID -sf $(cat $HAPROXY_PID)
|
||||||
|
}
|
506
net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch
Normal file
506
net/haproxy/patches/001-haproxy-1.4.x-sendproxy.patch
Normal file
|
@ -0,0 +1,506 @@
|
||||||
|
From af2038557a14bf6e2915bed545e216a0f1a95fc5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bonte@free.fr>
|
||||||
|
Date: Mon, 15 Apr 2013 22:05:00 +0200
|
||||||
|
Subject: [PATCH] Proxy Protocol based on haproxy 1.4.23
|
||||||
|
|
||||||
|
---
|
||||||
|
doc/configuration.txt | 26 ++++++-
|
||||||
|
include/common/standard.h | 25 ++++++-
|
||||||
|
include/proto/client.h | 1 +
|
||||||
|
include/types/buffers.h | 20 ++---
|
||||||
|
include/types/protocols.h | 1 +
|
||||||
|
src/cfgparse.c | 15 +++-
|
||||||
|
src/client.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/proto_http.c | 4 +-
|
||||||
|
src/session.c | 7 ++
|
||||||
|
src/standard.c | 9 ++-
|
||||||
|
10 files changed, 275 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
Index: haproxy-1.4.25/doc/configuration.txt
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/doc/configuration.txt
|
||||||
|
+++ haproxy-1.4.25/doc/configuration.txt
|
||||||
|
@@ -1343,6 +1343,7 @@ bind [<address>]:<port_range> [, ...] tr
|
||||||
|
bind [<address>]:<port_range> [, ...] id <id>
|
||||||
|
bind [<address>]:<port_range> [, ...] name <name>
|
||||||
|
bind [<address>]:<port_range> [, ...] defer-accept
|
||||||
|
+bind [<address>]:<port_range> [, ...] accept-proxy
|
||||||
|
Define one or several listening addresses and/or ports in a frontend.
|
||||||
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
|
no | yes | yes | no
|
||||||
|
@@ -1423,6 +1424,19 @@ bind [<address>]:<port_range> [, ...] de
|
||||||
|
with front firewalls which would see an established
|
||||||
|
connection while the proxy will only see it in SYN_RECV.
|
||||||
|
|
||||||
|
+ accept-proxy is an optional keyword which enforces use of the PROXY
|
||||||
|
+ protocol over any connection accepted by this listener. The
|
||||||
|
+ PROXY protocol dictates the layer 3/4 addresses of the
|
||||||
|
+ incoming connection to be used everywhere an address is used,
|
||||||
|
+ with the only exception of "tcp-request connection" rules
|
||||||
|
+ which will only see the real connection address. Logs will
|
||||||
|
+ reflect the addresses indicated in the protocol, unless it is
|
||||||
|
+ violated, in which case the real address will still be used.
|
||||||
|
+ This keyword combined with support from external components
|
||||||
|
+ can be used as an efficient and reliable alternative to the
|
||||||
|
+ X-Forwarded-For mechanism which is not always reliable and
|
||||||
|
+ not even always usable.
|
||||||
|
+
|
||||||
|
It is possible to specify a list of address:port combinations delimited by
|
||||||
|
commas. The frontend will then listen on all of these addresses. There is no
|
||||||
|
fixed limit to the number of addresses and ports which can be listened on in
|
||||||
|
@@ -1433,8 +1447,10 @@ bind [<address>]:<port_range> [, ...] de
|
||||||
|
listen http_proxy
|
||||||
|
bind :80,:443
|
||||||
|
bind 10.0.0.1:10080,10.0.0.1:10443
|
||||||
|
+ bind 127.0.0.1:8443 accept-proxy
|
||||||
|
|
||||||
|
- See also : "source".
|
||||||
|
+ See also : "source", "option forwardfor" and the PROXY protocol
|
||||||
|
+ documentation.
|
||||||
|
|
||||||
|
|
||||||
|
bind-process [ all | odd | even | <number 1-32> ] ...
|
||||||
|
@@ -7257,7 +7273,9 @@ marked with a star ('*') after the field
|
||||||
|
|
||||||
|
Detailed fields description :
|
||||||
|
- "client_ip" is the IP address of the client which initiated the TCP
|
||||||
|
- connection to haproxy.
|
||||||
|
+ connection to haproxy. Note that when the connection is accepted on a
|
||||||
|
+ socket configured with "accept-proxy" and the PROXY protocol is correctly
|
||||||
|
+ used, then the logs will reflect the forwarded connection's information.
|
||||||
|
|
||||||
|
- "client_port" is the TCP port of the client which initiated the connection.
|
||||||
|
|
||||||
|
@@ -7430,7 +7448,9 @@ with a star ('*') after the field name b
|
||||||
|
|
||||||
|
Detailed fields description :
|
||||||
|
- "client_ip" is the IP address of the client which initiated the TCP
|
||||||
|
- connection to haproxy.
|
||||||
|
+ connection to haproxy. Note that when the connection is accepted on a
|
||||||
|
+ socket configured with "accept-proxy" and the PROXY protocol is correctly
|
||||||
|
+ used, then the logs will reflect the forwarded connection's information.
|
||||||
|
|
||||||
|
- "client_port" is the TCP port of the client which initiated the connection.
|
||||||
|
|
||||||
|
Index: haproxy-1.4.25/include/common/standard.h
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/include/common/standard.h
|
||||||
|
+++ haproxy-1.4.25/include/common/standard.h
|
||||||
|
@@ -269,6 +269,28 @@ static inline unsigned int __strl2uic(co
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* This function reads an unsigned integer from the string pointed to by <s>
|
||||||
|
+ * and returns it. The <s> pointer is adjusted to point to the first unread
|
||||||
|
+ * char. The function automatically stops at <end>.
|
||||||
|
+ */
|
||||||
|
+static inline unsigned int __read_uint(const char **s, const char *end)
|
||||||
|
+{
|
||||||
|
+ const char *ptr = *s;
|
||||||
|
+ unsigned int i = 0;
|
||||||
|
+ unsigned int j, k;
|
||||||
|
+
|
||||||
|
+ while (ptr < end) {
|
||||||
|
+ j = *ptr - '0';
|
||||||
|
+ k = i * 10;
|
||||||
|
+ if (j > 9)
|
||||||
|
+ break;
|
||||||
|
+ i = k + j;
|
||||||
|
+ ptr++;
|
||||||
|
+ }
|
||||||
|
+ *s = ptr;
|
||||||
|
+ return i;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
extern unsigned int str2ui(const char *s);
|
||||||
|
extern unsigned int str2uic(const char *s);
|
||||||
|
extern unsigned int strl2ui(const char *s, int len);
|
||||||
|
@@ -276,9 +298,10 @@ extern unsigned int strl2uic(const char
|
||||||
|
extern int strl2ic(const char *s, int len);
|
||||||
|
extern int strl2irc(const char *s, int len, int *ret);
|
||||||
|
extern int strl2llrc(const char *s, int len, long long *ret);
|
||||||
|
+extern unsigned int read_uint(const char **s, const char *end);
|
||||||
|
unsigned int inetaddr_host(const char *text);
|
||||||
|
unsigned int inetaddr_host_lim(const char *text, const char *stop);
|
||||||
|
-unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret);
|
||||||
|
+unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret);
|
||||||
|
|
||||||
|
static inline char *cut_crlf(char *s) {
|
||||||
|
|
||||||
|
Index: haproxy-1.4.25/include/proto/client.h
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/include/proto/client.h
|
||||||
|
+++ haproxy-1.4.25/include/proto/client.h
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
#include <common/config.h>
|
||||||
|
#include <types/session.h>
|
||||||
|
|
||||||
|
+int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit);
|
||||||
|
void get_frt_addr(struct session *s);
|
||||||
|
int event_accept(int fd);
|
||||||
|
|
||||||
|
Index: haproxy-1.4.25/include/types/buffers.h
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/include/types/buffers.h
|
||||||
|
+++ haproxy-1.4.25/include/types/buffers.h
|
||||||
|
@@ -135,16 +135,16 @@
|
||||||
|
* The field is blanked by buffer_init() and only by analysers themselves
|
||||||
|
* afterwards.
|
||||||
|
*/
|
||||||
|
-#define AN_REQ_INSPECT 0x00000001 /* inspect request contents */
|
||||||
|
-#define AN_REQ_WAIT_HTTP 0x00000002 /* wait for an HTTP request */
|
||||||
|
-#define AN_REQ_HTTP_PROCESS_FE 0x00000004 /* process the frontend's HTTP part */
|
||||||
|
-#define AN_REQ_SWITCHING_RULES 0x00000008 /* apply the switching rules */
|
||||||
|
-#define AN_REQ_HTTP_PROCESS_BE 0x00000010 /* process the backend's HTTP part */
|
||||||
|
-#define AN_REQ_HTTP_INNER 0x00000020 /* inner processing of HTTP request */
|
||||||
|
-#define AN_REQ_HTTP_TARPIT 0x00000040 /* wait for end of HTTP tarpit */
|
||||||
|
-#define AN_REQ_HTTP_BODY 0x00000080 /* inspect HTTP request body */
|
||||||
|
-#define AN_REQ_STICKING_RULES 0x00000100 /* table persistence matching */
|
||||||
|
-/* unused: 0x200 */
|
||||||
|
+#define AN_REQ_DECODE_PROXY 0x00000001 /* take the proxied address from a 'PROXY' line */
|
||||||
|
+#define AN_REQ_INSPECT 0x00000002 /* inspect request contents */
|
||||||
|
+#define AN_REQ_WAIT_HTTP 0x00000004 /* wait for an HTTP request */
|
||||||
|
+#define AN_REQ_HTTP_PROCESS_FE 0x00000008 /* process the frontend's HTTP part */
|
||||||
|
+#define AN_REQ_SWITCHING_RULES 0x00000010 /* apply the switching rules */
|
||||||
|
+#define AN_REQ_HTTP_PROCESS_BE 0x00000020 /* process the backend's HTTP part */
|
||||||
|
+#define AN_REQ_HTTP_INNER 0x00000040 /* inner processing of HTTP request */
|
||||||
|
+#define AN_REQ_HTTP_TARPIT 0x00000080 /* wait for end of HTTP tarpit */
|
||||||
|
+#define AN_REQ_HTTP_BODY 0x00000100 /* inspect HTTP request body */
|
||||||
|
+#define AN_REQ_STICKING_RULES 0x00000200 /* table persistence matching */
|
||||||
|
#define AN_REQ_PRST_RDP_COOKIE 0x00000400 /* persistence on rdp cookie */
|
||||||
|
#define AN_REQ_HTTP_XFER_BODY 0x00000800 /* forward request body */
|
||||||
|
|
||||||
|
Index: haproxy-1.4.25/include/types/protocols.h
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/include/types/protocols.h
|
||||||
|
+++ haproxy-1.4.25/include/types/protocols.h
|
||||||
|
@@ -72,6 +72,7 @@
|
||||||
|
#define LI_O_FOREIGN 0x0002 /* permit listening on foreing addresses */
|
||||||
|
#define LI_O_NOQUICKACK 0x0004 /* disable quick ack of immediate data (linux) */
|
||||||
|
#define LI_O_DEF_ACCEPT 0x0008 /* wait up to 1 second for data before accepting */
|
||||||
|
+#define LI_O_ACC_PROXY 0x0010 /* find the proxied address in the first request line */
|
||||||
|
|
||||||
|
/* The listener will be directly referenced by the fdtab[] which holds its
|
||||||
|
* socket. The listener provides the protocol-specific accept() function to
|
||||||
|
Index: haproxy-1.4.25/src/cfgparse.c
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/src/cfgparse.c
|
||||||
|
+++ haproxy-1.4.25/src/cfgparse.c
|
||||||
|
@@ -1467,6 +1467,16 @@ int cfg_parse_listen(const char *file, i
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!strcmp(args[cur_arg], "accept-proxy")) { /* expect a 'PROXY' line first */
|
||||||
|
+ struct listener *l;
|
||||||
|
+
|
||||||
|
+ for (l = curproxy->listen; l != last_listen; l = l->next)
|
||||||
|
+ l->options |= LI_O_ACC_PROXY;
|
||||||
|
+
|
||||||
|
+ cur_arg ++;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!strcmp(args[cur_arg], "name")) {
|
||||||
|
struct listener *l;
|
||||||
|
|
||||||
|
@@ -1519,7 +1529,7 @@ int cfg_parse_listen(const char *file, i
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- Alert("parsing [%s:%d] : '%s' only supports the 'transparent', 'defer-accept', 'name', 'id', 'mss' and 'interface' options.\n",
|
||||||
|
+ Alert("parsing [%s:%d] : '%s' only supports the 'transparent', 'accept-proxy', 'defer-accept', 'name', 'id', 'mss' and 'interface' options.\n",
|
||||||
|
file, linenum, args[0]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
@@ -5743,6 +5753,9 @@ out_uri_auth_compat:
|
||||||
|
listener->handler = process_session;
|
||||||
|
listener->analysers |= curproxy->fe_req_ana;
|
||||||
|
|
||||||
|
+ if (listener->options & LI_O_ACC_PROXY)
|
||||||
|
+ listener->analysers |= AN_REQ_DECODE_PROXY;
|
||||||
|
+
|
||||||
|
/* smart accept mode is automatic in HTTP mode */
|
||||||
|
if ((curproxy->options2 & PR_O2_SMARTACC) ||
|
||||||
|
(curproxy->mode == PR_MODE_HTTP &&
|
||||||
|
Index: haproxy-1.4.25/src/client.c
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/src/client.c
|
||||||
|
+++ haproxy-1.4.25/src/client.c
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
|
||||||
|
#include <common/compat.h>
|
||||||
|
#include <common/config.h>
|
||||||
|
+#include <common/debug.h>
|
||||||
|
#include <common/time.h>
|
||||||
|
|
||||||
|
#include <types/global.h>
|
||||||
|
@@ -43,6 +44,191 @@
|
||||||
|
#include <proto/task.h>
|
||||||
|
|
||||||
|
|
||||||
|
+/* This analyser tries to fetch a line from the request buffer which looks like :
|
||||||
|
+ *
|
||||||
|
+ * "PROXY" <SP> PROTO <SP> SRC3 <SP> DST3 <SP> SRC4 <SP> <DST4> "\r\n"
|
||||||
|
+ *
|
||||||
|
+ * There must be exactly one space between each field. Fields are :
|
||||||
|
+ * - PROTO : layer 4 protocol, which must be "TCP4" or "TCP6".
|
||||||
|
+ * - SRC3 : layer 3 (eg: IP) source address in standard text form
|
||||||
|
+ * - DST3 : layer 3 (eg: IP) destination address in standard text form
|
||||||
|
+ * - SRC4 : layer 4 (eg: TCP port) source address in standard text form
|
||||||
|
+ * - DST4 : layer 4 (eg: TCP port) destination address in standard text form
|
||||||
|
+ *
|
||||||
|
+ * This line MUST be at the beginning of the buffer and MUST NOT wrap.
|
||||||
|
+ *
|
||||||
|
+ * Once the data is fetched, the values are set in the session's field and data
|
||||||
|
+ * are removed from the buffer. The function returns zero if it needs to wait
|
||||||
|
+ * for more data (max: timeout_client), or 1 if it has finished and removed itself.
|
||||||
|
+ */
|
||||||
|
+int frontend_decode_proxy_request(struct session *s, struct buffer *req, int an_bit)
|
||||||
|
+{
|
||||||
|
+ char *line = req->data;
|
||||||
|
+ char *end = req->data + req->l;
|
||||||
|
+ int len;
|
||||||
|
+
|
||||||
|
+ DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
|
||||||
|
+ now_ms, __FUNCTION__,
|
||||||
|
+ s,
|
||||||
|
+ req,
|
||||||
|
+ req->rex, req->wex,
|
||||||
|
+ req->flags,
|
||||||
|
+ req->l,
|
||||||
|
+ req->analysers);
|
||||||
|
+
|
||||||
|
+ if (req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT))
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ len = MIN(req->l, 6);
|
||||||
|
+ if (!len)
|
||||||
|
+ goto missing;
|
||||||
|
+
|
||||||
|
+ /* Decode a possible proxy request, fail early if it does not match */
|
||||||
|
+ if (strncmp(line, "PROXY ", len) != 0)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ line += 6;
|
||||||
|
+ if (req->l < 18) /* shortest possible line */
|
||||||
|
+ goto missing;
|
||||||
|
+
|
||||||
|
+ if (!memcmp(line, "TCP4 ", 5) != 0) {
|
||||||
|
+ u32 src3, dst3, sport, dport;
|
||||||
|
+
|
||||||
|
+ line += 5;
|
||||||
|
+
|
||||||
|
+ src3 = inetaddr_host_lim_ret(line, end, &line);
|
||||||
|
+ if (line == end)
|
||||||
|
+ goto missing;
|
||||||
|
+ if (*line++ != ' ')
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ dst3 = inetaddr_host_lim_ret(line, end, &line);
|
||||||
|
+ if (line == end)
|
||||||
|
+ goto missing;
|
||||||
|
+ if (*line++ != ' ')
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ sport = read_uint((const char **)&line, end);
|
||||||
|
+ if (line == end)
|
||||||
|
+ goto missing;
|
||||||
|
+ if (*line++ != ' ')
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ dport = read_uint((const char **)&line, end);
|
||||||
|
+ if (line > end - 2)
|
||||||
|
+ goto missing;
|
||||||
|
+ if (*line++ != '\r')
|
||||||
|
+ goto fail;
|
||||||
|
+ if (*line++ != '\n')
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ /* update the session's addresses and mark them set */
|
||||||
|
+ ((struct sockaddr_in *)&s->cli_addr)->sin_family = AF_INET;
|
||||||
|
+ ((struct sockaddr_in *)&s->cli_addr)->sin_addr.s_addr = htonl(src3);
|
||||||
|
+ ((struct sockaddr_in *)&s->cli_addr)->sin_port = htons(sport);
|
||||||
|
+
|
||||||
|
+ ((struct sockaddr_in *)&s->frt_addr)->sin_family = AF_INET;
|
||||||
|
+ ((struct sockaddr_in *)&s->frt_addr)->sin_addr.s_addr = htonl(dst3);
|
||||||
|
+ ((struct sockaddr_in *)&s->frt_addr)->sin_port = htons(dport);
|
||||||
|
+ s->flags |= SN_FRT_ADDR_SET;
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+ else if (!memcmp(line, "TCP6 ", 5) != 0) {
|
||||||
|
+ u32 sport, dport;
|
||||||
|
+ char *src_s;
|
||||||
|
+ char *dst_s, *sport_s, *dport_s;
|
||||||
|
+ struct in6_addr src3, dst3;
|
||||||
|
+
|
||||||
|
+ line+=5;
|
||||||
|
+
|
||||||
|
+ src_s = line;
|
||||||
|
+ dst_s = sport_s = dport_s = NULL;
|
||||||
|
+ while (1) {
|
||||||
|
+ if (line > end - 2) {
|
||||||
|
+ goto missing;
|
||||||
|
+ }
|
||||||
|
+ else if (*line == '\r') {
|
||||||
|
+ *line = 0;
|
||||||
|
+ line++;
|
||||||
|
+ if (*line++ != '\n')
|
||||||
|
+ goto fail;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*line == ' ') {
|
||||||
|
+ *line = 0;
|
||||||
|
+ if (!dst_s)
|
||||||
|
+ dst_s = line+1;
|
||||||
|
+ else if (!sport_s)
|
||||||
|
+ sport_s = line+1;
|
||||||
|
+ else if (!dport_s)
|
||||||
|
+ dport_s = line+1;
|
||||||
|
+ }
|
||||||
|
+ line++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!dst_s || !sport_s || !dport_s)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ sport = read_uint((const char **)&sport_s,dport_s-1);
|
||||||
|
+ if ( *sport_s != 0 )
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ dport = read_uint((const char **)&dport_s,line-2);
|
||||||
|
+ if ( *dport_s != 0 )
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ if (inet_pton(AF_INET6, src_s, (void *)&src3) != 1)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ if (inet_pton(AF_INET6, dst_s, (void *)&dst3) != 1)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
+ /* update the session's addresses and mark them set */
|
||||||
|
+ ((struct sockaddr_in6 *)&s->cli_addr)->sin6_family = AF_INET6;
|
||||||
|
+ memcpy(&((struct sockaddr_in6 *)&s->cli_addr)->sin6_addr, &src3, sizeof(struct in6_addr));
|
||||||
|
+ ((struct sockaddr_in6 *)&s->cli_addr)->sin6_port = htons(sport);
|
||||||
|
+
|
||||||
|
+ ((struct sockaddr_in6 *)&s->frt_addr)->sin6_family = AF_INET6;
|
||||||
|
+ memcpy(&((struct sockaddr_in6 *)&s->frt_addr)->sin6_addr, &dst3, sizeof(struct in6_addr));
|
||||||
|
+ ((struct sockaddr_in6 *)&s->frt_addr)->sin6_port = htons(dport);
|
||||||
|
+ s->flags |= SN_FRT_ADDR_SET;
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* remove the PROXY line from the request */
|
||||||
|
+ len = line - req->data;
|
||||||
|
+ buffer_replace2(req, req->data, line, NULL, 0);
|
||||||
|
+ req->total -= len; /* don't count the header line */
|
||||||
|
+
|
||||||
|
+ req->analysers &= ~an_bit;
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ missing:
|
||||||
|
+ if (!(req->flags & (BF_SHUTR|BF_FULL))) {
|
||||||
|
+ buffer_dont_connect(s->req);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ /* missing data and buffer is either full or shutdown => fail */
|
||||||
|
+
|
||||||
|
+ fail:
|
||||||
|
+ buffer_abort(req);
|
||||||
|
+ buffer_abort(s->rep);
|
||||||
|
+ req->analysers = 0;
|
||||||
|
+
|
||||||
|
+ s->fe->counters.failed_req++;
|
||||||
|
+ if (s->listener->counters)
|
||||||
|
+ s->listener->counters->failed_req++;
|
||||||
|
+
|
||||||
|
+ if (!(s->flags & SN_ERR_MASK))
|
||||||
|
+ s->flags |= SN_ERR_PRXCOND;
|
||||||
|
+ if (!(s->flags & SN_FINST_MASK))
|
||||||
|
+ s->flags |= SN_FINST_R;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Retrieves the original destination address used by the client, and sets the
|
||||||
|
* SN_FRT_ADDR_SET flag.
|
||||||
|
*/
|
||||||
|
Index: haproxy-1.4.25/src/proto_http.c
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/src/proto_http.c
|
||||||
|
+++ haproxy-1.4.25/src/proto_http.c
|
||||||
|
@@ -4209,7 +4209,8 @@ void http_end_txn_clean_session(struct s
|
||||||
|
if (s->rep->lr >= s->rep->data + s->rep->size)
|
||||||
|
s->rep->lr -= s->req->size;
|
||||||
|
|
||||||
|
- s->req->analysers |= s->fe->fe_req_ana;
|
||||||
|
+ s->req->analysers = s->fe->fe_req_ana;
|
||||||
|
+ s->req->analysers &= ~AN_REQ_DECODE_PROXY;
|
||||||
|
s->rep->analysers = 0;
|
||||||
|
|
||||||
|
http_silent_debug(__LINE__, s);
|
||||||
|
@@ -7807,7 +7808,6 @@ void http_reset_txn(struct session *s)
|
||||||
|
http_init_txn(s);
|
||||||
|
|
||||||
|
s->be = s->fe;
|
||||||
|
- s->req->analysers = s->listener->analysers;
|
||||||
|
s->logs.logwait = s->fe->to_log;
|
||||||
|
s->srv = s->prev_srv = s->srv_conn = NULL;
|
||||||
|
/* re-init store persistence */
|
||||||
|
Index: haproxy-1.4.25/src/session.c
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/src/session.c
|
||||||
|
+++ haproxy-1.4.25/src/session.c
|
||||||
|
@@ -34,6 +34,7 @@
|
||||||
|
#include <proto/proxy.h>
|
||||||
|
#include <proto/queue.h>
|
||||||
|
#include <proto/server.h>
|
||||||
|
+#include <proto/client.h>
|
||||||
|
#include <proto/stick_table.h>
|
||||||
|
#include <proto/stream_interface.h>
|
||||||
|
#include <proto/stream_sock.h>
|
||||||
|
@@ -1083,6 +1084,12 @@ resync_stream_interface:
|
||||||
|
while (ana_list && max_loops--) {
|
||||||
|
/* Warning! ensure that analysers are always placed in ascending order! */
|
||||||
|
|
||||||
|
+ if (ana_list & AN_REQ_DECODE_PROXY) {
|
||||||
|
+ if (!frontend_decode_proxy_request(s, s->req, AN_REQ_DECODE_PROXY))
|
||||||
|
+ break;
|
||||||
|
+ UPDATE_ANALYSERS(s->req->analysers, ana_list, ana_back, AN_REQ_DECODE_PROXY);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (ana_list & AN_REQ_INSPECT) {
|
||||||
|
if (!tcp_inspect_request(s, s->req, AN_REQ_INSPECT))
|
||||||
|
break;
|
||||||
|
Index: haproxy-1.4.25/src/standard.c
|
||||||
|
===================================================================
|
||||||
|
--- haproxy-1.4.25.orig/src/standard.c
|
||||||
|
+++ haproxy-1.4.25/src/standard.c
|
||||||
|
@@ -569,6 +569,11 @@ unsigned int strl2uic(const char *s, int
|
||||||
|
return __strl2uic(s, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
+unsigned int read_uint(const char **s, const char *end)
|
||||||
|
+{
|
||||||
|
+ return __read_uint(s, end);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This one is 7 times faster than strtol() on athlon with checks.
|
||||||
|
* It returns the value of the number composed of all valid digits read,
|
||||||
|
* and can process negative numbers too.
|
||||||
|
@@ -993,12 +998,12 @@ unsigned int inetaddr_host_lim(const cha
|
||||||
|
* Idem except the pointer to first unparsed byte is returned into <ret> which
|
||||||
|
* must not be NULL.
|
||||||
|
*/
|
||||||
|
-unsigned int inetaddr_host_lim_ret(const char *text, char *stop, const char **ret)
|
||||||
|
+unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret)
|
||||||
|
{
|
||||||
|
const unsigned int ascii_zero = ('0' << 24) | ('0' << 16) | ('0' << 8) | '0';
|
||||||
|
register unsigned int dig100, dig10, dig1;
|
||||||
|
int s;
|
||||||
|
- const char *p, *d;
|
||||||
|
+ char *p, *d;
|
||||||
|
|
||||||
|
dig1 = dig10 = dig100 = ascii_zero;
|
||||||
|
s = 24;
|
Loading…
Reference in a new issue