diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-19 22:06:20 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-10-19 22:06:20 +0300 |
commit | 0d8954ca25771bc6c6f5d9cf9bfa38a2b1bbba6e (patch) | |
tree | cba9192cbf520ef5527e3b1c7efccf69df24a334 /src | |
parent | b5a739de9d8ada25c4ce7cf5f365ecde89f470e5 (diff) | |
download | mailfromd-0d8954ca25771bc6c6f5d9cf9bfa38a2b1bbba6e.tar.gz mailfromd-0d8954ca25771bc6c6f5d9cf9bfa38a2b1bbba6e.tar.bz2 |
Improve DNS resolver API
Remove arbitrary size limits.
* NEWS: Version 8.2.90
* configure.ac: Likewise. Require Mailutils 3.3
* doc/calloutd.texi: Update.
* doc/functions.texi: Update.
* doc/mailfromd.texi: Update.
* doc/upgrade.texi: Update.
* lib/dns.c: Rewrite.
* lib/dns.h (MAXMXCOUNT, MXF_MAX): Remove.
(mxbuf_init,dns_resolve_ipstr)
(a_lookup,ptr_lookup,txt_lookup)
(spf_lookup): Change protos.
(dns_reply): New struct.
(dns_reply_free,dns_reply_ip): New functions.
* lib/libmf.h (getmxip): Change proto.
* src/builtin/dns.bi: Remove runtime configuration statements:
max-dns-reply-a, max-dns-reply-ptr, and max-dns-reply-mx. Rewrite using
the new DNS API.
* src/callout.c: Update.
* src/mailfromd.h: Update.
* src/main.c: Remove the max-match-mx configuration statement.
* src/prog.c: Update.
* src/spf.c: Update.
* src/spf.h: Update.
* src/srvcfg.c: Remove the max-callout-mx configuration statement.
Diffstat (limited to 'src')
-rw-r--r-- | src/builtin/dns.bi | 94 | ||||
-rw-r--r-- | src/callout.c | 2 | ||||
-rw-r--r-- | src/mailfromd.h | 3 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/prog.c | 2 | ||||
-rw-r--r-- | src/spf.c | 80 | ||||
-rw-r--r-- | src/spf.h | 3 | ||||
-rw-r--r-- | src/srvcfg.c | 5 |
8 files changed, 76 insertions, 118 deletions
diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi index 46433a00..faf8998d 100644 --- a/src/builtin/dns.bi +++ b/src/builtin/dns.bi | |||
@@ -21,20 +21,6 @@ | |||
21 | #include "srvcfg.h" | 21 | #include "srvcfg.h" |
22 | #include "global.h" | 22 | #include "global.h" |
23 | 23 | ||
24 | static size_t max_ptr = MAX_DNS_PTR; | ||
25 | static size_t max_a = MAX_DNS_A; | ||
26 | static size_t max_mx = MAX_DNS_MX; | ||
27 | static struct mu_cfg_param dns_cfg_param[] = { | ||
28 | { "max-dns-reply-a", mu_c_size, &max_a, 0, NULL, | ||
29 | N_("Maximum number of A records in a DNS reply.") }, | ||
30 | { "max-dns-reply-ptr", mu_c_size, &max_a, 0, NULL, | ||
31 | N_("Maximum number of PTR records in a DNS reply.") }, | ||
32 | { "max-dns-reply-mx", mu_c_size, &max_mx, 0, NULL, | ||
33 | N_("Maximum number of MX records in a DNS reply.") }, | ||
34 | { NULL } | ||
35 | }; | ||
36 | |||
37 | |||
38 | MF_DEFUN(primitive_hostname, STRING, STRING string) | 24 | MF_DEFUN(primitive_hostname, STRING, STRING string) |
39 | { | 25 | { |
40 | char *hbuf; | 26 | char *hbuf; |
@@ -75,8 +61,8 @@ END | |||
75 | static int | 61 | static int |
76 | ipaddr_cmp(const void *a, const void *b) | 62 | ipaddr_cmp(const void *a, const void *b) |
77 | { | 63 | { |
78 | GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T*)a); | 64 | GACOPYZ_UINT32_T ipa = ntohl(**(GACOPYZ_UINT32_T**)a); |
79 | GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T*)b); | 65 | GACOPYZ_UINT32_T ipb = ntohl(**(GACOPYZ_UINT32_T**)b); |
80 | if (ipa < ipb) | 66 | if (ipa < ipb) |
81 | return -1; | 67 | return -1; |
82 | if (ipa > ipb) | 68 | if (ipa > ipb) |
@@ -86,37 +72,33 @@ ipaddr_cmp(const void *a, const void *b) | |||
86 | 72 | ||
87 | MF_DEFUN(dns_getaddr, STRING, STRING string) | 73 | MF_DEFUN(dns_getaddr, STRING, STRING string) |
88 | { | 74 | { |
89 | GACOPYZ_UINT32_T *ipbuf; | 75 | size_t i; |
90 | size_t i, ipcount; | ||
91 | unsigned long ttl; | 76 | unsigned long ttl; |
92 | dns_status dnstat; | 77 | dns_status dnstat; |
93 | 78 | struct dns_reply r; | |
94 | ipbuf = mu_calloc(max_a, sizeof(ipbuf[0])); | 79 | |
95 | dnstat = a_lookup(string, ipbuf, max_a, &ipcount, | 80 | dnstat = a_lookup(string, &r, &ttl); |
96 | &ttl, NULL, 0); | ||
97 | switch (dnstat) { | 81 | switch (dnstat) { |
98 | case dns_success: { | 82 | case dns_success: { |
99 | MF_OBSTACK_BEGIN(); | 83 | MF_OBSTACK_BEGIN(); |
100 | qsort(ipbuf, ipcount, sizeof ipbuf[0], ipaddr_cmp); | 84 | qsort(r.base, r.count, sizeof r.base[0], ipaddr_cmp); |
101 | for (i = 0; i < ipcount; i++) { | 85 | for (i = 0; i < r.count; i++) { |
102 | struct in_addr addr; | 86 | struct in_addr addr; |
103 | char *q; | 87 | char *q; |
104 | 88 | ||
105 | addr.s_addr = ipbuf[i]; | 89 | addr.s_addr = dns_reply_ip(&r, i); |
106 | q = inet_ntoa(addr); | 90 | q = inet_ntoa(addr); |
107 | if (i > 0) | 91 | if (i > 0) |
108 | MF_OBSTACK_1GROW(' '); | 92 | MF_OBSTACK_1GROW(' '); |
109 | MF_OBSTACK_GROW(q); | 93 | MF_OBSTACK_GROW(q); |
110 | } | 94 | } |
111 | free(ipbuf); | 95 | dns_reply_free(&r); |
112 | MF_OBSTACK_1GROW(0); | 96 | MF_OBSTACK_1GROW(0); |
113 | MF_RETURN_OBSTACK(); | 97 | MF_RETURN_OBSTACK(); |
114 | } | 98 | } |
115 | case dns_not_found: | 99 | case dns_not_found: |
116 | free(ipbuf); | ||
117 | MF_RETURN(""); | 100 | MF_RETURN(""); |
118 | default: | 101 | default: |
119 | free(ipbuf); | ||
120 | MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)), | 102 | MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)), |
121 | _("failed to get A record for %s"), string); | 103 | _("failed to get A record for %s"), string); |
122 | } | 104 | } |
@@ -134,42 +116,33 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr) | |||
134 | dns_status dnstat; | 116 | dns_status dnstat; |
135 | struct in_addr addr; | 117 | struct in_addr addr; |
136 | unsigned long ttl; | 118 | unsigned long ttl; |
137 | char **names; | 119 | struct dns_reply r; |
138 | 120 | ||
139 | MF_ASSERT(inet_aton(ipstr, &addr), | 121 | MF_ASSERT(inet_aton(ipstr, &addr), |
140 | mfe_invip, | 122 | mfe_invip, |
141 | _("invalid IP: %s"), ipstr); | 123 | _("invalid IP: %s"), ipstr); |
142 | 124 | ||
143 | names = mu_calloc(max_ptr, sizeof(names[0])); | 125 | dnstat = ptr_lookup(addr, &r, &ttl); |
144 | dnstat = ptr_lookup(addr, names, max_ptr, &ttl, NULL, 0); | ||
145 | switch (dnstat) { | 126 | switch (dnstat) { |
146 | case dns_success: { | 127 | case dns_success: { |
147 | size_t i; | 128 | size_t i; |
148 | size_t ncount; | ||
149 | 129 | ||
150 | for (ncount = 0; ncount < max_ptr && names[ncount]; | 130 | qsort(r.base, r.count, sizeof r.base[0], hostname_cmp); |
151 | ncount++); | ||
152 | |||
153 | qsort(names, ncount, sizeof names[0], hostname_cmp); | ||
154 | 131 | ||
155 | MF_OBSTACK_BEGIN(); | 132 | MF_OBSTACK_BEGIN(); |
156 | for (i = 0; i < ncount; i++) { | 133 | for (i = 0; i < r.count; i++) { |
157 | if (i > 0) | 134 | if (i > 0) |
158 | MF_OBSTACK_1GROW(' '); | 135 | MF_OBSTACK_1GROW(' '); |
159 | MF_OBSTACK_GROW(names[i]); | 136 | MF_OBSTACK_GROW((char*)r.base[i]); |
160 | } | 137 | } |
161 | MF_OBSTACK_1GROW(0); | 138 | MF_OBSTACK_1GROW(0); |
162 | 139 | ||
163 | for (; i < ncount; i++) | 140 | dns_reply_free(&r); |
164 | free(names[i]); | ||
165 | free(names); | ||
166 | MF_RETURN_OBSTACK(); | 141 | MF_RETURN_OBSTACK(); |
167 | } | 142 | } |
168 | case dns_not_found: | 143 | case dns_not_found: |
169 | free(names); | ||
170 | MF_RETURN(""); | 144 | MF_RETURN(""); |
171 | default: | 145 | default: |
172 | free(names); | ||
173 | MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)), | 146 | MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)), |
174 | _("failed to get PTR record for %s"), ipstr); | 147 | _("failed to get PTR record for %s"), ipstr); |
175 | } | 148 | } |
@@ -204,15 +177,12 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve) | |||
204 | GACOPYZ_UINT32_T *ipbuf; | 177 | GACOPYZ_UINT32_T *ipbuf; |
205 | size_t ipcount; | 178 | size_t ipcount; |
206 | 179 | ||
207 | ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0])); | 180 | mxstat = getmxip(domain, &ipbuf, &ipcount); |
208 | mxstat = getmxip(domain, ipbuf, max_mx, &ipcount); | ||
209 | if (!mf_resolved(mxstat)) { | 181 | if (!mf_resolved(mxstat)) { |
210 | free(ipbuf); | ||
211 | MF_THROW(mf_status_to_exception(mxstat), | 182 | MF_THROW(mf_status_to_exception(mxstat), |
212 | _("cannot get MX records for %s"), domain); | 183 | _("cannot get MX records for %s"), domain); |
213 | } | 184 | } |
214 | if (mxstat == mf_not_found) { | 185 | if (mxstat == mf_not_found) { |
215 | free(ipbuf); | ||
216 | MF_RETURN(""); | 186 | MF_RETURN(""); |
217 | } else { | 187 | } else { |
218 | int i; | 188 | int i; |
@@ -233,8 +203,6 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve) | |||
233 | } else { | 203 | } else { |
234 | struct mxbuf mxbuf; | 204 | struct mxbuf mxbuf; |
235 | 205 | ||
236 | mxbuf.mx_max = max_mx; | ||
237 | mxbuf.mx_flags = MXF_MAX; | ||
238 | mxstat = getmx(domain, &mxbuf); | 206 | mxstat = getmx(domain, &mxbuf); |
239 | if (!mf_resolved(mxstat)) { | 207 | if (!mf_resolved(mxstat)) { |
240 | mxbuf_free(&mxbuf); | 208 | mxbuf_free(&mxbuf); |
@@ -301,11 +269,9 @@ MF_DEFUN(primitive_ismx, NUMBER, STRING domain, STRING ipstr) | |||
301 | _("cannot resolve host name %s"), ipstr); | 269 | _("cannot resolve host name %s"), ipstr); |
302 | ip = ntohl(ip); | 270 | ip = ntohl(ip); |
303 | 271 | ||
304 | ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0])); | 272 | mxstat = getmxip(domain, &ipbuf, &ipcount); |
305 | mxstat = getmxip(domain, ipbuf, max_mx, &ipcount); | ||
306 | 273 | ||
307 | if (mxstat != mf_success) { | 274 | if (mxstat != mf_success) { |
308 | free(ipbuf); | ||
309 | MF_THROW(mf_status_to_exception(mxstat), | 275 | MF_THROW(mf_status_to_exception(mxstat), |
310 | _("cannot get MXs for %s"), domain); | 276 | _("cannot get MXs for %s"), domain); |
311 | } | 277 | } |
@@ -328,6 +294,22 @@ MF_DEFUN(relayed, NUMBER, STRING s) | |||
328 | } | 294 | } |
329 | END | 295 |