| | |
| | | // Synchronize SSL unwrap with channel reads. |
| | | synchronized (unwrapLock) |
| | | { |
| | | // Repeat if there is underflow or overflow. |
| | | // Read SSL packets until some unwrapped data is produced or no more |
| | | // data is available on the underlying channel. |
| | | boolean needRead = true; |
| | | int read = 0; |
| | | while (true) |
| | | { |
| | | // Read wrapped data if needed. |
| | | if (needRead) |
| | | { |
| | | recvWrappedBuffer.compact(); // Prepare for append. |
| | | final int read = channel.read(recvWrappedBuffer); |
| | | read = channel.read(recvWrappedBuffer); |
| | | recvWrappedBuffer.flip(); // Restore for read. |
| | | if (read < 0) |
| | | { |
| | |
| | | break; // Retry unwrap. |
| | | case BUFFER_UNDERFLOW: |
| | | // Not enough data was read. This either means that the inbound |
| | | // buffer was too small, or not enough data is available. |
| | | // buffer was too small, or not enough data was read. |
| | | final int newPktSize = sslEngine.getSession().getPacketBufferSize(); |
| | | if (newPktSize > recvWrappedBuffer.capacity()) |
| | | { |
| | | // Buffer needs resizing. |
| | | // Increase the buffer size and reread. |
| | | final ByteBuffer newRecvWrappedBuffer = ByteBuffer |
| | | .allocate(newPktSize); |
| | | newRecvWrappedBuffer.put(recvWrappedBuffer); |
| | |
| | | recvWrappedBuffer = newRecvWrappedBuffer; |
| | | break; |
| | | } |
| | | else |
| | | else if (read == 0) |
| | | { |
| | | // Not enough data is available to read a complete SSL packet. |
| | | return 0; |
| | | } |
| | | else |
| | | { |
| | | // The channel read may only partially fill the buffer due to |
| | | // buffering in the underlying channel layer, so try reading again |
| | | // until we are sure that we are unable to proceed. |
| | | break; |
| | | } |
| | | case CLOSED: |
| | | // Peer sent SSL close notification. |
| | | sslEngine.closeInbound(); |
| | |
| | | // No application data was read, but if we are handshaking then |
| | | // try to continue. |
| | | if (result.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP |
| | | && !recvWrappedBuffer.hasRemaining()) |
| | | && !recvWrappedBuffer.hasRemaining() && read == 0) |
| | | { |
| | | // Not enough data is available to continue handshake. |
| | | return 0; |
| | |
| | | doHandshake(true /* isReading */); |
| | | } |
| | | } |
| | | else |
| | | else if (read == 0) |
| | | { |
| | | // No data available and not handshaking. |
| | | return 0; |
| | | } |
| | | else |
| | | { |
| | | // The channel read may only partially fill the buffer due to |
| | | // buffering in the underlying channel layer, so try reading again |
| | | // until we are sure that we are unable to proceed. |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |