Mercurial > hg > nginx
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 } |