users@grizzly.java.net

Re: SSL BUFFER_OVERFLOW problem

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Wed, 22 Apr 2009 15:28:19 +0200

>> I created a test file of around 17k and POSTed it (non-chunked) to
>> grizzly server using the "curl" command line http client.
>> Most of the time the GrizzlyAdapter reads all of the bytes posted
>> from the curl client . However, occasionally only part of the data
>> is read, and "is.read(bytes)" in my GrizzlyAdapter blocks for 30
>> seconds (the read timeout) eventually returning -1.
>> I think I have tracked the issue to a problem with how Grizzly
>> handles a SSLEngine BUFFER_OVERFLOW. If the byte buffer associated
>> with the WorkerThread is not large enough to contain the decrypted
>> data from the SSLEngine, SSLUtils:214 allocates a larger one:
>> case BUFFER_OVERFLOW:
>> byteBuffer = reallocate(byteBuffer);
>> break;
>> However, it seems the WorkerThread is never updated with a
>> reference to this new byteBuffer. So the data in the larger
>> reallocated byte buffer is 'lost'. Therefore when my GrizzlyAdapter
>> comes to read the bytes from the InputStream, it can only read as
>> much as was in the original WorkerThread byte buffer. The
>> underlying Grizzly implementation of the InputStream knows that
>> there should be more data available (from the value of the http
>> content-length header), so it creates a temporary selector to read
>> the data... but the data has already been read and discarded, so
>> is.read(bytes) sits there waiting until the read timeout is
>> triggered.
>
> You are right. We need to re-attach that ByteBuffer to the thread.
IMHO better solution could be "not reallocate buffer at all", cause
for example InputReader is not aware of any thread associated
ByteBuffer. It uses internal ByteBuffer.
I think the problem with unwrapAll - is that plain ByteBuffer has
enough place just for one SSL block to be decoded, and when we try to
decode more blocks - it fails with BUFFER_OVERFLOW. Reallocation could
solve the issue temporary, but we can not be sure reallocated
ByteBuffer size will be enough to decode *all* available SSL blocks.
But if we will work with original ByteBuffer, which could be used just
for single SSL block decoding, and meet BUFFER_OVERFLOW - we return
ready decoded data, and the rest of SSL data will be decoded next time
unwrapAll will be called.

What do you think?

WBR,
Alexey.

>
>
>
>> This problem is very dependent on network conditions; a
>> BUFFER_OVERFLOW only happens occasionally. However, if I put a
>> break point in the SSLUtils.unwrap() method, this generally causes
>> the encrypted input buffer to fill up such that a BUFFER_OVERFLOW
>> is triggered.
>> Is this a bug, or am I simply not configuring grizzly correctly?
>
> A bug
>
> Issue
>> https://grizzly.dev.java.net/issues/show_bug.cgi?id=501 did seem
>> similar, but that was fixed in 1.9.11, and I am using 1.9.14.
>
> Can you file an issue? I will go ahead and work on a fix and attach
> a patch to the issue so you can test it. If it works, I will commit
> and can release an official release if you needs it.
>
> Thanks!!
>
> -- Jeanfrancois
>
>
>> Any help would be much appreciated!
>> Thanks,
>> Tom
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>