28
28
import javax .net .ssl .SSLEngineResult .HandshakeStatus ;
29
29
import javax .net .ssl .SSLEngineResult .Status ;
30
30
31
- import org .neo4j .driver .v1 .Logger ;
32
31
import org .neo4j .driver .internal .util .BytePrinter ;
33
32
import org .neo4j .driver .v1 .Config .TrustStrategy ;
33
+ import org .neo4j .driver .v1 .Logger ;
34
34
import org .neo4j .driver .v1 .exceptions .ClientException ;
35
35
36
36
import static javax .net .ssl .SSLEngineResult .HandshakeStatus .FINISHED ;
@@ -163,8 +163,8 @@ private HandshakeStatus runDelegatedTasks()
163
163
* To verify if deciphering is done successfully, we could check if any bytes has been read into {@code buffer},
164
164
* as the deciphered bytes will only be saved into {@code buffer} when deciphering is carried out successfully.
165
165
*
166
- * @param buffer
167
- * @return
166
+ * @param buffer to read data into.
167
+ * @return The status of the current handshake.
168
168
* @throws IOException
169
169
*/
170
170
private HandshakeStatus unwrap ( ByteBuffer buffer ) throws IOException
@@ -261,7 +261,7 @@ private HandshakeStatus unwrap( ByteBuffer buffer ) throws IOException
261
261
* a loop
262
262
*
263
263
* @param buffer contains the bytes to send to channel
264
- * @return
264
+ * @return The status of the current handshake
265
265
* @throws IOException
266
266
*/
267
267
private HandshakeStatus wrap ( ByteBuffer buffer ) throws IOException
@@ -277,7 +277,7 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
277
277
case OK :
278
278
handshakeStatus = runDelegatedTasks ();
279
279
cipherOut .flip ();
280
- while ( cipherOut .hasRemaining ())
280
+ while ( cipherOut .hasRemaining () )
281
281
{
282
282
channel .write ( cipherOut );
283
283
}
@@ -287,19 +287,30 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
287
287
// Enlarge the buffer and return the old status
288
288
int curNetSize = cipherOut .capacity ();
289
289
int netSize = sslEngine .getSession ().getPacketBufferSize ();
290
- if ( curNetSize >= netSize || buffer . capacity () > netSize )
290
+ if ( netSize > curNetSize )
291
291
{
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 () ) );
292
+ // enlarge the peer application data buffer
293
+ cipherOut = ByteBuffer .allocate ( netSize );
294
+ logger .debug ( "Enlarged network output buffer from %s to %s. " +
295
+ "This operation should be a rare operation." , curNetSize , netSize );
296
+ }
297
+ else
298
+ {
299
+ // flush as much data as possible
300
+ cipherOut .flip ();
301
+ int written = channel .write ( cipherOut );
302
+ if (written == 0 )
303
+ {
304
+ throw new ClientException (
305
+ String .format (
306
+ "Failed to enlarge network buffer from %s to %s. This is either because the " +
307
+ "new size is however less than the old size, or because the application " +
308
+ "buffer size %s is so big that the application data still cannot fit into the " +
309
+ "new network buffer." , curNetSize , netSize , buffer .capacity () ) );
310
+ }
311
+ cipherOut .compact ();
312
+ logger .debug ( "Network output buffer couldn't be enlarged, flushing data to the channel instead." );
298
313
}
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 );
303
314
break ;
304
315
default :
305
316
throw new ClientException ( "Got unexpected status " + status );
@@ -320,9 +331,9 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
320
331
* After the method call, the new position of {@code from.pos} will be {@code from.pos + p}, and similarly,
321
332
* the new position of {@code to.pos} will be {@code to.pos + p}
322
333
*
323
- * @param from
324
- * @param to
325
- * @return
334
+ * @param from buffer to copy from
335
+ * @param to buffer to copy to
336
+ * @return the number of transferred bytes
326
337
*/
327
338
static int bufferCopy ( ByteBuffer from , ByteBuffer to )
328
339
{
@@ -341,9 +352,9 @@ static int bufferCopy( ByteBuffer from, ByteBuffer to )
341
352
342
353
/**
343
354
* Create SSLEngine with the SSLContext just created.
344
- * @param host
345
- * @param port
346
- * @param sslContext
355
+ * @param host the host to connect to
356
+ * @param port the port to connect to
357
+ * @param sslContext the current ssl context
347
358
*/
348
359
private static SSLEngine createSSLEngine ( String host , int port , SSLContext sslContext )
349
360
{
@@ -431,10 +442,10 @@ public void close() throws IOException
431
442
channel .close ();
432
443
logger .debug ( "TLS connection closed" );
433
444
}
434
- catch ( IOException e )
445
+ catch ( IOException e )
435
446
{
436
447
// Treat this as ok - the connection is closed, even if the TLS session did not exit cleanly.
437
- logger .warn ( "TLS socket could not be closed cleanly: '" + e .getMessage ()+ "'" , e );
448
+ logger .warn ( "TLS socket could not be closed cleanly: '" + e .getMessage () + "'" , e );
438
449
}
439
450
}
440
451
0 commit comments