Index: nginx-1.4.7/auto/modules
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/auto/modules
|
|
+++ nginx-1.4.7/auto/modules
|
|
@@ -297,6 +297,10 @@ if [ $HTTP_SSL = YES ]; then
|
|
HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS"
|
|
fi
|
|
|
|
+if [ $PROXY_PROTOCOL = YES ]; then
|
|
+ have=NGX_PROXY_PROTOCOL . auto/have
|
|
+fi
|
|
+
|
|
if [ $HTTP_PROXY = YES ]; then
|
|
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
|
|
#USE_MD5=YES
|
|
Index: nginx-1.4.7/auto/options
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/auto/options
|
|
+++ nginx-1.4.7/auto/options
|
|
@@ -47,6 +47,8 @@ USE_THREADS=NO
|
|
NGX_FILE_AIO=NO
|
|
NGX_IPV6=NO
|
|
|
|
+PROXY_PROTOCOL=NO
|
|
+
|
|
HTTP=YES
|
|
|
|
NGX_HTTP_LOG_PATH=
|
|
@@ -192,6 +194,8 @@ do
|
|
--with-file-aio) NGX_FILE_AIO=YES ;;
|
|
--with-ipv6) NGX_IPV6=YES ;;
|
|
|
|
+ --with-proxy-protocol) PROXY_PROTOCOL=YES ;;
|
|
+
|
|
--without-http) HTTP=NO ;;
|
|
--without-http-cache) HTTP_CACHE=NO ;;
|
|
|
|
@@ -350,6 +354,8 @@ cat << END
|
|
--with-file-aio enable file AIO support
|
|
--with-ipv6 enable IPv6 support
|
|
|
|
+ --with-proxy-protocol enable proxy protocol support
|
|
+
|
|
--with-http_ssl_module enable ngx_http_ssl_module
|
|
--with-http_spdy_module enable ngx_http_spdy_module
|
|
--with-http_realip_module enable ngx_http_realip_module
|
|
Index: nginx-1.4.7/auto/sources
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/auto/sources
|
|
+++ nginx-1.4.7/auto/sources
|
|
@@ -36,7 +36,8 @@ CORE_DEPS="src/core/nginx.h \
|
|
src/core/ngx_conf_file.h \
|
|
src/core/ngx_resolver.h \
|
|
src/core/ngx_open_file_cache.h \
|
|
- src/core/ngx_crypt.h"
|
|
+ src/core/ngx_crypt.h \
|
|
+ src/core/ngx_proxy_protocol.h"
|
|
|
|
|
|
CORE_SRCS="src/core/nginx.c \
|
|
@@ -67,7 +68,8 @@ CORE_SRCS="src/core/nginx.c \
|
|
src/core/ngx_conf_file.c \
|
|
src/core/ngx_resolver.c \
|
|
src/core/ngx_open_file_cache.c \
|
|
- src/core/ngx_crypt.c"
|
|
+ src/core/ngx_crypt.c \
|
|
+ src/core/ngx_proxy_protocol.c"
|
|
|
|
|
|
REGEX_MODULE=ngx_regex_module
|
|
Index: nginx-1.4.7/src/core/ngx_connection.h
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/core/ngx_connection.h
|
|
+++ nginx-1.4.7/src/core/ngx_connection.h
|
|
@@ -63,6 +63,10 @@ struct ngx_listening_s {
|
|
unsigned shared:1; /* shared between threads or processes */
|
|
unsigned addr_ntop:1;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ unsigned accept_proxy_protocol:2; /* proxy_protocol flag */
|
|
+#endif
|
|
+
|
|
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
|
unsigned ipv6only:1;
|
|
#endif
|
|
@@ -148,6 +152,10 @@ struct ngx_connection_s {
|
|
|
|
ngx_uint_t requests;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ ngx_uint_t proxy_protocol;
|
|
+#endif
|
|
+
|
|
unsigned buffered:8;
|
|
|
|
unsigned log_error:3; /* ngx_connection_log_error_e */
|
|
Index: nginx-1.4.7/src/core/ngx_core.h
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/core/ngx_core.h
|
|
+++ nginx-1.4.7/src/core/ngx_core.h
|
|
@@ -77,6 +77,9 @@ typedef void (*ngx_connection_handler_pt
|
|
#include <ngx_open_file_cache.h>
|
|
#include <ngx_os.h>
|
|
#include <ngx_connection.h>
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+#include <ngx_proxy_protocol.h>
|
|
+#endif
|
|
|
|
|
|
#define LF (u_char) 10
|
|
Index: nginx-1.4.7/src/core/ngx_proxy_protocol.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ nginx-1.4.7/src/core/ngx_proxy_protocol.c
|
|
@@ -0,0 +1,430 @@
|
|
+
|
|
+/*
|
|
+ * Copyright (C) Baptiste Assmann
|
|
+ * Copyright (C) Exceliance
|
|
+ */
|
|
+
|
|
+
|
|
+#include <ngx_config.h>
|
|
+#include <ngx_core.h>
|
|
+#include <ngx_event.h>
|
|
+
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+
|
|
+int
|
|
+ngx_recv_proxy_protocol(ngx_connection_t *c, u_char *buf, ssize_t n)
|
|
+{
|
|
+ u_char *end, *p, *t;
|
|
+ size_t len;
|
|
+ ssize_t s;
|
|
+ int step = 0;
|
|
+ ngx_proxy_protocol_t pp;
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "processing proxy protocol");
|
|
+
|
|
+ /* 16 is the minimal length of the proxy protocol string */
|
|
+ if (n < 18) {
|
|
+ step = 1;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ s = n;
|
|
+ end = memchr(buf, '\n', n);
|
|
+ if (end == NULL) {
|
|
+ step = 2;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ p = buf;
|
|
+ if (memcmp(p, "PROXY ", 6) != 0) {
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "incorrect proxy protocol header string");
|
|
+ step = 3;
|
|
+ goto fail;
|
|
+ }
|
|
+ p += 6;
|
|
+ s -= 6;
|
|
+ if (s <= 0) {
|
|
+ step = 4;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ ngx_memzero(&pp, sizeof(ngx_proxy_protocol_t));
|
|
+
|
|
+ if (memcmp(p, "TCP4 ", 5) == 0) {
|
|
+ struct sockaddr_in *sin_src;
|
|
+ struct sockaddr_in *sin_dst;
|
|
+
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP4;
|
|
+ pp.pp_src3.ss_family = AF_INET;
|
|
+ pp.pp_dst3.ss_family = AF_INET;
|
|
+ sin_src = (struct sockaddr_in *) &pp.pp_src3;
|
|
+ sin_dst = (struct sockaddr_in *) &pp.pp_dst3;
|
|
+
|
|
+ p += 5;
|
|
+ s -= 5;
|
|
+ if (s <= 0) {
|
|
+ step = 5;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l3 source address */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 6;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ if ((sin_src->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
|
|
+ step = 7;
|
|
+ goto fail;
|
|
+ }
|
|
+ pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
|
|
+ ngx_memcpy(pp.pp_src3_text.data, p, len);
|
|
+ pp.pp_src3_text.len = len;
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 8;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l3 destination address */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 9;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ if ((sin_dst->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
|
|
+ step = 10;
|
|
+ goto fail;
|
|
+ }
|
|
+// FIXME pointer shift ???
|
|
+ pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
|
|
+ ngx_memcpy(pp.pp_dst3_text.data, p, len);
|
|
+ pp.pp_dst3_text.len = len;
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 11;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l4 source port */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 12;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ pp.pp_src4 = ngx_atoi(p, len);
|
|
+ if ((pp.pp_src4 < 1024)
|
|
+ || (pp.pp_src4 > 65535)) {
|
|
+ step = 13;
|
|
+ goto fail;
|
|
+ }
|
|
+ sin_src->sin_port = htons(pp.pp_src4);
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 14;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l4 destination port */
|
|
+ if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
|
|
+ step = 15;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ pp.pp_dst4 = ngx_atoi(p, len);
|
|
+ if (pp.pp_dst4 > 65535) {
|
|
+ step = 16;
|
|
+ goto fail;
|
|
+ }
|
|
+ sin_dst->sin_port = htons(pp.pp_dst4);
|
|
+
|
|
+ if (p[len + 1] != '\n') {
|
|
+ step = 17;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ p += (len + 2);
|
|
+ s -= (len + 2);
|
|
+
|
|
+
|
|
+ /* if we managed to get there, then we can safely replace the
|
|
+ * information in the connection structure
|
|
+ */
|
|
+
|
|
+ /* updating connection with source information provided by proxy protocol */
|
|
+ if (pp.pp_src3_text.len > c->addr_text.len) {
|
|
+ ngx_pfree(c->pool, c->addr_text.data);
|
|
+ c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
|
|
+ } else {
|
|
+ ngx_memzero(c->addr_text.data, c->addr_text.len);
|
|
+ }
|
|
+ ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
|
|
+ c->addr_text.len = pp.pp_src3_text.len;
|
|
+
|
|
+ ngx_pfree(c->pool, c->sockaddr);
|
|
+ c->socklen = NGX_SOCKADDRLEN;
|
|
+ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
|
|
+ ngx_memcpy(c->sockaddr, sin_src, c->socklen);
|
|
+
|
|
+ if (c->sockaddr->sa_family != AF_INET) {
|
|
+ ngx_pfree(c->pool, c->sockaddr);
|
|
+ c->socklen = NGX_SOCKADDRLEN;
|
|
+ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
|
|
+ } else {
|
|
+ ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in));
|
|
+ c->socklen = NGX_SOCKADDRLEN;
|
|
+ }
|
|
+ ngx_memcpy(c->sockaddr, sin_src, c->socklen);
|
|
+
|
|
+ /* updating connection with destination information provided by proxy protocol */
|
|
+ ngx_pfree(c->pool, c->local_sockaddr);
|
|
+ c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
|
|
+ ngx_memcpy(c->local_sockaddr, sin_dst, NGX_SOCKADDRLEN);
|
|
+
|
|
+ }
|
|
+
|
|
+#if (NGX_HAVE_INET6)
|
|
+
|
|
+ else if (memcmp(p, "TCP6 ", 5) == 0) {
|
|
+
|
|
+ struct sockaddr_in6 *sin6_src;
|
|
+ struct sockaddr_in6 *sin6_dst;
|
|
+
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP6;
|
|
+ pp.pp_src3.ss_family = AF_INET6;
|
|
+ pp.pp_dst3.ss_family = AF_INET6;
|
|
+ sin6_src = (struct sockaddr_in6 *) &pp.pp_src3;
|
|
+ sin6_dst = (struct sockaddr_in6 *) &pp.pp_dst3;
|
|
+
|
|
+ p += 5;
|
|
+ s -= 5;
|
|
+ if (s <= 0) {
|
|
+ step = 18;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l3 source address */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 19;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ if (ngx_inet6_addr(p, len, sin6_src->sin6_addr.s6_addr) != NGX_OK) {
|
|
+ step = 20;
|
|
+ goto fail;
|
|
+ }
|
|
+ pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
|
|
+ ngx_memcpy(pp.pp_src3_text.data, p, len);
|
|
+ pp.pp_src3_text.len = len;
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 21;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l3 destination address */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 22;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ if (ngx_inet6_addr(p, len, sin6_dst->sin6_addr.s6_addr) != NGX_OK) {
|
|
+ step = 23;
|
|
+ goto fail;
|
|
+ }
|
|
+ pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
|
|
+ ngx_memcpy(pp.pp_dst3_text.data, p, len);
|
|
+ pp.pp_dst3_text.len = len;
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 24;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l4 source port */
|
|
+ if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
|
|
+ step = 25;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ pp.pp_src4 = ngx_atoi(p, len);
|
|
+ if ((pp.pp_src4 < 1024)
|
|
+ || (pp.pp_src4 > 65535)) {
|
|
+ step = 26;
|
|
+ goto fail;
|
|
+ }
|
|
+ sin6_src->sin6_port = htons(pp.pp_src4);
|
|
+
|
|
+ p += (len + 1);
|
|
+ s -= (len + 1);
|
|
+ if (s <= 0) {
|
|
+ step = 27;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* l4 destination port */
|
|
+ if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
|
|
+ step = 28;
|
|
+ goto fail;
|
|
+ }
|
|
+ len = t - p;
|
|
+ pp.pp_dst4 = ngx_atoi(p, len);
|
|
+ if (pp.pp_dst4 > 65535) {
|
|
+ step = 29;
|
|
+ goto fail;
|
|
+ }
|
|
+ sin6_dst->sin6_port = htons(pp.pp_dst4);
|
|
+
|
|
+ if (p[len + 1] != '\n') {
|
|
+ step = 30;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ p += (len + 2);
|
|
+ s -= (len + 2);
|
|
+
|
|
+ /* if we managed to get there, then we can safely replace the
|
|
+ * information in the connection structure
|
|
+ */
|
|
+
|
|
+ /* updating connection with source provided by proxy protocol */
|
|
+ if (pp.pp_src3_text.len > c->addr_text.len) {
|
|
+ ngx_pfree(c->pool, c->addr_text.data);
|
|
+ c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
|
|
+ } else {
|
|
+ ngx_memzero(c->addr_text.data, c->addr_text.len);
|
|
+ }
|
|
+ ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
|
|
+ c->addr_text.len = pp.pp_src3_text.len;
|
|
+
|
|
+ ngx_pfree(c->pool, c->sockaddr);
|
|
+ c->socklen = NGX_SOCKADDRLEN;
|
|
+ c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
|
|
+ ngx_memcpy(c->sockaddr, sin6_src, c->socklen);
|
|
+
|
|
+ /* updating connection with destination provided by proxy protocol */
|
|
+ if (c->sockaddr->sa_family != AF_INET6) {
|
|
+ ngx_pfree(c->pool, c->local_sockaddr);
|
|
+ c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
|
|
+ } else {
|
|
+ ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in6));
|
|
+ c->socklen = NGX_SOCKADDRLEN;
|
|
+ }
|
|
+// ngx_memcpy(c->local_sockaddr, sin6_dst, NGX_SOCKADDRLEN);
|
|
+//FIXME must be finished here
|
|
+
|
|
+ }
|
|
+
|
|
+#endif
|
|
+
|
|
+ else {
|
|
+ step = 31;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ ngx_print_proxy_protocol(&pp, c->log);
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "proxy_protocol, asking to remove %z chars",
|
|
+ end + 1 - buf);
|
|
+
|
|
+ return (end + 1 - buf);
|
|
+
|
|
+fail:
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
+ "proxy_protocol error at step: %d", step);
|
|
+
|
|
+ return 0;
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
+void
|
|
+ngx_print_proxy_protocol(ngx_proxy_protocol_t *p, ngx_log_t *log)
|
|
+{
|
|
+ switch (p->pp_proto) {
|
|
+ case NGX_PP_PROTO_TCP4:
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, proto: TCP4");
|
|
+ break;
|
|
+ case NGX_PP_PROTO_TCP6:
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, proto: TCP6");
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, string length: %d", ngx_proxy_protocol_string_length(p));
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, src3: %s, %d", p->pp_src3_text.data, p->pp_src3_text.len);
|
|
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, dst3: %s, %d", p->pp_dst3_text.data, p->pp_dst3_text.len);
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, src4: %d", p->pp_src4);
|
|
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
|
|
+ "proxy_protocol, dst4: %d", p->pp_dst4);
|
|
+}
|
|
+
|
|
+
|
|
+int
|
|
+ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *p)
|
|
+{
|
|
+ int len = 0;
|
|
+
|
|
+ /* 'PROXY ' */
|
|
+ len += (sizeof("PROXY ") - 1);
|
|
+
|
|
+ /* protocol version (TCP4 or TCP6) + space */
|
|
+ len += (sizeof("TCP0 ") - 1);
|
|
+
|
|
+ /* src3 + space */
|
|
+ len += p->pp_src3_text.len;
|
|
+ len += 1;
|
|
+
|
|
+ /* dst3 + space */
|
|
+ len += p->pp_dst3_text.len;
|
|
+ len += 1;
|
|
+
|
|
+ /* src4 */
|
|
+ if (p->pp_src4 < 10000)
|
|
+ /* 4 digits + 1 space */
|
|
+ len += (sizeof("0000 ") - 1);
|
|
+ else
|
|
+ /* 5 digits + 1 space */
|
|
+ len += (sizeof("00000 ") - 1);
|
|
+
|
|
+ /* dst4 */
|
|
+ if (p->pp_dst4 >= 10000)
|
|
+ /* 5 digits */
|
|
+ len += (sizeof("00000 ") - 1);
|
|
+ else if (p->pp_dst4 >= 1000)
|
|
+ /* 4 digits */
|
|
+ len += (sizeof("0000 ") - 1);
|
|
+ else if (p->pp_dst4 >= 100)
|
|
+ /* 3 digits */
|
|
+ len += (sizeof("000 ") - 1);
|
|
+ else if (p->pp_dst4 >= 10)
|
|
+ /* 2 digits */
|
|
+ len += (sizeof("00 ") - 1);
|
|
+ else
|
|
+ /* 1 digit */
|
|
+ len += (sizeof("0 ") - 1);
|
|
+
|
|
+ /* CRLF */
|
|
+ len += (sizeof(CRLF) - 1);
|
|
+
|
|
+ return len - 1;
|
|
+}
|
|
+
|
|
+#endif
|
|
Index: nginx-1.4.7/src/core/ngx_proxy_protocol.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ nginx-1.4.7/src/core/ngx_proxy_protocol.h
|
|
@@ -0,0 +1,45 @@
|
|
+
|
|
+/*
|
|
+ * Copyright (C) Baptiste Assmann
|
|
+ * Copyright (C) Exceliance
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef _NGX_PROXY_PROTOCOL_H_INCLUDED_
|
|
+#define _NGX_PROXY_PROTOCOL_H_INCLUDED_
|
|
+
|
|
+
|
|
+#include <ngx_config.h>
|
|
+#include <ngx_core.h>
|
|
+
|
|
+
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+
|
|
+typedef struct ngx_proxy_protocol_s ngx_proxy_protocol_t;
|
|
+
|
|
+typedef enum {
|
|
+ NGX_PP_PROTO_TCP4 = 1,
|
|
+ NGX_PP_PROTO_TCP6
|
|
+} ngx_pp_proto;
|
|
+
|
|
+
|
|
+struct ngx_proxy_protocol_s {
|
|
+ unsigned int pp_proto; /* proxy protocol related information */
|
|
+ struct sockaddr_storage pp_src3;
|
|
+ ngx_str_t pp_src3_text;
|
|
+ struct sockaddr_storage pp_dst3;
|
|
+ ngx_str_t pp_dst3_text;
|
|
+ unsigned int pp_src4;
|
|
+ unsigned int pp_dst4;
|
|
+};
|
|
+
|
|
+
|
|
+int ngx_recv_proxy_protocol(ngx_connection_t *, u_char *, ssize_t);
|
|
+void ngx_print_proxy_protocol(ngx_proxy_protocol_t *, ngx_log_t *);
|
|
+int ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *);
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+#endif /* _NGX_CONNECTION_H_INCLUDED_ */
|
|
+
|
|
Index: nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/modules/ngx_http_proxy_module.c
|
|
+++ nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
|
|
@@ -8,7 +8,9 @@
|
|
#include <ngx_config.h>
|
|
#include <ngx_core.h>
|
|
#include <ngx_http.h>
|
|
-
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+#include <ngx_proxy_protocol.h>
|
|
+#endif
|
|
|
|
typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
|
|
|
|
@@ -365,6 +367,17 @@ static ngx_command_t ngx_http_proxy_com
|
|
offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf),
|
|
NULL },
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+
|
|
+ { ngx_string("send_proxy_protocol"),
|
|
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
|
+ ngx_conf_set_flag_slot,
|
|
+ NGX_HTTP_LOC_CONF_OFFSET,
|
|
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.send_proxy_protocol),
|
|
+ NULL },
|
|
+
|
|
+#endif
|
|
+
|
|
#if (NGX_HTTP_CACHE)
|
|
|
|
{ ngx_string("proxy_cache"),
|
|
@@ -2420,6 +2433,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
|
|
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
|
|
|
|
conf->upstream.intercept_errors = NGX_CONF_UNSET;
|
|
+
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ conf->upstream.send_proxy_protocol = NGX_CONF_UNSET;
|
|
+#endif
|
|
+
|
|
#if (NGX_HTTP_SSL)
|
|
conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
|
|
#endif
|
|
@@ -2695,6 +2713,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
|
|
ngx_conf_merge_value(conf->upstream.intercept_errors,
|
|
prev->upstream.intercept_errors, 0);
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ ngx_conf_merge_value(conf->upstream.send_proxy_protocol,
|
|
+ prev->upstream.send_proxy_protocol, 0);
|
|
+#endif
|
|
+
|
|
#if (NGX_HTTP_SSL)
|
|
ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
|
|
prev->upstream.ssl_session_reuse, 1);
|
|
Index: nginx-1.4.7/src/http/ngx_http.c
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http.c
|
|
+++ nginx-1.4.7/src/http/ngx_http.c
|
|
@@ -1228,6 +1228,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
|
|
#if (NGX_HTTP_SPDY)
|
|
ngx_uint_t spdy;
|
|
#endif
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ ngx_uint_t accept_proxy_protocol;
|
|
+#endif
|
|
|
|
/*
|
|
* we cannot compare whole sockaddr struct's as kernel
|
|
@@ -1283,6 +1286,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
|
|
#if (NGX_HTTP_SPDY)
|
|
spdy = lsopt->spdy || addr[i].opt.spdy;
|
|
#endif
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ accept_proxy_protocol = lsopt->accept_proxy_protocol
|
|
+ || addr[i].opt.accept_proxy_protocol;
|
|
+#endif
|
|
|
|
if (lsopt->set) {
|
|
|
|
@@ -1316,6 +1323,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
|
|
#if (NGX_HTTP_SPDY)
|
|
addr[i].opt.spdy = spdy;
|
|
#endif
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ addr[i].opt.accept_proxy_protocol = accept_proxy_protocol;
|
|
+#endif
|
|
|
|
return NGX_OK;
|
|
}
|
|
@@ -1762,6 +1772,11 @@ ngx_http_add_listening(ngx_conf_t *cf, n
|
|
ls->pool_size = cscf->connection_pool_size;
|
|
ls->post_accept_timeout = cscf->client_header_timeout;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+// CLEANUP: ls->accept_proxy_protocol = cscf->accept_proxy_protocol;
|
|
+ ls->accept_proxy_protocol = addr->opt.accept_proxy_protocol;
|
|
+#endif
|
|
+
|
|
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
|
|
|
|
ls->logp = clcf->error_log;
|
|
@@ -1840,6 +1855,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h
|
|
#if (NGX_HTTP_SPDY)
|
|
addrs[i].conf.spdy = addr[i].opt.spdy;
|
|
#endif
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ addrs[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
|
|
+#endif
|
|
|
|
if (addr[i].hash.buckets == NULL
|
|
&& (addr[i].wc_head == NULL
|
|
@@ -1904,6 +1922,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_
|
|
#if (NGX_HTTP_SPDY)
|
|
addrs6[i].conf.spdy = addr[i].opt.spdy;
|
|
#endif
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ addrs6[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
|
|
+#endif
|
|
|
|
if (addr[i].hash.buckets == NULL
|
|
&& (addr[i].wc_head == NULL
|
|
Index: nginx-1.4.7/src/http/ngx_http_core_module.c
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http_core_module.c
|
|
+++ nginx-1.4.7/src/http/ngx_http_core_module.c
|
|
@@ -4090,6 +4090,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
|
|
continue;
|
|
}
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ if (ngx_strncmp(value[n].data, "accept_proxy_protocol=on", 24) == 0) {
|
|
+ lsopt.accept_proxy_protocol = 1;
|
|
+ lsopt.set = 1;
|
|
+ lsopt.bind = 1;
|
|
+ continue;
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
|
|
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
|
struct sockaddr *sa;
|
|
Index: nginx-1.4.7/src/http/ngx_http_core_module.h
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http_core_module.h
|
|
+++ nginx-1.4.7/src/http/ngx_http_core_module.h
|
|
@@ -78,6 +78,11 @@ typedef struct {
|
|
#if (NGX_HTTP_SPDY)
|
|
unsigned spdy:1;
|
|
#endif
|
|
+
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ unsigned accept_proxy_protocol:2;
|
|
+#endif
|
|
+
|
|
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
|
unsigned ipv6only:1;
|
|
#endif
|
|
@@ -234,6 +239,10 @@ struct ngx_http_addr_conf_s {
|
|
|
|
ngx_http_virtual_names_t *virtual_names;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ ngx_flag_t accept_proxy_protocol;
|
|
+#endif
|
|
+
|
|
#if (NGX_HTTP_SSL)
|
|
unsigned ssl:1;
|
|
#endif
|
|
Index: nginx-1.4.7/src/http/ngx_http_request.c
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http_request.c
|
|
+++ nginx-1.4.7/src/http/ngx_http_request.c
|
|
@@ -63,6 +63,9 @@ static void ngx_http_ssl_handshake(ngx_e
|
|
static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
|
|
#endif
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+static void ngx_http_proxy_protocol(ngx_event_t *rev);
|
|
+#endif
|
|
|
|
static char *ngx_http_client_errors[] = {
|
|
|
|
@@ -343,6 +346,14 @@ ngx_http_init_connection(ngx_connection_
|
|
}
|
|
#endif
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ {
|
|
+ if (hc->addr_conf->accept_proxy_protocol) {
|
|
+ rev->handler = ngx_http_proxy_protocol;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (rev->ready) {
|
|
/* the deferred accept(), rtsig, aio, iocp */
|
|
|
|
@@ -364,7 +375,6 @@ ngx_http_init_connection(ngx_connection_
|
|
}
|
|
}
|
|
|
|
-
|
|
static void
|
|
ngx_http_wait_request_handler(ngx_event_t *rev)
|
|
{
|
|
@@ -469,6 +479,12 @@ ngx_http_wait_request_handler(ngx_event_
|
|
}
|
|
|
|
rev->handler = ngx_http_process_request_line;
|
|
+
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ if (hc->addr_conf->accept_proxy_protocol)
|
|
+ rev->handler = ngx_http_proxy_protocol;
|
|
+#endif
|
|
+
|
|
ngx_http_process_request_line(rev);
|
|
}
|
|
|
|
@@ -582,6 +598,67 @@ ngx_http_create_request(ngx_connection_t
|
|
return r;
|
|
}
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+
|
|
+static void
|
|
+ngx_http_proxy_protocol(ngx_event_t *rev)
|
|
+{
|
|
+ ssize_t n;
|
|
+ size_t size = 1024;
|
|
+ u_char tmpbuf[size];
|
|
+ ngx_connection_t *c;
|
|
+ ngx_http_connection_t *hc;
|
|
+
|
|
+ c = rev->data;
|
|
+ hc = c->data;
|
|
+ rev->handler = ngx_http_wait_request_handler;
|
|
+
|
|
+#if (NGX_HTTP_SPDY)
|
|
+ {
|
|
+ if (hc->addr_conf->spdy) {
|
|
+ rev->handler = ngx_http_spdy_init;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+#if (NGX_HTTP_SSL)
|
|
+ {
|
|
+ if (hc->addr_conf->ssl) {
|
|
+ rev->handler = ngx_http_ssl_handshake;
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ n = recv(c->fd, tmpbuf, size, MSG_PEEK);
|
|
+
|
|
+ if ((n <= 0) && (c->listening)
|
|
+ && (hc->addr_conf->accept_proxy_protocol)
|
|
+ && (!c->proxy_protocol)) {
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
|
|
+ return;
|
|
+ }
|
|
+ if ((n > 0) && (c->listening)
|
|
+ && (hc->addr_conf->accept_proxy_protocol)
|
|
+ && (!c->proxy_protocol)) {
|
|
+ ssize_t m;
|
|
+ if (!(m = ngx_recv_proxy_protocol(c, tmpbuf, n))) {
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
|
|
+ ngx_http_close_connection(c);
|
|
+ return;
|
|
+ }
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required and found");
|
|
+
|
|
+ c->proxy_protocol = 1;
|
|
+
|
|
+ /* strip the proxy protocol string from the buffer */
|
|
+ recv(c->fd, tmpbuf, m, 0);
|
|
+ }
|
|
+
|
|
+ rev->handler(rev);
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
|
|
#if (NGX_HTTP_SSL)
|
|
|
|
@@ -1291,6 +1368,10 @@ ngx_http_read_request_header(ngx_http_re
|
|
c = r->connection;
|
|
rev = c->read;
|
|
|
|
+fprintf(stderr, "DEBUG: pos: %p, last: %p, start: %p, end: %p\n",
|
|
+ r->header_in->pos, r->header_in->last, r->header_in->start,
|
|
+ r->header_in->end);
|
|
+
|
|
n = r->header_in->last - r->header_in->pos;
|
|
|
|
if (n > 0) {
|
|
Index: nginx-1.4.7/src/http/ngx_http_upstream.c
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http_upstream.c
|
|
+++ nginx-1.4.7/src/http/ngx_http_upstream.c
|
|
@@ -31,6 +31,10 @@ static ngx_int_t ngx_http_upstream_reini
|
|
ngx_http_upstream_t *u);
|
|
static void ngx_http_upstream_send_request(ngx_http_request_t *r,
|
|
ngx_http_upstream_t *u);
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+static void ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r,
|
|
+ ngx_http_upstream_t *u);
|
|
+#endif
|
|
static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
|
ngx_http_upstream_t *u);
|
|
static void ngx_http_upstream_process_header(ngx_http_request_t *r,
|
|
@@ -1255,6 +1259,13 @@ ngx_http_upstream_connect(ngx_http_reque
|
|
|
|
u->request_sent = 0;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ if (u->conf->send_proxy_protocol && !(u->ssl && c->ssl == NULL)) {
|
|
+ ngx_http_upstream_send_proxy_protocol(r, u);
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (rc == NGX_AGAIN) {
|
|
ngx_add_timer(c->write, u->conf->connect_timeout);
|
|
return;
|
|
@@ -1498,6 +1509,228 @@ ngx_http_upstream_send_request(ngx_http_
|
|
}
|
|
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+
|
|
+static void
|
|
+ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|
+{
|
|
+ size_t len;
|
|
+ ngx_int_t rc;
|
|
+ ngx_connection_t *uc;
|
|
+ ngx_connection_t *cc;
|
|
+ ngx_chain_t *pp_string;
|
|
+ ngx_proxy_protocol_t pp;
|
|
+ ngx_buf_t *b;
|
|
+ char port[6];
|
|
+ u_char *addr;
|
|
+ struct sockaddr_storage sa_src;
|
|
+ struct sockaddr_storage sa_dst;
|
|
+ socklen_t addrlen = NGX_SOCKADDRLEN;
|
|
+ struct sockaddr_in *sin_src;
|
|
+ struct sockaddr_in *sin_dst;
|
|
+
|
|
+#if (NGX_HAVE_INET6)
|
|
+
|
|
+ struct sockaddr_in6 *sin6_src;
|
|
+ struct sockaddr_in6 *sin6_dst;
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+ uc = u->peer.connection;
|
|
+ cc = r->connection;
|
|
+
|
|
+ if ( !(u->conf->send_proxy_protocol) ) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
|
|
+ "http upstream send proxy protocol");
|
|
+
|
|
+ if (!u->request_sent && ngx_http_upstream_test_connect(uc) != NGX_OK) {
|
|
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ uc->log->action = "sending proxy protocol to upstream";
|
|
+
|
|
+ len = 0;
|
|
+
|
|
+ if (r->connection->proxy_protocol) {
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
|
|
+ "PP: got proxy-protocol from client connection");
|
|
+
|
|
+ switch (cc->sockaddr->sa_family) {
|
|
+
|
|
+#if (NGX_HAVE_INET6)
|
|
+
|
|
+ case AF_INET6:
|
|
+
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP6;
|
|
+ sin6_dst = (struct sockaddr_in6 *) cc->local_sockaddr;
|
|
+ sin6_src = (struct sockaddr_in6 *) cc->sockaddr;
|
|
+
|
|
+ break;
|
|
+
|
|
+#endif
|
|
+
|
|
+ default:
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP4;
|
|
+ sin_dst = (struct sockaddr_in *) cc->local_sockaddr;
|
|
+ sin_src = (struct sockaddr_in *) cc->sockaddr;
|
|
+
|
|
+ }
|
|
+
|
|
+ } else {
|
|
+
|
|
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
|
|
+ "PP: collecting information from socket fd");
|
|
+
|
|
+ getsockname(cc->fd, (struct sockaddr *) &sa_dst, &addrlen);
|
|
+
|
|
+ switch (sa_dst.ss_family) {
|
|
+
|
|
+#if (NGX_HAVE_INET6)
|
|
+
|
|
+ case AF_INET6:
|
|
+
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP6;
|
|
+ sin6_dst = (struct sockaddr_in6 *) &sa_dst;
|
|
+
|
|
+ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
|
|
+ sin6_src = (struct sockaddr_in6 *) &sa_src;
|
|
+
|
|
+ break;
|
|
+
|
|
+#endif
|
|
+
|
|
+ default:
|
|
+
|
|
+ pp.pp_proto = NGX_PP_PROTO_TCP4;
|
|
+ sin_dst = (struct sockaddr_in *) &sa_dst;
|
|
+ getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
|
|
+ sin_src = (struct sockaddr_in *) &sa_src;
|
|
+ }
|
|
+
|
|
+
|
|
+ }
|
|
+
|
|
+ switch (pp.pp_proto) {
|
|
+
|
|
+#if (NGX_HAVE_INET6)
|
|
+
|
|
+ case NGX_PP_PROTO_TCP6:
|
|
+
|
|
+ /* dst3 and dst4 */
|
|
+ addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
|
|
+ ngx_inet_ntop(AF_INET6, &sin6_dst->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
|
|
+ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
|
|
+ pp.pp_dst3_text.len = ngx_strlen(addr);
|
|
+ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
|
|
+ pp.pp_dst4 = htons(sin6_dst->sin6_port);
|
|
+
|
|
+ ngx_memzero(addr, NGX_INET6_ADDRSTRLEN);
|
|
+
|
|
+ /* src3 and src4 */
|
|
+ ngx_inet_ntop(AF_INET6, &sin6_src->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
|
|
+ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
|
|
+ pp.pp_src3_text.len = ngx_strlen(addr);
|
|
+ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
|
|
+ pp.pp_src4 = htons(sin6_src->sin6_port);
|
|
+
|
|
+ break;
|
|
+
|
|
+#endif
|
|
+
|
|
+ default:
|
|
+
|
|
+ /* dst3 and dst4 */
|
|
+ addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
|
|
+ ngx_inet_ntop(AF_INET, &sin_dst->sin_addr, addr, NGX_INET_ADDRSTRLEN);
|
|
+ pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
|
|
+ pp.pp_dst3_text.len = ngx_strlen(addr);
|
|
+ ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
|
|
+ pp.pp_dst4 = htons(sin_dst->sin_port);
|
|
+
|
|
+ ngx_memzero(addr, NGX_INET_ADDRSTRLEN);
|
|
+
|
|
+ /* src3 and src4 */
|
|
+ ngx_inet_ntop(AF_INET, &sin_src->sin_addr, addr, NGX_INET_ADDRSTRLEN);
|
|
+ pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
|
|
+ pp.pp_src3_text.len = ngx_strlen(addr);
|
|
+ ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
|
|
+ pp.pp_src4 = htons(sin_src->sin_port);
|
|
+
|
|
+ }
|
|
+
|
|
+ len += ngx_proxy_protocol_string_length(&pp);
|
|
+
|
|
+ ngx_print_proxy_protocol(&pp, uc->log);
|
|
+
|
|
+ b = ngx_create_temp_buf(uc->pool, len);
|
|
+ if (b == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ pp_string = ngx_alloc_chain_link(uc->pool);
|
|
+ if (pp_string == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ pp_string->buf = b;
|
|
+ pp_string->next = NULL;
|
|
+
|
|
+ b->last = ngx_cpymem(b->last, "PROXY ", sizeof("PROXY ") - 1);
|
|
+
|
|
+ switch (pp.pp_proto) {
|
|
+ case NGX_PP_PROTO_TCP4:
|
|
+ b->last = ngx_cpymem(b->last, "TCP4 ", sizeof("TCP4 ") - 1);
|
|
+ break;
|
|
+ case NGX_PP_PROTO_TCP6:
|
|
+ b->last = ngx_cpymem(b->last, "TCP6 ", sizeof("TCP6 ") - 1);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* src3 */
|
|
+ b->last = ngx_cpymem(b->last, pp.pp_src3_text.data, pp.pp_src3_text.len);
|
|
+ b->last = ngx_cpymem(b->last, " ", 1);
|
|
+
|
|
+ /* dst3 */
|
|
+ b->last = ngx_cpymem(b->last, pp.pp_dst3_text.data, pp.pp_dst3_text.len);
|
|
+ b->last = ngx_cpymem(b->last, " ", 1);
|
|
+
|
|
+ /* src4 */
|
|
+ ngx_memzero(port, 6);
|
|
+ sprintf(port,"%d", pp.pp_src4);
|
|
+ b->last = ngx_cpymem(b->last, port, strlen(port));
|
|
+ b->last = ngx_cpymem(b->last, " ", 1);
|
|
+
|
|
+ /* dst4 */
|
|
+ ngx_memzero(port, 6);
|
|
+ sprintf(port,"%d", pp.pp_dst4);
|
|
+ b->last = ngx_cpymem(b->last, port, strlen(port));
|
|
+
|
|
+ /* CRLF */
|
|
+ b->last = ngx_cpymem(b->last, CRLF, sizeof(CRLF) - 1);
|
|
+
|
|
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, uc->log, 0,
|
|
+ "http upstream send proxy protocol: %d -%*s-",
|
|
+ ngx_proxy_protocol_string_length(&pp),
|
|
+ ngx_proxy_protocol_string_length(&pp) - 2,
|
|
+ b->start);
|
|
+
|
|
+ rc = ngx_output_chain(&u->output, pp_string);
|
|
+
|
|
+ if (rc == NGX_ERROR) {
|
|
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
static void
|
|
ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
|
ngx_http_upstream_t *u)
|
|
Index: nginx-1.4.7/src/http/ngx_http_upstream.h
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/src/http/ngx_http_upstream.h
|
|
+++ nginx-1.4.7/src/http/ngx_http_upstream.h
|
|
@@ -188,6 +188,10 @@ typedef struct {
|
|
unsigned intercept_404:1;
|
|
unsigned change_buffering:1;
|
|
|
|
+#if (NGX_PROXY_PROTOCOL)
|
|
+ ngx_flag_t send_proxy_protocol;
|
|
+#endif
|
|
+
|
|
#if (NGX_HTTP_SSL)
|
|
ngx_ssl_t *ssl;
|
|
ngx_flag_t ssl_session_reuse;
|
|
Index: nginx-1.4.7/auto/cc/gcc
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/auto/cc/gcc
|
|
+++ nginx-1.4.7/auto/cc/gcc
|
|
@@ -168,7 +168,7 @@ esac
|
|
|
|
|
|
# stop on warning
|
|
-CFLAGS="$CFLAGS -Werror"
|
|
+CFLAGS="$CFLAGS"
|
|
|
|
# debug
|
|
CFLAGS="$CFLAGS -g"
|
|
Index: nginx-1.4.7/auto/cc/icc
|
|
===================================================================
|
|
--- nginx-1.4.7.orig/auto/cc/icc
|
|
+++ nginx-1.4.7/auto/cc/icc
|
|
@@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
|
|
esac
|
|
|
|
# stop on warning
|
|
-CFLAGS="$CFLAGS -Werror"
|
|
+CFLAGS="$CFLAGS "
|
|
|
|
# debug
|
|
CFLAGS="$CFLAGS -g"
|