3232import org .neo4j .driver .internal .net .BoltServerAddress ;
3333import org .neo4j .driver .v1 .Logger ;
3434import org .neo4j .driver .internal .util .BytePrinter ;
35+ import org .neo4j .driver .internal .util .BytePrinter ;
36+ import org .neo4j .driver .v1 .Config .TrustStrategy ;
37+ import org .neo4j .driver .v1 .Logger ;
3538import org .neo4j .driver .v1 .exceptions .ClientException ;
3639
3740import static javax .net .ssl .SSLEngineResult .HandshakeStatus .FINISHED ;
@@ -67,8 +70,7 @@ public class TLSSocketChannel implements ByteChannel
6770 public TLSSocketChannel ( BoltServerAddress address , SecurityPlan securityPlan , ByteChannel channel , Logger logger )
6871 throws GeneralSecurityException , IOException
6972 {
70- this (channel , logger , createSSLEngine ( address , createSSLContext ( securityPlan ) ) );
71-
73+ this ( channel , logger , createSSLEngine ( address , securityPlan .sslContext () ) );
7274 }
7375
7476 public TLSSocketChannel ( ByteChannel channel , Logger logger , SSLEngine sslEngine ) throws GeneralSecurityException , IOException
@@ -163,8 +165,8 @@ private HandshakeStatus runDelegatedTasks()
163165 * To verify if deciphering is done successfully, we could check if any bytes has been read into {@code buffer},
164166 * as the deciphered bytes will only be saved into {@code buffer} when deciphering is carried out successfully.
165167 *
166- * @param buffer
167- * @return
168+ * @param buffer to read data into.
169+ * @return The status of the current handshake.
168170 * @throws IOException
169171 */
170172 private HandshakeStatus unwrap ( ByteBuffer buffer ) throws IOException
@@ -261,7 +263,7 @@ private HandshakeStatus unwrap( ByteBuffer buffer ) throws IOException
261263 * a loop
262264 *
263265 * @param buffer contains the bytes to send to channel
264- * @return
266+ * @return The status of the current handshake
265267 * @throws IOException
266268 */
267269 private HandshakeStatus wrap ( ByteBuffer buffer ) throws IOException
@@ -277,7 +279,7 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
277279 case OK :
278280 handshakeStatus = runDelegatedTasks ();
279281 cipherOut .flip ();
280- while ( cipherOut .hasRemaining ())
282+ while ( cipherOut .hasRemaining () )
281283 {
282284 channel .write ( cipherOut );
283285 }
@@ -287,19 +289,30 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
287289 // Enlarge the buffer and return the old status
288290 int curNetSize = cipherOut .capacity ();
289291 int netSize = sslEngine .getSession ().getPacketBufferSize ();
290- if ( curNetSize >= netSize || buffer . capacity () > netSize )
292+ if ( netSize > curNetSize )
291293 {
292- // TODO
293- throw new ClientException (
294- String .format ( "Failed to enlarge network buffer from %s to %s. This is either because the " +
295- "new size is however less than the old size, or because the application " +
296- "buffer size %s is so big that the application data still cannot fit into the " +
297- "new network buffer." , curNetSize , netSize , buffer .capacity () ) );
294+ // enlarge the peer application data buffer
295+ cipherOut = ByteBuffer .allocate ( netSize );
296+ logger .debug ( "Enlarged network output buffer from %s to %s. " +
297+ "This operation should be a rare operation." , curNetSize , netSize );
298+ }
299+ else
300+ {
301+ // flush as much data as possible
302+ cipherOut .flip ();
303+ int written = channel .write ( cipherOut );
304+ if (written == 0 )
305+ {
306+ throw new ClientException (
307+ String .format (
308+ "Failed to enlarge network buffer from %s to %s. This is either because the " +
309+ "new size is however less than the old size, or because the application " +
310+ "buffer size %s is so big that the application data still cannot fit into the " +
311+ "new network buffer." , curNetSize , netSize , buffer .capacity () ) );
312+ }
313+ cipherOut .compact ();
314+ logger .debug ( "Network output buffer couldn't be enlarged, flushing data to the channel instead." );
298315 }
299-
300- cipherOut = ByteBuffer .allocate ( netSize );
301- logger .debug ( "Enlarged network output buffer from %s to %s. " +
302- "This operation should be a rare operation." , curNetSize , netSize );
303316 break ;
304317 default :
305318 throw new ClientException ( "Got unexpected status " + status );
@@ -320,9 +333,9 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
320333 * After the method call, the new position of {@code from.pos} will be {@code from.pos + p}, and similarly,
321334 * the new position of {@code to.pos} will be {@code to.pos + p}
322335 *
323- * @param from
324- * @param to
325- * @return
336+ * @param from buffer to copy from
337+ * @param to buffer to copy to
338+ * @return the number of transferred bytes
326339 */
327340 static int bufferCopy ( ByteBuffer from , ByteBuffer to )
328341 {
@@ -339,25 +352,10 @@ static int bufferCopy( ByteBuffer from, ByteBuffer to )
339352 return maxTransfer ;
340353 }
341354
342- /**
343- * Create an SSLContext based on a given SecurityPlan.
344- *
345- * @param securityPlan
346- * @return
347- * @throws GeneralSecurityException
348- * @throws IOException
349- */
350- private static SSLContext createSSLContext ( SecurityPlan securityPlan ) throws GeneralSecurityException , IOException
351- {
352- SSLContext sslContext = SSLContext .getInstance ( "TLS" );
353- sslContext .init ( new KeyManager [0 ], securityPlan .trustManagers (), null );
354- return sslContext ;
355- }
356-
357355 /**
358356 * Create SSLEngine with the SSLContext just created.
359- * @param address
360- * @param sslContext
357+ * @param address the host to connect to
358+ * @param sslContext the current ssl context
361359 */
362360 private static SSLEngine createSSLEngine ( BoltServerAddress address , SSLContext sslContext )
363361 {
@@ -445,10 +443,10 @@ public void close() throws IOException
445443 channel .close ();
446444 logger .debug ( "~~ [CLOSED SECURE CHANNEL]" );
447445 }
448- catch ( IOException e )
446+ catch ( IOException e )
449447 {
450448 // Treat this as ok - the connection is closed, even if the TLS session did not exit cleanly.
451- logger .warn ( "TLS socket could not be closed cleanly: '" + e .getMessage ()+ "'" , e );
449+ logger .warn ( "TLS socket could not be closed cleanly: '" + e .getMessage () + "'" , e );
452450 }
453451 }
454452
0 commit comments