diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java index 674265258d..cef0b941ef 100644 --- a/app/src/main/java/eu/faircode/email/ApplicationEx.java +++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java @@ -117,6 +117,14 @@ public class ApplicationEx extends Application { registerReceiver(onScreenOff, new IntentFilter(Intent.ACTION_SCREEN_OFF)); + if (BuildConfig.DEBUG) + new Thread(new Runnable() { + @Override + public void run() { + DnsHelper.test(ApplicationEx.this); + } + }).start(); + long end = new Date().getTime(); Log.i("App created " + (end - start) + " ms"); } diff --git a/app/src/main/java/eu/faircode/email/DnsHelper.java b/app/src/main/java/eu/faircode/email/DnsHelper.java index 654c75deba..02f158b4ad 100644 --- a/app/src/main/java/eu/faircode/email/DnsHelper.java +++ b/app/src/main/java/eu/faircode/email/DnsHelper.java @@ -38,6 +38,7 @@ import org.xbill.DNS.Type; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.ArrayList; import java.util.List; import javax.mail.Address; @@ -107,28 +108,54 @@ public class DnsHelper { } @NonNull - static Record[] lookup(Context context, String name, int type) throws TextParseException, UnknownHostException { - Lookup lookup = new Lookup(name, type); + static DnsRecord[] lookup(Context context, String name, String type) throws UnknownHostException { + int rtype; + switch (type) { + case "mx": + rtype = Type.MX; + break; + case "srv": + rtype = Type.SRV; + break; + default: + throw new IllegalArgumentException(type); + } - SimpleResolver resolver = new SimpleResolver(getDnsServer(context)); - lookup.setResolver(resolver); - Log.i("Lookup name=" + name + " @" + resolver.getAddress() + " type=" + type); - Record[] records = lookup.run(); + try { + Lookup lookup = new Lookup(name, rtype); - if (lookup.getResult() != Lookup.SUCCESSFUL) - if (lookup.getResult() == Lookup.HOST_NOT_FOUND || - lookup.getResult() == Lookup.TYPE_NOT_FOUND) + SimpleResolver resolver = new SimpleResolver(getDnsServer(context)); + lookup.setResolver(resolver); + Log.i("Lookup name=" + name + " @" + resolver.getAddress() + " type=" + rtype); + Record[] records = lookup.run(); + + if (lookup.getResult() != Lookup.SUCCESSFUL) + if (lookup.getResult() == Lookup.HOST_NOT_FOUND || + lookup.getResult() == Lookup.TYPE_NOT_FOUND) + throw new UnknownHostException(name); + else + throw new UnknownHostException(lookup.getErrorString()); + + if (records.length == 0) throw new UnknownHostException(name); - else - throw new UnknownHostException(lookup.getErrorString()); - if (records.length == 0) - throw new UnknownHostException(name); + List result = new ArrayList<>(); + for (Record record : records) { + Log.i("Found record=" + record); + if (record instanceof MXRecord) { + MXRecord mx = (MXRecord) record; + result.add(new DnsRecord(mx.getTarget().toString(true))); + } else if (record instanceof SRVRecord) { + SRVRecord srv = (SRVRecord) record; + result.add(new DnsRecord(srv.getTarget().toString(true), srv.getPort())); + } else + throw new IllegalArgumentException(record.getClass().getName()); + } - for (Record record : records) - Log.i("Found record=" + record); - - return records; + return result.toArray(new DnsRecord[0]); + } catch (TextParseException ex) { + throw new UnknownHostException(ex.getMessage()); + } } static String getParentDomain(String host) { @@ -174,14 +201,27 @@ public class DnsHelper { return dns.get(0).getHostAddress(); } + static class DnsRecord { + String name; + Integer port; + + DnsRecord(String name) { + this.name = name; + } + + DnsRecord(String name, int port) { + this.name = name; + this.port = port; + } + } + static void test(Context context) { try { String domain = "gmail.com"; boolean ok = lookupMx(context, new Address[]{Log.myAddress()}); InetAddress iaddr = lookupMx(context, domain); - Record[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, Type.SRV); - SRVRecord srv = (SRVRecord) records[0]; - Log.i("DNS ok=" + ok + " iaddr=" + iaddr + " srv=" + srv.getTarget().toString()); + DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv"); + Log.i("DNS ok=" + ok + " iaddr=" + iaddr + " srv=" + records[0].name + ":" + records[0].port); } catch (Throwable ex) { Log.e("DNS", ex); } diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index cf53f2778e..cc8f17c882 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -25,11 +25,6 @@ import android.text.TextUtils; import androidx.annotation.NonNull; -import org.xbill.DNS.MXRecord; -import org.xbill.DNS.Record; -import org.xbill.DNS.SRVRecord; -import org.xbill.DNS.TextParseException; -import org.xbill.DNS.Type; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; @@ -226,9 +221,9 @@ public class EmailProvider { try { // Retry at MX server addresses - Record[] records = DnsHelper.lookup(context, domain, Type.MX); - for (Record record : records) { - String target = ((MXRecord) record).getTarget().toString(true); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx"); + for (DnsHelper.DnsRecord record : records) { + String target = record.name; while (autoconfig == null && target != null && target.indexOf('.') > 0) { try { autoconfig = _fromDomain(context, target.toLowerCase(Locale.ROOT), email, discover); @@ -498,35 +493,32 @@ public class EmailProvider { } @NonNull - private static EmailProvider fromDNS(Context context, String domain, Discover discover) throws TextParseException, UnknownHostException { + private static EmailProvider fromDNS(Context context, String domain, Discover discover) throws UnknownHostException { // https://tools.ietf.org/html/rfc6186 EmailProvider provider = new EmailProvider(domain); if (discover == Discover.ALL || discover == Discover.IMAP) { try { // Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server. - Record[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, Type.SRV); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv"); // ... service is not supported at all at a particular domain by setting the target of an SRV RR to "." - SRVRecord srv = (SRVRecord) records[0]; - provider.imap.host = srv.getTarget().toString(true); - provider.imap.port = srv.getPort(); + provider.imap.host = records[0].name; + provider.imap.port = records[0].port; provider.imap.starttls = false; } catch (UnknownHostException ex) { // Identifies an IMAP server that MAY ... require the MUA to use the "STARTTLS" command - Record[] records = DnsHelper.lookup(context, "_imap._tcp." + domain, Type.SRV); - SRVRecord srv = (SRVRecord) records[0]; - provider.imap.host = srv.getTarget().toString(true); - provider.imap.port = srv.getPort(); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imap._tcp." + domain, "srv"); + provider.imap.host = records[0].name; + provider.imap.port = records[0].port; provider.imap.starttls = (provider.imap.port == 143); } } if (discover == Discover.ALL || discover == Discover.SMTP) { // Note that this covers connections both with and without Transport Layer Security (TLS) - Record[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, Type.SRV); - SRVRecord srv = (SRVRecord) records[0]; - provider.smtp.host = srv.getTarget().toString(true); - provider.smtp.port = srv.getPort(); + DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, "srv"); + provider.smtp.host = records[0].name; + provider.smtp.port = records[0].port; provider.smtp.starttls = (provider.smtp.port == 587); }