jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
changeset 30904 ec0224270f90
parent 29377 d3f457ce9c48
child 30905 bba6fefdd660
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java	Mon Jun 01 10:29:06 2015 -0400
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java	Tue Jun 02 04:01:04 2015 +0000
@@ -109,6 +109,8 @@
     private String[]            peerSupportedSignAlgs;
     private List<SNIServerName>    requestedServerNames;
 
+    private int                 negotiatedMaxFragLen;
+    private int                 maximumPacketSize;
 
     // Principals for non-certificate based cipher suites
     private Principal peerPrincipal;
@@ -177,6 +179,7 @@
         sessionCount = ++counter;
         localSupportedSignAlgs =
             SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
+        negotiatedMaxFragLen = -1;
 
         if (debug != null && Debug.isOn("session")) {
             System.out.println("%% Initialized:  " + this);
@@ -785,8 +788,30 @@
      */
     @Override
     public synchronized int getPacketBufferSize() {
-        return acceptLargeFragments ?
-                Record.maxLargeRecordSize : Record.maxRecordSize;
+        // Use the bigger packet size calculated from maximumPacketSize
+        // and negotiatedMaxFragLen.
+        int packetSize = 0;
+        if (negotiatedMaxFragLen > 0) {
+            packetSize = cipherSuite.calculatePacketSize(
+                    negotiatedMaxFragLen, protocolVersion,
+                    protocolVersion.isDTLSProtocol());
+        }
+
+        if (maximumPacketSize > 0) {
+            return (maximumPacketSize > packetSize) ?
+                    maximumPacketSize : packetSize;
+        }
+
+        if (packetSize != 0) {
+           return packetSize;
+        }
+
+        if (protocolVersion.isDTLSProtocol()) {
+            return DTLSRecord.maxRecordSize;
+        } else {
+            return acceptLargeFragments ?
+                    SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
+        }
     }
 
     /**
@@ -795,7 +820,64 @@
      */
     @Override
     public synchronized int getApplicationBufferSize() {
-        return getPacketBufferSize() - Record.headerSize;
+        // Use the bigger fragment size calculated from maximumPacketSize
+        // and negotiatedMaxFragLen.
+        int fragmentSize = 0;
+        if (maximumPacketSize > 0) {
+            fragmentSize = cipherSuite.calculateFragSize(
+                    maximumPacketSize, protocolVersion,
+                    protocolVersion.isDTLSProtocol());
+        }
+
+        if (negotiatedMaxFragLen > 0) {
+            return (negotiatedMaxFragLen > fragmentSize) ?
+                    negotiatedMaxFragLen : fragmentSize;
+        }
+
+        if (fragmentSize != 0) {
+            return fragmentSize;
+        }
+
+        if (protocolVersion.isDTLSProtocol()) {
+            return Record.maxDataSize;
+        } else {
+            int maxPacketSize = acceptLargeFragments ?
+                        SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
+            return (maxPacketSize - SSLRecord.headerSize);
+        }
+    }
+
+    /**
+     * Sets the negotiated maximum fragment length, as specified by the
+     * max_fragment_length ClientHello extension in RFC 6066.
+     *
+     * @param  negotiatedMaxFragLen
+     *         the negotiated maximum fragment length, or {@code -1} if
+     *         no such length has been negotiated.
+     */
+    synchronized void setNegotiatedMaxFragSize(
+            int negotiatedMaxFragLen) {
+
+        this.negotiatedMaxFragLen = negotiatedMaxFragLen;
+    }
+
+    /**
+     * Get the negotiated maximum fragment length, as specified by the
+     * max_fragment_length ClientHello extension in RFC 6066.
+     *
+     * @return the negotiated maximum fragment length, or {@code -1} if
+     *         no such length has been negotiated.
+     */
+    synchronized int getNegotiatedMaxFragSize() {
+        return negotiatedMaxFragLen;
+    }
+
+    synchronized void setMaximumPacketSize(int maximumPacketSize) {
+        this.maximumPacketSize = maximumPacketSize;
+    }
+
+    synchronized int getMaximumPacketSize() {
+        return maximumPacketSize;
     }
 
     /**