NetworkDNS/src-wip/org/handwerkszeug/dns/aaaa/DNSServer.java

134 lines
3.6 KiB
Java
Executable File

package org.handwerkszeug.dns.aaaa;
import java.io.File;
import java.net.MalformedURLException;
import java.net.SocketAddress;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.handwerkszeug.dns.Markers;
import org.handwerkszeug.dns.conf.ServerConfiguration;
import org.handwerkszeug.dns.conf.ServerConfigurationImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.channel.ChannelFactory;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import werkzeugkasten.common.util.Disposable;
import werkzeugkasten.common.util.Initializable;
public class DNSServer implements Initializable, Disposable {
protected static Logger LOG = LoggerFactory.getLogger(DNSServer.class);
protected ServerConfiguration config;
protected ChannelFactory serverChannelFactory;
protected ChannelFactory clientChannelFactory;
protected ConnectionlessBootstrap bootstrap;
protected ChannelGroup group;
public static void main(String[] args) throws Exception {
ServerConfiguration conf = parseArgs(args);
final DNSServer server = new DNSServer(conf);
server.initialize();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
server.dispose();
}
});
server.process();
}
public static ServerConfiguration parseArgs(String[] args) throws Exception {
ServerConfigurationImpl config = new ServerConfigurationImpl();
URL from = null;
if ((args != null) && (0 < args.length)) {
from = readFrom(args[0]);
}
if (from == null) {
from = readFrom("named.yml");
}
if (from == null) {
LOG.info("read named.default.yml from ClassLoader");
ClassLoader cl = Thread.currentThread().getContextClassLoader();
from = cl.getResource("named.default.yml");
}
if (from == null) {
throw new IllegalStateException("configuration file is not found.");
}
config.load(from);
return config;
}
public static URL readFrom(String path) throws MalformedURLException {
File f = new File(path);
LOG.info("read from {}", f.getAbsolutePath());
if (f.exists()) {
if (f.canRead()) {
return f.toURI().toURL();
} else {
LOG.info("{} cannot read", f.getAbsolutePath());
}
} else {
LOG.info("{} is not exists", f.getAbsolutePath());
}
return null;
}
public DNSServer(ServerConfiguration config) {
this.config = config;
}
@Override
public void initialize() {
LOG.debug(Markers.LIFECYCLE, "initialize server");
ExecutorService executor = Executors.newFixedThreadPool(this.config.getThreadPoolSize());
// TODO need TCP?
this.clientChannelFactory = new NioDatagramChannelFactory(executor);
// TODO TCP and/or UDP
this.serverChannelFactory = new NioDatagramChannelFactory(executor);
ChannelPipelineFactory pipelineFactory = new DNSServerPipelineFactory(this.config, this.clientChannelFactory);
this.bootstrap = new ConnectionlessBootstrap(this.serverChannelFactory);
this.bootstrap.setPipelineFactory(pipelineFactory);
this.group = new DefaultChannelGroup();
}
public void process() {
for (SocketAddress sa : this.config.getBindingHosts()) {
LOG.info(Markers.BOUNDARY, "binding {}", sa);
this.group.add(this.bootstrap.bind(sa));
}
}
@Override
public void dispose() {
try {
this.group.close().awaitUninterruptibly();
} finally {
dispose(this.clientChannelFactory);
dispose(this.serverChannelFactory);
}
}
protected void dispose(ExternalResourceReleasable releasable) {
try {
releasable.releaseExternalResources();
} catch (Exception e) {
LOG.error(e.getLocalizedMessage(), e);
}
}
}