diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c index 03c3a2aad..551972ea8 100644 --- a/src/core/ngx_proxy_protocol.c +++ b/src/core/ngx_proxy_protocol.c @@ -101,6 +101,7 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) { size_t len; u_char *p; + ngx_uint_t family; ngx_proxy_protocol_t *pp; static const u_char signature[] = "\r\n\r\n\0\r\nQUIT\n"; @@ -134,6 +135,9 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) goto invalid; } + family = (p[3] == '4') ? NGX_PROXY_PROTOCOL_AF_INET + : NGX_PROXY_PROTOCOL_AF_INET6; + p += 5; pp = ngx_pcalloc(c->pool, sizeof(ngx_proxy_protocol_t)); @@ -141,6 +145,8 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) return NULL; } + pp->family = family; + p = ngx_proxy_protocol_read_addr(c, p, last, &pp->src_addr); if (p == NULL) { goto invalid; @@ -279,7 +285,8 @@ ngx_proxy_protocol_read_port(u_char *p, u_char *last, in_port_t *port, u_char * ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) { - ngx_uint_t port, lport; + ngx_uint_t port, lport; + ngx_proxy_protocol_t *pp; if (last - buf < NGX_PROXY_PROTOCOL_V1_MAX_HEADER) { ngx_log_error(NGX_LOG_ALERT, c->log, 0, @@ -287,6 +294,36 @@ ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) return NULL; } + pp = c->proxy_protocol; + + if (pp) { + switch (pp->family) { + + case NGX_PROXY_PROTOCOL_AF_INET: + buf = ngx_cpymem(buf, "PROXY TCP4 ", + sizeof("PROXY TCP4 ") - 1); + break; + + case NGX_PROXY_PROTOCOL_AF_INET6: + buf = ngx_cpymem(buf, "PROXY TCP6 ", + sizeof("PROXY TCP6 ") - 1); + break; + + default: + return ngx_cpymem(buf, "PROXY UNKNOWN" CRLF, + sizeof("PROXY UNKNOWN" CRLF) - 1); + } + + buf = ngx_cpymem(buf, pp->src_addr.data, pp->src_addr.len); + + *buf++ = ' '; + + buf = ngx_cpymem(buf, pp->dst_addr.data, pp->dst_addr.len); + + return ngx_slprintf(buf, last, " %ui %ui" CRLF, pp->src_port, + pp->dst_port); + } + if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { return NULL; } @@ -409,6 +446,7 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last) pp->src_port = ngx_proxy_protocol_parse_uint16(in->src_port); pp->dst_port = ngx_proxy_protocol_parse_uint16(in->dst_port); + pp->family = family; socklen = sizeof(struct sockaddr_in); @@ -436,6 +474,7 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last) pp->src_port = ngx_proxy_protocol_parse_uint16(in6->src_port); pp->dst_port = ngx_proxy_protocol_parse_uint16(in6->dst_port); + pp->family = family; socklen = sizeof(struct sockaddr_in6); diff --git a/src/core/ngx_proxy_protocol.h b/src/core/ngx_proxy_protocol.h index d1749f57b..6907174cc 100644 --- a/src/core/ngx_proxy_protocol.h +++ b/src/core/ngx_proxy_protocol.h @@ -22,6 +22,7 @@ struct ngx_proxy_protocol_s { ngx_str_t dst_addr; in_port_t src_port; in_port_t dst_port; + ngx_uint_t family; ngx_str_t tlvs; };