use of io.undertow.protocols.ssl.SslConduit in project undertow by undertow-io.
the class ALPNClientSelector method runAlpn.
public static void runAlpn(final SslConnection sslConnection, final ChannelListener<SslConnection> fallback, final ClientCallback<ClientConnection> failedListener, final ALPNProtocol... details) {
SslConduit conduit = UndertowXnioSsl.getSslConduit(sslConnection);
final ALPNProvider provider = ALPNManager.INSTANCE.getProvider(conduit.getSSLEngine());
if (provider == null) {
fallback.handleEvent(sslConnection);
return;
}
String[] protocols = new String[details.length];
final Map<String, ALPNProtocol> protocolMap = new HashMap<>();
for (int i = 0; i < protocols.length; ++i) {
protocols[i] = details[i].getProtocol();
protocolMap.put(details[i].getProtocol(), details[i]);
}
final SSLEngine sslEngine = provider.setProtocols(conduit.getSSLEngine(), protocols);
conduit.setSslEngine(sslEngine);
final AtomicReference<Boolean> handshakeDone = new AtomicReference<>(false);
try {
sslConnection.startHandshake();
sslConnection.getHandshakeSetter().set(new ChannelListener<SslConnection>() {
@Override
public void handleEvent(SslConnection channel) {
if (handshakeDone.get()) {
return;
}
handshakeDone.set(true);
}
});
sslConnection.getSourceChannel().getReadSetter().set(new ChannelListener<StreamSourceChannel>() {
@Override
public void handleEvent(StreamSourceChannel channel) {
String selectedProtocol = provider.getSelectedProtocol(sslEngine);
if (selectedProtocol != null) {
handleSelected(selectedProtocol);
} else {
ByteBuffer buf = ByteBuffer.allocate(100);
try {
int read = channel.read(buf);
if (read > 0) {
buf.flip();
PushBackStreamSourceConduit pb = new PushBackStreamSourceConduit(sslConnection.getSourceChannel().getConduit());
pb.pushBack(new ImmediatePooled<>(buf));
sslConnection.getSourceChannel().setConduit(pb);
} else if (read == -1) {
failedListener.failed(new ClosedChannelException());
}
selectedProtocol = provider.getSelectedProtocol(sslEngine);
if (selectedProtocol != null) {
handleSelected(selectedProtocol);
} else if (read > 0 || handshakeDone.get()) {
sslConnection.getSourceChannel().suspendReads();
fallback.handleEvent(sslConnection);
return;
}
} catch (IOException e) {
failedListener.failed(e);
}
}
}
private void handleSelected(String selected) {
if (selected.isEmpty()) {
sslConnection.getSourceChannel().suspendReads();
fallback.handleEvent(sslConnection);
return;
} else {
ALPNClientSelector.ALPNProtocol details = protocolMap.get(selected);
if (details == null) {
//should never happen
sslConnection.getSourceChannel().suspendReads();
fallback.handleEvent(sslConnection);
return;
} else {
sslConnection.getSourceChannel().suspendReads();
details.getSelected().handleEvent(sslConnection);
}
}
}
});
sslConnection.getSourceChannel().resumeReads();
} catch (IOException e) {
failedListener.failed(e);
} catch (Throwable e) {
failedListener.failed(new IOException(e));
}
}
use of io.undertow.protocols.ssl.SslConduit in project undertow by undertow-io.
the class AlpnOpenListener method handleEvent.
public void handleEvent(final StreamConnection channel) {
if (UndertowLogger.REQUEST_LOGGER.isTraceEnabled()) {
UndertowLogger.REQUEST_LOGGER.tracef("Opened connection with %s", channel.getPeerAddress());
}
final SslConduit sslConduit = UndertowXnioSsl.getSslConduit((SslConnection) channel);
final SSLEngine sslEngine = sslConduit.getSSLEngine();
if (!engineSupportsHTTP2(sslEngine)) {
UndertowLogger.REQUEST_LOGGER.debugf("ALPN has been configured however %s is not present, falling back to default protocol", REQUIRED_CIPHER);
if (fallbackProtocol != null) {
ListenerEntry listener = listeners.get(fallbackProtocol);
if (listener != null) {
listener.listener.handleEvent(channel);
return;
}
}
}
ALPNProvider provider = alpnManager.getProvider(sslEngine);
if (provider == null) {
if (fallbackProtocol != null) {
ListenerEntry listener = listeners.get(fallbackProtocol);
if (listener != null) {
listener.listener.handleEvent(channel);
return;
}
}
UndertowLogger.REQUEST_LOGGER.debugf("No ALPN provider available and no fallback defined");
IoUtils.safeClose(channel);
return;
}
SSLEngine newEngine = provider.setProtocols(sslEngine, protocols);
if (newEngine != sslEngine) {
sslConduit.setSslEngine(newEngine);
}
final AlpnConnectionListener potentialConnection = new AlpnConnectionListener(channel, newEngine, provider);
channel.getSourceChannel().setReadListener(potentialConnection);
potentialConnection.handleEvent(channel.getSourceChannel());
}
Aggregations