public void handleEvent(final ConnectedMessageChannel channel) { final Pooled<ByteBuffer> pooledBuffer = connection.allocate(); boolean free = true; try { final ByteBuffer buffer = pooledBuffer.getResource(); synchronized (connection.getLock()) { final int res; try { res = channel.receive(buffer); } catch (IOException e) { connection.handleException(e); saslDispose(saslClient); return; } if (res == 0) { return; } if (res == -1) { connection.handleException(client.abruptClose(connection)); saslDispose(saslClient); return; } } buffer.flip(); final byte msgType = buffer.get(); switch (msgType) { case Protocol.CONNECTION_ALIVE: { client.trace("Client received connection alive"); connection.sendAliveResponse(); return; } case Protocol.CONNECTION_ALIVE_ACK: { client.trace("Client received connection alive ack"); return; } case Protocol.CONNECTION_CLOSE: { client.trace("Client received connection close request"); connection.handlePreAuthCloseRequest(); saslDispose(saslClient); return; } case Protocol.AUTH_CHALLENGE: { client.trace("Client received authentication challenge"); channel.suspendReads(); connection .getExecutor() .execute( () -> { try { final boolean clientComplete = saslClient.isComplete(); if (clientComplete) { connection.handleException( new SaslException("Received extra auth message after completion")); return; } final byte[] response; final byte[] challenge = Buffers.take(buffer, buffer.remaining()); try { response = saslClient.evaluateChallenge(challenge); } catch (Throwable e) { final String mechanismName = saslClient.getMechanismName(); client.debugf( "Client authentication failed for mechanism %s: %s", mechanismName, e); failedMechs.put(mechanismName, e.toString()); saslDispose(saslClient); sendCapRequest(serverName); return; } client.trace("Client sending authentication response"); final Pooled<ByteBuffer> pooled = connection.allocate(); boolean ok = false; try { final ByteBuffer sendBuffer = pooled.getResource(); sendBuffer.put(Protocol.AUTH_RESPONSE); sendBuffer.put(response); sendBuffer.flip(); connection.send(pooled); ok = true; channel.resumeReads(); } finally { if (!ok) pooled.free(); } return; } finally { pooledBuffer.free(); } }); free = false; return; } case Protocol.AUTH_COMPLETE: { client.trace("Client received authentication complete"); channel.suspendReads(); connection .getExecutor() .execute( () -> { try { final boolean clientComplete = saslClient.isComplete(); final byte[] challenge = Buffers.take(buffer, buffer.remaining()); if (!clientComplete) try { final byte[] response = saslClient.evaluateChallenge(challenge); if (response != null && response.length > 0) { connection.handleException( new SaslException( "Received extra auth message after completion")); saslDispose(saslClient); return; } if (!saslClient.isComplete()) { connection.handleException( new SaslException( "Client not complete after processing auth complete message")); saslDispose(saslClient); return; } } catch (Throwable e) { final String mechanismName = saslClient.getMechanismName(); client.debugf( "Client authentication failed for mechanism %s: %s", mechanismName, e); failedMechs.put(mechanismName, e.toString()); saslDispose(saslClient); sendCapRequest(serverName); return; } final Object qop = saslClient.getNegotiatedProperty(Sasl.QOP); if ("auth-int".equals(qop) || "auth-conf".equals(qop)) { connection.setSaslWrapper(SaslWrapper.create(saslClient)); } // auth complete. final ConnectionHandlerFactory connectionHandlerFactory = connectionContext -> { // this happens immediately. final RemoteConnectionHandler connectionHandler = new RemoteConnectionHandler( connectionContext, connection, maxInboundChannels, maxOutboundChannels, remoteEndpointName, behavior); connection.setReadListener( new RemoteReadListener(connectionHandler, connection), false); connection .getRemoteConnectionProvider() .addConnectionHandler(connectionHandler); return connectionHandler; }; connection.getResult().setResult(connectionHandlerFactory); channel.resumeReads(); return; } finally { pooledBuffer.free(); } }); free = false; return; } case Protocol.AUTH_REJECTED: { final String mechanismName = saslClient.getMechanismName(); client.debugf( "Client received authentication rejected for mechanism %s", mechanismName); failedMechs.put(mechanismName, "Server rejected authentication"); saslDispose(saslClient); sendCapRequest(serverName); return; } default: { client.unknownProtocolId(msgType); connection.handleException(client.invalidMessage(connection)); saslDispose(saslClient); return; } } } finally { if (free) pooledBuffer.free(); } }