Set readTimeout for upstreams, cache no TTL for 5s
This commit is contained in:
parent
652e098cc2
commit
b45ffed48a
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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() +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user