No Description

400-nginx-1.4.x_proxy_protocol_patch_v2.patch 34KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183
  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. Index: nginx-1.4.7/src/http/ngx_http_upstream.c
  842. ===================================================================
  843. --- nginx-1.4.7.orig/src/http/ngx_http_upstream.c
  844. +++ nginx-1.4.7/src/http/ngx_http_upstream.c
  845. @@ -31,6 +31,10 @@ static ngx_int_t ngx_http_upstream_reini
  846. ngx_http_upstream_t *u);
  847. static void ngx_http_upstream_send_request(ngx_http_request_t *r,
  848. ngx_http_upstream_t *u);
  849. +#if (NGX_PROXY_PROTOCOL)
  850. +static void ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r,
  851. + ngx_http_upstream_t *u);
  852. +#endif
  853. static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
  854. ngx_http_upstream_t *u);
  855. static void ngx_http_upstream_process_header(ngx_http_request_t *r,
  856. @@ -1255,6 +1259,13 @@ ngx_http_upstream_connect(ngx_http_reque
  857. u->request_sent = 0;
  858. +#if (NGX_PROXY_PROTOCOL)
  859. + if (u->conf->send_proxy_protocol && !(u->ssl && c->ssl == NULL)) {
  860. + ngx_http_upstream_send_proxy_protocol(r, u);
  861. + return;
  862. + }
  863. +#endif
  864. +
  865. if (rc == NGX_AGAIN) {
  866. ngx_add_timer(c->write, u->conf->connect_timeout);
  867. return;
  868. @@ -1498,6 +1509,228 @@ ngx_http_upstream_send_request(ngx_http_
  869. }
  870. +#if (NGX_PROXY_PROTOCOL)
  871. +
  872. +static void
  873. +ngx_http_upstream_send_proxy_protocol(ngx_http_request_t *r, ngx_http_upstream_t *u)
  874. +{
  875. + size_t len;
  876. + ngx_int_t rc;
  877. + ngx_connection_t *uc;
  878. + ngx_connection_t *cc;
  879. + ngx_chain_t *pp_string;
  880. + ngx_proxy_protocol_t pp;
  881. + ngx_buf_t *b;
  882. + char port[6];
  883. + u_char *addr;
  884. + struct sockaddr_storage sa_src;
  885. + struct sockaddr_storage sa_dst;
  886. + socklen_t addrlen = NGX_SOCKADDRLEN;
  887. + struct sockaddr_in *sin_src;
  888. + struct sockaddr_in *sin_dst;
  889. +
  890. +#if (NGX_HAVE_INET6)
  891. +
  892. + struct sockaddr_in6 *sin6_src;
  893. + struct sockaddr_in6 *sin6_dst;
  894. +
  895. +#endif
  896. +
  897. +
  898. + uc = u->peer.connection;
  899. + cc = r->connection;
  900. +
  901. + if ( !(u->conf->send_proxy_protocol) ) {
  902. + return;
  903. + }
  904. +
  905. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  906. + "http upstream send proxy protocol");
  907. +
  908. + if (!u->request_sent && ngx_http_upstream_test_connect(uc) != NGX_OK) {
  909. + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
  910. + return;
  911. + }
  912. +
  913. + uc->log->action = "sending proxy protocol to upstream";
  914. +
  915. + len = 0;
  916. +
  917. + if (r->connection->proxy_protocol) {
  918. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  919. + "PP: got proxy-protocol from client connection");
  920. +
  921. + switch (cc->sockaddr->sa_family) {
  922. +
  923. +#if (NGX_HAVE_INET6)
  924. +
  925. + case AF_INET6:
  926. +
  927. + pp.pp_proto = NGX_PP_PROTO_TCP6;
  928. + sin6_dst = (struct sockaddr_in6 *) cc->local_sockaddr;
  929. + sin6_src = (struct sockaddr_in6 *) cc->sockaddr;
  930. +
  931. + break;
  932. +
  933. +#endif
  934. +
  935. + default:
  936. + pp.pp_proto = NGX_PP_PROTO_TCP4;
  937. + sin_dst = (struct sockaddr_in *) cc->local_sockaddr;
  938. + sin_src = (struct sockaddr_in *) cc->sockaddr;
  939. +
  940. + }
  941. +
  942. + } else {
  943. +
  944. + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  945. + "PP: collecting information from socket fd");
  946. +
  947. + getsockname(cc->fd, (struct sockaddr *) &sa_dst, &addrlen);
  948. +
  949. + switch (sa_dst.ss_family) {
  950. +
  951. +#if (NGX_HAVE_INET6)
  952. +
  953. + case AF_INET6:
  954. +
  955. + pp.pp_proto = NGX_PP_PROTO_TCP6;
  956. + sin6_dst = (struct sockaddr_in6 *) &sa_dst;
  957. +
  958. + getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
  959. + sin6_src = (struct sockaddr_in6 *) &sa_src;
  960. +
  961. + break;
  962. +
  963. +#endif
  964. +
  965. + default:
  966. +
  967. + pp.pp_proto = NGX_PP_PROTO_TCP4;
  968. + sin_dst = (struct sockaddr_in *) &sa_dst;
  969. + getpeername(cc->fd, (struct sockaddr *) &sa_src, &addrlen);
  970. + sin_src = (struct sockaddr_in *) &sa_src;
  971. + }
  972. +
  973. +
  974. + }
  975. +
  976. + switch (pp.pp_proto) {
  977. +
  978. +#if (NGX_HAVE_INET6)
  979. +
  980. + case NGX_PP_PROTO_TCP6:
  981. +
  982. + /* dst3 and dst4 */
  983. + addr = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  984. + ngx_inet_ntop(AF_INET6, &sin6_dst->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
  985. + pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  986. + pp.pp_dst3_text.len = ngx_strlen(addr);
  987. + ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
  988. + pp.pp_dst4 = htons(sin6_dst->sin6_port);
  989. +
  990. + ngx_memzero(addr, NGX_INET6_ADDRSTRLEN);
  991. +
  992. + /* src3 and src4 */
  993. + ngx_inet_ntop(AF_INET6, &sin6_src->sin6_addr, addr, NGX_INET6_ADDRSTRLEN);
  994. + pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET6_ADDRSTRLEN);
  995. + pp.pp_src3_text.len = ngx_strlen(addr);
  996. + ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
  997. + pp.pp_src4 = htons(sin6_src->sin6_port);
  998. +
  999. + break;
  1000. +
  1001. +#endif
  1002. +
  1003. + default:
  1004. +
  1005. + /* dst3 and dst4 */
  1006. + addr = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1007. + ngx_inet_ntop(AF_INET, &sin_dst->sin_addr, addr, NGX_INET_ADDRSTRLEN);
  1008. + pp.pp_dst3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1009. + pp.pp_dst3_text.len = ngx_strlen(addr);
  1010. + ngx_memcpy(pp.pp_dst3_text.data, addr, pp.pp_dst3_text.len);
  1011. + pp.pp_dst4 = htons(sin_dst->sin_port);
  1012. +
  1013. + ngx_memzero(addr, NGX_INET_ADDRSTRLEN);
  1014. +
  1015. + /* src3 and src4 */
  1016. + ngx_inet_ntop(AF_INET, &sin_src->sin_addr, addr, NGX_INET_ADDRSTRLEN);
  1017. + pp.pp_src3_text.data = ngx_pcalloc(r->pool, NGX_INET_ADDRSTRLEN);
  1018. + pp.pp_src3_text.len = ngx_strlen(addr);
  1019. + ngx_memcpy(pp.pp_src3_text.data, addr, pp.pp_src3_text.len);
  1020. + pp.pp_src4 = htons(sin_src->sin_port);
  1021. +
  1022. + }
  1023. +
  1024. + len += ngx_proxy_protocol_string_length(&pp);
  1025. +
  1026. + ngx_print_proxy_protocol(&pp, uc->log);
  1027. +
  1028. + b = ngx_create_temp_buf(uc->pool, len);
  1029. + if (b == NULL) {
  1030. + return;
  1031. + }
  1032. +
  1033. + pp_string = ngx_alloc_chain_link(uc->pool);
  1034. + if (pp_string == NULL) {
  1035. + return;
  1036. + }
  1037. +
  1038. + pp_string->buf = b;
  1039. + pp_string->next = NULL;
  1040. +
  1041. + b->last = ngx_cpymem(b->last, "PROXY ", sizeof("PROXY ") - 1);
  1042. +
  1043. + switch (pp.pp_proto) {
  1044. + case NGX_PP_PROTO_TCP4:
  1045. + b->last = ngx_cpymem(b->last, "TCP4 ", sizeof("TCP4 ") - 1);
  1046. + break;
  1047. + case NGX_PP_PROTO_TCP6:
  1048. + b->last = ngx_cpymem(b->last, "TCP6 ", sizeof("TCP6 ") - 1);
  1049. + break;
  1050. + }
  1051. +
  1052. + /* src3 */
  1053. + b->last = ngx_cpymem(b->last, pp.pp_src3_text.data, pp.pp_src3_text.len);
  1054. + b->last = ngx_cpymem(b->last, " ", 1);
  1055. +
  1056. + /* dst3 */
  1057. + b->last = ngx_cpymem(b->last, pp.pp_dst3_text.data, pp.pp_dst3_text.len);
  1058. + b->last = ngx_cpymem(b->last, " ", 1);
  1059. +
  1060. + /* src4 */
  1061. + ngx_memzero(port, 6);
  1062. + sprintf(port,"%d", pp.pp_src4);
  1063. + b->last = ngx_cpymem(b->last, port, strlen(port));
  1064. + b->last = ngx_cpymem(b->last, " ", 1);
  1065. +
  1066. + /* dst4 */
  1067. + ngx_memzero(port, 6);
  1068. + sprintf(port,"%d", pp.pp_dst4);
  1069. + b->last = ngx_cpymem(b->last, port, strlen(port));
  1070. +
  1071. + /* CRLF */
  1072. + b->last = ngx_cpymem(b->last, CRLF, sizeof(CRLF) - 1);
  1073. +
  1074. + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, uc->log, 0,
  1075. + "http upstream send proxy protocol: %d -%*s-",
  1076. + ngx_proxy_protocol_string_length(&pp),
  1077. + ngx_proxy_protocol_string_length(&pp) - 2,
  1078. + b->start);
  1079. +
  1080. + rc = ngx_output_chain(&u->output, pp_string);
  1081. +
  1082. + if (rc == NGX_ERROR) {
  1083. + ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
  1084. + return;
  1085. + }
  1086. +
  1087. +}
  1088. +
  1089. +#endif
  1090. +
  1091. +
  1092. static void
  1093. ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
  1094. ngx_http_upstream_t *u)
  1095. Index: nginx-1.4.7/src/http/ngx_http_upstream.h
  1096. ===================================================================
  1097. --- nginx-1.4.7.orig/src/http/ngx_http_upstream.h
  1098. +++ nginx-1.4.7/src/http/ngx_http_upstream.h
  1099. @@ -188,6 +188,10 @@ typedef struct {
  1100. unsigned intercept_404:1;
  1101. unsigned change_buffering:1;
  1102. +#if (NGX_PROXY_PROTOCOL)
  1103. + ngx_flag_t send_proxy_protocol;
  1104. +#endif
  1105. +
  1106. #if (NGX_HTTP_SSL)
  1107. ngx_ssl_t *ssl;
  1108. ngx_flag_t ssl_session_reuse;
  1109. Index: nginx-1.4.7/auto/cc/gcc
  1110. ===================================================================
  1111. --- nginx-1.4.7.orig/auto/cc/gcc
  1112. +++ nginx-1.4.7/auto/cc/gcc
  1113. @@ -168,7 +168,7 @@ esac
  1114. # stop on warning
  1115. -CFLAGS="$CFLAGS -Werror"
  1116. +CFLAGS="$CFLAGS"
  1117. # debug
  1118. CFLAGS="$CFLAGS -g"
  1119. Index: nginx-1.4.7/auto/cc/icc
  1120. ===================================================================
  1121. --- nginx-1.4.7.orig/auto/cc/icc
  1122. +++ nginx-1.4.7/auto/cc/icc
  1123. @@ -115,7 +115,7 @@ case "$NGX_ICC_VER" in
  1124. esac
  1125. # stop on warning
  1126. -CFLAGS="$CFLAGS -Werror"
  1127. +CFLAGS="$CFLAGS "
  1128. # debug
  1129. CFLAGS="$CFLAGS -g"