diff options
| author | Roman Arutyunyan <arut@nginx.com> | 2016-06-20 12:48:47 +0300 |
|---|---|---|
| committer | Roman Arutyunyan <arut@nginx.com> | 2016-06-20 12:48:47 +0300 |
| commit | 4c03c80e12158bd6daf3c6608aca3e3acce56640 (patch) | |
| tree | cd5dbcbca88cc7a9eddfb712d26a8308caae81c1 /src | |
| parent | 05879309c11a6b62be2ffe89882cf5d8ddc1427f (diff) | |
| download | nginx-4c03c80e12158bd6daf3c6608aca3e3acce56640.tar.gz nginx-4c03c80e12158bd6daf3c6608aca3e3acce56640.tar.bz2 | |
Stream: set SO_REUSEADDR for UDP upstream sockets.
The option is only set if the socket is bound to a specific port to allow
several such sockets coexist at the same time. This is required, for example,
when nginx acts as a transparent proxy and receives two datagrams from the same
client in a short time.
The feature is only implemented for Linux.
Diffstat (limited to 'src')
| -rw-r--r-- | src/event/ngx_event_connect.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c index 9a8f4d931..30cb59a04 100644 --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -21,6 +21,9 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc, type; +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) + in_port_t port; +#endif ngx_int_t event; ngx_err_t err; ngx_uint_t level; @@ -87,9 +90,13 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) } #endif +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) + port = ngx_inet_get_port(pc->sockaddr); +#endif + #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) - if (pc->sockaddr->sa_family != AF_UNIX) { + if (pc->sockaddr->sa_family != AF_UNIX && port == 0) { static int bind_address_no_port = 1; if (bind_address_no_port) { @@ -113,6 +120,23 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) #endif +#if (NGX_LINUX) + + if (pc->type == SOCK_DGRAM && port != 0) { + int reuse_addr = 1; + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &reuse_addr, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(SO_REUSEADDR) failed"); + goto failed; + } + } + +#endif + if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, "bind(%V) failed", &pc->local->name); |
