comparison src/event/ngx_event_connect.c @ 6530:1d0e03db9f8e

Upstream: the "transparent" parameter of proxy_bind and friends. This parameter lets binding the proxy connection to a non-local address. Upstream will see the connection as coming from that address. When used with $remote_addr, upstream will accept the connection from real client address. Example: proxy_bind $remote_addr transparent;
author Roman Arutyunyan <arut@nginx.com>
date Fri, 18 Dec 2015 19:05:27 +0300
parents 8f038068f4bc
children 2c7b488a61fb
comparison
equal deleted inserted replaced
6529:cb8177ca0990 6530:1d0e03db9f8e
7 7
8 #include <ngx_config.h> 8 #include <ngx_config.h>
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_event.h> 10 #include <ngx_event.h>
11 #include <ngx_event_connect.h> 11 #include <ngx_event_connect.h>
12
13
14 #if (NGX_HAVE_TRANSPARENT_PROXY)
15 static ngx_int_t ngx_event_connect_set_transparent(ngx_peer_connection_t *pc,
16 ngx_socket_t s);
17 #endif
12 18
13 19
14 ngx_int_t 20 ngx_int_t
15 ngx_event_connect_peer(ngx_peer_connection_t *pc) 21 ngx_event_connect_peer(ngx_peer_connection_t *pc)
16 { 22 {
70 76
71 goto failed; 77 goto failed;
72 } 78 }
73 79
74 if (pc->local) { 80 if (pc->local) {
81
82 #if (NGX_HAVE_TRANSPARENT_PROXY)
83 if (pc->transparent) {
84 if (ngx_event_connect_set_transparent(pc, s) != NGX_OK) {
85 goto failed;
86 }
87 }
88 #endif
89
75 if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { 90 if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
76 ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, 91 ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
77 "bind(%V) failed", &pc->local->name); 92 "bind(%V) failed", &pc->local->name);
78 93
79 goto failed; 94 goto failed;
247 262
248 return NGX_ERROR; 263 return NGX_ERROR;
249 } 264 }
250 265
251 266
267 #if (NGX_HAVE_TRANSPARENT_PROXY)
268
269 static ngx_int_t
270 ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s)
271 {
272 int value;
273
274 value = 1;
275
276 #if defined(SO_BINDANY)
277
278 if (setsockopt(s, SOL_SOCKET, SO_BINDANY,
279 (const void *) &value, sizeof(int)) == -1)
280 {
281 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
282 "setsockopt(SO_BINDANY) failed");
283 return NGX_ERROR;
284 }
285
286 #else
287
288 switch (pc->local->sockaddr->sa_family) {
289
290 case AF_INET:
291
292 #if defined(IP_TRANSPARENT)
293
294 if (setsockopt(s, IPPROTO_IP, IP_TRANSPARENT,
295 (const void *) &value, sizeof(int)) == -1)
296 {
297 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
298 "setsockopt(IP_TRANSPARENT) failed");
299 return NGX_ERROR;
300 }
301
302 #elif defined(IP_BINDANY)
303
304 if (setsockopt(s, IPPROTO_IP, IP_BINDANY,
305 (const void *) &value, sizeof(int)) == -1)
306 {
307 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
308 "setsockopt(IP_BINDANY) failed");
309 return NGX_ERROR;
310 }
311
312 #endif
313
314 break;
315
316 #if (NGX_HAVE_INET6)
317
318 case AF_INET6:
319
320 #if defined(IPV6_TRANSPARENT)
321
322 if (setsockopt(s, IPPROTO_IPV6, IPV6_TRANSPARENT,
323 (const void *) &value, sizeof(int)) == -1)
324 {
325 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
326 "setsockopt(IPV6_TRANSPARENT) failed");
327 return NGX_ERROR;
328 }
329
330 #elif defined(IPV6_BINDANY)
331
332 if (setsockopt(s, IPPROTO_IPV6, IPV6_BINDANY,
333 (const void *) &value, sizeof(int)) == -1)
334 {
335 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
336 "setsockopt(IPV6_BINDANY) failed");
337 return NGX_ERROR;
338 }
339
340 #endif
341 break;
342
343 #endif /* NGX_HAVE_INET6 */
344
345 }
346
347 #endif /* SO_BINDANY */
348
349 return NGX_OK;
350 }
351
352 #endif
353
354
252 ngx_int_t 355 ngx_int_t
253 ngx_event_get_peer(ngx_peer_connection_t *pc, void *data) 356 ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
254 { 357 {
255 return NGX_OK; 358 return NGX_OK;
256 } 359 }