
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