Add DNS fallback system.

This commit is contained in:
Greyson Parrelli
2020-03-28 00:49:30 -04:00
parent d6000af843
commit 711715ca1e
15 changed files with 207 additions and 20 deletions

View File

@@ -0,0 +1,62 @@
package org.thoughtcrime.securesms.net;
import androidx.annotation.NonNull;
import com.annimon.stream.Stream;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.SimpleResolver;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import okhttp3.Dns;
/**
* A {@link Dns} implementation that specifies the hostname of a specific DNS.
*/
public class CustomDns implements Dns {
private final String dnsHostname;
public CustomDns(@NonNull String dnsHostname) {
this.dnsHostname = dnsHostname;
}
@Override
public @NonNull List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
Resolver resolver = new SimpleResolver(dnsHostname);
Lookup lookup = doLookup(hostname);
lookup.setResolver(resolver);
Record[] records = lookup.run();
if (records != null) {
List<InetAddress> ipv4Addresses = Stream.of(records)
.filter(r -> r.getType() == Type.A)
.map(r -> (ARecord) r)
.map(ARecord::getAddress)
.toList();
if (ipv4Addresses.size() > 0) {
return ipv4Addresses;
}
}
throw new UnknownHostException(hostname);
}
private static @NonNull Lookup doLookup(@NonNull String hostname) throws UnknownHostException {
try {
return new Lookup(hostname);
} catch (TextParseException e) {
throw new UnknownHostException();
}
}
}

View File

@@ -0,0 +1,45 @@
package org.thoughtcrime.securesms.net;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.logging.Log;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import okhttp3.Dns;
/**
* Iterates through an ordered list of {@link Dns}, trying each one in sequence.
*/
public class SequentialDns implements Dns {
private static final String TAG = Log.tag(SequentialDns.class);
private List<Dns> dnsList;
public SequentialDns(Dns... dns) {
this.dnsList = Arrays.asList(dns);
}
@Override
public @NonNull List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
for (Dns dns : dnsList) {
try {
List<InetAddress> addresses = dns.lookup(hostname);
if (addresses.size() > 0) {
return addresses;
} else {
Log.w(TAG, String.format(Locale.ENGLISH, "Didn't find any addresses for %s using %s. Continuing.", hostname, dns.getClass().getSimpleName()));
}
} catch (UnknownHostException e) {
Log.w(TAG, String.format(Locale.ENGLISH, "Failed to resolve %s using %s. Continuing.", hostname, dns.getClass().getSimpleName()));
}
}
Log.w(TAG, "Failed to resolve using any DNS.");
throw new UnknownHostException(hostname);
}
}

View File

@@ -0,0 +1,35 @@
package org.thoughtcrime.securesms.net;
import androidx.annotation.NonNull;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import okhttp3.Dns;
/**
* A super simple {@link Dns} implementation that maps hostnames to a static IP addresses.
*/
public class StaticDns implements Dns {
private final Map<String, String> hostnameMap;
public StaticDns(@NonNull Map<String, String> hostnameMap) {
this.hostnameMap = hostnameMap;
}
@Override
public @NonNull List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
String ip = hostnameMap.get(hostname);
if (ip != null) {
return Collections.singletonList(InetAddress.getByName(ip));
} else {
throw new UnknownHostException(hostname);
}
}
}