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

eu.clarussecure.proxy.protocol.plugins.tcp.TCPServer Maven / Gradle / Ivy

The newest version!
package eu.clarussecure.proxy.protocol.plugins.tcp;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import eu.clarussecure.proxy.spi.protocol.Configuration;
import eu.clarussecure.proxy.spi.protocol.ProtocolServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class TCPServer, SI extends ChannelInitializer>
        implements ProtocolServer {

    private static final Logger LOGGER = LoggerFactory.getLogger(TCPServer.class);

    private final Configuration configuration;

    private final Map customData;

    private final Class clientSideChannelInitializerType;

    private final Class serverSideChannelInitializerType;

    private final int preferredServerEndpoint;

    private volatile boolean ready = false;

    public TCPServer(Configuration configuration, Class clientSideChannelInitializerType,
            Class serverSideChannelInitializerType, int preferredServerEndpoint) {
        this.configuration = configuration;
        this.customData = new HashMap<>();
        this.clientSideChannelInitializerType = clientSideChannelInitializerType;
        this.serverSideChannelInitializerType = serverSideChannelInitializerType;
        this.preferredServerEndpoint = preferredServerEndpoint;
    }

    @Override
    public Void call() throws Exception {
        EventLoopGroup acceptorGroup = new NioEventLoopGroup(configuration.getNbListenThreads());
        EventLoopGroup childGroup = new NioEventLoopGroup(configuration.getNbSessionThreads());
        try {
            ChannelInitializer clientSidePipelineInitializer = buildClientSidePipelineInitializer();
            ChannelInitializer serverSidePipelineInitializer = buildServerSidePipelineInitializer();
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(acceptorGroup, childGroup).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(configuration.getListenPort()))
                    .childAttr(TCPConstants.CONFIGURATION_KEY, configuration)
                    .childAttr(TCPConstants.CUSTOM_DATA_KEY, customData)
                    .childAttr(TCPConstants.PREFERRED_SERVER_ENDPOINT_KEY, preferredServerEndpoint)
                    .childAttr(TCPConstants.SERVER_INITIALIZER_KEY, serverSidePipelineInitializer)
                    .childHandler(clientSidePipelineInitializer).childOption(ChannelOption.AUTO_READ, false);
            ChannelFuture f = bootstrap.bind().sync();
            LOGGER.info("Server ready to serve requests at:" + f.channel().localAddress());
            synchronized (this) {
                ready = true;
                notifyAll();
            }
            f.channel().closeFuture().sync();
        } finally {
            acceptorGroup.shutdownGracefully().sync();
            childGroup.shutdownGracefully().sync();
        }
        return null;
    }

    @Override
    public void waitForServerIsReady() throws InterruptedException {
        while (!ready) {
            synchronized (this) {
                if (!ready) {
                    wait();
                }
            }
        }
    }

    protected ChannelInitializer buildClientSidePipelineInitializer() {
        try {
            return clientSideChannelInitializerType.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // Should not occur
            LOGGER.error("Cannot create instance of class {}: ", clientSideChannelInitializerType.getSimpleName(), e);
            throw new IllegalArgumentException(String.format("Cannot create instance of class %s: ",
                    clientSideChannelInitializerType.getSimpleName(), e));
        }
    }

    protected ChannelInitializer buildServerSidePipelineInitializer() {
        try {
            return serverSideChannelInitializerType.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            // Should not occur
            LOGGER.error("Cannot create instance of class {}: ", serverSideChannelInitializerType.getSimpleName(), e);
            throw new IllegalArgumentException(String.format("Cannot create instance of class %s: ",
                    serverSideChannelInitializerType.getSimpleName(), e));
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy