Author: markt
Date: Mon Jul  9 11:58:18 2018
New Revision: 1835413

URL: http://svn.apache.org/viewvc?rev=1835413&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62515
When a connector is configured (via setting bindOnInit to false) to bind/unbind 
the server socket during start/stop, close the socket earlier in the stop 
process so new connections do not sit in the TCP backlog during the shutdown 
process only to be dropped as stop completes. In this scenario new connections 
will now be refused immediately.

Modified:
    tomcat/trunk/java/org/apache/catalina/core/StandardService.java
    tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
    tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
    tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardService.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardService.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardService.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardService.java Mon Jul  9 
11:58:18 2018
@@ -458,6 +458,9 @@ public class StandardService extends Lif
         synchronized (connectorsLock) {
             for (Connector connector: connectors) {
                 connector.pause();
+                // Close server socket if bound on start
+                // Note: test is in AbstractEndpoint
+                connector.getProtocolHandler().closeServerSocketGraceful();
             }
         }
 

Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Mon Jul  9 
11:58:18 2018
@@ -631,6 +631,12 @@ public abstract class AbstractProtocol<S
     }
 
 
+    @Override
+    public void closeServerSocketGraceful() {
+        endpoint.closeServerSocketGraceful();
+    }
+
+
     // ------------------------------------------- Connection handler base 
class
 
     protected static class ConnectionHandler<S> implements 
