Core: revised the PROXY protocol v2 code.

- use normal prefixes for types and macros
- removed some macros and types
- revised debug messages
- removed useless check of ngx_sock_ntop() returning 0
- removed special processing of AF_UNSPEC
This commit is contained in:
Ruslan Ermilov 2018-04-02 18:40:04 +03:00
parent ecd6e243b6
commit 55f08fc9f7

View File

@ -9,54 +9,40 @@
#include <ngx_core.h> #include <ngx_core.h>
#define NGX_PP_V2_SIGLEN 12 #define NGX_PROXY_PROTOCOL_AF_INET 1
#define NGX_PP_V2_CMD_PROXY 1 #define NGX_PROXY_PROTOCOL_AF_INET6 2
#define NGX_PP_V2_STREAM 1
#define NGX_PP_V2_AF_UNSPEC 0
#define NGX_PP_V2_AF_INET 1
#define NGX_PP_V2_AF_INET6 2
#define ngx_pp_v2_get_u16(p) ((p)[0] << 8 | (p)[1]) #define ngx_proxy_protocol_parse_uint16(p) ((p)[0] << 8 | (p)[1])
typedef struct { typedef struct {
u_char signature[NGX_PP_V2_SIGLEN]; u_char signature[12];
u_char ver_cmd; u_char version_command;
u_char family_transport; u_char family_transport;
u_char len[2]; u_char len[2];
} ngx_pp_v2_header_t; } ngx_proxy_protocol_header_t;
typedef struct { typedef struct {
u_char src[4]; u_char s_addr[4];
u_char dst[4]; u_char d_addr[4];
u_char sport[2]; u_char s_port[2];
u_char dport[2]; u_char d_port[2];
} ngx_pp_v2_inet_addrs_t; } ngx_proxy_protocol_inet_addrs_t;
typedef struct { typedef struct {
u_char src[16]; u_char s_addr[16];
u_char dst[16]; u_char d_addr[16];
u_char sport[2]; u_char s_port[2];
u_char dport[2]; u_char d_port[2];
} ngx_pp_v2_inet6_addrs_t; } ngx_proxy_protocol_inet6_addrs_t;
typedef union {
ngx_pp_v2_inet_addrs_t inet;
ngx_pp_v2_inet6_addrs_t inet6;
} ngx_pp_v2_addrs_t;
static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf,
u_char *last); u_char *last);
static const u_char ngx_pp_v2_signature[NGX_PP_V2_SIGLEN] =
{ 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 0x55, 0x49, 0x54, 0x0a };
u_char * u_char *
ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
@ -65,11 +51,13 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last)
u_char ch, *p, *addr, *port; u_char ch, *p, *addr, *port;
ngx_int_t n; ngx_int_t n;
static const u_char signature[] = "\r\n\r\n\0\r\nQUIT\n";
p = buf; p = buf;
len = last - buf; len = last - buf;
if (len >= sizeof(ngx_pp_v2_header_t) if (len >= sizeof(ngx_proxy_protocol_header_t)
&& memcmp(p, ngx_pp_v2_signature, NGX_PP_V2_SIGLEN) == 0) && memcmp(p, signature, sizeof(signature) - 1) == 0)
{ {
return ngx_proxy_protocol_v2_read(c, buf, last); return ngx_proxy_protocol_v2_read(c, buf, last);
} }
@ -230,25 +218,27 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last)
u_char *end; u_char *end;
size_t len; size_t len;
socklen_t socklen; socklen_t socklen;
ngx_str_t *name; ngx_uint_t version, command, family, transport;
ngx_uint_t ver, cmd, family, transport;
ngx_sockaddr_t sockaddr; ngx_sockaddr_t sockaddr;
ngx_pp_v2_addrs_t *addrs; ngx_proxy_protocol_header_t *header;
ngx_pp_v2_header_t *hdr; ngx_proxy_protocol_inet_addrs_t *inet;
#if (NGX_HAVE_INET6)
ngx_proxy_protocol_inet6_addrs_t *inet6;
#endif
hdr = (ngx_pp_v2_header_t *) buf; header = (ngx_proxy_protocol_header_t *) buf;
buf += sizeof(ngx_pp_v2_header_t); buf += sizeof(ngx_proxy_protocol_header_t);
ver = hdr->ver_cmd >> 4; version = header->version_command >> 4;
if (ver != 2) { if (version != 2) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, ngx_log_error(NGX_LOG_ERR, c->log, 0,
"unsupported PROXY protocol version: %ui", ver); "unknown PROXY protocol version: %ui", version);
return NULL; return NULL;
} }
len = ngx_pp_v2_get_u16(hdr->len); len = ngx_proxy_protocol_parse_uint16(header->len);
if ((size_t) (last - buf) < len) { if ((size_t) (last - buf) < len) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "header is too large"); ngx_log_error(NGX_LOG_ERR, c->log, 0, "header is too large");
@ -257,102 +247,96 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last)
end = buf + len; end = buf + len;
cmd = hdr->ver_cmd & 0x0f; command = header->version_command & 0x0f;
if (cmd != NGX_PP_V2_CMD_PROXY) { /* only PROXY is supported */
if (command != 1) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 unsupported command 0x%xi", cmd); "PROXY protocol v2 unsupported command %ui", command);
return end; return end;
} }
transport = hdr->family_transport & 0x0f; transport = header->family_transport & 0x0f;
if (transport != NGX_PP_V2_STREAM) { /* only STREAM is supported */
if (transport != 1) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 unsupported transport 0x%xi", "PROXY protocol v2 unsupported transport %ui",
transport); transport);
return end; return end;
} }
family = hdr->family_transport >> 4; family = header->family_transport >> 4;
addrs = (ngx_pp_v2_addrs_t *) buf;
switch (family) { switch (family) {
case NGX_PP_V2_AF_UNSPEC: case NGX_PROXY_PROTOCOL_AF_INET:
ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 AF_UNSPEC ignored");
return end;
case NGX_PP_V2_AF_INET: if ((size_t) (end - buf) < sizeof(ngx_proxy_protocol_inet_addrs_t)) {
if ((size_t) (end - buf) < sizeof(ngx_pp_v2_inet_addrs_t)) {
return NULL; return NULL;
} }
inet = (ngx_proxy_protocol_inet_addrs_t *) buf;
sockaddr.sockaddr_in.sin_family = AF_INET; sockaddr.sockaddr_in.sin_family = AF_INET;
sockaddr.sockaddr_in.sin_port = 0; sockaddr.sockaddr_in.sin_port = 0;
memcpy(&sockaddr.sockaddr_in.sin_addr, addrs->inet.src, 4); memcpy(&sockaddr.sockaddr_in.sin_addr, inet->s_addr, 4);
c->proxy_protocol_port = ngx_pp_v2_get_u16(addrs->inet.sport); c->proxy_protocol_port = ngx_proxy_protocol_parse_uint16(inet->s_port);
socklen = sizeof(struct sockaddr_in); socklen = sizeof(struct sockaddr_in);
buf += sizeof(ngx_pp_v2_inet_addrs_t); buf += sizeof(ngx_proxy_protocol_inet_addrs_t);
break; break;
#if (NGX_HAVE_INET6) #if (NGX_HAVE_INET6)
case NGX_PP_V2_AF_INET6: case NGX_PROXY_PROTOCOL_AF_INET6:
if ((size_t) (end - buf) < sizeof(ngx_pp_v2_inet6_addrs_t)) { if ((size_t) (end - buf) < sizeof(ngx_proxy_protocol_inet6_addrs_t)) {
return NULL; return NULL;
} }
inet6 = (ngx_proxy_protocol_inet6_addrs_t *) buf;
sockaddr.sockaddr_in6.sin6_family = AF_INET6; sockaddr.sockaddr_in6.sin6_family = AF_INET6;
sockaddr.sockaddr_in6.sin6_port = 0; sockaddr.sockaddr_in6.sin6_port = 0;
memcpy(&sockaddr.sockaddr_in6.sin6_addr, addrs->inet6.src, 16); memcpy(&sockaddr.sockaddr_in6.sin6_addr, inet6->s_addr, 16);
c->proxy_protocol_port = ngx_pp_v2_get_u16(addrs->inet6.sport); c->proxy_protocol_port = ngx_proxy_protocol_parse_uint16(inet6->s_port);
socklen = sizeof(struct sockaddr_in6); socklen = sizeof(struct sockaddr_in6);
buf += sizeof(ngx_pp_v2_inet6_addrs_t); buf += sizeof(ngx_proxy_protocol_inet6_addrs_t);
break; break;
#endif #endif
default: default:
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 unsupported address family 0x%xi", "PROXY protocol v2 unsupported address family %ui",
family); family);
return end; return end;
} }
name = &c->proxy_protocol_addr; c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, NGX_SOCKADDR_STRLEN);
if (c->proxy_protocol_addr.data == NULL) {
name->data = ngx_pnalloc(c->pool, NGX_SOCKADDR_STRLEN);
if (name->data == NULL) {
return NULL; return NULL;
} }
name->len = ngx_sock_ntop(&sockaddr.sockaddr, socklen, name->data, c->proxy_protocol_addr.len = ngx_sock_ntop(&sockaddr.sockaddr, socklen,
c->proxy_protocol_addr.data,
NGX_SOCKADDR_STRLEN, 0); NGX_SOCKADDR_STRLEN, 0);
if (name->len == 0) {
return NULL;
}
ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 address: %V %d", name, "PROXY protocol v2 address: %V %d", &c->proxy_protocol_addr,
c->proxy_protocol_port); c->proxy_protocol_port);
if (buf < end) { if (buf < end) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
"PROXY protocol v2 %z bytes tlv ignored", end - buf); "PROXY protocol v2 %z bytes of tlv ignored", end - buf);
} }
return end; return end;