# HG changeset patch # User Andrei Belov # Date 1466408477 -10800 # Node ID 2c7b488a61fbbd36054bc7410c161ce73b7624b9 # Parent 04d8d1f8564989509f9b03085df1af7618b44be8 Set IP_BIND_ADDRESS_NO_PORT socket option for upstream sockets. diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -341,6 +341,19 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +# Linux IP_BIND_ADDRESS_NO_PORT + +ngx_feature="IP_BIND_ADDRESS_NO_PORT" +ngx_feature_name="NGX_HAVE_IP_BIND_ADDRESS_NO_PORT" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, NULL, 0)" +. auto/feature + + # Linux transparent proxying ngx_feature="IP_TRANSPARENT" diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -87,6 +87,32 @@ ngx_event_connect_peer(ngx_peer_connecti } #endif +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) + + if (pc->sockaddr->sa_family != AF_UNIX) { + static int bind_address_no_port = 1; + + if (bind_address_no_port) { + if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, + (const void *) &bind_address_no_port, + sizeof(int)) == -1) + { + err = ngx_socket_errno; + + if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) { + ngx_log_error(NGX_LOG_ALERT, pc->log, err, + "setsockopt(IP_BIND_ADDRESS_NO_PORT) " + "failed, ignored"); + + } else { + bind_address_no_port = 0; + } + } + } + } + +#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);