Mercurial > hg > nginx-quic
view src/core/ngx_proxy_protocol.c @ 7358:170922952477
Removed bgcolor attribute on body in error pages and autoindex.
The bgcolor attribute overrides compatibility settings in browsers
and leads to undesirable behavior when the default font color is set
to white in the browser, since font-color is not also overridden.
author | Nova DasSarma <nova@novalinium.com> |
---|---|
date | Wed, 19 Sep 2018 09:26:47 -0500 |
parents | 1fd992589ffe |
children | 06b01840bd42 |
line wrap: on
line source
/* * Copyright (C) Roman Arutyunyan * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> #define NGX_PROXY_PROTOCOL_AF_INET 1 #define NGX_PROXY_PROTOCOL_AF_INET6 2 #define ngx_proxy_protocol_parse_uint16(p) ((p)[0] << 8 | (p)[1]) typedef struct { u_char signature[12]; u_char version_command; u_char family_transport; u_char len[2]; } ngx_proxy_protocol_header_t; typedef struct { u_char src_addr[4]; u_char dst_addr[4]; u_char src_port[2]; u_char dst_port[2]; } ngx_proxy_protocol_inet_addrs_t; typedef struct { u_char src_addr[16]; u_char dst_addr[16]; u_char src_port[2]; u_char dst_port[2]; } ngx_proxy_protocol_inet6_addrs_t; static u_char *ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last); 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; static const u_char signature[] = "\r\n\r\n\0\r\nQUIT\n"; p = buf; len = last - buf; if (len >= sizeof(ngx_proxy_protocol_header_t) && memcmp(p, signature, sizeof(signature) - 1) == 0) { return ngx_proxy_protocol_v2_read(c, buf, last); } if (len < 8 || ngx_strncmp(p, "PROXY ", 6) != 0) { goto invalid; } p += 6; len -= 6; if (len >= 7 && ngx_strncmp(p, "UNKNOWN", 7) == 0) { ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol unknown protocol"); p += 7; goto skip; } if (len < 5 || ngx_strncmp(p, "TCP", 3) != 0 || (p[3] != '4' && p[3] != '6') || p[4] != ' ') { goto invalid; } p += 5; addr = p; for ( ;; ) { if (p == last) { goto invalid; } ch = *p++; if (ch == ' ') { break; } if (ch != ':' && ch != '.' && (ch < 'a' || ch > 'f') && (ch < 'A' || ch > 'F') && (ch < '0' || ch > '9')) { goto invalid; } } len = p - addr - 1; c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, len); if (c->proxy_protocol_addr.data == NULL) { return NULL; } ngx_memcpy(c->proxy_protocol_addr.data, addr, len); c->proxy_protocol_addr.len = len; for ( ;; ) { if (p == last) { goto invalid; } if (*p++ == ' ') { break; } } port = p; for ( ;; ) { if (p == last) { 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 %d", &c->proxy_protocol_addr, c->proxy_protocol_port); skip: for ( /* void */ ; p < last - 1; p++) { if (p[0] == CR && p[1] == LF) { return p + 2; } } invalid: ngx_log_error(NGX_LOG_ERR, c->log, 0, "broken header: \"%*s\"", (size_t) (last - buf), buf); return NULL; } u_char * ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) { ngx_uint_t port, lport; if (last - buf < NGX_PROXY_PROTOCOL_MAX_HEADER) { return NULL; } if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { return NULL; } switch (c->sockaddr->sa_family) { case AF_INET: buf = ngx_cpymem(buf, "PROXY TCP4 ", sizeof("PROXY TCP4 ") - 1); break; #if (NGX_HAVE_INET6) case AF_INET6: buf = ngx_cpymem(buf, "PROXY TCP6 ", sizeof("PROXY TCP6 ") - 1); break; #endif default: return ngx_cpymem(buf, "PROXY UNKNOWN" CRLF, sizeof("PROXY UNKNOWN" CRLF) - 1); } buf += ngx_sock_ntop(c->sockaddr, c->socklen, buf, last - buf, 0); *buf++ = ' '; buf += ngx_sock_ntop(c->local_sockaddr, c->local_socklen, buf, last - buf, 0); port = ngx_inet_get_port(c->sockaddr); lport = ngx_inet_get_port(c->local_sockaddr); return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport); } static u_char * ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last) { u_char *end; size_t len; socklen_t socklen; ngx_uint_t version, command, family, transport; ngx_sockaddr_t sockaddr; ngx_proxy_protocol_header_t *header; ngx_proxy_protocol_inet_addrs_t *in; #if (NGX_HAVE_INET6) ngx_proxy_protocol_inet6_addrs_t *in6; #endif header = (ngx_proxy_protocol_header_t *) buf; buf += sizeof(ngx_proxy_protocol_header_t); version = header->version_command >> 4; if (version != 2) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "unknown PROXY protocol version: %ui", version); return NULL; } len = ngx_proxy_protocol_parse_uint16(header->len); if ((size_t) (last - buf) < len) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "header is too large"); return NULL; } end = buf + len; command = header->version_command & 0x0f; /* only PROXY is supported */ if (command != 1) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol v2 unsupported command %ui", command); return end; } transport = header->family_transport & 0x0f; /* only STREAM is supported */ if (transport != 1) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol v2 unsupported transport %ui", transport); return end; } family = header->family_transport >> 4; switch (family) { case NGX_PROXY_PROTOCOL_AF_INET: if ((size_t) (end - buf) < sizeof(ngx_proxy_protocol_inet_addrs_t)) { return NULL; } in = (ngx_proxy_protocol_inet_addrs_t *) buf; sockaddr.sockaddr_in.sin_family = AF_INET; sockaddr.sockaddr_in.sin_port = 0; memcpy(&sockaddr.sockaddr_in.sin_addr, in->src_addr, 4); c->proxy_protocol_port = ngx_proxy_protocol_parse_uint16(in->src_port); socklen = sizeof(struct sockaddr_in); buf += sizeof(ngx_proxy_protocol_inet_addrs_t); break; #if (NGX_HAVE_INET6) case NGX_PROXY_PROTOCOL_AF_INET6: if ((size_t) (end - buf) < sizeof(ngx_proxy_protocol_inet6_addrs_t)) { return NULL; } in6 = (ngx_proxy_protocol_inet6_addrs_t *) buf; sockaddr.sockaddr_in6.sin6_family = AF_INET6; sockaddr.sockaddr_in6.sin6_port = 0; memcpy(&sockaddr.sockaddr_in6.sin6_addr, in6->src_addr, 16); c->proxy_protocol_port = ngx_proxy_protocol_parse_uint16(in6->src_port); socklen = sizeof(struct sockaddr_in6); buf += sizeof(ngx_proxy_protocol_inet6_addrs_t); break; #endif default: ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol v2 unsupported address family %ui", family); return end; } c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, NGX_SOCKADDR_STRLEN); if (c->proxy_protocol_addr.data == NULL) { return NULL; } c->proxy_protocol_addr.len = ngx_sock_ntop(&sockaddr.sockaddr, socklen, c->proxy_protocol_addr.data, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol v2 address: %V %d", &c->proxy_protocol_addr, c->proxy_protocol_port); if (buf < end) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, "PROXY protocol v2 %z bytes of tlv ignored", end - buf); } return end; }