Search in sources :

Example 1 with SslConduit

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));
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) ClosedChannelException(java.nio.channels.ClosedChannelException) HashMap(java.util.HashMap) SSLEngine(javax.net.ssl.SSLEngine) SslConduit(io.undertow.protocols.ssl.SslConduit) PushBackStreamSourceConduit(org.xnio.conduits.PushBackStreamSourceConduit) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) SslConnection(org.xnio.ssl.SslConnection) ALPNProvider(io.undertow.protocols.alpn.ALPNProvider) ImmediatePooled(io.undertow.util.ImmediatePooled)

Example 2 with SslConduit

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());
}
Also used : ALPNProvider(io.undertow.protocols.alpn.ALPNProvider) SSLEngine(javax.net.ssl.SSLEngine) SslConduit(io.undertow.protocols.ssl.SslConduit)

Aggregations

ALPNProvider (io.undertow.protocols.alpn.ALPNProvider)2 SslConduit (io.undertow.protocols.ssl.SslConduit)2 SSLEngine (javax.net.ssl.SSLEngine)2 ImmediatePooled (io.undertow.util.ImmediatePooled)1 IOException (java.io.IOException)1 ByteBuffer (java.nio.ByteBuffer)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 HashMap (java.util.HashMap)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 StreamSourceChannel (org.xnio.channels.StreamSourceChannel)1 PushBackStreamSourceConduit (org.xnio.conduits.PushBackStreamSourceConduit)1 SslConnection (org.xnio.ssl.SslConnection)1