AbstractEndpoint.Handler<S> {

Modified: tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java Mon Jul  9 
11:58:18 2018
@@ -101,6 +101,14 @@ public interface ProtocolHandler {
 
 
     /**
+     * Close the server socket (to prevent further connections) if the server
+     * socket was bound on {@link #start()} (rather than on {@link #init()}
+     * but do not perform any further shutdown.
+     */
+    public void closeServerSocketGraceful();
+
+
+    /**
      * Requires APR/native library
      *
      * @return <code>true</code> if this Protocol Handler requires the

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Mon Jul  
9 11:58:18 2018
@@ -128,7 +128,7 @@ public abstract class AbstractEndpoint<S
     }
 
     protected enum BindState {
-        UNBOUND, BOUND_ON_INIT, BOUND_ON_START
+        UNBOUND, BOUND_ON_INIT, BOUND_ON_START, SOCKET_CLOSED_ON_STOP
     }
 
 
@@ -219,7 +219,8 @@ public abstract class AbstractEndpoint<S
         if (key == null || key.length() == 0) {
             throw new 
IllegalArgumentException(sm.getString("endpoint.noSslHostName"));
         }
-        if (bindState != BindState.UNBOUND && isSSLEnabled()) {
+        if (bindState != BindState.UNBOUND && bindState != 
BindState.SOCKET_CLOSED_ON_STOP &&
+                isSSLEnabled()) {
             sslHostConfig.setConfigType(getSslConfigType());
             try {
                 createSSLContext(sslHostConfig);
@@ -1153,7 +1154,7 @@ public abstract class AbstractEndpoint<S
 
     public final void stop() throws Exception {
         stopInternal();
-        if (bindState == BindState.BOUND_ON_START) {
+        if (bindState == BindState.BOUND_ON_START || bindState == 
BindState.SOCKET_CLOSED_ON_STOP) {
             unbind();
             bindState = BindState.UNBOUND;
         }
@@ -1206,6 +1207,33 @@ public abstract class AbstractEndpoint<S
         } else return -1;
     }
 
+
+    /**
+     * Close the server socket (to prevent further connections) if the server
+     * socket was originally bound on {@link #start()} (rather than on
+     * {@link #init()}).
+     *
+     * @see #getBindOnInit()
+     */
+    public final void closeServerSocketGraceful() {
+        if (bindState == BindState.BOUND_ON_START) {
+            bindState = BindState.SOCKET_CLOSED_ON_STOP;
+            try {
+                doCloseServerSocket();
+            } catch (IOException ioe) {
+                
getLog().warn(sm.getString("endpoint.serverSocket.closeFailed", getName()), 
ioe);
+            }
+        }
+    }
+
+
+    /**
+     * Actually close the server socket but don't perform any other clean-up.
+     *
+     * @throws IOException If an error occurs closing the socket
+     */
+    protected abstract void doCloseServerSocket() throws IOException;
+
     protected abstract U serverSocketAccept() throws Exception;
 
     protected abstract boolean setSocketOptions(U socket);

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Mon Jul  9 
11:58:18 2018
@@ -92,7 +92,7 @@ public class AprEndpoint extends Abstrac
     /**
      * Server socket "pointer".
      */
-    protected long serverSock = 0;
+    protected volatile long serverSock = 0;
 
 
     /**
@@ -774,11 +774,7 @@ public class AprEndpoint extends Abstrac
             serverSockPool = 0;
         }
 
-        // Close server socket if it was initialised
-        if (serverSock != 0) {
-            Socket.close(serverSock);
-            serverSock = 0;
-        }
+        doCloseServerSocket();
 
         if (sslContext != 0) {
             Long ctx = Long.valueOf(sslContext);
@@ -799,6 +795,16 @@ public class AprEndpoint extends Abstrac
     }
 
 
+    @Override
+    protected void doCloseServerSocket() {
+        // Close server socket if it was initialised
+        if (serverSock != 0) {
+            Socket.close(serverSock);
+            serverSock = 0;
+        }
+    }
+
+
     // ------------------------------------------------------ Protected Methods
 
     /**

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Mon 
Jul  9 11:58:18 2018
@@ -67,6 +67,7 @@ endpoint.removeDefaultSslHostConfig=The
 endpoint.sendfile.addfail=Sendfile failure: [{0}] [{1}]
 endpoint.sendfile.error=Unexpected sendfile error
 endpoint.sendfileThreadStop=The sendfile thread failed to stop in a timely 
manner
+endpoint.serverSocket.closeFailed=Failed to close server socket for [{0}]
 endpoint.setAttribute=Set [{0}] to [{1}]
 endpoint.timeout.err=Error processing socket timeout
 endpoint.unknownSslHostName=The SSL host name [{0}] is not recognised for this 
endpoint

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Mon Jul  9 
11:58:18 2018
@@ -70,7 +70,7 @@ public class Nio2Endpoint extends Abstra
     /**
      * Server socket "pointer".
      */
-    private AsynchronousServerSocketChannel serverSock = null;
+    private volatile AsynchronousServerSocketChannel serverSock = null;
 
     /**
      * Allows detecting if a completion handler completes inline.
@@ -227,9 +227,7 @@ public class Nio2Endpoint extends Abstra
         if (running) {
             stop();
         }
-        // Close server socket
-        serverSock.close();
-        serverSock = null;
+        doCloseServerSocket();
         destroySsl();
         super.unbind();
         // Unlike other connectors, the thread pool is tied to the server 
socket
@@ -239,6 +237,16 @@ public class Nio2Endpoint extends Abstra
         }
     }
 
+
+    @Override
+    protected void doCloseServerSocket() throws IOException {
+        // Close server socket
+        if (serverSock != null) {
+            serverSock.close();
+            serverSock = null;
+        }
+    }
+
 
     @Override
     public void shutdownExecutor() {

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Mon Jul  9 
11:58:18 2018
@@ -85,7 +85,7 @@ public class NioEndpoint extends Abstrac
     /**
      * Server socket "pointer".
      */
-    private ServerSocketChannel serverSock = null;
+    private volatile ServerSocketChannel serverSock = null;
 
     /**
      *
@@ -328,12 +328,7 @@ public class NioEndpoint extends Abstrac
         if (running) {
             stop();
         }
-        if (!getUseInheritedChannel()) {
-            // Close server socket
-            serverSock.socket().close();
-            serverSock.close();
-        }
-        serverSock = null;
+        doCloseServerSocket();
         destroySsl();
         super.unbind();
         if (getHandler() != null ) {
@@ -346,6 +341,17 @@ public class NioEndpoint extends Abstrac
     }
 
 
+    @Override
+    protected void doCloseServerSocket() throws IOException {
+        if (!getUseInheritedChannel() && serverSock != null) {
+            // Close server socket
+            serverSock.socket().close();
+            serverSock.close();
+        }
+        serverSock = null;
+    }
+
+
     // ------------------------------------------------------ Protected Methods
 
     public NioSelectorPool getSelectorPool() {

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1835413&r1=1835412&r2=1835413&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Jul  9 11:58:18 2018
@@ -88,6 +88,14 @@
         <code>Vary</code> HTTP response header to use a common utility method
         that addresses several additional edge cases. (markt)
       </fix>
+      <fix>
+        <bug>62515</bug>: When a connector is configured (via setting
+        <code>bindOnInit</code> to <code>false</code>) to bind/unbind the 
server
+        socket during start/stop, close the socket earlier in the stop process
+        so new connections do not sit in the TCP backlog during the shutdown
+        process only to be dropped as stop completes. In this scenario new
+        connections will now be refused immediately. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to