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)));
} else if (record instanceof SRVRecord) {
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) {
TXTRecord txt = (TXTRecord) record;
for (Object content : txt.getStrings()) {
@ -241,6 +241,9 @@ public class DnsHelper {
throw new IllegalArgumentException(record.getClass().getName());
}
for (DnsRecord record : result)
record.query = name;
return result.toArray(new DnsRecord[0]);
} catch (TextParseException ex) {
Log.e(ex);
@ -283,8 +286,11 @@ public class DnsHelper {
}
static class DnsRecord {
String query;
String name;
Integer port;
Integer priority;
Integer weight;
DnsRecord(String name) {
this.name = name;
@ -294,5 +300,18 @@ public class DnsHelper {
this.name = name;
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,55 +857,80 @@ public class EmailProvider implements Parcelable {
EmailProvider provider = new EmailProvider(domain);
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);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv");
if (records.length == 0)
throw new UnknownHostException(domain);
List<DnsHelper.DnsRecord> list = new ArrayList<>();
list.addAll(Arrays.asList(DnsHelper.lookup(context, "_imap._tcp." + domain, "srv")));
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;
provider.imap.host = records[0].name;
provider.imap.port = records[0].port;
provider.imap.starttls = false;
EntityLog.log(context, "_imaps._tcp." + domain + "=" + provider.imap);
} catch (UnknownHostException ignored) {
// Identifies an IMAP server that MAY ... require the MUA to use the "STARTTLS" command
intf.onStatus("SRV imap " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imap._tcp." + domain, "srv");
if (records.length == 0)
for (DnsHelper.DnsRecord record : new ArrayList<>(list))
if (TextUtils.isEmpty(record.name) || ".".equals(record.name))
list.remove(record);
if (list.size() == 0)
throw new UnknownHostException(domain);
provider.imap.score = 50;
provider.imap.host = records[0].name;
provider.imap.port = records[0].port;
provider.imap.starttls = (provider.imap.port == 143);
EntityLog.log(context, "_imap._tcp." + domain + "=" + provider.imap);
Collections.sort(list, new Comparator<DnsHelper.DnsRecord>() {
@Override
public int compare(DnsHelper.DnsRecord d1, DnsHelper.DnsRecord d2) {
int p = -Integer.compare(d1.priority, d2.priority);
if (p != 0)
return p;
int w = -Integer.compare(d1.weight, d2.weight);
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)
try {
// Note that this covers connections both with and without Transport Layer Security (TLS)
if (discover == Discover.ALL || discover == Discover.SMTP) {
intf.onStatus("SRV smtp " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, "srv");
if (records.length == 0)
throw new UnknownHostException(domain);
provider.smtp.score = 50;
provider.smtp.host = records[0].name;
provider.smtp.port = records[0].port;
provider.smtp.starttls = (provider.smtp.port == 587);
EntityLog.log(context, "_submission._tcp." + domain + "=" + provider.smtp);
} catch (UnknownHostException ignored) {
// https://tools.ietf.org/html/rfc8314
intf.onStatus("SRV smtps " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submissions._tcp." + domain, "srv");
if (records.length == 0)
List<DnsHelper.DnsRecord> list = new ArrayList<>();
// Note that this covers connections both with and without Transport Layer Security (TLS)
list.addAll(Arrays.asList(DnsHelper.lookup(context, "_submission._tcp." + domain, "srv")));
list.addAll(Arrays.asList(DnsHelper.lookup(context, "_submissions._tcp." + domain, "srv")));
for (DnsHelper.DnsRecord record : new ArrayList<>(list))
if (TextUtils.isEmpty(record.name) || ".".equals(record.name))
list.remove(record);
if (list.size() == 0)
throw new UnknownHostException(domain);
Collections.sort(list, new Comparator<DnsHelper.DnsRecord>() {
@Override
public int compare(DnsHelper.DnsRecord d1, DnsHelper.DnsRecord d2) {
int p = -Integer.compare(d1.priority, d2.priority);
if (p != 0)
return p;
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 = records[0].name;
provider.smtp.port = records[0].port;
provider.smtp.starttls = false;
EntityLog.log(context, "_submissions._tcp." + domain + "=" + provider.smtp);
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();

Loading…
Cancel
Save