mirror of
https://github.com/nginx/nginx.git
synced 2024-12-15 13:28:59 +08:00
92 lines
1.8 KiB
C
92 lines
1.8 KiB
C
|
|
||
|
/*
|
||
|
* Copyright (C) Roman Arutyunyan
|
||
|
* Copyright (C) Nginx, Inc.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <ngx_config.h>
|
||
|
#include <ngx_core.h>
|
||
|
|
||
|
|
||
|
u_char *
|
||
|
ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf, u_char *last)
|
||
|
{
|
||
|
size_t len;
|
||
|
u_char ch, *p, *addr;
|
||
|
|
||
|
p = buf;
|
||
|
len = last - buf;
|
||
|
|
||
|
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;
|
||
|
|
||
|
ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
|
||
|
"PROXY protocol address: \"%V\"", &c->proxy_protocol_addr);
|
||
|
|
||
|
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;
|
||
|
}
|