Set readTimeout for upstreams, cache no TTL for 5s

This commit is contained in:
Travis Burtrum 2018-03-09 23:51:48 -05:00
parent 652e098cc2
commit b45ffed48a
8 changed files with 68 additions and 27 deletions

View File

@ -5,11 +5,9 @@ import com.moparisthebest.dns.net.ParsedUrl;
import com.moparisthebest.dns.resolve.CacheResolver; import com.moparisthebest.dns.resolve.CacheResolver;
import com.moparisthebest.dns.resolve.QueueProcessingResolver; import com.moparisthebest.dns.resolve.QueueProcessingResolver;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.util.Arrays; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -20,11 +18,20 @@ public class DnsProxy {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
final Map<String, String> config; final Map<String, String> config;
try (FileInputStream fis = new FileInputStream(args.length > 0 ? args[0] : "jdnsproxy.properties")) { final File propsFile = new File(args.length > 0 ? args[0] : "jdnsproxy.properties");
final Properties props = new Properties(); if(propsFile.canRead()) {
props.load(fis); try (FileInputStream fis = new FileInputStream(propsFile)) {
@SuppressWarnings("unchecked") final Map<String, String> configUnchecked = (Map<String, String>) (Object) props; final Properties props = new Properties();
config = configUnchecked; props.load(fis);
@SuppressWarnings("unchecked") final Map<String, String> configUnchecked = (Map<String, String>) (Object) props;
config = configUnchecked;
}
} else {
if(args.length > 0) {
System.err.printf("Error: config file '%s' does not exist or can't be read%n", args[0]);
return;
}
config = Collections.emptyMap();
} }
System.out.println("config:" + config); System.out.println("config:" + config);
@ -44,8 +51,8 @@ public class DnsProxy {
//queueProcessingResolvers.add(new SocketResolver(5, "socket1", SocketFactory.getDefault(), new InetSocketAddress("8.8.4.4", 53))); //queueProcessingResolvers.add(new SocketResolver(5, "socket1", SocketFactory.getDefault(), new InetSocketAddress("8.8.4.4", 53)));
//queueProcessingResolvers.add(new HttpResolver(5, "http1", "https://dns.google.com/experimental?ct")); //queueProcessingResolvers.add(new HttpResolver(5, "http1", "https://dns.google.com/experimental?ct"));
final ExecutorService executor = ForkJoinPool.commonPool(); final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(40);
final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(8); final ExecutorService executor = scheduledExecutorService;//ForkJoinPool.commonPool();
final CacheResolver resolver = new CacheResolver(minTtl, staleResponseTtl, staleResponseTimeout, packetQueueLength, executor, scheduledExecutorService) final CacheResolver resolver = new CacheResolver(minTtl, staleResponseTtl, staleResponseTimeout, packetQueueLength, executor, scheduledExecutorService)
.startQueueProcessingResolvers(queueProcessingResolvers); .startQueueProcessingResolvers(queueProcessingResolvers);

View File

@ -63,13 +63,19 @@ public class Util {
/* /*
// temp debug code // temp debug code
public static void debugPacket(final byte[] packet) { public static void debugPacket(ByteBuffer packet) {
System.out.println(Base64.getUrlEncoder().encodeToString(packet)); //if(true) return;
int position = packet.position();
packet.position(0);
//System.out.println(Base64.getUrlEncoder().encodeToString(packet.array()));
//System.out.println(new Packet(ByteBuffer.wrap(packet, 2, packet.length - 2).slice())); //System.out.println(new Packet(ByteBuffer.wrap(packet, 2, packet.length - 2).slice()));
System.out.println(new Packet(ByteBuffer.wrap(packet).slice())); //packet.mark();
printPrettyHexBytes(ByteBuffer.wrap(packet)); System.out.println(new Packet(packet.slice()));
printPrettyChars(packet); //printPrettyHexBytes(packet);
printPrettyDecimalUnsignedBytes(ByteBuffer.wrap(packet)); //printPrettyChars(packet);
//printPrettyDecimalUnsignedBytes(packet);
packet.position(position);
//packet.reset();
} }
public static void printPrettyHexBytes(ByteBuffer bytes) { public static void printPrettyHexBytes(ByteBuffer bytes) {
@ -89,10 +95,12 @@ public class Util {
System.out.println("+++++++++++++++++++++++++++++"); System.out.println("+++++++++++++++++++++++++++++");
} }
public static void printPrettyChars(final byte[] bytes) { public static void printPrettyChars(ByteBuffer bytes) {
bytes = bytes.slice();
System.out.println("-----------------------------"); System.out.println("-----------------------------");
int count = 0; int count = 0;
for (final byte b : bytes) { for (int x = 0; x < bytes.limit(); ++x) {
final byte b = bytes.get(x);
System.out.printf("%02X(%c) ", b, (char) b); System.out.printf("%02X(%c) ", b, (char) b);
if (++count == 8) { if (++count == 8) {
System.out.println(); System.out.println();

View File

@ -212,6 +212,9 @@ public class Packet extends AbstractBufferWindow {
lowestTtl = rrTtl; lowestTtl = rrTtl;
} }
} }
if(lowestTtl == Integer.MAX_VALUE)
lowestTtl = 5; // todo: what is proper when no TTLs are available?
//System.out.println("lowestTtl: " + lowestTtl);
return lowestTtl; return lowestTtl;
} }
@ -238,7 +241,7 @@ public class Packet extends AbstractBufferWindow {
} }
public String getDohBase64() { public String getDohBase64() {
// todo: remove trailing equals // todo: remove trailing equals, this goes outside limit...
return Base64.getUrlEncoder().encodeToString(getBuf().array()); return Base64.getUrlEncoder().encodeToString(getBuf().array());
} }
@ -269,7 +272,7 @@ public class Packet extends AbstractBufferWindow {
", start=" + getStart() + ", start=" + getStart() +
", end=" + getEnd() + ", end=" + getEnd() +
", length=" + getLength() + ", length=" + getLength() +
", dohBase64=" + getDohBase64() + //", dohBase64=" + getDohBase64() +
'}'; '}';
} }
} }

View File

@ -41,10 +41,15 @@ public class TcpAsync implements Listener {
try { try {
bufChan.buf.flip(); bufChan.buf.flip();
bufChan.setRequest(new Packet(bufChan.buf)); bufChan.setRequest(new Packet(bufChan.buf));
//debugPacket(bufChan.getRequest().getBuf().array()); //debugPacket(bufChan.getRequest().getBuf());
resolver.resolveAsync(bufChan).thenAcceptAsync((bc) -> { resolver.resolveAsync(bufChan).whenCompleteAsync((bc, t) -> {
//debugPacket(bc.getResponse().getBuf().array()); //System.out.println("got completed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
if(t != null) {
t.printStackTrace();
return;
}
//debugPacket(bc.getResponse().getBuf());
bc.tcpHead.clear(); bc.tcpHead.clear();
bc.tcpHead.putShort((short) bc.getResponse().getBuf().capacity()); bc.tcpHead.putShort((short) bc.getResponse().getBuf().capacity());

View File

@ -40,10 +40,14 @@ public class UdpSync implements Listener {
final UdpRequestResponse requestResponse = new UdpRequestResponse(request.getSocketAddress(), final UdpRequestResponse requestResponse = new UdpRequestResponse(request.getSocketAddress(),
new Packet(ByteBuffer.wrap(request.getData(), request.getOffset(), request.getLength()).slice())); new Packet(ByteBuffer.wrap(request.getData(), request.getOffset(), request.getLength()).slice()));
//System.out.println(requestResponse); //System.out.println(requestResponse);
//debugPacket(request.getData()); //debugPacket(requestResponse.getRequest().getBuf());
resolver.resolveAsync(requestResponse).thenAcceptAsync((urr) -> { resolver.resolveAsync(requestResponse).whenCompleteAsync((urr, t) -> {
//debugPacket(bc.getResponse().getBuf().array()); if(t != null) {
t.printStackTrace();
return;
}
//debugPacket(urr.getResponse().getBuf());
//System.out.println("got response"); //System.out.println("got response");
final byte[] response = urr.getResponse().getBuf().array(); final byte[] response = urr.getResponse().getBuf().array();

View File

@ -110,8 +110,17 @@ public class CacheResolver implements Resolver, AutoCloseable {
return CompletableFuture.completedFuture(requestResponse); return CompletableFuture.completedFuture(requestResponse);
} }
} }
//System.out.println("no cachedPacket, querying upstream!");
requestResponse.setRequestPacketKey(key); requestResponse.setRequestPacketKey(key);
return requestAndCache(requestResponse); return requestAndCache(requestResponse);
/*
// todo: should not have to do this, some upstreams seem to eat stuff though, figure that out, I think readTimeout fixed this
final CompletableFuture<E> request = requestAndCache(requestResponse);
final CompletableFuture<E> abort = supplyAsyncOnTimeOut(scheduledExecutorService, 15000, TimeUnit.MILLISECONDS, () -> {
throw new RuntimeException("timed out cause upstream ate us");
});
return request.applyToEitherAsync(abort, s -> s);
*/
} }
//boolean first = true; //boolean first = true;

View File

@ -12,6 +12,7 @@ import static com.moparisthebest.dns.Util.readPacket;
public class HttpResolver extends AbstractQueueProcessingResolver { public class HttpResolver extends AbstractQueueProcessingResolver {
private final OpenConnection openConnection; private final OpenConnection openConnection;
private final int connectTimeout; private final int connectTimeout;
private final int readTimeout = 4000;
interface OpenConnection { interface OpenConnection {
HttpURLConnection open() throws Exception; HttpURLConnection open() throws Exception;
@ -47,6 +48,7 @@ public class HttpResolver extends AbstractQueueProcessingResolver {
final HttpURLConnection conn = openConnection.open(); final HttpURLConnection conn = openConnection.open();
conn.setConnectTimeout(connectTimeout); conn.setConnectTimeout(connectTimeout);
conn.setReadTimeout(readTimeout);
conn.setUseCaches(false); conn.setUseCaches(false);
conn.setDoInput(true); conn.setDoInput(true);
conn.setDoOutput(true); conn.setDoOutput(true);

View File

@ -16,6 +16,7 @@ import static com.moparisthebest.dns.Util.writeTcpPacket;
public class SocketResolver extends AbstractQueueProcessingResolver { public class SocketResolver extends AbstractQueueProcessingResolver {
private final OpenSocket openConnection; private final OpenSocket openConnection;
private final int readTimeout = 4000;
interface OpenSocket { interface OpenSocket {
Socket open() throws Exception; Socket open() throws Exception;
@ -105,6 +106,8 @@ public class SocketResolver extends AbstractQueueProcessingResolver {
OutputStream upOs = upstream.getOutputStream(); OutputStream upOs = upstream.getOutputStream();
DataOutputStream upDos = new DataOutputStream(upOs)) { DataOutputStream upDos = new DataOutputStream(upOs)) {
upstream.setSoTimeout(readTimeout);
writeTcpPacket(request, upDos); writeTcpPacket(request, upDos);
upDos.flush(); upDos.flush();