DoH: limit total time and max requests

Better loop checking, force DoH off for request
This commit is contained in:
zzz
2020-10-26 13:44:23 +00:00
parent af97eedcbb
commit cf88b3057a

View File

@ -43,9 +43,9 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
private static final Map<String, Result> v4Cache = new LHMCache<String, Result>(32);
private static final Map<String, Result> v6Cache = new LHMCache<String, Result>(32);
// v4 URLs to query, ending with '&'
private static final List<String> v4urls = new ArrayList<String>(4);
private static final List<String> v4urls = new ArrayList<String>(8);
// v6 URLs to query, ending with '&'
private static final List<String> v6urls = new ArrayList<String>(4);
private static final List<String> v6urls = new ArrayList<String>(8);
// consecutive failures
private static final ObjectCounter<String> fails = new ObjectCounter<String>();
@ -64,7 +64,11 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
} );
static {
// Warning: All hostnames MUST be in loop check in lookup() below
// Public lists:
// https://dnscrypt.info/public-servers/
// https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers
// https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Public+Resolvers#DNSPrivacyPublicResolvers-DNS-over-HTTPS(DoH)
// Google
// https://developers.google.com/speed/public-dns/docs/doh/
// 8.8.8.8 and 8.8.4.4 now redirect to dns.google, but SSLEepGet doesn't support redirect
@ -89,9 +93,13 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
// keep the timeout very short, as we try multiple addresses,
// and will be falling back to regular DNS.
private static final long TIMEOUT = 3*1000;
// total for v4 + v6
private static final long OVERALL_TIMEOUT = 10*1000;
private static final int MAX_TTL = 24*60*60;
// don't use a URL after this many consecutive failures
private static final int MAX_FAILS = 3;
// each for v4 and v6
private static final int MAX_REQUESTS = 4;
private static final int V4_CODE = 1;
private static final int CNAME_CODE = 5;
private static final int V6_CODE = 28;
@ -203,21 +211,22 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
private String query(String host, Type type) {
List<String> toQuery = new ArrayList<String>((type == Type.V6_ONLY) ? v6urls : v4urls);
Collections.shuffle(toQuery);
final long timeout = System.currentTimeMillis() + OVERALL_TIMEOUT;
if (type == Type.V4_ONLY || type == Type.V4_PREFERRED) {
// v4 query
String rv = query(host, false, toQuery);
String rv = query(host, false, toQuery, timeout);
if (rv != null)
return rv;
}
if (type != Type.V4_ONLY) {
// v6 query
String rv = query(host, true, toQuery);
String rv = query(host, true, toQuery, timeout);
if (rv != null)
return rv;
}
if (type == Type.V6_PREFERRED) {
// v4 query after v6 query
String rv = query(host, false, toQuery);
String rv = query(host, false, toQuery, timeout);
if (rv != null)
return rv;
}
@ -227,8 +236,16 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
/**
* @return null if not found
*/
private String query(String host, boolean isv6, List<String> toQuery) {
private String query(String host, boolean isv6, List<String> toQuery, long timeout) {
int requests = 0;
final String loopcheck = "https://" + host + '/';
for (String url : toQuery) {
if (requests >= MAX_REQUESTS)
break;
if (System.currentTimeMillis() >= timeout)
break;
if (url.startsWith(loopcheck))
continue;
if (fails.count(url) > MAX_FAILS)
continue;
int tcode = isv6 ? V6_CODE : V4_CODE;
@ -236,6 +253,7 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
log("Fetching " + furl);
baos.reset();
SSLEepGet eepget = new SSLEepGet(ctx, baos, furl, state);
eepget.forceDNSOverHTTPS(false);
if (ctx.isRouterContext())
eepget.addStatusListener(this);
else
@ -248,9 +266,11 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
if (state == null)
state = eepget.getSSLState();
// we treat all fails the same, whether server responded or not
requests++;
fails.increment(url);
log("No result from " + furl);
}
log("No result after " + requests + " attempts");
return null;
}
@ -343,7 +363,7 @@ public class DNSOverHTTPS implements EepGet.StatusListener {
}
log("Bad response:\n" + new String(b));
} else {
log("Fail fetching");
log("Fail fetching, rc: " + eepget.getStatusCode());
}
return null;
}