@Override public int drain(ByteBuffer dst) throws IOException { verifyHandshakeCompleted(); int totalBytesUnwrapped = 0; int bytesUnwrapped; do { bytesUnwrapped = applicationDataUnwrap(dst); totalBytesUnwrapped += bytesUnwrapped; } while (bytesUnwrapped > 0); return totalBytesUnwrapped; }
@Override public int write(ByteBuffer src) throws IOException { verifyHandshakeCompleted(); if (flush() == FlushResult.NEED_WRITE) return 0; int totalBytesWrapped = 0; int bytesWrapped; do { bytesWrapped = applicationDataWrap(src); totalBytesWrapped += bytesWrapped; } while (bytesWrapped > 0 && wrapBuffer.bytes() < sessionPacketBufferSize); return totalBytesWrapped; }
@Override public int read(ByteBuffer dst) throws IOException { verifyHandshakeCompleted(); int bytesUnwrapped = drain(dst); if (bytesUnwrapped > 0) return bytesUnwrapped; int bytesRead = channelRead(); if (bytesRead == 0) return 0; return drain(dst); }
break; case NEED_WRITE: channelWrite(); break; case NEED_READ: channelRead(); break; case COMPLETED: return HandshakeState.COMPLETED; default: throw unhandledStateException(state); case NEED_UNWRAP: if (wrapBuffer.bytes() > 0) return HandshakeState.NEED_WRITE; if (!handshakeUnwrap()) return HandshakeState.NEED_READ; break; case NEED_WRAP: if (!handshakeWrap()) return HandshakeState.NEED_WRITE; break; default:
@Override public FlushResult flush() throws IOException { verifyHandshakeCompleted(); channelWrite(); return wrapBuffer.bytes() > 0 ? FlushResult.NEED_WRITE : FlushResult.DONE; }
@Override public TlsCryptoSocket createCryptoSocket(SocketChannel channel, boolean isServer) { SSLEngine sslEngine = tlsContext.createSslEngine(); sslEngine.setNeedClientAuth(true); sslEngine.setUseClientMode(!isServer); return new TlsCryptoSocket(channel, sslEngine); }
@Override public HandshakeResult handshake() throws IOException { if (factory != null) { if (channel().read(buffer.getWritable(SNOOP_SIZE)) == -1) { throw new IOException("jrt: Connection closed by peer during tls detection"); } if (buffer.bytes() < SNOOP_SIZE) { return HandshakeResult.NEED_READ; } byte[] data = new byte[SNOOP_SIZE]; ByteBuffer src = buffer.getReadable(); for (int i = 0; i < SNOOP_SIZE; i++) { data[i] = src.get(i); } if (looksLikeTlsToMe(data)) { TlsCryptoSocket tlsSocket = factory.createCryptoSocket(channel(), true); tlsSocket.injectReadData(buffer); socket = tlsSocket; return socket.handshake(); } else { metrics.incrementServerUnencryptedConnectionsEstablished(); factory = null; } } return HandshakeResult.DONE; }