Skip to content

Commit feeee03

Browse files
committed
flush data on BUFFER_OVERFLOW
1 parent cd48e63 commit feeee03

File tree

2 files changed

+53
-24
lines changed

2 files changed

+53
-24
lines changed

driver/src/main/java/org/neo4j/driver/internal/connector/socket/TLSSocketChannel.java

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
2929
import javax.net.ssl.SSLEngineResult.Status;
3030

31-
import org.neo4j.driver.v1.Logger;
3231
import org.neo4j.driver.internal.util.BytePrinter;
3332
import org.neo4j.driver.v1.Config.TrustStrategy;
33+
import org.neo4j.driver.v1.Logger;
3434
import org.neo4j.driver.v1.exceptions.ClientException;
3535

3636
import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED;
@@ -163,8 +163,8 @@ private HandshakeStatus runDelegatedTasks()
163163
* To verify if deciphering is done successfully, we could check if any bytes has been read into {@code buffer},
164164
* as the deciphered bytes will only be saved into {@code buffer} when deciphering is carried out successfully.
165165
*
166-
* @param buffer
167-
* @return
166+
* @param buffer to read data into.
167+
* @return The status of the current handshake.
168168
* @throws IOException
169169
*/
170170
private HandshakeStatus unwrap( ByteBuffer buffer ) throws IOException
@@ -261,7 +261,7 @@ private HandshakeStatus unwrap( ByteBuffer buffer ) throws IOException
261261
* a loop
262262
*
263263
* @param buffer contains the bytes to send to channel
264-
* @return
264+
* @return The status of the current handshake
265265
* @throws IOException
266266
*/
267267
private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
@@ -277,7 +277,7 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
277277
case OK:
278278
handshakeStatus = runDelegatedTasks();
279279
cipherOut.flip();
280-
while(cipherOut.hasRemaining())
280+
while ( cipherOut.hasRemaining() )
281281
{
282282
channel.write( cipherOut );
283283
}
@@ -287,19 +287,30 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
287287
// Enlarge the buffer and return the old status
288288
int curNetSize = cipherOut.capacity();
289289
int netSize = sslEngine.getSession().getPacketBufferSize();
290-
if ( curNetSize >= netSize || buffer.capacity() > netSize )
290+
if ( netSize > curNetSize )
291291
{
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." );
298313
}
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 );
303314
break;
304315
default:
305316
throw new ClientException( "Got unexpected status " + status );
@@ -320,9 +331,9 @@ private HandshakeStatus wrap( ByteBuffer buffer ) throws IOException
320331
* After the method call, the new position of {@code from.pos} will be {@code from.pos + p}, and similarly,
321332
* the new position of {@code to.pos} will be {@code to.pos + p}
322333
*
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
326337
*/
327338
static int bufferCopy( ByteBuffer from, ByteBuffer to )
328339
{
@@ -341,9 +352,9 @@ static int bufferCopy( ByteBuffer from, ByteBuffer to )
341352

342353
/**
343354
* 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
347358
*/
348359
private static SSLEngine createSSLEngine( String host, int port, SSLContext sslContext )
349360
{
@@ -431,10 +442,10 @@ public void close() throws IOException
431442
channel.close();
432443
logger.debug( "TLS connection closed" );
433444
}
434-
catch(IOException e)
445+
catch ( IOException e )
435446
{
436447
// 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 );
438449
}
439450
}
440451

driver/src/test/java/org/neo4j/driver/v1/integration/TLSSocketChannelFragmentation.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/**
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
119
package org.neo4j.driver.v1.integration;
220

321
import org.junit.Before;

0 commit comments

Comments
 (0)