# HG changeset patch # User Roman Arutyunyan # Date 1458904238 -10800 # Node ID fd4b52e74f96aa51b6a2e70f07f0a3154d3d501e # Parent a01e315b3a7881ca7e716974f32ac7d2b4453680 Fixed socket inheritance on reload and binary upgrade. On nginx reload or binary upgrade, an attempt is made to inherit listen sockets from the previous configuration. Previously, no check for socket type was made and the inherited socket could have the wrong type. On binary upgrade, socket type was not detected at all. Wrong socket type could lead to errors on that socket due to different logic and unsupported syscalls. For example, a UDP socket, inherited as TCP, lead to the following error after arrival of a datagram: "accept() failed (102: Operation not supported on socket)". diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -210,6 +210,18 @@ ngx_set_inherited_sockets(ngx_cycle_t *c olen = sizeof(int); + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_TYPE, (void *) &ls[i].type, + &olen) + == -1) + { + ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno, + "getsockopt(SO_TYPE) %V failed", &ls[i].addr_text); + ls[i].ignore = 1; + continue; + } + + olen = sizeof(int); + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf, &olen) == -1) @@ -274,6 +286,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *c #endif + if (ls[i].type != SOCK_STREAM) { + continue; + } + #if (NGX_HAVE_TCP_FASTOPEN) olen = sizeof(int); diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -512,6 +512,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) continue; } + if (ls[i].type != nls[n].type) { + continue; + } + if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen, ls[i].sockaddr, ls[i].socklen, 1) == NGX_OK)