]> git.kaiwu.me - nginx.git/commitdiff
Fixed socket inheritance on reload and binary upgrade.
authorRoman Arutyunyan <arut@nginx.com>
Fri, 25 Mar 2016 11:10:38 +0000 (14:10 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Fri, 25 Mar 2016 11:10:38 +0000 (14:10 +0300)
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)".

src/core/ngx_connection.c
src/core/ngx_cycle.c

index 29aacc0359d3ef4228c0f846c483cc43fe845297..572def2632c36df2a7206a6c979e1aa3e501f05b 100644 (file)
@@ -210,6 +210,18 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
 
         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 *cycle)
 
 #endif
 
+        if (ls[i].type != SOCK_STREAM) {
+            continue;
+        }
+
 #if (NGX_HAVE_TCP_FASTOPEN)
 
         olen = sizeof(int);
index f1032668a6c4e4baf6840685ae391a510fdedb79..5785eb5b54d26bd1c15f3f40566a0fef35a3fa94 100644 (file)
@@ -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)