Skip to content

Commit

Permalink
Bind udp to all available interfaces (#304)
Browse files Browse the repository at this point in the history
  • Loading branch information
mageddo authored Feb 24, 2023
1 parent 5b2d08c commit 029c911
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 28 deletions.
24 changes: 18 additions & 6 deletions src/main/java/com/mageddo/dnsproxyserver/net/Networks.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,33 @@
import com.mageddo.dnsproxyserver.server.dns.IP;
import lombok.SneakyThrows;

import java.io.UncheckedIOException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Comparator;
import java.util.stream.Stream;

public class Networks {

@SneakyThrows
public static IP findCurrentMachineIP() {
return NetworkInterface
.networkInterfaces()
.flatMap(NetworkInterface::inetAddresses)
.filter(it -> it.getAddress().length == IP.BYTES)
.map(it -> IP.of(it.getHostAddress()))
.sorted(Comparator.comparing(it -> it.raw().startsWith("127") ? Integer.MAX_VALUE : 0))
return findMachineIps()
.findFirst()
.orElse(null);
}

public static Stream<IP> findMachineIps() {
try {
return NetworkInterface
.networkInterfaces()
.flatMap(NetworkInterface::inetAddresses)
.filter(it -> it.getAddress().length == IP.BYTES)
.filter(it -> !it.isLoopbackAddress())
.map(it -> IP.of(it.getHostAddress()))
.sorted(Comparator.comparing(it -> it.raw().startsWith("127") ? Integer.MAX_VALUE : 0))
;
} catch (SocketException e) {
throw new UncheckedIOException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public RemoteResolvers remoteResolvers(Function<IpAddr, Resolver> resolverProvid
public Function<IpAddr, Resolver> getResolverProvider() {
return it -> {
final var resolver = new SimpleResolver(InetAddresses.toSocketAddress(it.getRawIP(), it.getPortOrDef(53)));
resolver.setTimeout(Duration.ofMillis(250));
resolver.setTimeout(Duration.ofMillis(300));
return resolver;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public ServerStarter start() {
Config.findDnsServerProtocol(),
this.solvers
);
log.info("status=startingDnsServer, port={}", port);
log.trace("status=startingDnsServer, port={}", port);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@AllArgsConstructor(onConstructor = @__({@Inject}))
public class SimpleServer {

private final UDPServer udpServer;
private final UDPServerPool udpServerPool;
private final TCPServer tcpServer;
private final RequestHandler requestHandler;

Expand All @@ -31,12 +31,12 @@ public void start(int port, Protocol protocol, List<Solver> solvers) {
void start0(int port, Protocol protocol) {
final var tcpHandler = new TCPHandler(this.requestHandler);
switch (protocol) {
case UDP -> this.udpServer.start(port);
case UDP -> this.udpServerPool.start(port);
case TCP -> {
this.tcpServer.start(port, null, tcpHandler);
}
default -> {
this.udpServer.start(port);
this.udpServerPool.start(port);
this.tcpServer.start(port, null, tcpHandler);
}
}
Expand Down
33 changes: 16 additions & 17 deletions src/main/java/com/mageddo/dnsproxyserver/server/dns/UDPServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,34 @@
import lombok.extern.slf4j.Slf4j;
import org.xbill.DNS.Message;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;

@Slf4j
@Singleton
public class UDPServer {

public static final short BUFFER_SIZE = 512;

private final ExecutorService pool;
private final SocketAddress address;
private final RequestHandler requestHandler;

@Inject
public UDPServer(RequestHandler requestHandler) {
public UDPServer(SocketAddress address, RequestHandler requestHandler) {
this.address = address;
this.requestHandler = requestHandler;
this.pool = ThreadPool.create();
}

public void start(int port) {
this.pool.submit(() -> this.start0(port));
log.info("status=startingUdpServer, port={}", port);
public void start() {
this.pool.submit(this::start0);
log.trace("status=startingUdpServer, address={}", this.address);
}

private void start0(int port) {
private void start0() {
try {
final var server = new DatagramSocket(port);
final var server = new DatagramSocket(this.address);
while (!server.isClosed()) {

final var datagram = new DatagramPacket(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);
Expand All @@ -42,7 +41,7 @@ private void start0(int port) {

}
} catch (Exception e) {
log.error("status=dnsServerStartFailed, port={}, msg={}", port, e.getMessage(), e);
log.error("status=dnsServerStartFailed, address={}, msg={}", address, e.getMessage(), e);
throw new RuntimeException(e);
}
}
Expand All @@ -52,17 +51,17 @@ void handle(DatagramSocket server, DatagramPacket datagram) {
final var reqMsg = new Message(datagram.getData());
final var resData = this.requestHandler.handle(reqMsg, "udp").toWire();

final var out = new DatagramPacket(resData, resData.length);
out.setAddress(datagram.getAddress());
out.setPort(datagram.getPort());
server.send(out);
server.send(new DatagramPacket(resData, resData.length, datagram.getSocketAddress()));
log.debug(
"status=success, dataLength={}, datagramLength={}",
datagram.getData().length, datagram.getLength()
"status=success, dataLength={}, datagramLength={}, serverAddr={}, clientAddr={}",
datagram.getData().length, datagram.getLength(), server.getLocalAddress(), datagram.getSocketAddress()
);
} catch (Exception e) {
log.warn("status=messageHandleFailed, msg={}", e.getMessage(), e);
}
}

public SocketAddress getAddress() {
return this.address;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.mageddo.dnsproxyserver.server.dns;

import com.mageddo.dnsproxyserver.net.Networks;
import com.mageddo.dnsproxyserver.utils.Ips;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Singleton
@RequiredArgsConstructor(onConstructor = @__({@Inject}))
public class UDPServerPool {

private final RequestHandler requestHandler;
private List<UDPServer> servers = new ArrayList<>();

public void start(int port) {
this.servers = Networks
.findMachineIps()
.map(it -> new UDPServer(Ips.toSocketAddress(it.raw(), port), this.requestHandler))
.peek(UDPServer::start)
.toList();
final var addresses = this.servers
.stream()
.map(UDPServer::getAddress)
.map(SocketAddress::toString)
.collect(Collectors.joining(", "));
log.info("Starting UDP server, addresses={}", addresses);
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/utils/Ips.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import java.io.UncheckedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;

public class Ips {
Expand Down Expand Up @@ -37,4 +39,8 @@ public static InetAddress toAddress(byte[] ip) {
public static InetAddress toAddress(IP ip) {
return toAddress(ip.raw());
}

public static SocketAddress toSocketAddress(String ip, int port) {
return new InetSocketAddress(Ips.toAddress(ip), port);
}
}

0 comments on commit 029c911

Please sign in to comment.