[PATCH] proxy-protocol dst variables and proxy-proxy-protocol
Dmitry Volyntsev
xeioex at nginx.com
Tue Sep 20 11:16:55 UTC 2016
Could you please clarify what a problem are you trying to solve? Any
real world scenario?
http://nginx.org/en/docs/contributing_changes.html
> Try to make it clear why the suggested change is needed, and provide
a use case, if possible.
On 18.09.2016 15:11, Bjørnar Ness wrote:
> Introduce proxy_protocol_src/dst_addr/port and store proxy_protocol
> header in ngx_connection struct. This enables proxy-proxy-protocol
> in stream module if proxy_protocol is enabled on both listen and
> outgoing, which should be the logical default.
>
> Work in progress if/when this patch is accepted is proxy protocol
> support for the mail module.
> ---
> src/core/ngx_connection.h | 7 +-
> src/core/ngx_proxy_protocol.c | 111 ++++++++++++++++--------------
> src/http/modules/ngx_http_realip_module.c | 6 +-
> src/http/ngx_http_variables.c | 60 ++++++++--------
> src/stream/ngx_stream_realip_module.c | 10 +--
> src/stream/ngx_stream_variables.c | 60 ++++++++--------
> 6 files changed, 132 insertions(+), 122 deletions(-)
>
> diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
> index e484c81..c6e2337 100644
> --- a/src/core/ngx_connection.h
> +++ b/src/core/ngx_connection.h
> @@ -148,8 +148,11 @@ struct ngx_connection_s {
> socklen_t socklen;
> ngx_str_t addr_text;
>
> - ngx_str_t proxy_protocol_addr;
> - in_port_t proxy_protocol_port;
> + ngx_str_t proxy_protocol;
> + ngx_str_t proxy_protocol_src_addr;
> + ngx_str_t proxy_protocol_src_port;
> + ngx_str_t proxy_protocol_dst_addr;
> + ngx_str_t proxy_protocol_dst_port;
>
> #if (NGX_SSL)
> ngx_ssl_connection_t *ssl;
> diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c
> index 523ec35..04dae8b 100644
> --- a/src/core/ngx_proxy_protocol.c
> +++ b/src/core/ngx_proxy_protocol.c
> @@ -13,8 +13,9 @@ u_char *
> ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
> {
> size_t len;
> - u_char ch, *p, *addr, *port;
> - ngx_int_t n;
> + ngx_uint_t i, n;
> + u_char ch, *p, *pp;
> + ngx_str_t addr[2], port[2];
>
> p = buf;
> len = last - buf;
> @@ -40,77 +41,79 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
> }
>
> p += 5;
> - addr = p;
>
> - for ( ;; ) {
> - if (p == last) {
> - goto invalid;
> - }
> + for (i=0;i<2;i++) {
> + addr[i].data = p;
>
> - ch = *p++;
> + for ( ;; ) {
> + if (p == last) {
> + goto invalid;
> + }
>
> - if (ch == ' ') {
> - break;
> - }
> + ch = *p++;
>
> - if (ch != ':' && ch != '.'
> - && (ch < 'a' || ch > 'f')
> - && (ch < 'A' || ch > 'F')
> - && (ch < '0' || ch > '9'))
> - {
> - goto invalid;
> - }
> - }
> + if (ch == ' ') {
> + break;
> + }
>
> - len = p - addr - 1;
> - c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, len);
> + if (ch != ':' && ch != '.'
> + && (ch < 'a' || ch > 'f')
> + && (ch < 'A' || ch > 'F')
> + && (ch < '0' || ch > '9'))
> + {
> + goto invalid;
> + }
> + }
>
> - if (c->proxy_protocol_addr.data == NULL) {
> - return NULL;
> + addr[i].len = p - addr[i].data - 1;
> }
>
> - ngx_memcpy(c->proxy_protocol_addr.data, addr, len);
> - c->proxy_protocol_addr.len = len;
> + for (i=0;i<2;i++) {
> + port[i].data = p;
>
> - for ( ;; ) {
> - if (p == last) {
> - goto invalid;
> - }
> + for ( ;; ) {
> + if (p == last) {
> + goto invalid;
> + }
>
> - if (*p++ == ' ') {
> - break;
> + if ((*p++ == ' ' && i == 0) || (i == 1 && p != last && *p == CR)) {
> + break;
> + }
> }
> - }
>
> - port = p;
> + port[i].len = p - port[i].data - (1-i);
> + n = ngx_atoi(port[i].data, port[i].len);
>
> - for ( ;; ) {
> - if (p == last) {
> + if (n < 1 || n > 65535) {
> goto invalid;
> }
> -
> - if (*p++ == ' ') {
> - break;
> - }
> - }
> -
> - len = p - port - 1;
> -
> - n = ngx_atoi(port, len);
> -
> - if (n < 0 || n > 65535) {
> - goto invalid;
> }
>
> - c->proxy_protocol_port = (in_port_t) n;
> -
> - ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
> - "PROXY protocol address: %V %i", &c->proxy_protocol_addr, n);
> -
> skip:
>
> for ( /* void */ ; p < last - 1; p++) {
> if (p[0] == CR && p[1] == LF) {
> + len = p - buf - 6;
> + c->proxy_protocol.data = ngx_pnalloc(c->pool, len);
> + ngx_memcpy(c->proxy_protocol.data, buf + 6, len);
> + c->proxy_protocol.len = len;
> +
> + if (i) { /* not UNKNOWN */
> + pp = c->proxy_protocol.data;
> + c->proxy_protocol_src_addr.data = pp + (addr[0].data - buf - 6);
> + c->proxy_protocol_src_port.data = pp + (port[0].data - buf - 6);
> + c->proxy_protocol_dst_addr.data = pp + (addr[1].data - buf - 6);
> + c->proxy_protocol_dst_port.data = pp + (port[1].data - buf - 6);
> + c->proxy_protocol_src_addr.len = addr[0].len;
> + c->proxy_protocol_src_port.len = port[0].len;
> + c->proxy_protocol_dst_addr.len = addr[1].len;
> + c->proxy_protocol_dst_port.len = port[1].len;
> +
> + ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
> + "PROXY protocol address: %V %V",
> + &addr[0], &port[0]);
> + }
> +
> return p + 2;
> }
> }
> @@ -133,6 +136,10 @@ ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last)
> return NULL;
> }
>
> + if (c->proxy_protocol.len) {
> + return ngx_slprintf(buf, last, "PROXY %V" CRLF, &c->proxy_protocol);
> + }
> +
> if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
> return NULL;
> }
> diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
> index dba3c52..e2f7bdd 100644
> --- a/src/http/modules/ngx_http_realip_module.c
> +++ b/src/http/modules/ngx_http_realip_module.c
> @@ -180,7 +180,7 @@ ngx_http_realip_handler(ngx_http_request_t *r)
>
> case NGX_HTTP_REALIP_PROXY:
>
> - value = &r->connection->proxy_protocol_addr;
> + value = &r->connection->proxy_protocol_src_addr;
>
> if (value->len == 0) {
> return NGX_DECLINED;
> @@ -238,7 +238,9 @@ found:
> != NGX_DECLINED)
> {
> if (rlcf->type == NGX_HTTP_REALIP_PROXY) {
> - ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port);
> + ngx_inet_set_port(addr.sockaddr, (in_port_t)
> + ngx_atoi(c->proxy_protocol_src_port.data,
> + c->proxy_protocol_src_port.len));
> }
>
> return ngx_http_realip_set_addr(r, &addr);
> diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
> index 7e65b2e..6071874 100644
> --- a/src/http/ngx_http_variables.c
> +++ b/src/http/ngx_http_variables.c
> @@ -56,9 +56,7 @@ static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> -static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
> - ngx_http_variable_value_t *v, uintptr_t data);
> -static ngx_int_t ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
> +static ngx_int_t ngx_http_variable_proxy_protocol_value(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data);
> @@ -194,10 +192,28 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
> { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },
>
> { ngx_string("proxy_protocol_addr"), NULL,
> - ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_addr), 0, 0 },
> +
> + { ngx_string("proxy_protocol_src_addr"), NULL,
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_addr), 0, 0 },
> +
> + { ngx_string("proxy_protocol_dst_addr"), NULL,
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_dst_addr), 0, 0 },
>
> { ngx_string("proxy_protocol_port"), NULL,
> - ngx_http_variable_proxy_protocol_port, 0, 0, 0 },
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_port), 0, 0 },
> +
> + { ngx_string("proxy_protocol_src_port"), NULL,
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_port), 0, 0 },
> +
> + { ngx_string("proxy_protocol_dst_port"), NULL,
> + ngx_http_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_dst_port), 0, 0 },
>
> { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },
>
> @@ -1224,40 +1240,22 @@ ngx_http_variable_remote_port(ngx_http_request_t *r,
>
>
> static ngx_int_t
> -ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
> +ngx_http_variable_proxy_protocol_value(ngx_http_request_t *r,
> ngx_http_variable_value_t *v, uintptr_t data)
> {
> - v->len = r->connection->proxy_protocol_addr.len;
> - v->valid = 1;
> - v->no_cacheable = 0;
> - v->not_found = 0;
> - v->data = r->connection->proxy_protocol_addr.data;
> -
> - return NGX_OK;
> -}
> + ngx_str_t *a;
>
> + a = (ngx_str_t *) ((char *) r->connection + data);
>
> -static ngx_int_t
> -ngx_http_variable_proxy_protocol_port(ngx_http_request_t *r,
> - ngx_http_variable_value_t *v, uintptr_t data)
> -{
> - ngx_uint_t port;
> + if (a->data == NULL) {
> + return NGX_ERROR;
> + }
>
> - v->len = 0;
> + v->len = a->len;
> v->valid = 1;
> v->no_cacheable = 0;
> v->not_found = 0;
> -
> - v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
> - if (v->data == NULL) {
> - return NGX_ERROR;
> - }
> -
> - port = r->connection->proxy_protocol_port;
> -
> - if (port > 0 && port < 65536) {
> - v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
> - }
> + v->data = a->data;
>
> return NGX_OK;
> }
> diff --git a/src/stream/ngx_stream_realip_module.c b/src/stream/ngx_stream_realip_module.c
> index 0740431..3380aab 100644
> --- a/src/stream/ngx_stream_realip_module.c
> +++ b/src/stream/ngx_stream_realip_module.c
> @@ -108,7 +108,7 @@ ngx_stream_realip_handler(ngx_stream_session_t *s)
>
> c = s->connection;
>
> - if (c->proxy_protocol_addr.len == 0) {
> + if (c->proxy_protocol_src_addr.len == 0) {
> return NGX_DECLINED;
> }
>
> @@ -116,14 +116,16 @@ ngx_stream_realip_handler(ngx_stream_session_t *s)
> return NGX_DECLINED;
> }
>
> - if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol_addr.data,
> - c->proxy_protocol_addr.len)
> + if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol_src_addr.data,
> + c->proxy_protocol_src_addr.len)
> != NGX_OK)
> {
> return NGX_DECLINED;
> }
>
> - ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port);
> + ngx_inet_set_port(addr.sockaddr,
> + (in_port_t) ngx_atoi(c->proxy_protocol_src_port.data,
> + c->proxy_protocol_src_port.len));
>
> return ngx_stream_realip_set_addr(s, &addr);
> }
> diff --git a/src/stream/ngx_stream_variables.c b/src/stream/ngx_stream_variables.c
> index aa5361d..0aa4f73 100644
> --- a/src/stream/ngx_stream_variables.c
> +++ b/src/stream/ngx_stream_variables.c
> @@ -17,9 +17,7 @@ static ngx_int_t ngx_stream_variable_remote_addr(ngx_stream_session_t *s,
> ngx_stream_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_stream_variable_remote_port(ngx_stream_session_t *s,
> ngx_stream_variable_value_t *v, uintptr_t data);
> -static ngx_int_t ngx_stream_variable_proxy_protocol_addr(
> - ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
> -static ngx_int_t ngx_stream_variable_proxy_protocol_port(
> +static ngx_int_t ngx_stream_variable_proxy_protocol_value(
> ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
> static ngx_int_t ngx_stream_variable_server_addr(ngx_stream_session_t *s,
> ngx_stream_variable_value_t *v, uintptr_t data);
> @@ -62,10 +60,28 @@ static ngx_stream_variable_t ngx_stream_core_variables[] = {
> ngx_stream_variable_remote_port, 0, 0, 0 },
>
> { ngx_string("proxy_protocol_addr"), NULL,
> - ngx_stream_variable_proxy_protocol_addr, 0, 0, 0 },
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_addr), 0, 0 },
> +
> + { ngx_string("proxy_protocol_src_addr"), NULL,
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_addr), 0, 0 },
> +
> + { ngx_string("proxy_protocol_dst_addr"), NULL,
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_dst_addr), 0, 0 },
>
> { ngx_string("proxy_protocol_port"), NULL,
> - ngx_stream_variable_proxy_protocol_port, 0, 0, 0 },
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_port), 0, 0 },
> +
> + { ngx_string("proxy_protocol_src_port"), NULL,
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_src_port), 0, 0 },
> +
> + { ngx_string("proxy_protocol_dst_port"), NULL,
> + ngx_stream_variable_proxy_protocol_value,
> + offsetof(ngx_connection_t, proxy_protocol_dst_port), 0, 0 },
>
> { ngx_string("server_addr"), NULL,
> ngx_stream_variable_server_addr, 0, 0, 0 },
> @@ -428,40 +444,22 @@ ngx_stream_variable_remote_port(ngx_stream_session_t *s,
>
>
> static ngx_int_t
> -ngx_stream_variable_proxy_protocol_addr(ngx_stream_session_t *s,
> +ngx_stream_variable_proxy_protocol_value(ngx_stream_session_t *s,
> ngx_stream_variable_value_t *v, uintptr_t data)
> {
> - v->len = s->connection->proxy_protocol_addr.len;
> - v->valid = 1;
> - v->no_cacheable = 0;
> - v->not_found = 0;
> - v->data = s->connection->proxy_protocol_addr.data;
> -
> - return NGX_OK;
> -}
> + ngx_str_t *a;
>
> + a = (ngx_str_t *) ((char *) s->connection + data);
>
> -static ngx_int_t
> -ngx_stream_variable_proxy_protocol_port(ngx_stream_session_t *s,
> - ngx_stream_variable_value_t *v, uintptr_t data)
> -{
> - ngx_uint_t port;
> + if (a->data == NULL) {
> + return NGX_ERROR;
> + }
>
> - v->len = 0;
> + v->len = a->len;
> v->valid = 1;
> v->no_cacheable = 0;
> v->not_found = 0;
> -
> - v->data = ngx_pnalloc(s->connection->pool, sizeof("65535") - 1);
> - if (v->data == NULL) {
> - return NGX_ERROR;
> - }
> -
> - port = s->connection->proxy_protocol_port;
> -
> - if (port > 0 && port < 65536) {
> - v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
> - }
> + v->data = a->data;
>
> return NGX_OK;
> }
>
More information about the nginx-devel
mailing list