DNS auto discovery: use priority/weight

This commit is contained in:
M66B
2023-04-03 20:45:22 +02:00
parent f6faf0fecc
commit 785e7a5ee7
2 changed files with 93 additions and 49 deletions

View File

@@ -857,56 +857,81 @@ public class EmailProvider implements Parcelable {
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.
intf.onStatus("SRV imaps " + domain);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv");
if (records.length == 0)
throw new UnknownHostException(domain);
// ... 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)
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);
}
intf.onStatus("SRV imap " + domain);
// Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server.
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 "."
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;
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)
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)
throw new UnknownHostException(domain);
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);
}
if (discover == Discover.ALL || discover == Discover.SMTP) {
intf.onStatus("SRV smtp " + domain);
// https://tools.ietf.org/html/rfc8314
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 = 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();