aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-11-01 13:30:14 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2017-11-01 13:30:14 +0200
commite1ae6a6eb13992e21ee4102c45cc1a692017d891 (patch)
tree2ec401ca6feea878d2f492bd7185c9fe5903d1a0
parent64ea91a529e07f5444e23f05b7dccdcfec3f3db4 (diff)
downloadmailfromd-e1ae6a6eb13992e21ee4102c45cc1a692017d891.tar.gz
mailfromd-e1ae6a6eb13992e21ee4102c45cc1a692017d891.tar.bz2
Improve ADNS return status handling.
* lib/dns.c (adns_to_dns_status): Rewrite.
-rw-r--r--lib/dns.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/lib/dns.c b/lib/dns.c
index f3b1879c..7e792fba 100644
--- a/lib/dns.c
+++ b/lib/dns.c
@@ -248,21 +248,80 @@ errno_to_dns_status(int e)
return dns_failure;
}
}
-
+
+/* Table of correspondence between ADNS status codes and dns status.
+ Values are increased by 1 to be able to tell whether the entry is
+ initialized or not. */
+int adns_to_dns_tab[] = {
+#define STAT(s) ((s)+1)
+ [adns_s_ok] = STAT(dns_success),
+
+ [adns_s_nomemory] = STAT(dns_failure),
+ [adns_s_unknownrrtype] = STAT(dns_failure),
+ [adns_s_systemfail] = STAT(dns_failure),
+
+ /* remotely induced errors), detected locally */
+ [adns_s_timeout] = STAT(dns_temp_failure),
+ [adns_s_allservfail] = STAT(dns_temp_failure),
+ [adns_s_norecurse] = STAT(dns_temp_failure),
+ [adns_s_invalidresponse] = STAT(dns_failure),
+ [adns_s_unknownformat] = STAT(dns_failure),
+
+ /* remotely induced errors), reported by remote server to us */
+ [adns_s_rcodeservfail] = STAT(dns_not_found),
+ [adns_s_rcodeformaterror] = STAT(dns_not_found),
+ [adns_s_rcodenotimplemented] = STAT(dns_not_found),
+ [adns_s_rcoderefused] = STAT(dns_not_found),
+ [adns_s_rcodeunknown] = STAT(dns_not_found),
+
+ /* remote configuration errors */
+ [adns_s_inconsistent] = STAT(dns_not_found),
+ [adns_s_prohibitedcname] = STAT(dns_not_found),
+ [adns_s_answerdomaininvalid] = STAT(dns_not_found),
+ [adns_s_answerdomaintoolong] = STAT(dns_not_found),
+ [adns_s_invaliddata] = STAT(dns_not_found),
+
+ /* permanent problems with the query */
+ [adns_s_querydomainwrong] = STAT(dns_failure),
+ [adns_s_querydomaininvalid] = STAT(dns_failure),
+ [adns_s_querydomaintoolong] = STAT(dns_failure),
+
+ /* permanent errors */
+ [adns_s_nxdomain] = STAT(dns_not_found),
+ [adns_s_nodata] = STAT(dns_not_found),
+#undef STAT
+};
+
+/* Convert ADNS status code E to DNS status. */
static int
adns_to_dns_status(int e)
{
- switch (e) {
- case adns_s_ok:
- return dns_success;
- case adns_s_timeout:
+ int r;
+
+ /* If it is negative, fail right away */
+ if (e < 0)
+ return dns_failure;
+ /* If it is not in table, it still can be a valid, but unhandled
+ value */
+ if (e >= MU_ARRAY_SIZE(adns_to_dns_tab))
+ return e < adns_s_max_permfail ? dns_not_found : dns_failure;
+ /* Now, look up in the table */
+ if ((r = adns_to_dns_tab[e]) > 0)
+ return r - 1;
+ /* If not found in table, use adns_s_max_ constants to decide the
+ error class.
+ */
+ if (e < adns_s_max_localfail)
+ return dns_failure;
+ if (e < adns_s_max_remotefail)
+ return dns_not_found;
+ if (e < adns_s_max_tempfail)
return dns_temp_failure;
- case adns_s_nxdomain:
- case adns_s_nodata:
+ if (e < adns_s_max_misconfig)
return dns_not_found;
- default:
- return dns_failure;
- }
+ if (e < adns_s_max_misquery)
+ return dns_not_found;
+ return dns_not_found;
}
dns_status

Return to:

Send suggestions and report system problems to the System administrator.