summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS19
-rw-r--r--configure.ac2
-rw-r--r--doc/calloutd.texi1
-rw-r--r--doc/functions.texi22
-rw-r--r--doc/mailfromd.texi89
-rw-r--r--doc/upgrade.texi23
-rw-r--r--lib/dns.c397
-rw-r--r--lib/dns.h46
-rw-r--r--lib/libmf.h2
-rw-r--r--src/builtin/dns.bi94
-rw-r--r--src/callout.c2
-rw-r--r--src/mailfromd.h3
-rw-r--r--src/main.c5
-rw-r--r--src/prog.c2
-rw-r--r--src/spf.c80
-rw-r--r--src/spf.h3
-rw-r--r--src/srvcfg.c5
17 files changed, 370 insertions, 425 deletions
diff --git a/NEWS b/NEWS
index c372865..9e7a8d7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
-Mailfromd NEWS -- history of user-visible changes. 2017-10-18
+Mailfromd NEWS -- history of user-visible changes. 2017-10-19
Copyright (C) 2005-2017 Sergey Poznyakoff
@@ -7,2 +7,19 @@ Please send Mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
+Version 8.2.90
+
+* Removed arbitrary limits on the sizes of DNS RRs
+
+The following configuration statements are removed:
+
+** runtime.max-dns-reply-a
+
+** runtime.max-dns-reply-ptr
+
+** runtime.max-dns-reply-mx
+
+** max-match-mx
+
+** max-callout-mx
+
+
Version 8.2, 2017-10-18
diff --git a/configure.ac b/configure.ac
index 53e8742..2dd23ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,3 +19,3 @@ m4_define([MF_VERSION_MAJOR], 8)
m4_define([MF_VERSION_MINOR], 2)
-dnl m4_define([MF_VERSION_PATCH], 0)
+m4_define([MF_VERSION_PATCH], 90)
AC_INIT([mailfromd],
diff --git a/doc/calloutd.texi b/doc/calloutd.texi
index 87f5d62..5bd9191 100644
--- a/doc/calloutd.texi
+++ b/doc/calloutd.texi
@@ -83,3 +83,2 @@ mailutils, GNU Mailutils Manual}.
@item @code{mail-from-address} @tab @xref{conf-callout, mail-from-address}.
-@item @code{max-callout-mx} @tab @xref{conf-callout, max-callout-mx}.
@item @code{pidfile} @tab @xref{conf-calloutd-setup, pidfile}.
diff --git a/doc/functions.texi b/doc/functions.texi
index b5a33c7..a9fb3e3 100644
--- a/doc/functions.texi
+++ b/doc/functions.texi
@@ -1922,5 +1922,3 @@ require dns
Returns a whitespace-separated list of @acronym{IP} addresses (@code{A}
-records) for @var{domain}. At most @value{MAX_DNS_A} addresses are
-returned. @xref{conf-runtime, max-dns-reply-a}, for a description of how
-to change this limit.
+records) for @var{domain}.
@@ -1931,5 +1929,3 @@ to change this limit.
Returns a whitespace-separated list of domain names (@code{PTR}
-records) for the @acronym{IP}v4 address @var{ipstr}. At most
-@value{MAX_DNS_PTR} names are returned. @xref{conf-runtime,
-max-dns-reply-ptr}, for a description of how to change this limit.
+records) for the @acronym{IP}v4 address @var{ipstr}.
@@ -1957,8 +1953,4 @@ getmx("org.pl") @result{} ""
-@emph{Notes}:
+@emph{Note}:
@enumerate 1
-@item The number of @acronym{MX} names or @acronym{IP} addresses
-returned by @code{getmx} is limited by the value of
-@code{max-dns-reply-mx} configuration statement (default
-@value{MAX_DNS_MX}). @xref{conf-runtime, max-dns-reply-mx}.
@@ -2058,6 +2050,2 @@ exception @code{e_not_found}.
@code{temp_failure}, depending on the character of the failure.
-
- The number of @samp{MX} records examined by this function is limited
-by the value of the @code{max-dns-reply-mx} configuration statement
-(@pxref{conf-runtime, max-dns-reply-mx}.
@end deftypefn
@@ -2075,6 +2063,2 @@ records for the @var{domain}. Otherwise it returns @code{false}.
function returns @code{false}.
-
- The number of @samp{MX} records examined by this function is limited
-by the value of the @code{max-dns-reply-mx} configuration statement
-(@pxref{conf-runtime, max-dns-reply-mx}.
@end deftypefn
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 05c9e83..d28915f 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -341,3 +341,2 @@ Configuring @command{mailfromd}
* conf-runtime:: Runtime Constants
-* conf-other:: Other Configuration Statements
* conf-mailutils:: Standard Mailutils Statements
@@ -473,3 +472,3 @@ possibilities.
was not flexible enough. It took less than a month to implement a
-configuration file that allowed to control program and data flow
+configuration file that allowed the user to control program and data flow
during the @samp{envfrom} @acronym{SMTP} state. The new version, 1.0,
@@ -477,23 +476,23 @@ appeared in June, 2005.
- The next major release, 1.2 (1.1 contained mostly bugfixes),
-appeared two months later, which introduced @dfn{mail sending rate}
+ Next major release, 1.2 (1.1 contained mostly bugfixes),
+appeared two months later, and introduced @dfn{mail sending rate}
control (@pxref{Rate Limit}).
- The program evolved during the next year, which led to the
-release of version 2.0 in September, 2006. This version was a major
-change in the main idea of the program. Configuration file become a
-flexible filter script allowing to control almost all @acronym{SMTP}
-states. The program supplied in the script file
-was compiled into a pseudo-code at startup, this code being subsequently
-evaluated each time the filter was invoked. This caused a considerable
-speed-up in comparison with the previous versions, where the run-time
-evaluator was traversing the parse tree. This version also introduced
-(implicitly, at the time), two separate data types for the entities
-declared in the script, which also played its role in the speed
-improvement (in the previous versions all data were considered
-strings). Lots of improvements were made in the filter language
-(@acronym{MFL}, @pxref{MFL}) itself, such as user-defined functions,
-@code{switch} statement, @code{catch} statement that allows to handle
-run-time errors, etc. The set of built-in functions extended
-considerably. A testsuite (using @i{DejaGNU}) was introduced in this version.
+ The program evolved during the next year, and the version 2.0 was
+released in September, 2006. This version was a major change in the
+main idea of the program. Configuration file become a flexible filter
+script allowing the operator to control almost all @acronym{SMTP} states. The
+program supplied in the script file was compiled into a pseudo-code at
+startup, this code being subsequently evaluated each time the filter
+was invoked. This caused a considerable speed-up in comparison with
+the previous versions, where the run-time evaluator was traversing the
+parse tree. This version also introduced (implicitly, at the time),
+two separate data types for the entities declared in the script, which
+also played its role in the speed improvement (in the previous
+versions all data were considered strings). Lots of improvements were
+made in the filter language (@acronym{MFL}, @pxref{MFL}) itself, such
+as user-defined functions, the @code{switch} statement, the @code{catch}
+statement for handling run-time errors, etc. The set of
+built-in functions extended considerably. A testsuite (using
+@i{DejaGNU}) was introduced in this version.
@@ -504,3 +503,3 @@ that @command{mailfromd} should use its own @samp{Milter}
implementation. This new library, @command{libgacopyz} was the main
-new feature of the 3.0 release, that was released in November, 2006.
+new feature of the 3.0 release, which was released in November, 2006.
Another major feature was the @option{--dump-macros} option and
@@ -523,3 +522,3 @@ was re-implemented to facilitate introduction of object files in
future versions. Another new features in this release include
-@acronym{SPF} support and @command{mtasim} utility, an @acronym{MTA}
+@acronym{SPF} support and @command{mtasim} utility --- an @acronym{MTA}
simulator designed for testing @command{mailfromd} scripts
@@ -543,5 +542,5 @@ concatenation operator, static variables, etc.
- Starting from version 7.0, main focus of further development of
-@command{mailfromd} has shifted. While previously it was regarded
-as a mail-filtering server, now it is being developed as a system for
+ Starting from version 7.0, the focus of further development of
+@command{mailfromd} has shifted. While previously it had been regarded
+as a mail-filtering server, since then it was developed as a system for
extending @acronym{MTA} functionality in the broad sense, mail
@@ -6470,6 +6469,2 @@ match the globbing pattern @var{y}.
- These operators examine at most @value{MAX_DNS_MX} @samp{MX}
-records. To change this limit, use the @code{max-match-mx}
-configuration statement (@pxref{conf-other, max-match-mx}).
-
Both @code{mx matches} and @code{mx fnmatches} can signal the
@@ -9090,3 +9085,2 @@ program calloutd @{
* conf-runtime:: Runtime Constants
-* conf-other:: Other Configuration Statements
* conf-mailutils:: Standard Mailutils Statements
@@ -9534,7 +9528,2 @@ setvar mailfrom_address @var{string};
-@deffn {Mailfromd Conf} max-callout-mx number
- Sets the maximum number of MXs to be polled during a callout
-verification. Defaults to @value{MAX_DNS_MX}.
-@end deffn
-
@deffn {Mailfromd Conf} enable-vrfy bool
@@ -9682,30 +9671,2 @@ functions}, for details.
-@deffn {runtime} max-dns-reply-a number
-Sets the maximum number of @acronym{DNS} @samp{A} records to be
-returned in a reply. This affects the @code{dns_getaddr} function
-(@pxref{DNS functions, dns_getaddr}). The default value is @value{MAX_DNS_A}.
-@end deffn
-
-@deffn {runtime} max-dns-reply-ptr number
-Sets the maximum number of @acronym{DNS} @samp{PTR} records to be
-returned in a reply. This affects the @code{dns_getname} function
-(@pxref{DNS functions, dns_getname}). The default value is @value{MAX_DNS_PTR}.
-@end deffn
-
-@deffn {runtime} max-dns-reply-mx number
-Sets the maximum number of @acronym{DNS} @samp{MX} records to be
-returned in a reply. This affects the following functions:
-@code{getpx}, @code{ismx}, @code{primitive_mx}
-(@pxref{DNS functions}). The default value is @value{MAX_DNS_MX}.
-@end deffn
-
-@node conf-other
-@section Other Configuration Statements
-
-@deffn {Mailfromd Conf} max-match-mx number
-Sets the maximum number of MXs to use in @samp{mx matches} operations
-(@pxref{mx matches}). Defaults to @value{MAX_DNS_MX}.
-@end deffn
-
-
@node conf-mailutils
diff --git a/doc/upgrade.texi b/doc/upgrade.texi
index ab7f7ec..03c3f59 100644
--- a/doc/upgrade.texi
+++ b/doc/upgrade.texi
@@ -12,2 +12,3 @@ between the consecutive Mailfromd releases.
@menu
+* 820-830:: Upgrading from 8.2 to 8.3
* 700-800:: Upgrading from 7.0 to 8.0
@@ -27,2 +28,24 @@ between the consecutive Mailfromd releases.
+@node 820-830
+@appendixsec Upgrading from 8.2 to 8.3
+@cindex Upgrading from 8.2 to 8.3
+
+ Version 8.3 contains significant improvements in the DNS
+resolver. In particular, it removes arbitrary limits on the sizes
+of the RRs. Consequently, the following configurations statements
+are withdrawn:
+
+@table @code
+@item runtime.max-dns-reply-a
+
+@item runtime.max-dns-reply-ptr
+
+@item runtime.max-dns-reply-mx
+
+@item max-match-mx
+
+@item max-callout-mx
+@end table
+
+
@node 700-800
diff --git a/lib/dns.c b/lib/dns.c
index e23e9ce..73c2364 100644
--- a/lib/dns.c
+++ b/lib/dns.c
@@ -33,2 +33,3 @@
#include "mailutils/alloc.h"
+#include "mailutils/argcv.h"
@@ -72,4 +73,6 @@ _getmx(const char *host, unsigned char *answer, size_t answer_size,
{
- int i, n, nmx;
- struct mx_buffer mx_buffer[MAXMXCOUNT];
+ struct mx_buffer *mx_buffer = NULL;
+ size_t mx_max = 0;
+ size_t nmx = 0;
+ int i, n;
HEADER *hp;
@@ -151,4 +154,9 @@ _getmx(const char *host, unsigned char *answer, size_t answer_size,
cp += n;
+ if (nmx == mx_max)
+ mx_buffer = mu_2nrealloc(mx_buffer,
+ &mx_max,
+ sizeof(mx_buffer[0]));
+
mx_buffer[nmx].pref = pref;
- mx_buffer[nmx].name = strdup(tname);
+ mx_buffer[nmx].name = mu_strdup(tname);
mu_debug(debug_handle, MU_DEBUG_TRACE2,
@@ -156,4 +164,3 @@ _getmx(const char *host, unsigned char *answer, size_t answer_size,
mx_buffer[nmx].name));
- if (++nmx >= mxbuf->mx_max)
- break;
+ nmx++;
}
@@ -164,6 +171,7 @@ _getmx(const char *host, unsigned char *answer, size_t answer_size,
/* Prepare return value */
- mxbuf_init(mxbuf);
+ mxbuf_init(mxbuf, nmx);
for (i = 0; i < nmx; i++)
mxbuf->mx_buf[i] = mx_buffer[i].name;
- mxbuf->mx_cnt = nmx;
+ mxbuf->mx_cnt = i;
+ free(mx_buffer);
return dns_success;
@@ -213,24 +221,19 @@ dns_get_mx_records(const char *host, int maxdepth, struct mxbuf *mxbuf,
if (host) {
- unsigned char *answer = malloc(MAXPACKET);
- if (!answer)
- status = dns_failure;
- else {
- const char *p;
- int depth;
+ unsigned char *answer = mu_alloc(MAXPACKET);
+ const char *p;
+ int depth;
- for (p = host, depth = 0; p && depth < maxdepth;
- p++, depth++) {
- if (ttl)
- *ttl = ~(unsigned long)0;
- status = _getmx(p, answer, MAXPACKET, mxbuf,
- ttl);
- if (status == dns_success
- || status == dns_temp_failure)
- break;
- p = strchr(p, '.');
- if (!p)
- break;
- }
- free(answer);
+ for (p = host, depth = 0; p && depth < maxdepth;
+ p++, depth++) {
+ if (ttl)
+ *ttl = ~(unsigned long)0;
+ status = _getmx(p, answer, MAXPACKET, mxbuf, ttl);
+ if (status == dns_success
+ || status == dns_temp_failure)
+ break;
+ p = strchr(p, '.');
+ if (!p)
+ break;
}
+ free(answer);
}
@@ -242,10 +245,8 @@ dns_get_mx_records(const char *host, int maxdepth, struct mxbuf *mxbuf,
void
-mxbuf_init(struct mxbuf *mxbuf)
+mxbuf_init(struct mxbuf *mxbuf, size_t nmx)
{
- if (!(mxbuf->mx_flags & MXF_MAX))
- mxbuf->mx_max = MAXMXCOUNT;
if (mxbuf->mx_flags & MXF_REUSE) {
- int i;
+ size_t i;
- for (i = 0; i < mxbuf->mx_max && mxbuf->mx_buf[i]; i++) {
+ for (i = 0; i < mxbuf->mx_cnt; i++) {
free(mxbuf->mx_buf[i]);
@@ -253,5 +254,11 @@ mxbuf_init(struct mxbuf *mxbuf)
}
+ if (nmx > mxbuf->mx_max) {
+ mxbuf->mx_buf =
+ mu_realloc(mxbuf->mx_buf,
+ nmx * sizeof(mxbuf->mx_buf[0]));
+ mxbuf->mx_max = nmx;
+ }
} else {
- mxbuf->mx_buf = mu_calloc(mxbuf->mx_max,
- sizeof(mxbuf->mx_buf[0]));
+ mxbuf->mx_buf = mu_calloc(nmx, sizeof(mxbuf->mx_buf[0]));
+ mxbuf->mx_max = nmx;
mxbuf->mx_flags |= MXF_REUSE;
@@ -269,3 +276,6 @@ mxbuf_free(struct mxbuf *mxbuf)
free(mxbuf->mx_buf[i]);
+ free(mxbuf->mx_buf);
mxbuf->mx_buf = NULL;
+ mxbuf->mx_flags &= ~MXF_REUSE;
+ mxbuf->mx_cnt = mxbuf->mx_max = 0;
}
@@ -277,2 +287,40 @@ mxbuf_free(struct mxbuf *mxbuf)
+void
+dns_reply_free(struct dns_reply *r)
+{
+ if (r->base) {
+ size_t i;
+ for (i = 0; i < r->count; i++)
+ free(r->base[i]);
+ free(r->base);
+ }
+}
+
+static void
+dns_reply_append(struct dns_reply *r, void *ptr, size_t len, int last)
+{
+ if (r->count == r->max)
+ r->base = mu_2nrealloc(r->base,
+ &r->max,
+ sizeof(r->base[0]));
+ if (last && r->count) {
+ while (r->last_len + len > r->last_max)
+ r->base[r->count-1] =
+ mu_2nrealloc(r->base[r->count-1],
+ &r->last_max,
+ 1);
+ } else if (ptr == NULL) {
+ r->base[r->count] = NULL;
+ return;
+ } else {
+ r->base[r->count] = mu_alloc(len);
+ r->count++;
+ r->last_len = 0;
+ r->last_max = len;
+ }
+
+ memcpy((char*)r->base[r->count-1] + r->last_len, ptr, len);
+ r->last_len += len;
+}
+
struct loop_data {
@@ -287,5 +335,3 @@ struct loop_data {
/* Return data: */
- char *hbuf; /* Return buffer */
- size_t hbsize; /* Size of return buffer */
- size_t hbcount; /* Number of items returned */
+ struct dns_reply repl;
@@ -433,16 +479,7 @@ cname_loop_body(struct loop_data *lp)
("size (%d) too big", n));
+ } else if (n != sizeof(GACOPYZ_UINT32_T)) {
+ mu_debug(debug_handle, MU_DEBUG_TRACE0,
+ ("unsupported address size: %d", n));
} else {
- if (n != sizeof(GACOPYZ_UINT32_T)) {
- mu_debug(debug_handle, MU_DEBUG_TRACE0,
- ("unsupported address size: %d",
- n));
- } else if (lp->hbcount * sizeof(GACOPYZ_UINT32_T) >= lp->hbsize)
- mu_debug(debug_handle, MU_DEBUG_TRACE0,
- ("Too many addresses"));
- else {
- memmove((GACOPYZ_UINT32_T *)
- lp->hbuf + lp->hbcount,
- cp, n);
- lp->hbcount++;
- }
+ dns_reply_append(&lp->repl, cp, n, 0);
}
@@ -462,9 +499,4 @@ cname_loop_body(struct loop_data *lp)
return LOOKUP_FAILURE;
- }
- l = strlen(nbuf);
- if (lp->hbcount + l >= lp->hbsize)
- break;
- memcpy(lp->hbuf + lp->hbcount, nbuf, l);
- lp->hbcount += l;
- lp->hbuf[lp->hbcount++] = 0;
+ }
+ dns_reply_append(&lp->repl, nbuf, strlen(nbuf) + 1, 0);
lp->atype = T_PTR;
@@ -478,2 +510,4 @@ cname_loop_body(struct loop_data *lp)
unsigned char *cur, *end;
+ int i = 0;
+
cur = cp;
@@ -482,9 +516,8 @@ cname_loop_body(struct loop_data *lp)
l = *cur++;
- if (lp->hbcount + l >= lp->hbsize)
- break;
- memcpy(lp->hbuf + lp->hbcount, cur, l);
- lp->hbcount += l;
- cur += l;
+ dns_reply_append(&lp->repl,
+ cur, l,
+ i > 0);
+ i++;
}
- lp->hbuf[lp->hbcount++] = 0;
+ dns_reply_append(&lp->repl, "", 1, 1);
lp->atype = T_TXT;
@@ -536,2 +569,10 @@ cnameloop(struct loop_data *lp)
MUTEX_LOCK(dns_mutex);
+
+ lp->ttl = ~(unsigned long)0;
+ lp->repl.base = NULL;
+ lp->repl.max = 0;
+ lp->repl.count = 0;
+ lp->status = dns_failure;
+ lp->loopcnt = MAXCNAMEDEPTH;
+
if (!lp->answer) {
@@ -589,3 +630,3 @@ dns_resolve_ipstr(const char *ipstr, const char *domain,
unsigned char *answer, size_t answer_size,
- char *hbuf, size_t hbsize, unsigned long *ttl)
+ char **hbuf, unsigned long *ttl)
{
@@ -615,8 +656,2 @@ dns_resolve_ipstr(const char *ipstr, const char *domain,
ld.answer_size = answer_size;
- ld.hbuf = hbuf;
- ld.hbsize = hbsize;
- ld.hbcount = 0;
- ld.ttl = ~(unsigned long)0;
- ld.status = dns_failure;
- ld.loopcnt = MAXCNAMEDEPTH;
@@ -624,8 +659,12 @@ dns_resolve_ipstr(const char *ipstr, const char *domain,
- if (ld.status == dns_success && ld.atype == T_A) {
- struct in_addr s;
- char *p;
- s.s_addr = *(GACOPYZ_UINT32_T*)hbuf;
- p = inet_ntoa(s);
- strncpy(hbuf, p, hbsize);
+ if (ld.status == dns_success) {
+ if (ld.atype == T_A) {
+ struct in_addr s;
+ s.s_addr = *(GACOPYZ_UINT32_T*)ld.repl.base[0];
+ *hbuf = mu_strdup(inet_ntoa(s));
+ } else if (ld.atype == T_PTR) {
+ *hbuf = mu_strdup(ld.repl.base[0]);
+ } else
+ abort();
+ dns_reply_free(&ld.repl);
}
@@ -639,3 +678,3 @@ dns_resolve_hostname(const char *host,
unsigned char *answer, size_t answer_size,
- char *ipbuf, size_t ipbsize, unsigned long *ttl)
+ char **ipbuf, unsigned long *ttl)
{
@@ -655,8 +694,2 @@ dns_resolve_hostname(const char *host,
ld.answer_size = answer_size;
- ld.hbuf = ipbuf;
- ld.hbsize = ipbsize;
- ld.hbcount = 0;
- ld.ttl = ~(unsigned long)0;
- ld.status = dns_failure;
- ld.loopcnt = MAXCNAMEDEPTH;
@@ -666,6 +699,5 @@ dns_resolve_hostname(const char *host,
struct in_addr s;
- char *p;
- s.s_addr = *(GACOPYZ_UINT32_T*)ipbuf;
- p = inet_ntoa(s);
- strncpy(ipbuf, p, ipbsize);
+ s.s_addr = *(GACOPYZ_UINT32_T*)ld.repl.base[0];
+ *ipbuf = mu_strdup(inet_ntoa(s));
+ dns_reply_free(&ld.repl);
}
@@ -678,5 +710,3 @@ dns_resolve_hostname(const char *host,
dns_status
-a_lookup(const char *host,
- GACOPYZ_UINT32_T *ipbuf, size_t ipbsize, size_t *ipcount,
- unsigned long *ttl, unsigned char *answer, size_t answer_size)
+a_lookup(const char *host, struct dns_reply *repl, unsigned long *ttl)
{
@@ -693,10 +723,4 @@ a_lookup(const char *host,
ld.domain_size = sizeof domainbuf;
- ld.answer = answer;
- ld.answer_size = answer_size;
- ld.hbuf = (char*) ipbuf;
- ld.hbsize = ipbsize * sizeof ipbuf[0];
- ld.hbcount = 0;
- ld.ttl = ~(unsigned long)0;
- ld.status = dns_failure;
- ld.loopcnt = MAXCNAMEDEPTH;
+ ld.answer = NULL;
+ ld.answer_size = 0;
@@ -704,4 +728,3 @@ a_lookup(const char *host,
if (ld.status == dns_success) {
- if (ipcount)
- *ipcount = ld.hbcount;
+ *repl = ld.repl;
if (ttl)
@@ -712,18 +735,4 @@ a_lookup(const char *host,
-static void
-textbuf_to_argv(const char *hbuf, size_t hsize, char **argv, size_t argc)
-{
- size_t i;
- const char *p;
-
- for (i = 0, p = hbuf; i < argc - 1 && p < hbuf + hsize;
- p += strlen(p) + 1)
- argv[i++] = mu_strdup(p);
- argv[i] = NULL;
-}
-
dns_status
-ptr_lookup(struct in_addr ip,
- char **names, size_t maxnames, unsigned long *ttl,
- unsigned char *answer, size_t answer_size)
+ptr_lookup(struct in_addr ip, struct dns_reply *repl, unsigned long *ttl)
{
@@ -731,3 +740,2 @@ ptr_lookup(struct in_addr ip,
char domainbuf[NSIZE];
- char hbuf[NSIZE];
struct loop_data ld;
@@ -745,10 +753,4 @@ ptr_lookup(struct in_addr ip,
ld.domain_size = sizeof domainbuf;
- ld.answer = answer;
- ld.answer_size = answer_size;
- ld.hbuf = hbuf;
- ld.hbsize = sizeof hbuf;
- ld.hbcount = 0;
- ld.ttl = ~(unsigned long)0;
- ld.status = dns_failure;
- ld.loopcnt = MAXCNAMEDEPTH;
+ ld.answer = NULL;
+ ld.answer_size = 0;
@@ -757,3 +759,3 @@ ptr_lookup(struct in_addr ip,
if (ld.status == dns_success) {
- textbuf_to_argv(ld.hbuf, ld.hbcount, names, maxnames);
+ *repl = ld.repl;
if (ttl)
@@ -766,8 +768,5 @@ ptr_lookup(struct in_addr ip,
dns_status
-txt_lookup(const char *name,
- char **names, size_t maxnames, unsigned long *ttl,
- unsigned char *answer, size_t answer_size)
+txt_lookup(const char *name, struct dns_reply *repl, unsigned long *ttl)
{
char domainbuf[NSIZE];
- char hbuf[NSIZE];
struct loop_data ld;
@@ -781,10 +780,4 @@ txt_lookup(const char *name,
ld.domain_size = sizeof domainbuf;
- ld.answer = answer;
- ld.answer_size = answer_size;
- ld.hbuf = hbuf;
- ld.hbsize = sizeof hbuf;
- ld.hbcount = 0;
- ld.ttl = ~(unsigned long)0;
- ld.status = dns_failure;
- ld.loopcnt = MAXCNAMEDEPTH;
+ ld.answer = NULL;
+ ld.answer_size = 0;
@@ -795,3 +788,3 @@ txt_lookup(const char *name,
if (ld.status == dns_success) {
- textbuf_to_argv(ld.hbuf, ld.hbcount, names, maxnames);
+ *repl = ld.repl;
if (ttl)
@@ -803,12 +796,15 @@ txt_lookup(const char *name,
-/* FIXME: This is a placeholder for a function that should look up for any
- SPF or TXT records for DOMAIN. If any SPF are found, TXT should be
- discarded.
- For the time being, it handles only TXT */
dns_status
spf_lookup(const char *domain,
- char **txt, size_t maxtxt, unsigned long *ttl,
- unsigned char *answer, size_t answer_size)
+ char ***txtv, size_t *txtc, unsigned long *ttl)
{
- return txt_lookup(domain, txt, maxtxt, ttl, answer, answer_size);
+ dns_status res;
+ struct dns_reply r;
+ res = txt_lookup(domain, &r, ttl);
+ if (res == dns_success) {
+ *txtv = (char**)r.base;
+ if (txtc)
+ *txtc = r.count;
+ }
+ return res;
}
@@ -821,5 +817,3 @@ ptr_validate(const char *ipstr, char ***vnptr, size_t *vcount,
struct in_addr ip;
- char *names[11], **p;
- char *vnames[10];
- size_t vi = 0;
+ size_t i;
int status;
@@ -827,2 +821,6 @@ ptr_validate(const char *ipstr, char ***vnptr, size_t *vcount,
unsigned long ttl;
+ struct dns_reply ptr_repl;
+ char **sv = NULL;
+ size_t sc = 0;
+ size_t sn = 0;
@@ -831,3 +829,3 @@ ptr_validate(const char *ipstr, char ***vnptr, size_t *vcount,
- status = ptr_lookup(ip, names, NELEMS(names), &ttl, NULL, 0);
+ status = ptr_lookup(ip, &ptr_repl, &ttl);
@@ -837,40 +835,36 @@ ptr_validate(const char *ipstr, char ***vnptr, size_t *vcount,
UPDATE_TTL(minttl, ttl);
+ for (i = 0; i < ptr_repl.count; i++) {
+ struct dns_reply r;
+ status = a_lookup((char*)ptr_repl.base[i], &r, &ttl);
+ if (status == dns_success) {
+ size_t k;
- for (p = names; *p; p++) {
- GACOPYZ_UINT32_T ipbuf[10];
- size_t ipcount;
- status = a_lookup(*p,
- ipbuf, NELEMS(ipbuf),
- &ipcount,
- &ttl, NULL, 0);
- if (status == dns_success && vi < NELEMS(vnames[0])) {
- size_t i;
-
UPDATE_TTL(minttl, ttl);
- for (i = 0; i < ipcount; i++)
- if (ipbuf[i] == ip.s_addr) {
- vnames[vi++] = *p;
- if (vnptr)
- *p = NULL;
+ for (k = 0; k < r.count; k++) {
+ if (dns_reply_ip(&r, k) == ip.s_addr) {
+ if (sc == sn)
+ sv = mu_2nrealloc(sv, &sn,
+ sizeof(sv[0]));
+ sv[sc++] = mu_strdup(ptr_repl.base[i]);
break;
}
+ }
+ dns_reply_free(&r);
}
- free(*p);
}
-
- if (vi > 0) {
- if (pttl)
- *pttl = minttl;
- if (vnptr) {
- size_t i;
-
- *vnptr = mu_calloc(vi+1, sizeof vnptr[0]);
- for (i = 0; i < vi; i++)
- (*vnptr)[i] = vnames[i];
- (*vnptr)[i] = NULL;
- *vcount = vi;
- }
+ dns_reply_free(&ptr_repl);
+
+ if (sc == 0) {
+ return dns_not_found;
}
+ if (pttl)
+ *pttl = minttl;
+ if (vcount)
+ *vcount = sc;
+ if (vnptr)
+ *vnptr = sv;
+ else
+ mu_argcv_free(sc, sv);
- return vi > 0 ? dns_success : dns_not_found;
+ return dns_success;
}
@@ -893,3 +887,2 @@ getmx(const char *host, struct mxbuf *mxbuf)
{
- mxbuf_init(mxbuf);
return dns_to_mf_status(dns_get_mx_records(host, 1, mxbuf, NULL));
@@ -898,3 +891,3 @@ getmx(const char *host, struct mxbuf *mxbuf)
mf_status
-getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount)
+getmxip(char *host, GACOPYZ_UINT32_T **pipbuf, size_t *pcount)
{
@@ -902,7 +895,7 @@ getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount)
mf_status mxstat;
- size_t ipcount;
+ GACOPYZ_UINT32_T *ipbuf = NULL;
+ size_t ipcount = 0;
+ size_t ipmax = 0;
size_t i;
- mxbuf.mx_max = mxmax;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(host, &mxbuf);
@@ -913,15 +906,13 @@ getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount)
for (i = 0; i < mxbuf.mx_cnt; i++) {
- size_t ipn;
- dns_status stat = a_lookup(mxbuf.mx_buf[i],
- ipbuf + ipcount,
- mxmax - ipcount,
- &ipn,
- NULL, NULL, 0);
+ struct dns_reply r;
+ dns_status stat = a_lookup(mxbuf.mx_buf[i], &r, NULL);
if (stat == dns_success) {
size_t n;
- for (n = 0; ipcount < mxmax && n < ipn;
- n++, ipcount++)
- ipbuf[ipcount] = ntohl(ipbuf[ipcount]);
- if (ipcount == mxmax)
- break;
+ for (n = 0; n < r.count; n++, ipcount++) {
+ if (ipcount == ipmax)
+ ipbuf = mu_2nrealloc(ipbuf, &ipmax,
+ sizeof(ipbuf));
+ ipbuf[ipcount] = ntohl(dns_reply_ip(&r, n));
+ }
+ dns_reply_free(&r);
}
@@ -930,2 +921,3 @@ getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount)
mxbuf_free(&mxbuf);
+ *pipbuf = ipbuf;
*pcount = ipcount;
@@ -939,3 +931,3 @@ resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf)
unsigned long ttl;
- char buffer[256];
+ char *hbuf;
dns_status dstat;
@@ -948,3 +940,3 @@ resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf)
dstat = dns_resolve_ipstr(ipstr, domain, answer, MAXPACKET,
- buffer, sizeof buffer, &ttl);
+ &hbuf, &ttl);
@@ -953,4 +945,4 @@ resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf)
mu_debug(debug_handle, MU_DEBUG_TRACE8,
- ("%s resolved to %s", ipstr, buffer));
- *phbuf = mu_strdup(buffer);
+ ("%s resolved to %s", ipstr, hbuf));
+ *phbuf = hbuf;
break;
@@ -974,3 +966,2 @@ resolve_hostname(const char *host, char **pipbuf)
static unsigned char *answer;
- char buffer[256];
char *ipbuf;
@@ -981,3 +972,3 @@ resolve_hostname(const char *host, char **pipbuf)
if (!answer)
- answer = malloc(MAXPACKET);
+ answer = mu_alloc(MAXPACKET);
mu_debug(debug_handle, MU_DEBUG_TRACE8,
@@ -986,4 +977,3 @@ resolve_hostname(const char *host, char **pipbuf)
dstat = dns_resolve_hostname(tmphost, answer, MAXPACKET,
- buffer, sizeof buffer,
- &ttl);
+ &ipbuf, &ttl);
free(tmphost);
@@ -991,3 +981,2 @@ resolve_hostname(const char *host, char **pipbuf)
case dns_success:
- ipbuf = mu_strdup(buffer);
mu_debug(debug_handle, MU_DEBUG_TRACE8,
diff --git a/lib/dns.h b/lib/dns.h
index b2884b0..000c6da 100644
--- a/lib/dns.h
+++ b/lib/dns.h
@@ -33,5 +33,2 @@ typedef enum {
-#define MAXMXCOUNT 32
-
-#define MXF_MAX 0x01
#define MXF_REUSE 0x02
@@ -80,3 +77,3 @@ struct mxbuf {
-void mxbuf_init(struct mxbuf *mxbuf);
+void mxbuf_init(struct mxbuf *mxbuf, size_t n);
void mxbuf_free(struct mxbuf *mxbuf);
@@ -91,3 +88,3 @@ dns_status dns_resolve_ipstr(const char *ipstr, const char *domain,
unsigned char *answer, size_t answer_size,
- char *hbuf, size_t hbsize, unsigned long *ttl);
+ char **hbuf, unsigned long *ttl);
@@ -95,15 +92,28 @@ dns_status dns_resolve_hostname(const char *host,
unsigned char *answer, size_t answer_size,
- char *ipbuf, size_t ipbsize,
- unsigned long *ttl);
-dns_status a_lookup(const char *host,
- GACOPYZ_UINT32_T *ipbuf, size_t ipbsize, size_t *ipcount,
- unsigned long *ttl,
- unsigned char *answer, size_t answer_size);
+ char **ipbuf, unsigned long *ttl);
+
+struct dns_reply {
+ size_t count;
+ size_t max;
+
+ void **base;
+ size_t last_len;
+ size_t last_max;
+};
+
+void dns_reply_free(struct dns_reply *r);
+
+static inline GACOPYZ_UINT32_T
+dns_reply_ip(struct dns_reply const *repl, size_t n)
+{
+ return *(GACOPYZ_UINT32_T*)repl->base[n];
+}
+
+dns_status a_lookup(const char *host,
+ struct dns_reply *repl, unsigned long *ttl);
dns_status ptr_lookup(struct in_addr ip,
- char **names, size_t maxnames, unsigned long *ttl,
- unsigned char *answer, size_t answer_size);
+ struct dns_reply *repl, unsigned long *ttl);
dns_status txt_lookup(const char *name,
- char **names, size_t maxnames, unsigned long *ttl,
- unsigned char *answer, size_t answer_size);
+ struct dns_reply *repl, unsigned long *ttl);
@@ -111,3 +121,7 @@ dns_status ptr_validate(const char *ipstr, char ***vnptr, size_t *vcount,
unsigned long *pttl);
-
+
+dns_status spf_lookup(const char *domain,
+ char ***txtv, size_t *txtc, unsigned long *ttl);
+
+
#endif
diff --git a/lib/libmf.h b/lib/libmf.h
index 9842b75..5336b21 100644
--- a/lib/libmf.h
+++ b/lib/libmf.h
@@ -285,3 +285,3 @@ dns_status mf_to_dns_status(mf_status stat);
mf_status getmx(const char *host, struct mxbuf *mxbuf);
-mf_status getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t mxmax, size_t *pcount);
+mf_status getmxip(char *host, GACOPYZ_UINT32_T **ipbuf, size_t *pcount);
mf_status resolve_ipstr_domain(const char *ipstr, const char *domain, char **phbuf);
diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi
index 46433a0..faf8998 100644
--- a/src/builtin/dns.bi
+++ b/src/builtin/dns.bi
@@ -23,16 +23,2 @@
-static size_t max_ptr = MAX_DNS_PTR;
-static size_t max_a = MAX_DNS_A;
-static size_t max_mx = MAX_DNS_MX;
-static struct mu_cfg_param dns_cfg_param[] = {
- { "max-dns-reply-a", mu_c_size, &max_a, 0, NULL,
- N_("Maximum number of A records in a DNS reply.") },
- { "max-dns-reply-ptr", mu_c_size, &max_a, 0, NULL,
- N_("Maximum number of PTR records in a DNS reply.") },
- { "max-dns-reply-mx", mu_c_size, &max_mx, 0, NULL,
- N_("Maximum number of MX records in a DNS reply.") },
- { NULL }
-};
-
-
MF_DEFUN(primitive_hostname, STRING, STRING string)
@@ -77,4 +63,4 @@ ipaddr_cmp(const void *a, const void *b)
{
- GACOPYZ_UINT32_T ipa = ntohl(*(GACOPYZ_UINT32_T*)a);
- GACOPYZ_UINT32_T ipb = ntohl(*(GACOPYZ_UINT32_T*)b);
+ GACOPYZ_UINT32_T ipa = ntohl(**(GACOPYZ_UINT32_T**)a);
+ GACOPYZ_UINT32_T ipb = ntohl(**(GACOPYZ_UINT32_T**)b);
if (ipa < ipb)
@@ -88,10 +74,8 @@ MF_DEFUN(dns_getaddr, STRING, STRING string)
{
- GACOPYZ_UINT32_T *ipbuf;
- size_t i, ipcount;
+ size_t i;
unsigned long ttl;
dns_status dnstat;
-
- ipbuf = mu_calloc(max_a, sizeof(ipbuf[0]));
- dnstat = a_lookup(string, ipbuf, max_a, &ipcount,
- &ttl, NULL, 0);
+ struct dns_reply r;
+
+ dnstat = a_lookup(string, &r, &ttl);
switch (dnstat) {
@@ -99,4 +83,4 @@ MF_DEFUN(dns_getaddr, STRING, STRING string)
MF_OBSTACK_BEGIN();
- qsort(ipbuf, ipcount, sizeof ipbuf[0], ipaddr_cmp);
- for (i = 0; i < ipcount; i++) {
+ qsort(r.base, r.count, sizeof r.base[0], ipaddr_cmp);
+ for (i = 0; i < r.count; i++) {
struct in_addr addr;
@@ -104,3 +88,3 @@ MF_DEFUN(dns_getaddr, STRING, STRING string)
- addr.s_addr = ipbuf[i];
+ addr.s_addr = dns_reply_ip(&r, i);
q = inet_ntoa(addr);
@@ -110,3 +94,3 @@ MF_DEFUN(dns_getaddr, STRING, STRING string)
}
- free(ipbuf);
+ dns_reply_free(&r);
MF_OBSTACK_1GROW(0);
@@ -115,6 +99,4 @@ MF_DEFUN(dns_getaddr, STRING, STRING string)
case dns_not_found:
- free(ipbuf);
MF_RETURN("");
default:
- free(ipbuf);
MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)),
@@ -136,4 +118,4 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
unsigned long ttl;
- char **names;
-
+ struct dns_reply r;
+
MF_ASSERT(inet_aton(ipstr, &addr),
@@ -142,4 +124,3 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
- names = mu_calloc(max_ptr, sizeof(names[0]));
- dnstat = ptr_lookup(addr, names, max_ptr, &ttl, NULL, 0);
+ dnstat = ptr_lookup(addr, &r, &ttl);
switch (dnstat) {
@@ -147,14 +128,10 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
size_t i;
- size_t ncount;
- for (ncount = 0; ncount < max_ptr && names[ncount];
- ncount++);
-
- qsort(names, ncount, sizeof names[0], hostname_cmp);
+ qsort(r.base, r.count, sizeof r.base[0], hostname_cmp);
MF_OBSTACK_BEGIN();
- for (i = 0; i < ncount; i++) {
+ for (i = 0; i < r.count; i++) {
if (i > 0)
MF_OBSTACK_1GROW(' ');
- MF_OBSTACK_GROW(names[i]);
+ MF_OBSTACK_GROW((char*)r.base[i]);
}
@@ -162,5 +139,3 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
- for (; i < ncount; i++)
- free(names[i]);
- free(names);
+ dns_reply_free(&r);
MF_RETURN_OBSTACK();
@@ -168,6 +143,4 @@ MF_DEFUN(dns_getname, STRING, STRING ipstr)
case dns_not_found:
- free(names);
MF_RETURN("");
default:
- free(names);
MF_THROW(mf_status_to_exception(dns_to_mf_status(dnstat)),
@@ -206,6 +179,4 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
- ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0]));
- mxstat = getmxip(domain, ipbuf, max_mx, &ipcount);
+ mxstat = getmxip(domain, &ipbuf, &ipcount);
if (!mf_resolved(mxstat)) {
- free(ipbuf);
MF_THROW(mf_status_to_exception(mxstat),
@@ -214,3 +185,2 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
if (mxstat == mf_not_found) {
- free(ipbuf);
MF_RETURN("");
@@ -235,4 +205,2 @@ MF_DEFUN(getmx, STRING, STRING domain, OPTIONAL, NUMBER no_resolve)
- mxbuf.mx_max = max_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(domain, &mxbuf);
@@ -303,7 +271,5 @@ MF_DEFUN(primitive_ismx, NUMBER, STRING domain, STRING ipstr)
- ipbuf = mu_calloc(max_mx, sizeof(ipbuf[0]));
- mxstat = getmxip(domain, ipbuf, max_mx, &ipcount);
+ mxstat = getmxip(domain, &ipbuf, &ipcount);
if (mxstat != mf_success) {
- free(ipbuf);
MF_THROW(mf_status_to_exception(mxstat),
@@ -330,4 +296,20 @@ END
-MF_INIT([<
- mf_add_runtime_params(dns_cfg_param);
- >])
+MF_DEFUN(ptr_validate, NUMBER, STRING s)
+{
+ int rc, res;
+ switch (rc = ptr_validate(s, NULL, NULL, NULL)) {
+ case dns_success:
+ res = 1;
+ break;
+ case dns_not_found:
+ res = 0;
+ break;
+ default:
+ MF_THROW(mf_status_to_exception(dns_to_mf_status(rc)),
+ _("failed to get PTR record for %s"), s);
+ }
+ MF_RETURN(res);
+}
+END
+
+MF_INIT
diff --git a/src/callout.c b/src/callout.c
index e59e8f0..633a33b 100644
--- a/src/callout.c
+++ b/src/callout.c
@@ -639,4 +639,2 @@ callout_mx(struct smtp_io_data *iop, const char *hostname, int *pcount)
- mxbuf.mx_max = max_callout_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(hostname, &mxbuf);
diff --git a/src/mailfromd.h b/src/mailfromd.h
index 5cc7136..7f21e36 100644
--- a/src/mailfromd.h
+++ b/src/mailfromd.h
@@ -78,4 +78,3 @@ mf_status resolve_hostname(const char *host, char **pipbuf);
mf_status getmx(const char *ipstr, struct mxbuf *mxbuf);
-mf_status getmxip(char *host, GACOPYZ_UINT32_T *ipbuf, size_t ipmax,
- size_t *pcount);
+mf_status getmxip(char *host, GACOPYZ_UINT32_T **ipbuf, size_t *pcount);
diff --git a/src/main.c b/src/main.c
index 66a9780..9873ed0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -75,4 +75,2 @@ int stack_trace_option; /* Print stack traces on runtime errors */
-size_t max_match_mx = MAXMXCOUNT;
-
char *main_function_name = "main";
@@ -855,5 +853,2 @@ struct mu_cfg_param mf_cfg_param[] = {
- { "max-match-mx", mu_c_size, &max_match_mx, 0, NULL,
- N_("Maximum number of MXs used by MFL \"mx match\" operation.") },
-
{ "runtime", mu_cfg_section, NULL },
diff --git a/src/prog.c b/src/prog.c
index 12dc69e..3e90472 100644
--- a/src/prog.c
+++ b/src/prog.c
@@ -1604,4 +1604,2 @@ mx_match(eval_environ_t env, char *string,
p = string;
- mxbuf.mx_max = max_match_mx;
- mxbuf.mx_flags = MXF_MAX;
mxstat = getmx(p, &mxbuf);
diff --git a/src/spf.c b/src/spf.c
index 236efa5..9e8c1bf 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -632,5 +632,6 @@ mech_a(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
struct in_addr addr;
- GACOPYZ_UINT32_T ipbuf[64]; /* FIXME: arbitrary limit */
- size_t i, ipcount;
+ struct dns_reply r;
+ size_t i;
unsigned long ttl;
+ spf_term_result res;
@@ -646,4 +647,3 @@ mech_a(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
- DNS_CATCH(a_lookup(domain_spec, ipbuf, NELEMS(ipbuf), &ipcount,
- &ttl, NULL, 0));
+ DNS_CATCH(a_lookup(domain_spec, &r, &ttl));
UPDATE_ANSWER_TTL(dat, ttl);
@@ -653,12 +653,14 @@ mech_a(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
("A: s_addr=%x", addr.s_addr));
-
- for (i = 0; i < ipcount; i++) {
- if ((ntohl(ipbuf[i]) & netmask) == addr.s_addr) {
- mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1,
- ("A matches"));
- return spf_term_match;
+
+ res = spf_term_nomatch;
+ for (i = 0; i < r.count; i++) {
+ if (ntohl(dns_reply_ip(&r, i) & netmask) == addr.s_addr) {
+ res = spf_term_match;
+ break;
}
}
- mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1, ("A does not match"));
- return spf_term_nomatch;
+ dns_reply_free(&r);
+ mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE1,
+ (res == spf_term_match ? "A matches" : "A does not match"));
+ return res;
}
@@ -687,4 +689,2 @@ mech_mx(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
- mxbuf.mx_flags = MXF_MAX;
- mxbuf.mx_max = 10;
DNS_CATCH(dns_get_mx_records(domain_spec, 1, &mxbuf, &ttl));
@@ -781,2 +781,3 @@ mech_exists(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
unsigned long ttl;
+ struct dns_reply r;
if (!arg) {
@@ -790,3 +791,4 @@ mech_exists(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
- DNS_CATCH(a_lookup(arg->v.domain_spec, NULL, 0, NULL, &ttl, NULL, 0));
+ DNS_CATCH(a_lookup(arg->v.domain_spec, &r, &ttl));
+ dns_reply_free(&r);
UPDATE_ANSWER_TTL(dat, ttl);
@@ -818,7 +820,6 @@ mod_exp(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
{
- char *names[128]; /* FIXME: arbitrary limit */
+ struct dns_reply r;
+
if (arg->v.domain_spec
- && txt_lookup(arg->v.domain_spec,
- names, NELEMS(names), NULL,
- NULL, 0) == dns_success) {
+ && txt_lookup(arg->v.domain_spec, &r, NULL) == dns_success) {
int i;
@@ -826,6 +827,6 @@ mod_exp(spf_data *dat, spf_term_arg *arg, unsigned long masklen)
- for (i = 0; names[i]; i++) {
- mu_opool_appendz(dat->tmpool, names[i]);
- free(names[i]);
+ for (i = 0; i < r.count; i++) {
+ mu_opool_appendz(dat->tmpool, r.base[i]);
}
+ dns_reply_free(&r);
mu_opool_append_char(dat->tmpool, 0);
@@ -1215,4 +1216,6 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
{
- char *txt_rec[SPF_MAX_TXT_REC+1];
- int ntxt, i;
+ char **txt_rec;
+ size_t txt_num;
+ int i;
+ char *spf_rec = NULL;
struct spf_data dat;
@@ -1243,4 +1246,3 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
- switch (spf_lookup(q->domain, txt_rec, NELEMS(txt_rec),
- &ttl, NULL, 0)) {
+ switch (spf_lookup(q->domain, &txt_rec, &txt_num, &ttl)) {
case dns_success:
@@ -1258,3 +1260,2 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
/* Select SPF1 records */
- ntxt = 0;
for (i = 0; txt_rec[i]; i++) {
@@ -1264,10 +1265,8 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
("record: %s", txt_rec[i]));
- if (ntxt != i) {
- txt_rec[ntxt++] = txt_rec[i];
- txt_rec[i] = NULL;
- } else
- ntxt = i + 1;
- } else {
- free(txt_rec[i]);
- txt_rec[i] = NULL;
+ if (spf_rec) {
+ SPF_RETURN(spf_perm_error,
+ "too many SPF records published");
+ }
+ spf_rec = txt_rec[i];
+ break;
}
@@ -1275,9 +1274,4 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
- if (ntxt == 0)
- SPF_RETURN(spf_none, "no SPF records published");
- if (ntxt > 1)
- SPF_RETURN(spf_perm_error, "too many SPF records published");
-
mu_debug(MF_SOURCE_SPF, MU_DEBUG_TRACE0,
- ("SPF record: %s", txt_rec[0]));
+ ("SPF record: %s", spf_rec));
@@ -1288,6 +1282,6 @@ spf_check_host_internal(spf_query_t *q, spf_answer_t *a, size_t loopno)
- result = spf_exec_query(txt_rec[0], &dat);
+ result = spf_exec_query(spf_rec, &dat);
spf_data_free(&dat);
- free(txt_rec[0]);
+ mu_argcv_free(txt_num, txt_rec);
diff --git a/src/spf.h b/src/spf.h
index 9b3c8e6..229075e 100644
--- a/src/spf.h
+++ b/src/spf.h
@@ -16,3 +16,2 @@
-#define SPF_MAX_TXT_REC 10
#define SPF_MAX_RECURSION 10
@@ -51,4 +50,2 @@ spf_result spf_test_record(const char *rec,
spf_query_t *query, spf_answer_t *ans);
-dns_status spf_lookup(const char *domain, char **txt, size_t maxtxt,
- unsigned long *ttl, char *answer, size_t answer_size);
diff --git a/src/srvcfg.c b/src/srvcfg.c
index f04e4c6..a9527a5 100644
--- a/src/srvcfg.c
+++ b/src/srvcfg.c
@@ -44,4 +44,2 @@ char *db_type_str = DEFAULT_DB_TYPE;
-size_t max_callout_mx = MAXMXCOUNT;
-
/* Timeouts */
@@ -516,5 +514,2 @@ static struct mu_cfg_param srv_cfg_param[] = {
N_("Set logger stream.") },
- { "max-callout-mx", mu_c_size, &max_callout_mx, 0, NULL,
- N_("Maximum number of MXs to be polled during "
- "callout verification.") },
{ "state-directory", mu_cfg_callback, NULL, 0, cb_state_directory,

Return to:

Send suggestions and report system problems to the System administrator.