You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1194 lines
34 KiB

  1. Index: nginx-1.4.7/auto/modules
  2. ===================================================================
  3. --- nginx-1.4.7.orig/auto/modules
  4. +++ nginx-1.4.7/auto/modules
  5. @@ -297,6 +297,10 @@ if [ $HTTP_SSL = YES ]; then
  6. HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS"
  7. fi
  8. +if [ $PROXY_PROTOCOL = YES ]; then
  9. + have=NGX_PROXY_PROTOCOL . auto/have
  10. +fi
  11. +
  12. if [ $HTTP_PROXY = YES ]; then
  13. have=NGX_HTTP_X_FORWARDED_FOR . auto/have
  14. #USE_MD5=YES
  15. Index: nginx-1.4.7/auto/options
  16. ===================================================================
  17. --- nginx-1.4.7.orig/auto/options
  18. +++ nginx-1.4.7/auto/options
  19. @@ -47,6 +47,8 @@ USE_THREADS=NO
  20. NGX_FILE_AIO=NO
  21. NGX_IPV6=NO
  22. +PROXY_PROTOCOL=NO
  23. +
  24. HTTP=YES
  25. NGX_HTTP_LOG_PATH=
  26. @@ -192,6 +194,8 @@ do
  27. --with-file-aio) NGX_FILE_AIO=YES ;;
  28. --with-ipv6) NGX_IPV6=YES ;;
  29. + --with-proxy-protocol) PROXY_PROTOCOL=YES ;;
  30. +
  31. --without-http) HTTP=NO ;;
  32. --without-http-cache) HTTP_CACHE=NO ;;
  33. @@ -350,6 +354,8 @@ cat << END
  34. --with-file-aio enable file AIO support
  35. --with-ipv6 enable IPv6 support
  36. + --with-proxy-protocol enable proxy protocol support
  37. +
  38. --with-http_ssl_module enable ngx_http_ssl_module
  39. --with-http_spdy_module enable ngx_http_spdy_module
  40. --with-http_realip_module enable ngx_http_realip_module
  41. Index: nginx-1.4.7/auto/sources
  42. ===================================================================
  43. --- nginx-1.4.7.orig/auto/sources
  44. +++ nginx-1.4.7/auto/sources
  45. @@ -36,7 +36,8 @@ CORE_DEPS="src/core/nginx.h \
  46. src/core/ngx_conf_file.h \
  47. src/core/ngx_resolver.h \
  48. src/core/ngx_open_file_cache.h \
  49. - src/core/ngx_crypt.h"
  50. + src/core/ngx_crypt.h \
  51. + src/core/ngx_proxy_protocol.h"
  52. CORE_SRCS="src/core/nginx.c \
  53. @@ -67,7 +68,8 @@ CORE_SRCS="src/core/nginx.c \
  54. src/core/ngx_conf_file.c \
  55. src/core/ngx_resolver.c \
  56. src/core/ngx_open_file_cache.c \
  57. - src/core/ngx_crypt.c"
  58. + src/core/ngx_crypt.c \
  59. + src/core/ngx_proxy_protocol.c"
  60. REGEX_MODULE=ngx_regex_module
  61. Index: nginx-1.4.7/src/core/ngx_connection.h
  62. ===================================================================
  63. --- nginx-1.4.7.orig/src/core/ngx_connection.h
  64. +++ nginx-1.4.7/src/core/ngx_connection.h
  65. @@ -63,6 +63,10 @@ struct ngx_listening_s {
  66. unsigned shared:1; /* shared between threads or processes */
  67. unsigned addr_ntop:1;
  68. +#if (NGX_PROXY_PROTOCOL)
  69. + unsigned accept_proxy_protocol:2; /* proxy_protocol flag */
  70. +#endif
  71. +
  72. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  73. unsigned ipv6only:1;
  74. #endif
  75. @@ -148,6 +152,10 @@ struct ngx_connection_s {
  76. ngx_uint_t requests;
  77. +#if (NGX_PROXY_PROTOCOL)
  78. + ngx_uint_t proxy_protocol;
  79. +#endif
  80. +
  81. unsigned buffered:8;
  82. unsigned log_error:3; /* ngx_connection_log_error_e */
  83. Index: nginx-1.4.7/src/core/ngx_core.h
  84. ===================================================================
  85. --- nginx-1.4.7.orig/src/core/ngx_core.h
  86. +++ nginx-1.4.7/src/core/ngx_core.h
  87. @@ -77,6 +77,9 @@ typedef void (*ngx_connection_handler_pt
  88. #include <ngx_open_file_cache.h>
  89. #include <ngx_os.h>
  90. #include <ngx_connection.h>
  91. +#if (NGX_PROXY_PROTOCOL)
  92. +#include <ngx_proxy_protocol.h>
  93. +#endif
  94. #define LF (u_char) 10
  95. Index: nginx-1.4.7/src/core/ngx_proxy_protocol.c
  96. ===================================================================
  97. --- /dev/null
  98. +++ nginx-1.4.7/src/core/ngx_proxy_protocol.c
  99. @@ -0,0 +1,430 @@
  100. +
  101. +/*
  102. + * Copyright (C) Baptiste Assmann
  103. + * Copyright (C) Exceliance
  104. + */
  105. +
  106. +
  107. +#include <ngx_config.h>
  108. +#include <ngx_core.h>
  109. +#include <ngx_event.h>
  110. +
  111. +#if (NGX_PROXY_PROTOCOL)
  112. +
  113. +int
  114. +ngx_recv_proxy_protocol(ngx_connection_t *c, u_char *buf, ssize_t n)
  115. +{
  116. + u_char *end, *p, *t;
  117. + size_t len;
  118. + ssize_t s;
  119. + int step = 0;
  120. + ngx_proxy_protocol_t pp;
  121. +
  122. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "processing proxy protocol");
  123. +
  124. + /* 16 is the minimal length of the proxy protocol string */
  125. + if (n < 18) {
  126. + step = 1;
  127. + goto fail;
  128. + }
  129. +
  130. + s = n;
  131. + end = memchr(buf, '\n', n);
  132. + if (end == NULL) {
  133. + step = 2;
  134. + goto fail;
  135. + }
  136. +
  137. + p = buf;
  138. + if (memcmp(p, "PROXY ", 6) != 0) {
  139. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
  140. + "incorrect proxy protocol header string");
  141. + step = 3;
  142. + goto fail;
  143. + }
  144. + p += 6;
  145. + s -= 6;
  146. + if (s <= 0) {
  147. + step = 4;
  148. + goto fail;
  149. + }
  150. +
  151. + ngx_memzero(&pp, sizeof(ngx_proxy_protocol_t));
  152. +
  153. + if (memcmp(p, "TCP4 ", 5) == 0) {
  154. + struct sockaddr_in *sin_src;
  155. + struct sockaddr_in *sin_dst;
  156. +
  157. + pp.pp_proto = NGX_PP_PROTO_TCP4;
  158. + pp.pp_src3.ss_family = AF_INET;
  159. + pp.pp_dst3.ss_family = AF_INET;
  160. + sin_src = (struct sockaddr_in *) &pp.pp_src3;
  161. + sin_dst = (struct sockaddr_in *) &pp.pp_dst3;
  162. +
  163. + p += 5;
  164. + s -= 5;
  165. + if (s <= 0) {
  166. + step = 5;
  167. + goto fail;
  168. + }
  169. +
  170. + /* l3 source address */
  171. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  172. + step = 6;
  173. + goto fail;
  174. + }
  175. + len = t - p;
  176. + if ((sin_src->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
  177. + step = 7;
  178. + goto fail;
  179. + }
  180. + pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
  181. + ngx_memcpy(pp.pp_src3_text.data, p, len);
  182. + pp.pp_src3_text.len = len;
  183. +
  184. + p += (len + 1);
  185. + s -= (len + 1);
  186. + if (s <= 0) {
  187. + step = 8;
  188. + goto fail;
  189. + }
  190. +
  191. + /* l3 destination address */
  192. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  193. + step = 9;
  194. + goto fail;
  195. + }
  196. + len = t - p;
  197. + if ((sin_dst->sin_addr.s_addr = ngx_inet_addr(p, len)) == INADDR_NONE) {
  198. + step = 10;
  199. + goto fail;
  200. + }
  201. +// FIXME pointer shift ???
  202. + pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
  203. + ngx_memcpy(pp.pp_dst3_text.data, p, len);
  204. + pp.pp_dst3_text.len = len;
  205. +
  206. + p += (len + 1);
  207. + s -= (len + 1);
  208. + if (s <= 0) {
  209. + step = 11;
  210. + goto fail;
  211. + }
  212. +
  213. + /* l4 source port */
  214. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  215. + step = 12;
  216. + goto fail;
  217. + }
  218. + len = t - p;
  219. + pp.pp_src4 = ngx_atoi(p, len);
  220. + if ((pp.pp_src4 < 1024)
  221. + || (pp.pp_src4 > 65535)) {
  222. + step = 13;
  223. + goto fail;
  224. + }
  225. + sin_src->sin_port = htons(pp.pp_src4);
  226. +
  227. + p += (len + 1);
  228. + s -= (len + 1);
  229. + if (s <= 0) {
  230. + step = 14;
  231. + goto fail;
  232. + }
  233. +
  234. + /* l4 destination port */
  235. + if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
  236. + step = 15;
  237. + goto fail;
  238. + }
  239. + len = t - p;
  240. + pp.pp_dst4 = ngx_atoi(p, len);
  241. + if (pp.pp_dst4 > 65535) {
  242. + step = 16;
  243. + goto fail;
  244. + }
  245. + sin_dst->sin_port = htons(pp.pp_dst4);
  246. +
  247. + if (p[len + 1] != '\n') {
  248. + step = 17;
  249. + goto fail;
  250. + }
  251. +
  252. + p += (len + 2);
  253. + s -= (len + 2);
  254. +
  255. +
  256. + /* if we managed to get there, then we can safely replace the
  257. + * information in the connection structure
  258. + */
  259. +
  260. + /* updating connection with source information provided by proxy protocol */
  261. + if (pp.pp_src3_text.len > c->addr_text.len) {
  262. + ngx_pfree(c->pool, c->addr_text.data);
  263. + c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
  264. + } else {
  265. + ngx_memzero(c->addr_text.data, c->addr_text.len);
  266. + }
  267. + ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
  268. + c->addr_text.len = pp.pp_src3_text.len;
  269. +
  270. + ngx_pfree(c->pool, c->sockaddr);
  271. + c->socklen = NGX_SOCKADDRLEN;
  272. + c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
  273. + ngx_memcpy(c->sockaddr, sin_src, c->socklen);
  274. +
  275. + if (c->sockaddr->sa_family != AF_INET) {
  276. + ngx_pfree(c->pool, c->sockaddr);
  277. + c->socklen = NGX_SOCKADDRLEN;
  278. + c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
  279. + } else {
  280. + ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in));
  281. + c->socklen = NGX_SOCKADDRLEN;
  282. + }
  283. + ngx_memcpy(c->sockaddr, sin_src, c->socklen);
  284. +
  285. + /* updating connection with destination information provided by proxy protocol */
  286. + ngx_pfree(c->pool, c->local_sockaddr);
  287. + c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
  288. + ngx_memcpy(c->local_sockaddr, sin_dst, NGX_SOCKADDRLEN);
  289. +
  290. + }
  291. +
  292. +#if (NGX_HAVE_INET6)
  293. +
  294. + else if (memcmp(p, "TCP6 ", 5) == 0) {
  295. +
  296. + struct sockaddr_in6 *sin6_src;
  297. + struct sockaddr_in6 *sin6_dst;
  298. +
  299. + pp.pp_proto = NGX_PP_PROTO_TCP6;
  300. + pp.pp_src3.ss_family = AF_INET6;
  301. + pp.pp_dst3.ss_family = AF_INET6;
  302. + sin6_src = (struct sockaddr_in6 *) &pp.pp_src3;
  303. + sin6_dst = (struct sockaddr_in6 *) &pp.pp_dst3;
  304. +
  305. + p += 5;
  306. + s -= 5;
  307. + if (s <= 0) {
  308. + step = 18;
  309. + goto fail;
  310. + }
  311. +
  312. + /* l3 source address */
  313. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  314. + step = 19;
  315. + goto fail;
  316. + }
  317. + len = t - p;
  318. + if (ngx_inet6_addr(p, len, sin6_src->sin6_addr.s6_addr) != NGX_OK) {
  319. + step = 20;
  320. + goto fail;
  321. + }
  322. + pp.pp_src3_text.data = ngx_pcalloc(c->pool, len + 1);
  323. + ngx_memcpy(pp.pp_src3_text.data, p, len);
  324. + pp.pp_src3_text.len = len;
  325. +
  326. + p += (len + 1);
  327. + s -= (len + 1);
  328. + if (s <= 0) {
  329. + step = 21;
  330. + goto fail;
  331. + }
  332. +
  333. + /* l3 destination address */
  334. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  335. + step = 22;
  336. + goto fail;
  337. + }
  338. + len = t - p;
  339. + if (ngx_inet6_addr(p, len, sin6_dst->sin6_addr.s6_addr) != NGX_OK) {
  340. + step = 23;
  341. + goto fail;
  342. + }
  343. + pp.pp_dst3_text.data = ngx_pcalloc(c->pool, len + 1);
  344. + ngx_memcpy(pp.pp_dst3_text.data, p, len);
  345. + pp.pp_dst3_text.len = len;
  346. +
  347. + p += (len + 1);
  348. + s -= (len + 1);
  349. + if (s <= 0) {
  350. + step = 24;
  351. + goto fail;
  352. + }
  353. +
  354. + /* l4 source port */
  355. + if ( (t = (u_char *)memchr(p, ' ', s)) == NULL ) {
  356. + step = 25;
  357. + goto fail;
  358. + }
  359. + len = t - p;
  360. + pp.pp_src4 = ngx_atoi(p, len);
  361. + if ((pp.pp_src4 < 1024)
  362. + || (pp.pp_src4 > 65535)) {
  363. + step = 26;
  364. + goto fail;
  365. + }
  366. + sin6_src->sin6_port = htons(pp.pp_src4);
  367. +
  368. + p += (len + 1);
  369. + s -= (len + 1);
  370. + if (s <= 0) {
  371. + step = 27;
  372. + goto fail;
  373. + }
  374. +
  375. + /* l4 destination port */
  376. + if ( (t = (u_char *)memchr(p, '\r', s)) == NULL ) {
  377. + step = 28;
  378. + goto fail;
  379. + }
  380. + len = t - p;
  381. + pp.pp_dst4 = ngx_atoi(p, len);
  382. + if (pp.pp_dst4 > 65535) {
  383. + step = 29;
  384. + goto fail;
  385. + }
  386. + sin6_dst->sin6_port = htons(pp.pp_dst4);
  387. +
  388. + if (p[len + 1] != '\n') {
  389. + step = 30;
  390. + goto fail;
  391. + }
  392. +
  393. + p += (len + 2);
  394. + s -= (len + 2);
  395. +
  396. + /* if we managed to get there, then we can safely replace the
  397. + * information in the connection structure
  398. + */
  399. +
  400. + /* updating connection with source provided by proxy protocol */
  401. + if (pp.pp_src3_text.len > c->addr_text.len) {
  402. + ngx_pfree(c->pool, c->addr_text.data);
  403. + c->addr_text.data = ngx_pcalloc(c->pool, pp.pp_src3_text.len);
  404. + } else {
  405. + ngx_memzero(c->addr_text.data, c->addr_text.len);
  406. + }
  407. + ngx_memcpy(c->addr_text.data, pp.pp_src3_text.data, pp.pp_src3_text.len);
  408. + c->addr_text.len = pp.pp_src3_text.len;
  409. +
  410. + ngx_pfree(c->pool, c->sockaddr);
  411. + c->socklen = NGX_SOCKADDRLEN;
  412. + c->sockaddr = ngx_pcalloc(c->pool, c->socklen);
  413. + ngx_memcpy(c->sockaddr, sin6_src, c->socklen);
  414. +
  415. + /* updating connection with destination provided by proxy protocol */
  416. + if (c->sockaddr->sa_family != AF_INET6) {
  417. + ngx_pfree(c->pool, c->local_sockaddr);
  418. + c->local_sockaddr = ngx_pcalloc(c->pool, NGX_SOCKADDRLEN);
  419. + } else {
  420. + ngx_memzero(c->sockaddr, sizeof(struct sockaddr_in6));
  421. + c->socklen = NGX_SOCKADDRLEN;
  422. + }
  423. +// ngx_memcpy(c->local_sockaddr, sin6_dst, NGX_SOCKADDRLEN);
  424. +//FIXME must be finished here
  425. +
  426. + }
  427. +
  428. +#endif
  429. +
  430. + else {
  431. + step = 31;
  432. + goto fail;
  433. + }
  434. +
  435. + ngx_print_proxy_protocol(&pp, c->log);
  436. +
  437. + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  438. + "proxy_protocol, asking to remove %z chars",
  439. + end + 1 - buf);
  440. +
  441. + return (end + 1 - buf);
  442. +
  443. +fail:
  444. + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  445. + "proxy_protocol error at step: %d", step);
  446. +
  447. + return 0;
  448. +
  449. +}
  450. +
  451. +
  452. +void
  453. +ngx_print_proxy_protocol(ngx_proxy_protocol_t *p, ngx_log_t *log)
  454. +{
  455. + switch (p->pp_proto) {
  456. + case NGX_PP_PROTO_TCP4:
  457. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
  458. + "proxy_protocol, proto: TCP4");
  459. + break;
  460. + case NGX_PP_PROTO_TCP6:
  461. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, log, 0,
  462. + "proxy_protocol, proto: TCP6");
  463. + break;
  464. + }
  465. +
  466. + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
  467. + "proxy_protocol, string length: %d", ngx_proxy_protocol_string_length(p));
  468. + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  469. + "proxy_protocol, src3: %s, %d", p->pp_src3_text.data, p->pp_src3_text.len);
  470. + ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
  471. + "proxy_protocol, dst3: %s, %d", p->pp_dst3_text.data, p->pp_dst3_text.len);
  472. + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
  473. + "proxy_protocol, src4: %d", p->pp_src4);
  474. + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0,
  475. + "proxy_protocol, dst4: %d", p->pp_dst4);
  476. +}
  477. +
  478. +
  479. +int
  480. +ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *p)
  481. +{
  482. + int len = 0;
  483. +
  484. + /* 'PROXY ' */
  485. + len += (sizeof("PROXY ") - 1);
  486. +
  487. + /* protocol version (TCP4 or TCP6) + space */
  488. + len += (sizeof("TCP0 ") - 1);
  489. +
  490. + /* src3 + space */
  491. + len += p->pp_src3_text.len;
  492. + len += 1;
  493. +
  494. + /* dst3 + space */
  495. + len += p->pp_dst3_text.len;
  496. + len += 1;
  497. +
  498. + /* src4 */
  499. + if (p->pp_src4 < 10000)
  500. + /* 4 digits + 1 space */
  501. + len += (sizeof("0000 ") - 1);
  502. + else
  503. + /* 5 digits + 1 space */
  504. + len += (sizeof("00000 ") - 1);
  505. +
  506. + /* dst4 */
  507. + if (p->pp_dst4 >= 10000)
  508. + /* 5 digits */
  509. + len += (sizeof("00000 ") - 1);
  510. + else if (p->pp_dst4 >= 1000)
  511. + /* 4 digits */
  512. + len += (sizeof("0000 ") - 1);
  513. + else if (p->pp_dst4 >= 100)
  514. + /* 3 digits */
  515. + len += (sizeof("000 ") - 1);
  516. + else if (p->pp_dst4 >= 10)
  517. + /* 2 digits */
  518. + len += (sizeof("00 ") - 1);
  519. + else
  520. + /* 1 digit */
  521. + len += (sizeof("0 ") - 1);
  522. +
  523. + /* CRLF */
  524. + len += (sizeof(CRLF) - 1);
  525. +
  526. + return len - 1;
  527. +}
  528. +
  529. +#endif
  530. Index: nginx-1.4.7/src/core/ngx_proxy_protocol.h
  531. ===================================================================
  532. --- /dev/null
  533. +++ nginx-1.4.7/src/core/ngx_proxy_protocol.h
  534. @@ -0,0 +1,45 @@
  535. +
  536. +/*
  537. + * Copyright (C) Baptiste Assmann
  538. + * Copyright (C) Exceliance
  539. + */
  540. +
  541. +
  542. +#ifndef _NGX_PROXY_PROTOCOL_H_INCLUDED_
  543. +#define _NGX_PROXY_PROTOCOL_H_INCLUDED_
  544. +
  545. +
  546. +#include <ngx_config.h>
  547. +#include <ngx_core.h>
  548. +
  549. +
  550. +#if (NGX_PROXY_PROTOCOL)
  551. +
  552. +typedef struct ngx_proxy_protocol_s ngx_proxy_protocol_t;
  553. +
  554. +typedef enum {
  555. + NGX_PP_PROTO_TCP4 = 1,
  556. + NGX_PP_PROTO_TCP6
  557. +} ngx_pp_proto;
  558. +
  559. +
  560. +struct ngx_proxy_protocol_s {
  561. + unsigned int pp_proto; /* proxy protocol related information */
  562. + struct sockaddr_storage pp_src3;
  563. + ngx_str_t pp_src3_text;
  564. + struct sockaddr_storage pp_dst3;
  565. + ngx_str_t pp_dst3_text;
  566. + unsigned int pp_src4;
  567. + unsigned int pp_dst4;
  568. +};
  569. +
  570. +
  571. +int ngx_recv_proxy_protocol(ngx_connection_t *, u_char *, ssize_t);
  572. +void ngx_print_proxy_protocol(ngx_proxy_protocol_t *, ngx_log_t *);
  573. +int ngx_proxy_protocol_string_length(ngx_proxy_protocol_t *);
  574. +
  575. +
  576. +#endif
  577. +
  578. +#endif /* _NGX_CONNECTION_H_INCLUDED_ */
  579. +
  580. Index: nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
  581. ===================================================================
  582. --- nginx-1.4.7.orig/src/http/modules/ngx_http_proxy_module.c
  583. +++ nginx-1.4.7/src/http/modules/ngx_http_proxy_module.c
  584. @@ -8,7 +8,9 @@
  585. #include <ngx_config.h>
  586. #include <ngx_core.h>
  587. #include <ngx_http.h>
  588. -
  589. +#if (NGX_PROXY_PROTOCOL)
  590. +#include <ngx_proxy_protocol.h>
  591. +#endif
  592. typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
  593. @@ -365,6 +367,17 @@ static ngx_command_t ngx_http_proxy_com
  594. offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf),
  595. NULL },
  596. +#if (NGX_PROXY_PROTOCOL)
  597. +
  598. + { ngx_string("send_proxy_protocol"),
  599. + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  600. + ngx_conf_set_flag_slot,
  601. + NGX_HTTP_LOC_CONF_OFFSET,
  602. + offsetof(ngx_http_proxy_loc_conf_t, upstream.send_proxy_protocol),
  603. + NULL },
  604. +
  605. +#endif
  606. +
  607. #if (NGX_HTTP_CACHE)
  608. { ngx_string("proxy_cache"),
  609. @@ -2420,6 +2433,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
  610. conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
  611. conf->upstream.intercept_errors = NGX_CONF_UNSET;
  612. +
  613. +#if (NGX_PROXY_PROTOCOL)
  614. + conf->upstream.send_proxy_protocol = NGX_CONF_UNSET;
  615. +#endif
  616. +
  617. #if (NGX_HTTP_SSL)
  618. conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
  619. #endif
  620. @@ -2695,6 +2713,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
  621. ngx_conf_merge_value(conf->upstream.intercept_errors,
  622. prev->upstream.intercept_errors, 0);
  623. +#if (NGX_PROXY_PROTOCOL)
  624. + ngx_conf_merge_value(conf->upstream.send_proxy_protocol,
  625. + prev->upstream.send_proxy_protocol, 0);
  626. +#endif
  627. +
  628. #if (NGX_HTTP_SSL)
  629. ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
  630. prev->upstream.ssl_session_reuse, 1);
  631. Index: nginx-1.4.7/src/http/ngx_http.c
  632. ===================================================================
  633. --- nginx-1.4.7.orig/src/http/ngx_http.c
  634. +++ nginx-1.4.7/src/http/ngx_http.c
  635. @@ -1228,6 +1228,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
  636. #if (NGX_HTTP_SPDY)
  637. ngx_uint_t spdy;
  638. #endif
  639. +#if (NGX_PROXY_PROTOCOL)
  640. + ngx_uint_t accept_proxy_protocol;
  641. +#endif
  642. /*
  643. * we cannot compare whole sockaddr struct's as kernel
  644. @@ -1283,6 +1286,10 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
  645. #if (NGX_HTTP_SPDY)
  646. spdy = lsopt->spdy || addr[i].opt.spdy;
  647. #endif
  648. +#if (NGX_PROXY_PROTOCOL)
  649. + accept_proxy_protocol = lsopt->accept_proxy_protocol
  650. + || addr[i].opt.accept_proxy_protocol;
  651. +#endif
  652. if (lsopt->set) {
  653. @@ -1316,6 +1323,9 @@ ngx_http_add_addresses(ngx_conf_t *cf, n
  654. #if (NGX_HTTP_SPDY)
  655. addr[i].opt.spdy = spdy;
  656. #endif
  657. +#if (NGX_PROXY_PROTOCOL)
  658. + addr[i].opt.accept_proxy_protocol = accept_proxy_protocol;
  659. +#endif
  660. return NGX_OK;
  661. }
  662. @@ -1762,6 +1772,11 @@ ngx_http_add_listening(ngx_conf_t *cf, n
  663. ls->pool_size = cscf->connection_pool_size;
  664. ls->post_accept_timeout = cscf->client_header_timeout;
  665. +#if (NGX_PROXY_PROTOCOL)
  666. +// CLEANUP: ls->accept_proxy_protocol = cscf->accept_proxy_protocol;
  667. + ls->accept_proxy_protocol = addr->opt.accept_proxy_protocol;
  668. +#endif
  669. +
  670. clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
  671. ls->logp = clcf->error_log;
  672. @@ -1840,6 +1855,9 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_h
  673. #if (NGX_HTTP_SPDY)
  674. addrs[i].conf.spdy = addr[i].opt.spdy;
  675. #endif
  676. +#if (NGX_PROXY_PROTOCOL)
  677. + addrs[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
  678. +#endif
  679. if (addr[i].hash.buckets == NULL
  680. && (addr[i].wc_head == NULL
  681. @@ -1904,6 +1922,9 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_
  682. #if (NGX_HTTP_SPDY)
  683. addrs6[i].conf.spdy = addr[i].opt.spdy;
  684. #endif
  685. +#if (NGX_PROXY_PROTOCOL)
  686. + addrs6[i].conf.accept_proxy_protocol = addr[i].opt.accept_proxy_protocol;
  687. +#endif
  688. if (addr[i].hash.buckets == NULL
  689. && (addr[i].wc_head == NULL
  690. Index: nginx-1.4.7/src/http/ngx_http_core_module.c
  691. ===================================================================
  692. --- nginx-1.4.7.orig/src/http/ngx_http_core_module.c
  693. +++ nginx-1.4.7/src/http/ngx_http_core_module.c
  694. @@ -4090,6 +4090,15 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
  695. continue;
  696. }
  697. +#if (NGX_PROXY_PROTOCOL)
  698. + if (ngx_strncmp(value[n].data, "accept_proxy_protocol=on", 24) == 0) {
  699. + lsopt.accept_proxy_protocol = 1;
  700. + lsopt.set = 1;
  701. + lsopt.bind = 1;
  702. + continue;
  703. + }
  704. +#endif
  705. +
  706. if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
  707. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  708. struct sockaddr *sa;
  709. Index: nginx-1.4.7/src/http/ngx_http_core_module.h
  710. ===================================================================
  711. --- nginx-1.4.7.orig/src/http/ngx_http_core_module.h
  712. +++ nginx-1.4.7/src/http/ngx_http_core_module.h
  713. @@ -78,6 +78,11 @@ typedef struct {
  714. #if (NGX_HTTP_SPDY)
  715. unsigned spdy:1;
  716. #endif
  717. +
  718. +#if (NGX_PROXY_PROTOCOL)
  719. + unsigned accept_proxy_protocol:2;
  720. +#endif
  721. +
  722. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  723. unsigned ipv6only:1;
  724. #endif
  725. @@ -234,6 +239,10 @@ struct ngx_http_addr_conf_s {
  726. ngx_http_virtual_names_t *virtual_names;
  727. +#if (NGX_PROXY_PROTOCOL)
  728. + ngx_flag_t accept_proxy_protocol;
  729. +#endif
  730. +
  731. #if (NGX_HTTP_SSL)
  732. unsigned ssl:1;
  733. #endif
  734. Index: nginx-1.4.7/src/http/ngx_http_request.c
  735. ===================================================================
  736. --- nginx-1.4.7.orig/src/http/ngx_http_request.c
  737. +++ nginx-1.4.7/src/http/ngx_http_request.c
  738. @@ -63,6 +63,9 @@ static void ngx_http_ssl_handshake(ngx_e
  739. static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
  740. #endif
  741. +#if (NGX_PROXY_PROTOCOL)
  742. +static void ngx_http_proxy_protocol(ngx_event_t *rev);
  743. +#endif
  744. static char *ngx_http_client_errors[] = {
  745. @@ -343,6 +346,14 @@ ngx_http_init_connection(ngx_connection_
  746. }
  747. #endif
  748. +#if (NGX_PROXY_PROTOCOL)
  749. + {
  750. + if (hc->addr_conf->accept_proxy_protocol) {
  751. + rev->handler = ngx_http_proxy_protocol;
  752. + }
  753. + }
  754. +#endif
  755. +
  756. if (rev->ready) {
  757. /* the deferred accept(), rtsig, aio, iocp */
  758. @@ -364,7 +375,6 @@ ngx_http_init_connection(ngx_connection_
  759. }
  760. }
  761. -
  762. static void
  763. ngx_http_wait_request_handler(ngx_event_t *rev)
  764. {
  765. @@ -469,6 +479,12 @@ ngx_http_wait_request_handler(ngx_event_
  766. }
  767. rev->handler = ngx_http_process_request_line;
  768. +
  769. +#if (NGX_PROXY_PROTOCOL)
  770. + if (hc->addr_conf->accept_proxy_protocol)
  771. + rev->handler = ngx_http_proxy_protocol;
  772. +#endif
  773. +
  774. ngx_http_process_request_line(rev);
  775. }
  776. @@ -582,6 +598,67 @@ ngx_http_create_request(ngx_connection_t
  777. return r;
  778. }
  779. +#if (NGX_PROXY_PROTOCOL)
  780. +
  781. +static void
  782. +ngx_http_proxy_protocol(ngx_event_t *rev)
  783. +{
  784. + ssize_t n;
  785. + size_t size = 1024;
  786. + u_char tmpbuf[size];
  787. + ngx_connection_t *c;
  788. + ngx_http_connection_t *hc;
  789. +
  790. + c = rev->data;
  791. + hc = c->data;
  792. + rev->handler = ngx_http_wait_request_handler;
  793. +
  794. +#if (NGX_HTTP_SPDY)
  795. + {
  796. + if (hc->addr_conf->spdy) {
  797. + rev->handler = ngx_http_spdy_init;
  798. + }
  799. + }
  800. +#endif
  801. +
  802. +#if (NGX_HTTP_SSL)
  803. + {
  804. + if (hc->addr_conf->ssl) {
  805. + rev->handler = ngx_http_ssl_handshake;
  806. + }
  807. + }
  808. +#endif
  809. +
  810. + n = recv(c->fd, tmpbuf, size, MSG_PEEK);
  811. +
  812. + if ((n <= 0) && (c->listening)
  813. + && (hc->addr_conf->accept_proxy_protocol)
  814. + && (!c->proxy_protocol)) {
  815. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
  816. + return;
  817. + }
  818. + if ((n > 0) && (c->listening)
  819. + && (hc->addr_conf->accept_proxy_protocol)
  820. + && (!c->proxy_protocol)) {
  821. + ssize_t m;
  822. + if (!(m = ngx_recv_proxy_protocol(c, tmpbuf, n))) {
  823. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required but not found");
  824. + ngx_http_close_connection(c);
  825. + return;
  826. + }
  827. + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_http_proxy_protocol: pp required and found");
  828. +
  829. + c->proxy_protocol = 1;
  830. +
  831. + /* strip the proxy protocol string from the buffer */
  832. + recv(c->fd, tmpbuf, m, 0);
  833. + }
  834. +
  835. + rev->handler(rev);
  836. +}
  837. +
  838. +#endif
  839. +
  840. #if (NGX_HTTP_SSL)
  841. @@ -1291,6 +1368,10 @@ ngx_http_read_request_header(ngx_http_re
  842. c = r->connection;
  843. rev = c->read;
  844. +fprintf(stderr, "DEBUG: pos: %p, last: %p, start: %p, end: %p\n",
  845. + r->header_in->pos, r->header_in->last, r->header_in->start,
  846. + r->header_in->end);
  847. +
  848. n = r->header_in->last - r->header_in->pos;
  849. if (n > 0) {
  850. Index: nginx-1.4.7/src/http/ngx_http_upstream.c
  851. ===================================================================
  852. --- nginx-1.4.7.orig/src/http/ngx_http_upstream.c
  853. +++ nginx-1.4.7/src/http/ngx_http_upstream.c
  854. @@ -31,6 +31,10 @@ static ngx_int_t ngx_http_upstream_reini
  855. ngx_http_upstream_t *u);
  856. static void ngx_http_upstream_send_request(ngx_http_request_t *r,
  857. ngx_http_upstream_t *u);
  858. +#if (NGX_PROXY_PROTOCOL)
  859. +static void ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r,
  860. + ngx_http_upstream_t *u);
  861. +#endif
  862. static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
  863. ngx_http_upstream_t *u);
  864. static void ngx_http_upstream_process_header(ngx_http_request_t *r,
  865. @@ -1255,6 +1259,13 @@ ngx_http_upstream_connect(ngx_http_reque
  866. u->request_sent = 0;
  867. +#if (NGX_PROXY_PROTOCOL)
  868. + if (u->conf->send_proxy_protocol && !(u->ssl && c->ssl == NULL)) {
  869. + ngx_http_upstream_send_proxy_protocol(r, u);
  870. + return;
  871. + }
  872. +#endif
  873. +
  874. if (rc == NGX_AGAIN) {
  875. ngx_add_timer(c->write, u->conf->connect_timeout);
  876. return;
  877. @@ -1498,6 +1509,228 @@ ngx_http_upstream_send_request(ngx_http_
  878. }
  879. +#if (NGX_PROXY_PROTOCOL)
  880. +
  881. +static void
  882. +ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ngx_http_upstream_t *u)
  883. +{
  884. + size_t len;
  885. + ngx_int_t rc;
  886. + ngx_connection_t *uc;
  887. + ngx_connection_t *cc;
  888. + ngx_chain_t *pp_string;
  889. + ngx_proxy_protocol_t pp;
  890. + ngx_buf_t *b;
  891. + char port[6];
  892. + u_char *addr;
  893. + struct sockaddr_storage sa_src;
  894. + struct sockaddr_storage sa_dst;
  895. + socklen_t addrlen = NGX_SOCKADDRLEN;
  896. + struct sockaddr_in *sin_src;
  897. + struct sockaddr_in *sin_dst;
  898. +
  899. +#if (NGX_HAVE_INET6)
  900. +
  901. + struct sockaddr_in6 *sin6_src;
  902. + struct sockaddr_in6 *sin6_dst;
  903. +
  904. +#endif
  905. +
  906. +
  907. + uc = u->peer.connection;
  908. + cc = r->connection;
  909. +
  910. + if ( !(u->conf->send_proxy_protocol) ) {
  911. + return;
  912. + }
  913. +
  914. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  915. + "http upstream send proxy protocol");
  916. +
  917. + if (!u->request_sent && ngx_http_upstream_test_connect(uc) != NGX_OK) {
  918. + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
  919. + return;
  920. + }
  921. +
  922. + uc->log->action = "sending proxy protocol to upstream";
  923. +
  924. + len = 0;
  925. +
  926. + if (r->connection->proxy_protocol) {
  927. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  928. + "PP: got proxy-protocol from client connection");
  929. +
  930. + switch (cc->sockaddr->sa_family) {
  931. +
  932. +#if (NGX_HAVE_INET6)
  933. +
  934. + case AF_INET6:
  935. +
  936. + pp.pp_proto = NGX_PP_PROTO_TCP6;
  937. + sin6_dst = (struct sockaddr_in6 *) cc->local_sockaddr;
  938. + sin6_src = (struct sockaddr_in6 *) cc->sockaddr;
  939. +
  940. + break;
  941. +
  942. +#endif
  943. +
  944. + default:
  945. + pp.pp_proto = NGX_PP_PROTO_TCP4;
  946. + sin_dst = (struct sockaddr_in *) cc->local_sockaddr;
  947. + sin_src = (struct sockaddr_in *) cc->sockaddr;
  948. +
  949. + }
  950. +
  951. + } else {
  952. +
  953. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  954. + "PP: collecting information from socket fd");
  955. +
  956. + getsockname(cc->fd, (struct sockaddr *) &sa_dst, &addrlen);
  957. +
  958. + switch (sa_dst.ss_family) {
  959. +
  960. +#if (NGX_HAVE_INET6)
  961. +
  962. + case AF_INET6:
  963. +
  964. + pp.pp_proto = NGX_PP_PROTO_TCP6;
  965. + sin6_dst = (struct sockaddr_in6 *) &sa_dst;
  966. +
  967. + getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
  968. + sin6_src = (struct sockaddr_in6 *) &sa_src;
  969. +
  970. + break;
  971. +
  972. +#endif
  973. +
  974. + default:
  975. +
  976. + pp.pp_proto = NGX_PP_PROTO_TCP4;
  977. + sin_dst = (struct sockaddr_in *) &sa_dst;
  978. + getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
  979. + sin_src = (struct sockaddr_in *) &sa_src;
  980. + }
  981. +
  982. +
  983. + }
  984. +
  985. + switch (pp.pp_proto) {
  986. +
  987. +#if (NGX_HAVE_INET6)
  988. +
  989. + case NGX_PP_PROTO_TCP6:
  990. +
  991. + /* dst3 and dst4 */
  992. + addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  993. + ngx_inet_ntop(AF_INET6, &sin6_dst->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
  994. + pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  995. + pp.pp_dst3_text.len = ngx_strlen(addr);
  996. + ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
  997. + pp.pp_dst4 = htons(sin6_dst->sin6_port);
  998. +
  999. + ngx_memzero(addr, NGX_INET6_ADDRSTRLEN);
  1000. +
  1001. + /* src3 and src4 */
  1002. + ngx_inet_ntop(AF_INET6, &sin6_src->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
  1003. + pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  1004. + pp.pp_src3_text.len = ngx_strlen(addr);
  1005. + ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
  1006. + pp.pp_src4 = htons(sin6_src->sin6_port);
  1007. +
  1008. + break;
  1009. +
  1010. +#endif
  1011. +
  1012. + default:
  1013. +
  1014. + /* dst3 and dst4 */
  1015. + addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1016. + ngx_inet_ntop(AF_INET, &sin_dst->sin_addr, addr, NGX_INET_ADDRSTRLEN);
  1017. + pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1018. + pp.pp_dst3_text.len = ngx_strlen(addr);
  1019. + ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
  1020. + pp.pp_dst4 = htons(sin_dst->sin_port);
  1021. +
  1022. + ngx_memzero(addr, NGX_INET_ADDRSTRLEN);
  1023. +
  1024. + /* src3 and src4 */
  1025. + ngx_inet_ntop(AF_INET, &sin_src->sin_addr, addr, NGX_INET_ADDRSTRLEN);
  1026. + pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1027. + pp.pp_src3_text.len = ngx_strlen(addr);
  1028. + ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
  1029. + pp.pp_src4 = htons(sin_src->sin_port);
  1030. +
  1031. + }
  1032. +
  1033. + len += ngx_proxy_protocol_string_length(&pp);
  1034. +
  1035. + ngx_print_proxy_protocol(&pp, uc->log);
  1036. +
  1037. + b = ngx_create_temp_buf(uc->pool, len);
  1038. + if (b == NULL) {
  1039. + return;
  1040. + }
  1041. +
  1042. + pp_string = ngx_alloc_chain_link(uc->pool);
  1043. + if (pp_string == NULL) {
  1044. + return;
  1045. + }
  1046. +
  1047. + pp_string->buf = b;
  1048. + pp_string->next = NULL;
  1049. +
  1050. + b->last = ngx_cpymem(b->last, "PROXY ", sizeof("PROXY ") - 1);
  1051. +
  1052. + switch (pp.pp_proto) {
  1053. + case NGX_PP_PROTO_TCP4:
  1054. + b->last = ngx_cpymem(b->last, "TCP4 ", sizeof("TCP4 ") - 1);
  1055. + break;
  1056. + case NGX_PP_PROTO_TCP6:
  1057. + b->last = ngx_cpymem(b->last, "TCP6 ", sizeof("TCP6 ") - 1);
  1058. + break;
  1059. + }
  1060. +
  1061. + /* src3 */
  1062. + b->last = ngx_cpymem(b->last, pp.pp_src3_text.data, pp.pp_src3_text.len);
  1063. + b->last = ngx_cpymem(b->last, " ", 1);
  1064. +
  1065. + /* dst3 */
  1066. + b->last = ngx_cpymem(b->last, pp.pp_dst3_text.data, pp.pp_dst3_text.len);
  1067. + b->last = ngx_cpymem(b->last, " ", 1);
  1068. +
  1069. + /* src4 */
  1070. + ngx_memzero(port, 6);
  1071. + sprintf(port,"%d", pp.pp_src4);
  1072. + b->last = ngx_cpymem(b->last, port, strlen(port));
  1073. + b->last = ngx_cpymem(b->last, " ", 1);
  1074. +
  1075. + /* dst4 */
  1076. + ngx_memzero(port, 6);
  1077. + sprintf(port,"%d", pp.pp_dst4);
  1078. + b->last = ngx_cpymem(b->last, port, strlen(port));
  1079. +
  1080. + /* CRLF */
  1081. + b->last = ngx_cpymem(b->last, CRLF, sizeof(CRLF) - 1);
  1082. +
  1083. + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  1084. + "http upstream send proxy protocol: %d -%*s-",
  1085. + ngx_proxy_protocol_string_length(&pp),
  1086. + ngx_proxy_protocol_string_length(&pp) - 2,
  1087. + b->start);
  1088. +
  1089. + rc = ngx_output_chain(&u->output, pp_string);
  1090. +
  1091. + if (rc == NGX_ERROR) {
  1092. + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
  1093. + return;
  1094. + }
  1095. +
  1096. +}
  1097. +
  1098. +#endif
  1099. +
  1100. +
  1101. static void
  1102. ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
  1103. ngx_http_upstream_t *u)
  1104. Index: nginx-1.4.7/src/http/ngx_http_upstream.h
  1105. ===================================================================
  1106. --- nginx-1.4.7.orig/src/http/ngx_http_upstream.h
  1107. +++ nginx-1.4.7/src/http/ngx_http_upstream.h
  1108. @@ -188,6 +188,10 @@ typedef struct {
  1109. unsigned intercept_404:1;
  1110. unsigned change_buffering:1;
  1111. +#if (NGX_PROXY_PROTOCOL)
  1112. + ngx_flag_t send_proxy_protocol;
  1113. +#endif
  1114. +
  1115. #if (NGX_HTTP_SSL)
  1116. ngx_ssl_t *ssl;
  1117. ngx_flag_t ssl_session_reuse;
  1118. Index: nginx-1.4.7/auto/cc/gcc
  1119. ===================================================================
  1120. --- nginx-1.4.7.orig/auto/cc/gcc
  1121. +++ nginx-1.4.7/auto/cc/gcc
  1122. @@ -168,7 +168,7 @@ esac
  1123. # stop on warning
  1124. -CFLAGS="$CFLAGS -Werror"
  1125. +CFLAGS="$CFLAGS"
  1126. # debug
  1127. CFLAGS="$CFLAGS -g"
  1128. Index: nginx-1.4.7/auto/cc/icc
  1129. ===================================================================
  1130. --- nginx-1.4.7.orig/auto/cc/icc
  1131. +++ nginx-1.4.7/auto/cc/icc
  1132. @@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
  1133. esac
  1134. # stop on warning
  1135. -CFLAGS="$CFLAGS -Werror"
  1136. +CFLAGS="$CFLAGS "
  1137. # debug
  1138. CFLAGS="$CFLAGS -g"