Mercurial > hg > nginx
changeset 6596:e778fe9a4463
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.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Mon, 20 Jun 2016 12:48:47 +0300 |
parents | 0c98c4092440 |
children | 0a820872dd4c |
files | src/event/ngx_event_connect.c |
diffstat | 1 files changed, 25 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/event/ngx_event_connect.c Mon Jun 20 11:50:44 2016 +0300 +++ b/src/event/ngx_event_connect.c Mon Jun 20 12:48:47 2016 +0300 @@ -21,6 +21,9 @@ 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 @@ } #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 @@ #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);