All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xnio.ssl.JsseSslConnection Maven / Gradle / Ivy

There is a newer version: 62
Show newest version
package org.xnio.ssl;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.Set;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import org.xnio.ChannelListener;
import org.xnio.ChannelListeners;
import org.xnio.Option;
import org.xnio.Options;
import org.xnio.Pool;
import org.xnio.SslClientAuthMode;
import org.xnio.StreamConnection;

public final class JsseSslConnection extends SslConnection {
    private final StreamConnection streamConnection;
    private final JsseStreamConduit conduit;

    private final ChannelListener.SimpleSetter handshakeSetter = new ChannelListener.SimpleSetter<>();

    public JsseSslConnection(final StreamConnection streamConnection, final SSLEngine engine) {
        this(streamConnection, engine, JsseXnioSsl.bufferPool, JsseXnioSsl.bufferPool);
    }

    JsseSslConnection(final StreamConnection streamConnection, final SSLEngine engine, final Pool socketBufferPool, final Pool applicationBufferPool) {
        super(streamConnection.getIoThread());
        this.streamConnection = streamConnection;
        conduit = new JsseStreamConduit(this, engine, streamConnection.getSourceChannel().getConduit(), streamConnection.getSinkChannel().getConduit(), socketBufferPool, applicationBufferPool);
        setSourceConduit(conduit);
        setSinkConduit(conduit);
    }

    public void startHandshake() throws IOException {
        conduit.beginHandshake();
    }

    public SSLSession getSslSession() {
        return conduit.getSslSession();
    }

    protected void closeAction() throws IOException {
        try {
            if (!conduit.isWriteShutdown()) {
                conduit.terminateWrites();
            }
            if (!conduit.isReadShutdown()) {
                conduit.terminateReads();
            }
            conduit.flush();
            conduit.markTerminated();
            streamConnection.close();
        } catch (Throwable t) {
            // just make sure the connection is not left inconsistent
            try {
                if (!conduit.isReadShutdown()) {
                    conduit.terminateReads();
                }
            } catch (Throwable ignored) {}
            try {
                conduit.markTerminated();
                streamConnection.close();
            } catch (Throwable ignored) {}
            throw t;
        }
    }

    protected void notifyWriteClosed() {}

    protected void notifyReadClosed() {}

    public SocketAddress getPeerAddress() {
        return streamConnection.getPeerAddress();
    }

    public SocketAddress getLocalAddress() {
        return streamConnection.getLocalAddress();
    }

    public ChannelListener.Setter getHandshakeSetter() {
        return handshakeSetter;
    }

    void invokeHandshakeListener() {
        ChannelListeners.invokeChannelListener(this, handshakeSetter.get());
    }

    /** {@inheritDoc} */
    @Override
    public  T setOption(final Option option, final T value) throws IllegalArgumentException, IOException {
        if (option == Options.SSL_CLIENT_AUTH_MODE) {
            final SSLEngine engine = conduit.getEngine();
            try {
                return option.cast(engine.getNeedClientAuth() ? SslClientAuthMode.REQUIRED : engine.getWantClientAuth() ? SslClientAuthMode.REQUESTED : SslClientAuthMode.NOT_REQUESTED);
            } finally {
                engine.setNeedClientAuth(value == SslClientAuthMode.REQUIRED);
                engine.setWantClientAuth(value == SslClientAuthMode.REQUESTED);
            }
        } else if (option == Options.SECURE) {
            throw new IllegalArgumentException();
        } else {
            return streamConnection.setOption(option, value);
        }
    }

    /** {@inheritDoc} */
    @Override
    public  T getOption(final Option option) throws IOException {
        if (option == Options.SSL_CLIENT_AUTH_MODE) {
            final SSLEngine engine = conduit.getEngine();
            return option.cast(engine.getNeedClientAuth() ? SslClientAuthMode.REQUIRED : engine.getWantClientAuth() ? SslClientAuthMode.REQUESTED : SslClientAuthMode.NOT_REQUESTED);
        } else {
            return option == Options.SECURE ? option.cast(Boolean.valueOf(conduit.isTls())) : streamConnection.getOption(option);
        }
    }

    private static final Set> SUPPORTED_OPTIONS = Option.setBuilder().add(Options.SECURE, Options.SSL_CLIENT_AUTH_MODE).create();

    /** {@inheritDoc} */
    @Override
    public boolean supportsOption(final Option option) {
        return SUPPORTED_OPTIONS.contains(option) || streamConnection.supportsOption(option);
    }

    @Override
    public boolean isOpen() {
        return streamConnection.isOpen();
    }

    @Override
    public boolean isWriteShutdown() {
        return streamConnection.isWriteShutdown();
    }

    @Override
    public boolean isReadShutdown() {
        return streamConnection.isReadShutdown();
    }

    public SSLEngine getEngine() {
        return conduit.getEngine();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy