comparison src/event/ngx_event_connect.c @ 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 2c7b488a61fb
children 7fd6b93face8
comparison
equal deleted inserted replaced
6595:0c98c4092440 6596:e778fe9a4463
19 19
20 ngx_int_t 20 ngx_int_t
21 ngx_event_connect_peer(ngx_peer_connection_t *pc) 21 ngx_event_connect_peer(ngx_peer_connection_t *pc)
22 { 22 {
23 int rc, type; 23 int rc, type;
24 #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX)
25 in_port_t port;
26 #endif
24 ngx_int_t event; 27 ngx_int_t event;
25 ngx_err_t err; 28 ngx_err_t err;
26 ngx_uint_t level; 29 ngx_uint_t level;
27 ngx_socket_t s; 30 ngx_socket_t s;
28 ngx_event_t *rev, *wev; 31 ngx_event_t *rev, *wev;
85 goto failed; 88 goto failed;
86 } 89 }
87 } 90 }
88 #endif 91 #endif
89 92
93 #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX)
94 port = ngx_inet_get_port(pc->sockaddr);
95 #endif
96
90 #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) 97 #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT)
91 98
92 if (pc->sockaddr->sa_family != AF_UNIX) { 99 if (pc->sockaddr->sa_family != AF_UNIX && port == 0) {
93 static int bind_address_no_port = 1; 100 static int bind_address_no_port = 1;
94 101
95 if (bind_address_no_port) { 102 if (bind_address_no_port) {
96 if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 103 if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT,
97 (const void *) &bind_address_no_port, 104 (const void *) &bind_address_no_port,
106 113
107 } else { 114 } else {
108 bind_address_no_port = 0; 115 bind_address_no_port = 0;
109 } 116 }
110 } 117 }
118 }
119 }
120
121 #endif
122
123 #if (NGX_LINUX)
124
125 if (pc->type == SOCK_DGRAM && port != 0) {
126 int reuse_addr = 1;
127
128 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
129 (const void *) &reuse_addr, sizeof(int))
130 == -1)
131 {
132 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
133 "setsockopt(SO_REUSEADDR) failed");
134 goto failed;
111 } 135 }
112 } 136 }
113 137
114 #endif 138 #endif
115 139