DNS auto discovery: use priority/weight

pull/212/head
M66B 3 years ago
parent f6faf0fecc
commit 785e7a5ee7

@ -210,7 +210,7 @@ public class DnsHelper {
result.add(new DnsRecord(soa.getHost().toString(true))); result.add(new DnsRecord(soa.getHost().toString(true)));
} else if (record instanceof SRVRecord) { } else if (record instanceof SRVRecord) {
SRVRecord srv = (SRVRecord) record; SRVRecord srv = (SRVRecord) record;
result.add(new DnsRecord(srv.getTarget().toString(true), srv.getPort())); result.add(new DnsRecord(srv.getTarget().toString(true), srv.getPort(), srv.getPriority(), srv.getWeight()));
} else if (record instanceof TXTRecord) { } else if (record instanceof TXTRecord) {
TXTRecord txt = (TXTRecord) record; TXTRecord txt = (TXTRecord) record;
for (Object content : txt.getStrings()) { for (Object content : txt.getStrings()) {
@ -241,6 +241,9 @@ public class DnsHelper {
throw new IllegalArgumentException(record.getClass().getName()); throw new IllegalArgumentException(record.getClass().getName());
} }
for (DnsRecord record : result)
record.query = name;
return result.toArray(new DnsRecord[0]); return result.toArray(new DnsRecord[0]);
} catch (TextParseException ex) { } catch (TextParseException ex) {
Log.e(ex); Log.e(ex);
@ -283,8 +286,11 @@ public class DnsHelper {
} }
static class DnsRecord { static class DnsRecord {
String query;
String name; String name;
Integer port; Integer port;
Integer priority;
Integer weight;
DnsRecord(String name) { DnsRecord(String name) {
this.name = name; this.name = name;
@ -294,5 +300,18 @@ public class DnsHelper {
this.name = name; this.name = name;
this.port = port; this.port = port;
} }
DnsRecord(String name, int port, int priority, int weight) {
this.name = name;
this.port = port;
this.priority = priority;
this.weight = weight;
}
@NonNull
@Override
public String toString() {
return query + "=" + name + ":" + port + " " + priority + "/" + weight;
}
} }
} }

@ -857,56 +857,81 @@ public class EmailProvider implements Parcelable {
EmailProvider provider = new EmailProvider(domain); EmailProvider provider = new EmailProvider(domain);
if (discover == Discover.ALL || discover == Discover.IMAP) { if (discover == Discover.ALL || discover == Discover.IMAP) {
try { intf.onStatus("SRV imap " + domain);
// Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server.
intf.onStatus("SRV imaps " + domain); // Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server.
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv"); List<DnsHelper.DnsRecord> list = new ArrayList<>();
if (records.length == 0) list.addAll(Arrays.asList(DnsHelper.lookup(context, "_imap._tcp." + domain, "srv")));
throw new UnknownHostException(domain); list.addAll(Arrays.asList(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 "."
provider.imap.score = 50; // ... service is not supported at all at a particular domain by setting the target of an SRV RR to "."
provider.imap.host = records[0].name; for (DnsHelper.DnsRecord record : new ArrayList<>(list))
provider.imap.port = records[0].port; if (TextUtils.isEmpty(record.name) || ".".equals(record.name))
provider.imap.starttls = false; list.remove(record);
EntityLog.log(context, "_imaps._tcp." + domain + "=" + provider.imap);
} catch (UnknownHostException ignored) { if (list.size() == 0)
// Identifies an IMAP server that MAY ... require the MUA to use the "STARTTLS" command throw new UnknownHostException(domain);
intf.onStatus("SRV imap " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imap._tcp." + domain, "srv"); Collections.sort(list, new Comparator<DnsHelper.DnsRecord>() {
if (records.length == 0) @Override
throw new UnknownHostException(domain); public int compare(DnsHelper.DnsRecord d1, DnsHelper.DnsRecord d2) {
provider.imap.score = 50; int p = -Integer.compare(d1.priority, d2.priority);
provider.imap.host = records[0].name; if (p != 0)
provider.imap.port = records[0].port; return p;
provider.imap.starttls = (provider.imap.port == 143); int w = -Integer.compare(d1.weight, d2.weight);
EntityLog.log(context, "_imap._tcp." + domain + "=" + provider.imap); if (w != 0)
} return w;
return -Boolean.compare(d1.query.startsWith("_imaps._tcp."), d2.query.startsWith("_imaps._tcp."));
}
});
DnsHelper.DnsRecord pref = list.get(0);
provider.imap.score = 50;
provider.imap.host = pref.name;
provider.imap.port = pref.port;
provider.imap.starttls = (!pref.query.startsWith("_imaps._tcp.") && pref.port == 143);
EntityLog.log(context, pref.query + "=" + provider.imap);
} }
if (discover == Discover.ALL || discover == Discover.SMTP) if (discover == Discover.ALL || discover == Discover.SMTP) {
try { intf.onStatus("SRV smtp " + domain);
// Note that this covers connections both with and without Transport Layer Security (TLS) // https://tools.ietf.org/html/rfc8314
intf.onStatus("SRV smtp " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, "srv"); List<DnsHelper.DnsRecord> list = new ArrayList<>();
if (records.length == 0) // Note that this covers connections both with and without Transport Layer Security (TLS)
throw new UnknownHostException(domain); list.addAll(Arrays.asList(DnsHelper.lookup(context, "_submission._tcp." + domain, "srv")));
provider.smtp.score = 50; list.addAll(Arrays.asList(DnsHelper.lookup(context, "_submissions._tcp." + domain, "srv")));
provider.smtp.host = records[0].name;
provider.smtp.port = records[0].port; for (DnsHelper.DnsRecord record : new ArrayList<>(list))
provider.smtp.starttls = (provider.smtp.port == 587); if (TextUtils.isEmpty(record.name) || ".".equals(record.name))
EntityLog.log(context, "_submission._tcp." + domain + "=" + provider.smtp); list.remove(record);
} catch (UnknownHostException ignored) {
// https://tools.ietf.org/html/rfc8314 if (list.size() == 0)
intf.onStatus("SRV smtps " + domain); throw new UnknownHostException(domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submissions._tcp." + domain, "srv");
if (records.length == 0) Collections.sort(list, new Comparator<DnsHelper.DnsRecord>() {
throw new UnknownHostException(domain); @Override
provider.smtp.score = 50; public int compare(DnsHelper.DnsRecord d1, DnsHelper.DnsRecord d2) {
provider.smtp.host = records[0].name; int p = -Integer.compare(d1.priority, d2.priority);
provider.smtp.port = records[0].port; if (p != 0)
provider.smtp.starttls = false; return p;
EntityLog.log(context, "_submissions._tcp." + domain + "=" + provider.smtp); int w = -Integer.compare(d1.weight, d2.weight);
} if (w != 0)
return w;
// submission is being preferred
return -Boolean.compare(d1.query.startsWith("_submission._tcp."), d2.query.startsWith("_submission._tcp."));
}
});
DnsHelper.DnsRecord pref = list.get(0);
provider.smtp.score = 50;
provider.smtp.host = pref.name;
provider.smtp.port = pref.port;
provider.smtp.starttls = (!pref.query.startsWith("_submissions._tcp.") && pref.port == 587);
EntityLog.log(context, pref.query + "=" + provider.smtp);
}
provider.validate(); provider.validate();

Loading…
Cancel
Save