diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-20 19:32:28 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-20 19:32:28 +0300 |
commit | b74300677afd3f489f6dc65959f722be28c2804b (patch) | |
tree | 39afd042f53ed37160031e2da1298d479be63765 | |
parent | ef49628b07df9ddb5f6035fc4941a10136a73b22 (diff) | |
download | mailfromd-b74300677afd3f489f6dc65959f722be28c2804b.tar.gz mailfromd-b74300677afd3f489f6dc65959f722be28c2804b.tar.bz2 |
Improve DNS API consistency
* lib/dns.c (dns_get_mx_records, getmx, getmxip): Replace
with a single function mx_lookup. All uses updated.
-rw-r--r-- | lib/dns.c | 80 | ||||
-rw-r--r-- | lib/dns.h | 2 | ||||
-rw-r--r-- | lib/libmf.h | 2 | ||||
-rw-r--r-- | src/builtin/dns.bi | 74 | ||||
-rw-r--r-- | src/callout.c | 2 | ||||
-rw-r--r-- | src/prog.c | 2 | ||||
-rw-r--r-- | src/spf.c | 2 | ||||
-rw-r--r-- | tests/resolv.c | 49 |
8 files changed, 101 insertions, 112 deletions
@@ -144,9 +144,41 @@ adns_to_dns_status(int e) } } +static dns_status +dns_reply_resolve(struct dns_reply *reply) +{ + GACOPYZ_UINT32_T *ipbuf = NULL; + size_t ipcount = 0; + size_t ipmax = 0; + size_t i; + + ipcount = 0; + for (i = 0; i < reply->count; i++) { + struct dns_reply r; + dns_status stat = a_lookup(reply->data.str[i], &r); + if (stat == dns_success) { + size_t n; + for (n = 0; n < r.count; n++, ipcount++) { + if (ipcount == ipmax) + ipbuf = mu_2nrealloc(ipbuf, &ipmax, + sizeof(ipbuf)); + ipbuf[ipcount] = ntohl(r.data.ip[n]); + } + dns_reply_free(&r); + } + } + dns_reply_free(reply); + if (ipcount == 0) + return dns_not_found; + reply->type = dns_reply_ip; + reply->count = ipcount; + reply->data.ip = ipbuf; + return dns_success; +} + /* Return MX records for the given HOST. */ dns_status -dns_get_mx_records(const char *host, struct dns_reply *reply) +mx_lookup(const char *host, int resolve, struct dns_reply *reply) { dns_status status = dns_failure; int rc; @@ -169,6 +201,10 @@ dns_get_mx_records(const char *host, struct dns_reply *reply) for (i = 0; i < ans->nrrs; i++) reply->data.str[i] = mu_strdup(ans->rrs.inthostaddr[i].ha.host); free(ans); + + if (resolve) + status = dns_reply_resolve(reply); + return status; } @@ -444,48 +480,6 @@ mf_to_dns_status(mf_status stat) } mf_status -getmx(const char *host, struct dns_reply *reply) -{ - return dns_to_mf_status(dns_get_mx_records(host, reply)); -} - -mf_status -getmxip(char *host, struct dns_reply *reply) -{ - struct dns_reply mxnames; - mf_status mxstat; - GACOPYZ_UINT32_T *ipbuf = NULL; - size_t ipcount = 0; - size_t ipmax = 0; - size_t i; - - mxstat = getmx(host, &mxnames); - if (mxstat != mf_success) - return mxstat; - - ipcount = 0; - for (i = 0; i < mxnames.count; i++) { - struct dns_reply r; - dns_status stat = a_lookup(mxnames.data.str[i], &r); - if (stat == dns_success) { - size_t n; - for (n = 0; n < r.count; n++, ipcount++) { - if (ipcount == ipmax) - ipbuf = mu_2nrealloc(ipbuf, &ipmax, - sizeof(ipbuf)); - ipbuf[ipcount] = ntohl(r.data.ip[n]); - } - dns_reply_free(&r); - } - } - dns_reply_free(&mxnames); - reply->type = dns_reply_ip; - reply->count = ipcount; - reply->data.ip = ipbuf; - return mf_success; -} - -mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf) { char *hbuf; @@ -43,7 +43,6 @@ struct dns_reply { void dns_reply_free(struct dns_reply *r); int dns_str_is_ipv4(const char *addr); -dns_status dns_get_mx_records(const char *host, struct dns_reply *repl); int dns_reverse_ipstr(const char *ipstr, char *revipstr); @@ -61,5 +60,6 @@ dns_status ptr_validate(const char *ipstr, struct dns_reply *repl); dns_status spf_lookup(const char *domain, char **record); +dns_status mx_lookup(const char *host, int resolve, struct dns_reply *repl); #endif diff --git a/lib/libmf.h b/lib/libmf.h index cf57e7a4..ebfd0e3e 100644 --- a/lib/libmf.h +++ b/lib/libmf.h @@ -282,8 +282,6 @@ size_t format_time_str(FILE *fp, time_t timestamp); void dnsbase_init(); mf_status dns_to_mf_status(dns_status stat); dns_status mf_to_dns_status(mf_status stat); -mf_status getmx(const char *host, struct dns_reply *repl); -mf_status getmxip(char *host, struct dns_reply *reply); mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf); mf_status resolve_ipstr(const char *ipstr, char **phbuf); mf_status resolve_hostname(const char *host, char **pipbuf); diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi index 4bde9676..8d28748a 100644 --- a/src/builtin/dns.bi +++ b/src/builtin/dns.bi @@ -152,7 +152,7 @@ MF_DEFUN(primitive_hasmx, NUMBER, STRING string) struct dns_reply repl; mf_status mxstat; - mxstat = getmx(string, &repl); + mxstat = dns_to_mf_status(mx_lookup(string, 0, &repl)); MF_ASSERT(mxstat == mf_success || mxstat == mf_not_found, mf_status_to_exception(mxstat), @@ -166,57 +166,41 @@ MF_DEFUN(primitive_hasmx, NUMBER, STRING string) } END -MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve) +MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER resolve) { mf_status mxstat; struct dns_reply reply; - - if (MF_OPTVAL(no_resolve)) { - mxstat = getmxip(domain, &reply); - if (!mf_resolved(mxstat)) { - MF_THROW(mf_status_to_exception(mxstat), - _("cannot get MX records for %s"), domain); - } - if (mxstat == mf_not_found) { - MF_RETURN(""); - } else { - int i; + int i; + + mxstat = dns_to_mf_status(mx_lookup(domain, MF_OPTVAL(resolve), + &reply)); + if (!mf_resolved(mxstat)) { + MF_THROW(mf_status_to_exception(mxstat), + _("cannot get MX records for %s"), domain); + } + if (mxstat == mf_not_found) { + MF_RETURN(""); + } else if (reply.type == dns_reply_ip) { + MF_OBSTACK_BEGIN(); + for (i = 0; i < reply.count; i++) { + struct in_addr s; + s.s_addr = htonl(reply.data.ip[i]); - MF_OBSTACK_BEGIN(); - for (i = 0; i < reply.count; i++) { - struct in_addr s; - s.s_addr = htonl(reply.data.ip[i]); - - if (i > 0) - MF_OBSTACK_1GROW(' '); - MF_OBSTACK_GROW(inet_ntoa(s)); - } - MF_OBSTACK_1GROW(0); - dns_reply_free(&reply); - MF_RETURN_OBSTACK(); + if (i > 0) + MF_OBSTACK_1GROW(' '); + MF_OBSTACK_GROW(inet_ntoa(s)); } } else { - mxstat = getmx(domain, &reply); - if (!mf_resolved(mxstat)) { - MF_THROW(mf_status_to_exception(mxstat), - _("cannot get MX records for %s"), domain); - } - if (mxstat == mf_not_found) { - MF_RETURN(""); - } else { - int i; - - MF_OBSTACK_BEGIN(); - for (i = 0; i < reply.count; i++) { - if (i > 0) - MF_OBSTACK_1GROW(' '); - MF_OBSTACK_GROW(reply.data.str[i]); - } - MF_OBSTACK_1GROW(0); - dns_reply_free(&reply); - MF_RETURN_OBSTACK(); + MF_OBSTACK_BEGIN(); + for (i = 0; i < reply.count; i++) { + if (i > 0) + MF_OBSTACK_1GROW(' '); + MF_OBSTACK_GROW(reply.data.str[i]); } } + MF_OBSTACK_1GROW(0); + dns_reply_free(&reply); + MF_RETURN_OBSTACK(); } END @@ -259,7 +243,7 @@ MF_DEFUN(primitive_ismx, NUMBER, STRING domain, STRING ipstr) _("cannot resolve host name %s"), ipstr); ip = ntohl(ip); - mxstat = getmxip(domain, &reply); + mxstat = dns_to_mf_status(mx_lookup(domain, 1, &reply)); if (mxstat != mf_success) { MF_THROW(mf_status_to_exception(mxstat), diff --git a/src/callout.c b/src/callout.c index 1d46bc70..8b7cd3c1 100644 --- a/src/callout.c +++ b/src/callout.c @@ -637,7 +637,7 @@ callout_mx(struct smtp_io_data *iop, const char *hostname, int *pcount) struct dns_reply reply; mf_status rc, mxstat; - mxstat = getmx(hostname, &reply); + mxstat = dns_to_mf_status(mx_lookup(hostname, 0, &reply)); if (pcount) *pcount = 0; @@ -1602,7 +1602,7 @@ mx_match(eval_environ_t env, char *string, p++; else p = string; - mxstat = getmx(p, &reply); + mxstat = dns_to_mf_status(mx_lookup(p, 0, &reply)); rc = 0; if (mxstat == mf_success) { int i; @@ -672,7 +672,7 @@ mech_mx(spf_data *dat, spf_term_arg *arg, unsigned long masklen) ("MX domain_spec=%s, netmask=%lx", domain_spec, netmask)); - DNS_CATCH(dns_get_mx_records(domain_spec, &reply)); + DNS_CATCH(mx_lookup(domain_spec, 0, &reply)); for (i = 0; i < reply.count; i++) { spf_term_arg targ; diff --git a/tests/resolv.c b/tests/resolv.c index 460b14b2..35d2d80a 100644 --- a/tests/resolv.c +++ b/tests/resolv.c @@ -35,12 +35,13 @@ hostname_cmp(const void *a, const void *b) } void -reply_print_str(struct dns_reply *reply) +reply_print_str(struct dns_reply *reply, int sorted) { int i; - - qsort(reply->data.str, reply->count, sizeof reply->data.str[0], - hostname_cmp); + + if (sorted) + qsort(reply->data.str, reply->count, sizeof reply->data.str[0], + hostname_cmp); for (i = 0; i < reply->count; i++) { printf("%s\n", reply->data.str[i]); } @@ -59,12 +60,13 @@ ipaddr_cmp(const void *a, const void *b) } void -reply_print_ip(struct dns_reply *reply) +reply_print_ip(struct dns_reply *reply, int sorted) { int i; - - qsort(reply->data.ip, reply->count, sizeof reply->data.ip[0], - ipaddr_cmp); + + if (sorted) + qsort(reply->data.ip, reply->count, sizeof reply->data.ip[0], + ipaddr_cmp); for (i = 0; i < reply->count; i++) { struct in_addr ip; ip.s_addr = reply->data.ip[i]; @@ -73,14 +75,14 @@ reply_print_ip(struct dns_reply *reply) } void -reply_print(struct dns_reply *reply) +reply_print(struct dns_reply *reply, int sorted) { switch (reply->type) { case dns_reply_str: - reply_print_str(reply); + reply_print_str(reply, sorted); break; case dns_reply_ip: - reply_print_ip(reply); + reply_print_ip(reply, sorted); break; default: mu_error("%s:%d: unrecognized reply type", __FILE__, __LINE__); @@ -98,7 +100,7 @@ res_a(int argc, char **argv) status = a_lookup(argv[0], &reply); status_print(status); if (status == dns_success) { - reply_print(&reply); + reply_print(&reply, 1); dns_reply_free(&reply); } return 0; @@ -120,7 +122,7 @@ res_ptr(int argc, char **argv) status = ptr_lookup(in, &reply); status_print(status); if (status == dns_success) { - reply_print(&reply); + reply_print(&reply, 1); dns_reply_free(&reply); } return 0; @@ -136,7 +138,7 @@ res_ptr_val(int argc, char **argv) status = ptr_validate(argv[0], &reply); status_print(status); if (status == dns_success) { - reply_print(&reply); + reply_print(&reply, 1); dns_reply_free(&reply); } return 0; @@ -152,7 +154,7 @@ res_txt(int argc, char **argv) status = txt_lookup(argv[0], &reply); status_print(status); if (status == dns_success) { - reply_print(&reply); + reply_print(&reply, 1); dns_reply_free(&reply); } return 0; @@ -163,12 +165,23 @@ res_mx(int argc, char **argv) { dns_status status; struct dns_reply reply; - + int ip = 0; + + if (argc == 2) { + if (strcmp(argv[0], "-ip") == 0) + ip = 1; + else { + mu_error("bad arguments"); + abort(); + } + argc--; + argv++; + } assert(argc == 1); - status = dns_get_mx_records(argv[0], &reply); + status = mx_lookup(argv[0], ip, &reply); status_print(status); if (status == dns_success) { - reply_print(&reply); + reply_print(&reply, 0); dns_reply_free(&reply); } return 0; |