src/core/ngx_proxy_protocol.c - nginx-1.7.10

Functions defined

Source code


  1. /*
  2. * Copyright (C) Roman Arutyunyan
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>


  7. u_char *
  8. ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf, u_char *last)
  9. {
  10.     size_t  len;
  11.     u_char  ch, *p, *addr;

  12.     p = buf;
  13.     len = last - buf;

  14.     if (len < 8 || ngx_strncmp(p, "PROXY ", 6) != 0) {
  15.         goto invalid;
  16.     }

  17.     p += 6;
  18.     len -= 6;

  19.     if (len >= 7 && ngx_strncmp(p, "UNKNOWN", 7) == 0) {
  20.         ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
  21.                        "PROXY protocol unknown protocol");
  22.         p += 7;
  23.         goto skip;
  24.     }

  25.     if (len < 5 || ngx_strncmp(p, "TCP", 3) != 0
  26.         || (p[3] != '4' && p[3] != '6') || p[4] != ' ')
  27.     {
  28.         goto invalid;
  29.     }

  30.     p += 5;
  31.     addr = p;

  32.     for ( ;; ) {
  33.         if (p == last) {
  34.             goto invalid;
  35.         }

  36.         ch = *p++;

  37.         if (ch == ' ') {
  38.             break;
  39.         }

  40.         if (ch != ':' && ch != '.'
  41.             && (ch < 'a' || ch > 'f')
  42.             && (ch < 'A' || ch > 'F')
  43.             && (ch < '0' || ch > '9'))
  44.         {
  45.             goto invalid;
  46.         }
  47.     }

  48.     len = p - addr - 1;
  49.     c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, len);

  50.     if (c->proxy_protocol_addr.data == NULL) {
  51.         return NULL;
  52.     }

  53.     ngx_memcpy(c->proxy_protocol_addr.data, addr, len);
  54.     c->proxy_protocol_addr.len = len;

  55.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
  56.                    "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr);

  57. skip:

  58.     for ( /* void */ ; p < last - 1; p++) {
  59.         if (p[0] == CR && p[1] == LF) {
  60.             return p + 2;
  61.         }
  62.     }

  63. invalid:

  64.     ngx_log_error(NGX_LOG_ERR, c->log, 0,
  65.                   "broken header: \"%*s\"", (size_t) (last - buf), buf);

  66.     return NULL;
  67. }