Last active
December 23, 2015 18:49
-
-
Save yostinso/6678367 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- debian/rules 2012-07-12 11:55:28.000000000 -0700 | |
+++ debian/rules 2013-09-23 16:20:57.885799032 -0700 | |
@@ -84,6 +84,7 @@ | |
--with-md5=/usr/include/openssl \ | |
--with-mail \ | |
--with-mail_ssl_module \ | |
+ --with-proxy-protocol \ | |
--add-module=$(MODULESDIR)/nginx-auth-pam \ | |
--add-module=$(MODULESDIR)/nginx-echo \ | |
--add-module=$(MODULESDIR)/nginx-upstream-fair \ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Nrpu nginx-1.2.4.orig/auto/modules nginx-1.2.4/auto/modules | |
--- nginx-1.2.4.orig/auto/modules 2012-07-02 19:41:52.000000000 +0200 | |
+++ nginx-1.2.4/auto/modules 2012-11-26 22:40:37.069218221 +0100 | |
@@ -275,6 +275,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_PROXY . auto/have | |
have=NGX_HTTP_X_FORWARDED_FOR . auto/have | |
diff -Nrpu nginx-1.2.4.orig/auto/options nginx-1.2.4/auto/options | |
--- nginx-1.2.4.orig/auto/options 2012-07-02 18:41:13.000000000 +0200 | |
+++ nginx-1.2.4/auto/options 2012-11-26 22:46:10.254651119 +0100 | |
@@ -47,6 +47,8 @@ USE_THREADS=NO | |
NGX_FILE_AIO=NO | |
NGX_IPV6=NO | |
+PROXY_PROTOCOL=NO | |
+ | |
HTTP=YES | |
NGX_HTTP_LOG_PATH= | |
@@ -190,6 +192,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 ;; | |
@@ -346,6 +350,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_realip_module enable ngx_http_realip_module | |
--with-http_addition_module enable ngx_http_addition_module | |
diff -Nrpu nginx-1.2.4.orig/auto/sources nginx-1.2.4/auto/sources | |
--- nginx-1.2.4.orig/auto/sources 2012-07-02 18:41:13.000000000 +0200 | |
+++ nginx-1.2.4/auto/sources 2012-10-20 09:27:22.836430795 +0200 | |
@@ -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 | |
diff -Nrpu nginx-1.2.4.orig/src/core/ngx_connection.h nginx-1.2.4/src/core/ngx_connection.h | |
--- nginx-1.2.4.orig/src/core/ngx_connection.h 2012-01-18 16:07:43.000000000 +0100 | |
+++ nginx-1.2.4/src/core/ngx_connection.h 2012-11-26 21:39:17.840420536 +0100 | |
@@ -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:1; | |
+#endif | |
+ | |
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
unsigned ipv6only:2; | |
#endif | |
@@ -148,6 +152,10 @@ struct ngx_connection_s { | |
ngx_uint_t requests; | |
+#if (NGX_PROXY_PROTOCOL) | |
+ struct ngx_proxy_protocol_s *proxy_protocol; /* PP information */ | |
+#endif | |
+ | |
unsigned buffered:8; | |
unsigned log_error:3; /* ngx_connection_log_error_e */ | |
diff -Nrpu nginx-1.2.4.orig/src/core/ngx_core.h nginx-1.2.4/src/core/ngx_core.h | |
--- nginx-1.2.4.orig/src/core/ngx_core.h 2012-02-13 17:29:04.000000000 +0100 | |
+++ nginx-1.2.4/src/core/ngx_core.h 2012-11-26 21:38:36.636258441 +0100 | |
@@ -22,6 +22,9 @@ typedef struct ngx_file_s ngx_fil | |
typedef struct ngx_event_s ngx_event_t; | |
typedef struct ngx_event_aio_s ngx_event_aio_t; | |
typedef struct ngx_connection_s ngx_connection_t; | |
+#if (NGX_PROXY_PROTOCOL) | |
+typedef struct ngx_proxy_protocol_s ngx_proxy_protocol_t; | |
+#endif | |
typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); | |
typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); | |
@@ -78,6 +81,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 | |
diff -Nrpu nginx-1.2.4.orig/src/core/ngx_proxy_protocol.c nginx-1.2.4/src/core/ngx_proxy_protocol.c | |
--- nginx-1.2.4.orig/src/core/ngx_proxy_protocol.c 1970-01-01 01:00:00.000000000 +0100 | |
+++ nginx-1.2.4/src/core/ngx_proxy_protocol.c 2012-12-13 23:58:15.080939359 +0100 | |
@@ -0,0 +1,268 @@ | |
+ | |
+/* | |
+ * 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; | |
+ size_t len; | |
+ ssize_t s; | |
+ | |
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "processing proxy protocol"); | |
+ s = n; | |
+ end = memchr(buf, '\n', n); | |
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
+ "proxy_protocol: %s", buf); | |
+ | |
+ p = buf; | |
+ if (memcmp(p, "PROXY ", 6) != 0) { | |
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
+ "incorrect proxy protocol header string"); | |
+ goto fail; | |
+ } | |
+ p += 6; | |
+ s -= 6; | |
+ | |
+ c->proxy_protocol = ngx_pnalloc(c->pool, sizeof(ngx_proxy_protocol_t)); | |
+ ngx_memzero(c->proxy_protocol, sizeof(ngx_proxy_protocol_t)); | |
+ | |
+ if (memcmp(p, "TCP4 ", 5) == 0) { | |
+ c->proxy_protocol->pp_proto = NGX_PP_PROTO_TCP4; | |
+ c->proxy_protocol->pp_src3 = ngx_pnalloc(c->pool, sizeof(struct sockaddr_in)); | |
+ c->proxy_protocol->pp_dst3 = ngx_pnalloc(c->pool, sizeof(struct sockaddr_in)); | |
+ ((struct sockaddr_in *)c->proxy_protocol->pp_src3)->sin_family = AF_INET; | |
+ ((struct sockaddr_in *)c->proxy_protocol->pp_dst3)->sin_family = AF_INET; | |
+ | |
+ p += 5; | |
+ s -= 5; | |
+ | |
+ /* l3 source address */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ if ((((struct sockaddr_in *)c->proxy_protocol->pp_src3)->sin_addr.s_addr | |
+ = ngx_inet_addr(p, len)) == INADDR_NONE) | |
+ goto fail; | |
+ c->proxy_protocol->pp_src3_text.data = ngx_pnalloc(c->pool, len + 1); | |
+ ngx_memcpy(c->proxy_protocol->pp_src3_text.data, p, len); | |
+ c->proxy_protocol->pp_src3_text.len = len; | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l3 destination address */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ if ((((struct sockaddr_in *)c->proxy_protocol->pp_dst3)->sin_addr.s_addr | |
+ = ngx_inet_addr(p,len)) == INADDR_NONE) { | |
+ goto fail; | |
+ } | |
+ c->proxy_protocol->pp_dst3_text.data = ngx_pnalloc(c->pool, len + 1); | |
+ ngx_memcpy(c->proxy_protocol->pp_dst3_text.data, p, len); | |
+ c->proxy_protocol->pp_dst3_text.len = len; | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l4 source port */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ c->proxy_protocol->pp_src4 = ngx_atoi(p, len); | |
+ if ((c->proxy_protocol->pp_src4 < 1) // avoid ICMP? -- yostinso | |
+ || (c->proxy_protocol->pp_src4 > 65535)) | |
+ goto fail; | |
+ ((struct sockaddr_in *)c->proxy_protocol->pp_src3)->sin_port = | |
+ htons(c->proxy_protocol->pp_src4); | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l4 destination port */ | |
+ len = (u_char *)memchr(p, '\r', s) - p; | |
+ c->proxy_protocol->pp_dst4 = ngx_atoi(p, len); | |
+ if ((c->proxy_protocol->pp_dst4 < 1) // avoid ICMP? -- yostinso | |
+ || (c->proxy_protocol->pp_dst4 > 65535)) { | |
+ goto fail; | |
+ } | |
+ ((struct sockaddr_in *)c->proxy_protocol->pp_dst3)->sin_port = | |
+ htons(c->proxy_protocol->pp_dst4); | |
+ | |
+ 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 */ | |
+ ngx_pfree(c->pool, c->addr_text.data); | |
+ c->addr_text = c->proxy_protocol->pp_src3_text; | |
+ ngx_pfree(c->pool, c->sockaddr); | |
+ c->sockaddr = c->proxy_protocol->pp_src3; | |
+ /* updating connection with destination provided by proxy protocol */ | |
+ ngx_pfree(c->pool, c->local_sockaddr); | |
+ c->local_sockaddr = c->proxy_protocol->pp_dst3; | |
+ | |
+#if (NGX_HAVE_INET6) | |
+ } else if (memcmp(p, "TCP6 ", 5) == 0) { | |
+ c->proxy_protocol->pp_proto = NGX_PP_PROTO_TCP6; | |
+ c->proxy_protocol->pp_src3 = ngx_pnalloc(c->pool, sizeof(struct sockaddr_in6)); | |
+ c->proxy_protocol->pp_dst3 = ngx_pnalloc(c->pool, sizeof(struct sockaddr_in6)); | |
+ ((struct sockaddr_in6 *)c->proxy_protocol->pp_src3)->sin6_family = AF_INET6; | |
+ ((struct sockaddr_in6 *)c->proxy_protocol->pp_dst3)->sin6_family = AF_INET6; | |
+ | |
+ p += 5; | |
+ s -= 5; | |
+ | |
+ /* l3 source address */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ if (ngx_inet6_addr(p, len, (((struct sockaddr_in6 *)c->proxy_protocol->pp_src3)->sin6_addr.s6_addr)) != NGX_OK) | |
+ goto fail; | |
+ c->proxy_protocol->pp_src3_text.data = ngx_pnalloc(c->pool, len + 1); | |
+ ngx_memcpy(c->proxy_protocol->pp_src3_text.data, p, len); | |
+ c->proxy_protocol->pp_src3_text.len = len; | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l3 destination address */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ if (ngx_inet6_addr(p, len, (((struct sockaddr_in6 *)c->proxy_protocol->pp_dst3)->sin6_addr.s6_addr)) != NGX_OK) | |
+ goto fail; | |
+ c->proxy_protocol->pp_dst3_text.data = ngx_pnalloc(c->pool, len + 1); | |
+ ngx_memcpy(c->proxy_protocol->pp_dst3_text.data, p, len); | |
+ c->proxy_protocol->pp_dst3_text.len = len; | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l4 source port */ | |
+ len = (u_char *)memchr(p, ' ', s) - p; | |
+ c->proxy_protocol->pp_src4 = ngx_atoi(p, len); | |
+ if ((c->proxy_protocol->pp_src4 < 1) // avoid ICMP? -- yostinso | |
+ || (c->proxy_protocol->pp_src4 > 65535)) { | |
+ goto fail; | |
+ } | |
+ ((struct sockaddr_in6 *)c->proxy_protocol->pp_src3)->sin6_port = | |
+ htons(c->proxy_protocol->pp_src4); | |
+ | |
+ p += (len + 1); | |
+ s -= (len + 1); | |
+ | |
+ /* l4 destination port */ | |
+ len = (u_char *)memchr(p, '\r', s) - p; | |
+ c->proxy_protocol->pp_dst4 = ngx_atoi(p, len); | |
+ if (c->proxy_protocol->pp_dst4 > 65535) { | |
+ goto fail; | |
+ } | |
+ ((struct sockaddr_in6 *)c->proxy_protocol->pp_dst3)->sin6_port = | |
+ htons(c->proxy_protocol->pp_dst4); | |
+ | |
+ 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 */ | |
+ ngx_pfree(c->pool, c->addr_text.data); | |
+ c->addr_text = c->proxy_protocol->pp_src3_text; | |
+ ngx_pfree(c->pool, c->sockaddr); | |
+ c->sockaddr = c->proxy_protocol->pp_src3; | |
+ /* updating connection with destination provided by proxy protocol */ | |
+ ngx_pfree(c->pool, c->local_sockaddr); | |
+ c->local_sockaddr = c->proxy_protocol->pp_dst3; | |
+#endif | |
+ } else { | |
+ goto fail; | |
+ } | |
+ | |
+ 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: | |
+ if (c->proxy_protocol) | |
+ ngx_pfree(c->pool, c->proxy_protocol); | |
+ 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) | |
+ /* 4 digits */ | |
+ len += (sizeof("0000 ") - 1); | |
+ else | |
+ /* 5 digits */ | |
+ len += (sizeof("00000 ") - 1); | |
+ | |
+ /* CRLF */ | |
+ len += (sizeof(CRLF) - 1); | |
+ | |
+ return len; | |
+} | |
+ | |
+#endif | |
diff -Nrpu nginx-1.2.4.orig/src/core/ngx_proxy_protocol.h nginx-1.2.4/src/core/ngx_proxy_protocol.h | |
--- nginx-1.2.4.orig/src/core/ngx_proxy_protocol.h 1970-01-01 01:00:00.000000000 +0100 | |
+++ nginx-1.2.4/src/core/ngx_proxy_protocol.h 2012-11-26 21:41:57.109295151 +0100 | |
@@ -0,0 +1,43 @@ | |
+ | |
+/* | |
+ * 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 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 *pp_src3; | |
+ ngx_str_t pp_src3_text; | |
+ struct sockaddr *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(struct ngx_proxy_protocol_s *, ngx_log_t *); | |
+int ngx_proxy_protocol_string_length(struct ngx_proxy_protocol_s *); | |
+ | |
+ | |
+#endif | |
+ | |
+#endif /* _NGX_CONNECTION_H_INCLUDED_ */ | |
+ | |
diff -Nrpu nginx-1.2.4.orig/src/http/modules/ngx_http_proxy_module.c nginx-1.2.4/src/http/modules/ngx_http_proxy_module.c | |
--- nginx-1.2.4.orig/src/http/modules/ngx_http_proxy_module.c 2012-04-23 12:40:01.000000000 +0200 | |
+++ nginx-1.2.4/src/http/modules/ngx_http_proxy_module.c 2012-11-26 21:48:45.596338701 +0100 | |
@@ -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; | |
@@ -368,6 +370,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"), | |
@@ -2651,6 +2664,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 | |
@@ -2922,6 +2940,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); | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http.c nginx-1.2.4/src/http/ngx_http.c | |
--- nginx-1.2.4.orig/src/http/ngx_http.c 2012-08-06 18:03:56.000000000 +0200 | |
+++ nginx-1.2.4/src/http/ngx_http.c 2012-11-26 21:49:55.036820260 +0100 | |
@@ -1745,6 +1745,10 @@ 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) | |
+ ls->accept_proxy_protocol = cscf->accept_proxy_protocol; | |
+#endif | |
+ | |
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
ls->logp = clcf->error_log; | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http_core_module.c nginx-1.2.4/src/http/ngx_http_core_module.c | |
--- nginx-1.2.4.orig/src/http/ngx_http_core_module.c 2012-09-24 21:06:48.000000000 +0200 | |
+++ nginx-1.2.4/src/http/ngx_http_core_module.c 2012-11-26 21:52:09.249705056 +0100 | |
@@ -291,6 +291,17 @@ static ngx_command_t ngx_http_core_comm | |
offsetof(ngx_http_core_srv_conf_t, underscores_in_headers), | |
NULL }, | |
+#if (NGX_PROXY_PROTOCOL) | |
+ | |
+ { ngx_string("accept_proxy_protocol"), | |
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, | |
+ ngx_conf_set_flag_slot, | |
+ NGX_HTTP_SRV_CONF_OFFSET, | |
+ offsetof(ngx_http_core_srv_conf_t, accept_proxy_protocol), | |
+ NULL }, | |
+ | |
+#endif | |
+ | |
{ ngx_string("location"), | |
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, | |
ngx_http_core_location, | |
@@ -3362,6 +3373,9 @@ ngx_http_core_create_srv_conf(ngx_conf_t | |
cscf->ignore_invalid_headers = NGX_CONF_UNSET; | |
cscf->merge_slashes = NGX_CONF_UNSET; | |
cscf->underscores_in_headers = NGX_CONF_UNSET; | |
+#if (NGX_PROXY_PROTOCOL) | |
+ cscf->accept_proxy_protocol = NGX_CONF_UNSET; | |
+#endif | |
return cscf; | |
} | |
@@ -3405,6 +3419,11 @@ ngx_http_core_merge_srv_conf(ngx_conf_t | |
ngx_conf_merge_value(conf->underscores_in_headers, | |
prev->underscores_in_headers, 0); | |
+#if (NGX_PROXY_PROTOCOL) | |
+ ngx_conf_merge_value(conf->accept_proxy_protocol, | |
+ prev->accept_proxy_protocol, 0); | |
+#endif | |
+ | |
if (conf->server_names.nelts == 0) { | |
/* the array has 4 empty preallocated elements, so push cannot fail */ | |
sn = ngx_array_push(&conf->server_names); | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http_core_module.h nginx-1.2.4/src/http/ngx_http_core_module.h | |
--- nginx-1.2.4.orig/src/http/ngx_http_core_module.h 2012-06-04 13:58:12.000000000 +0200 | |
+++ nginx-1.2.4/src/http/ngx_http_core_module.h 2012-11-26 22:21:59.909603456 +0100 | |
@@ -195,6 +195,9 @@ typedef struct { | |
ngx_flag_t ignore_invalid_headers; | |
ngx_flag_t merge_slashes; | |
ngx_flag_t underscores_in_headers; | |
+#if (NGX_PROXY_PROTOCOL) | |
+ ngx_flag_t accept_proxy_protocol; | |
+#endif | |
unsigned listen:1; | |
#if (NGX_PCRE) | |
@@ -420,6 +423,10 @@ struct ngx_http_core_loc_conf_s { | |
ngx_flag_t open_file_cache_errors; | |
ngx_flag_t open_file_cache_events; | |
+#if (NGX_PROXY_PROTOCOL) | |
+ ngx_flag_t accept_proxy_protocol; | |
+#endif | |
+ | |
ngx_log_t *error_log; | |
ngx_uint_t types_hash_max_size; | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http_request.c nginx-1.2.4/src/http/ngx_http_request.c | |
--- nginx-1.2.4.orig/src/http/ngx_http_request.c 2012-08-06 19:36:30.000000000 +0200 | |
+++ nginx-1.2.4/src/http/ngx_http_request.c 2012-11-26 22:04:26.144997094 +0100 | |
@@ -64,6 +64,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[] = { | |
@@ -516,10 +519,61 @@ ngx_http_init_request(ngx_event_t *rev) | |
(void) ngx_atomic_fetch_add(ngx_stat_requests, 1); | |
#endif | |
+#if (NGX_PROXY_PROTOCOL) | |
+ rev->handler = ngx_http_proxy_protocol; | |
+#endif | |
+ | |
rev->handler(rev); | |
} | |
+#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; | |
+ | |
+ c = rev->data; | |
+ rev->handler = ngx_http_process_request_line; | |
+ | |
+#if (NGX_HTTP_SSL) | |
+ { | |
+ if (c->ssl) { | |
+ rev->handler = ngx_http_ssl_handshake; | |
+ } | |
+ | |
+ } | |
+#endif | |
+ | |
+ n = recv(c->fd, tmpbuf, size, MSG_PEEK); | |
+ | |
+ if ((n <= 0) && (c->listening) && | |
+ (c->listening->accept_proxy_protocol == 1) && (!c->proxy_protocol)) { | |
+ rev->handler = ngx_http_ssl_handshake; | |
+ 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) && | |
+ (c->listening->accept_proxy_protocol == 1) && (!c->proxy_protocol)) { | |
+ ssize_t m; | |
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required and found"); | |
+ if (!(m = ngx_recv_proxy_protocol(c, tmpbuf, n))) | |
+ return; | |
+ /* strip the proxy protocol string from the buffer */ | |
+ recv(c->fd, tmpbuf, m, 0); | |
+ ngx_print_proxy_protocol(c->proxy_protocol, c->log); | |
+ } | |
+ | |
+ rev->handler(rev); | |
+} | |
+ | |
+#endif | |
+ | |
+ | |
#if (NGX_HTTP_SSL) | |
static void | |
@@ -591,6 +645,12 @@ ngx_http_ssl_handshake(ngx_event_t *rev) | |
c->log->action = "reading client request line"; | |
rev->handler = ngx_http_process_request_line; | |
+ | |
+#if (NGX_PROXY_PROTOCOL) | |
+ if (c->listening->accept_proxy_protocol) | |
+ rev->handler = ngx_http_proxy_protocol; | |
+#endif | |
+ | |
ngx_http_process_request_line(rev); | |
} | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http_upstream.c nginx-1.2.4/src/http/ngx_http_upstream.c | |
--- nginx-1.2.4.orig/src/http/ngx_http_upstream.c 2012-08-06 19:34:08.000000000 +0200 | |
+++ nginx-1.2.4/src/http/ngx_http_upstream.c 2012-12-13 21:52:26.110603738 +0100 | |
@@ -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, | |
@@ -1217,6 +1221,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; | |
@@ -1459,6 +1470,189 @@ 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]; | |
+ | |
+ | |
+ pp = r->connection->proxy_protocol; | |
+ 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) { | |
+ | |
+ len += ngx_proxy_protocol_string_length(pp); | |
+ | |
+ } else { | |
+ u_char *addr; | |
+ struct sockaddr_storage sa; | |
+ socklen_t addrlen = NGX_SOCKADDRLEN; | |
+ struct sockaddr_in *sin; | |
+ | |
+#if (NGX_HAVE_INET6) | |
+ | |
+ struct sockaddr_in6 *sin6; | |
+ | |
+#endif | |
+ | |
+ pp = ngx_pcalloc(r->pool, sizeof(ngx_proxy_protocol_t)); | |
+ | |
+ getsockname(cc->fd, (struct sockaddr *) &sa, &addrlen); | |
+ | |
+ switch (sa.ss_family) { | |
+ | |
+#if (NGX_HAVE_INET6) | |
+ | |
+ case AF_INET6: | |
+ | |
+ /* protocol version */ | |
+ pp->pp_proto = NGX_PP_PROTO_TCP6; | |
+ | |
+ /* dst3 and dst4 */ | |
+ sin6 = (struct sockaddr_in6 *) &sa; | |
+ addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN); | |
+ ngx_inet_ntop(AF_INET6, &sin6->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->sin6_port); | |
+ | |
+ ngx_memzero(&sa, sizeof(struct sockaddr_storage)); | |
+ ngx_memzero(addr, NGX_INET6_ADDRSTRLEN); | |
+ | |
+ /* src3 and src4 */ | |
+ getpeername(cc->fd, (struct sockaddr *) &sa, &addrlen); | |
+ sin6 = (struct sockaddr_in6 *) &sa; | |
+ ngx_inet_ntop(AF_INET6, &sin6->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->sin6_port); | |
+ | |
+ break; | |
+ | |
+#endif | |
+ | |
+ default: | |
+ | |
+ /* protocol version */ | |
+ pp->pp_proto = NGX_PP_PROTO_TCP4; | |
+ | |
+ /* dst3 and dst4 */ | |
+ sin = (struct sockaddr_in *) &sa; | |
+ addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN); | |
+ ngx_inet_ntop(AF_INET, &sin->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->sin_port); | |
+ | |
+ ngx_memzero(&sa, sizeof(struct sockaddr)); | |
+ ngx_memzero(addr, NGX_INET_ADDRSTRLEN); | |
+ | |
+ /* src3 and src4 */ | |
+ getpeername(cc->fd, (struct sockaddr *) &sa, &addrlen); | |
+ sin = (struct sockaddr_in *) &sa; | |
+ ngx_inet_ntop(AF_INET, &sin->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->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; | |
+ | |
+ 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_debug2(NGX_LOG_DEBUG_HTTP, uc->log, 0, | |
+ "http upstream send proxy protocol: %d -%s-", | |
+ ngx_strlen(b->start) + 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) | |
diff -Nrpu nginx-1.2.4.orig/src/http/ngx_http_upstream.h nginx-1.2.4/src/http/ngx_http_upstream.h | |
--- nginx-1.2.4.orig/src/http/ngx_http_upstream.h 2012-02-13 12:01:58.000000000 +0100 | |
+++ nginx-1.2.4/src/http/ngx_http_upstream.h 2012-11-26 22:11:20.390599787 +0100 | |
@@ -181,6 +181,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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment