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