|
|
- 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)
-
- 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"
|