Author: markt
Date: Fri Feb  1 10:28:22 2019
New Revision: 1852702

URL: http://svn.apache.org/viewvc?rev=1852702&view=rev
Log:
Track overhead and close connections with excessive overhead

Modified:
    tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
    tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java

Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java?rev=1852702&r1=1852701&r2=1852702&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2Protocol.java Fri Feb  1 
10:28:22 2019
@@ -54,6 +54,8 @@ public class Http2Protocol implements Up
     // This default is defined by the HTTP/2 specification
     static final int DEFAULT_INITIAL_WINDOW_SIZE = (1 << 16) - 1;
 
+    static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 1;
+
     private static final String HTTP_UPGRADE_NAME = "h2c";
     private static final String ALPN_NAME = "h2";
     private static final byte[] ALPN_IDENTIFIER = 
ALPN_NAME.getBytes(StandardCharsets.UTF_8);
@@ -79,6 +81,8 @@ public class Http2Protocol implements Up
     private int maxHeaderSize = Constants.DEFAULT_MAX_HEADER_SIZE;
     private int maxTrailerCount = Constants.DEFAULT_MAX_TRAILER_COUNT;
     private int maxTrailerSize = Constants.DEFAULT_MAX_TRAILER_SIZE;
+    private int overheadCountFactor = DEFAULT_OVERHEAD_COUNT_FACTOR;
+
     private boolean initiatePingDisabled = false;
     private boolean useSendfile = true;
     // Compression
@@ -306,6 +310,16 @@ public class Http2Protocol implements Up
     }
 
 
+    public int getOverheadCountFactor() {
+        return overheadCountFactor;
+    }
+
+
+    public void setOverheadCountFactor(int overheadCountFactor) {
+        this.overheadCountFactor = overheadCountFactor;
+    }
+
+
     public void setInitiatePingDisabled(boolean initiatePingDisabled) {
         this.initiatePingDisabled = initiatePingDisabled;
     }

Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1852702&r1=1852701&r2=1852702&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Fri Feb  
1 10:28:22 2019
@@ -30,6 +30,7 @@ import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.servlet.http.WebConnection;
@@ -139,6 +140,9 @@ class Http2UpgradeHandler extends Abstra
     private AtomicInteger streamConcurrency = null;
     private Queue<StreamRunnable> queuedRunnable = null;
 
+    // Track 'overhead' frames vs 'request/response' frames
+    private final AtomicLong overheadCount = new AtomicLong(-10);
+
 
     Http2UpgradeHandler(Http2Protocol protocol, Adapter adapter, Request 
coyoteRequest) {
         super (STREAM_ID_ZERO);
@@ -330,6 +334,10 @@ class Http2UpgradeHandler extends Abstra
                         }
                     }
 
+                    if (overheadCount.get() > 0) {
+                        throw new ConnectionException("Too much overhead", 
Http2Error.ENHANCE_YOUR_CALM);
+                    }
+
                     if (activeRemoteStreamCount.get() == 0) {
                         // No streams currently active. Use the keep-alive
                         // timeout for the connection.
@@ -638,6 +646,9 @@ class Http2UpgradeHandler extends Abstra
             log.debug(sm.getString("upgradeHandler.writeBody", connectionId, 
stream.getIdentifier(),
                     Integer.toString(len)));
         }
+
+        reduceOverheadCount();
+
         // Need to check this now since sending end of stream will change this.
         boolean writeable = stream.canWrite();
         byte[] header = new byte[9];
@@ -1193,6 +1204,16 @@ class Http2UpgradeHandler extends Abstra
     }
 
 
+    private void reduceOverheadCount() {
+        overheadCount.decrementAndGet();
+    }
+
+
+    private void increaseOverheadCount() {
+        overheadCount.addAndGet(getProtocol().getOverheadCountFactor());
+    }
+
+
     // ----------------------------------------------- Http2Parser.Input 
methods
 
     @Override
@@ -1247,6 +1268,7 @@ class Http2UpgradeHandler extends Abstra
 
     @Override
     public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize) 
throws Http2Exception {
+        reduceOverheadCount();
         Stream stream = getStream(streamId, true);
         stream.checkState(FrameType.DATA);
         stream.receivedData(payloadSize);
@@ -1291,6 +1313,8 @@ class Http2UpgradeHandler extends Abstra
         // determines if a new stream is created or if this stream is ignored.
         checkPauseState();
 
+        reduceOverheadCount();
+
         if (connectionState.get().isNewStreamAllowed()) {
             Stream stream = getStream(streamId, false);
             if (stream == null) {
@@ -1340,6 +1364,9 @@ class Http2UpgradeHandler extends Abstra
             throw new 
ConnectionException(sm.getString("upgradeHandler.dependency.invalid",
                     getConnectionId(), Integer.valueOf(streamId)), 
Http2Error.PROTOCOL_ERROR);
         }
+
+        increaseOverheadCount();
+
         Stream stream = getStream(streamId, false);
         if (stream == null) {
             stream = createRemoteStream(streamId);
@@ -1384,6 +1411,9 @@ class Http2UpgradeHandler extends Abstra
 
     @Override
     public void setting(Setting setting, long value) throws 
ConnectionException {
+
+        increaseOverheadCount();
+
         // Special handling required
         if (setting == Setting.INITIAL_WINDOW_SIZE) {
             long oldValue = remoteSettings.getInitialWindowSize();
@@ -1425,6 +1455,9 @@ class Http2UpgradeHandler extends Abstra
 
     @Override
     public void pingReceive(byte[] payload, boolean ack) throws IOException {
+        if (!ack) {
+            increaseOverheadCount();
+        }
         pingManager.receivePing(payload, ack);
     }
 



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

Reply via email to