summaryrefslogtreecommitdiffstats
path: root/src/dns
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dns/Makefile.in26
-rw-r--r--src/dns/dns_lookup.c8
-rw-r--r--src/dns/dns_rr_test.c433
-rw-r--r--src/dns/mxonly_test.ref2
-rw-r--r--src/dns/no-mx.ref6
-rw-r--r--src/dns/test_dns_lookup.c5
-rw-r--r--src/dnsblog/dnsblog.c3
7 files changed, 473 insertions, 10 deletions
diff --git a/src/dns/Makefile.in b/src/dns/Makefile.in
index 3ebf75f..5ea09cf 100644
--- a/src/dns/Makefile.in
+++ b/src/dns/Makefile.in
@@ -11,7 +11,8 @@ DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
INCL =
LIB = lib$(LIB_PREFIX)dns$(LIB_SUFFIX)
-TESTPROG= test_dns_lookup dns_rr_to_pa dns_rr_to_sa dns_sa_to_rr dns_rr_eq_sa
+TESTPROG= test_dns_lookup dns_rr_to_pa dns_rr_to_sa dns_sa_to_rr dns_rr_eq_sa \
+ dns_rr_test
LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
LIB_DIR = ../../lib
@@ -31,7 +32,7 @@ test: $(TESTPROG)
tests: test dns_rr_to_pa_test dns_rr_to_sa_test dns_sa_to_rr_test \
dns_rr_eq_sa_test no-a-test no-aaaa-test no-mx-test \
error-filter-test nullmx_test nxdomain_test mxonly_test \
- dnsbl_tests
+ dnsbl_tests dns_rr_tests
dnsbl_tests: \
dnsbl_ttl_127.0.0.2_bind_plain_test \
@@ -57,7 +58,7 @@ DNSBL_EXIST_REPLY_FIX = \
-e 's/ [0-9]* [0-9]* [0-9]* [0-9]* [0-9]*/ D D D D D/' \
-e 's/127.0.0.[0-9]*$$/127.0.0.D/' \
| uniq
-
+
root_tests:
$(LIB): $(OBJS)
@@ -240,6 +241,12 @@ dnsbl_ttl_127.0.0.2_priv_ncache_test: test_dns_lookup dnsbl_ttl_127.0.0.2_bind_p
diff dnsbl_ttl_127.0.0.2_bind_plain.ref dnsbl_ttl_127.0.0.2_priv_ncache.tmp
rm -f dnsbl_ttl_127.0.0.2_priv_ncache.tmp
+dns_rr_tests: dns_rr_test
+ $(SHLIB_ENV) $(VALGRIND) ./dns_rr_test
+
+dns_rr_test: dns_rr_test.o $(LIB) $(LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
@@ -319,6 +326,19 @@ dns_rr_filter.o: ../../include/vstream.h
dns_rr_filter.o: ../../include/vstring.h
dns_rr_filter.o: dns.h
dns_rr_filter.o: dns_rr_filter.c
+dns_rr_test.o: ../../include/check_arg.h
+dns_rr_test.o: ../../include/msg.h
+dns_rr_test.o: ../../include/msg_vstream.h
+dns_rr_test.o: ../../include/myaddrinfo.h
+dns_rr_test.o: ../../include/mymalloc.h
+dns_rr_test.o: ../../include/sock_addr.h
+dns_rr_test.o: ../../include/stringops.h
+dns_rr_test.o: ../../include/sys_defs.h
+dns_rr_test.o: ../../include/vbuf.h
+dns_rr_test.o: ../../include/vstream.h
+dns_rr_test.o: ../../include/vstring.h
+dns_rr_test.o: dns.h
+dns_rr_test.o: dns_rr_test.c
dns_rr_to_pa.o: ../../include/check_arg.h
dns_rr_to_pa.o: ../../include/msg.h
dns_rr_to_pa.o: ../../include/myaddrinfo.h
diff --git a/src/dns/dns_lookup.c b/src/dns/dns_lookup.c
index c21b619..4cf9a5f 100644
--- a/src/dns/dns_lookup.c
+++ b/src/dns/dns_lookup.c
@@ -85,6 +85,12 @@
/* an invalid name is reported as a DNS_INVAL result, while
/* malformed replies are reported as transient errors.
/*
+/* Note: in dns_lookup*() results and queries, a name may start
+/* with a "*" label, which is valid according to RFC 1034
+/* section 4.3.3. Such a name will not pass valid_hostname()
+/* checks in the rest of Postfix, because it is not a valid
+/* host or domain name.
+/*
/* dns_get_h_errno() returns the last error. This deprecates
/* usage of the global h_errno variable. We should not rely
/* on that being updated.
@@ -300,7 +306,7 @@ typedef struct DNS_REPLY {
/*
* Use the threadsafe resolver API if available, not because it is
- * theadsafe, but because it has more functionality.
+ * threadsafe, but because it has more functionality.
*/
#ifdef USE_RES_NCALLS
static struct __res_state dns_res_state;
diff --git a/src/dns/dns_rr_test.c b/src/dns/dns_rr_test.c
new file mode 100644
index 0000000..7bbe769
--- /dev/null
+++ b/src/dns/dns_rr_test.c
@@ -0,0 +1,433 @@
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <stdlib.h>
+
+ /*
+ * Utility library.
+ */
+#include <msg.h>
+#include <msg_vstream.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <vstring.h>
+
+ /*
+ * DNS library.
+ */
+#include <dns.h>
+
+#define STR(x) vstring_str(x)
+
+ /*
+ * Test helpers. TODO: move eq_dns_rr() to testing/dns_rr_testers.c; need to
+ * verify that the expected difference is reported, or use a GTEST matcher.
+ */
+
+/* print_dns_rr - format as { qname, reply, flags } */
+
+static char *print_dns_rr(VSTRING *buf, DNS_RR *rr)
+{
+ static VSTRING *tmp;
+
+ if (tmp == 0)
+ tmp = vstring_alloc(100);
+ vstring_sprintf(buf, "{qname=%s, reply='%s', flags=0x%x}",
+ rr->qname, dns_strrecord(tmp, rr), rr->flags);
+ return (STR(buf));
+}
+
+/* eq_dns_rr - predicate that two lists are equivalent */
+
+static int eq_dns_rr(DNS_RR *got, DNS_RR *want)
+{
+ VSTRING *got_buf = 0;
+ VSTRING *want_buf = 0;
+
+#define EQ_DNS_RR_RETURN(val) do { \
+ if (got_buf) \
+ vstring_free(got_buf); \
+ if (want_buf) \
+ vstring_free(want_buf); \
+ return (val); \
+ } while (0)
+
+ /* Same length. */
+ if (got == 0 && want == 0)
+ EQ_DNS_RR_RETURN(1);
+ if (want == 0) {
+ msg_warn("got %s, want null",
+ print_dns_rr(got_buf = vstring_alloc(100), got));
+ }
+ if (got == 0) {
+ msg_warn("got null, want %s",
+ print_dns_rr(want_buf = vstring_alloc(100), want));
+ EQ_DNS_RR_RETURN(0);
+ }
+ /* Same query name, resource record, flags. */
+ if (strcmp(print_dns_rr(got_buf = vstring_alloc(100), got),
+ print_dns_rr(want_buf = vstring_alloc(100), want)) != 0) {
+ msg_warn("got %s, want %s", STR(want_buf), STR(got_buf));
+ EQ_DNS_RR_RETURN(0);
+ }
+ /* Same children. */
+ EQ_DNS_RR_RETURN(eq_dns_rr(got->next, want->next));
+}
+
+static int eq_dns_rr_free(DNS_RR *got, DNS_RR *want)
+{
+ int res = eq_dns_rr(got, want);
+
+ dns_rr_free(got);
+ dns_rr_free(want);
+ return (res);
+}
+
+ /*
+ * Tests and test cases.
+ */
+typedef struct TEST_CASE {
+ const char *label; /* identifies test case */
+ int (*fn) (void);
+} TEST_CASE;
+
+#define PASS (0)
+#define FAIL (1)
+
+ /*
+ * Begin helper tests. TODO: move these to testing/dns_rr_testers_test.c.
+ */
+
+static int eq_dns_rr_qname_differ(void)
+{
+ DNS_RR *got = dns_rr_create("qa", "ra", T_SRV, C_IN, 3600, 1, 25, 1, "mxa", 4);
+ DNS_RR *want = dns_rr_copy(got);
+
+ myfree(want->qname);
+ want->qname = mystrdup("qb");
+ return (!eq_dns_rr_free(got, want));
+}
+
+static int eq_dns_rr_reply_differ(void)
+{
+ DNS_RR *got = dns_rr_create("qa", "ra", T_SRV, C_IN, 3600, 1, 25, 1, "mxa", 4);
+ DNS_RR *want = dns_rr_copy(got);
+
+ want->port += 1;
+ return (!eq_dns_rr_free(got, want));
+}
+
+ /*
+ * End helper tests.
+ */
+
+ /*
+ * Begin DNS_RR tests.
+ */
+
+static int eq_dns_rr_flags_differ(void)
+{
+ DNS_RR *got = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *want = dns_rr_copy(got);
+
+ want->flags |= DNS_RR_FLAG_TRUNCATED;
+ return (!eq_dns_rr_free(got, want));
+}
+
+static int append_to_null_from_null(void)
+{
+ DNS_RR *got = dns_rr_append((DNS_RR *) 0, (DNS_RR *) 0);
+ DNS_RR *want = 0;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_elem_from_null(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append(dns_rr_copy(a), (DNS_RR *) 0);
+
+ want = a;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int appent_to_null_from_elem(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append((DNS_RR *) 0, dns_rr_copy(a));
+
+ want = a;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_elem_from_elem(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append(dns_rr_copy(a), dns_rr_copy(b));
+
+ (want = a)->next = b;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_elem_from_list(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append(dns_rr_copy(a),
+ dns_rr_append(dns_rr_copy(b),
+ dns_rr_copy(c)));
+
+ ((want = a)->next = b)->next = c;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_elem(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append(dns_rr_append(dns_rr_copy(a),
+ dns_rr_copy(b)),
+ dns_rr_copy(c));
+
+ ((want = a)->next = b)->next = c;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_list(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *d = dns_rr_create_noport("qd", "rd", T_MX, C_IN, 3600, 1, "mxd", 4);
+ DNS_RR *got, *want;
+
+ got = dns_rr_append(dns_rr_append(dns_rr_copy(a),
+ dns_rr_copy(b)),
+ dns_rr_append(dns_rr_copy(c),
+ dns_rr_copy(d)));
+
+ (((want = a)->next = b)->next = c)->next = d;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_propagates_flags(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *d = dns_rr_create_noport("qd", "rd", T_MX, C_IN, 3600, 1, "mxd", 4);
+ DNS_RR *left = dns_rr_append(dns_rr_copy(a), dns_rr_copy(b));
+ DNS_RR *rite = dns_rr_append(dns_rr_copy(c), dns_rr_copy(d));
+ DNS_RR *got, *want, *rr;
+
+ for (rr = rite; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ got = dns_rr_append(left, rite);
+
+ (((want = a)->next = b)->next = c)->next = d;
+ for (rr = want; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_list_truncate(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *d = dns_rr_create_noport("qd", "rd", T_MX, C_IN, 3600, 1, "mxd", 4);
+ DNS_RR *got, *want, *rr;
+
+ var_dns_rr_list_limit = 3;
+
+ ((want = dns_rr_copy(a))->next = dns_rr_copy(b))->next = dns_rr_copy(c);
+ for (rr = want; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ got = dns_rr_append(dns_rr_append(a, b),
+ dns_rr_append(c, d));
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_elem_elem_truncate(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *d = dns_rr_create_noport("qd", "rd", T_MX, C_IN, 3600, 1, "mxd", 4);
+ DNS_RR *got, *want, *rr;
+
+ var_dns_rr_list_limit = 2;
+
+ (want = dns_rr_copy(a))->next = dns_rr_copy(b);
+ for (rr = want; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ got = dns_rr_append(a, b);
+ got = dns_rr_append(got, c); /* should be logged */
+ got = dns_rr_append(got, d); /* should be silent */
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_elem_truncate(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want, *rr;
+
+ var_dns_rr_list_limit = 2;
+
+ (want = dns_rr_copy(a))->next = dns_rr_copy(b);
+ for (rr = want; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ got = dns_rr_append(dns_rr_append(a, b), c);
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_elem_from_list_truncate(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want, *rr;
+
+ var_dns_rr_list_limit = 2;
+
+ (want = dns_rr_copy(a))->next = dns_rr_copy(b);
+ for (rr = want; rr; rr = rr->next)
+ rr->flags |= DNS_RR_FLAG_TRUNCATED;
+
+ got = dns_rr_append(a, dns_rr_append(b, c));
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_list_from_elem_exact_fit(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want;
+
+ var_dns_rr_list_limit = 3;
+
+ ((want = dns_rr_copy(a))->next = dns_rr_copy(b))->next = dns_rr_copy(c);
+
+ got = dns_rr_append(dns_rr_append(a, b), c);
+
+ return (eq_dns_rr_free(got, want));
+}
+
+static int append_to_elem_from_list_exact_fit(void)
+{
+ DNS_RR *a = dns_rr_create_noport("qa", "ra", T_MX, C_IN, 3600, 1, "mxa", 4);
+ DNS_RR *b = dns_rr_create_noport("qb", "rb", T_MX, C_IN, 3600, 1, "mxb", 4);
+ DNS_RR *c = dns_rr_create_noport("qc", "rc", T_MX, C_IN, 3600, 1, "mxc", 4);
+ DNS_RR *got, *want;
+
+ var_dns_rr_list_limit = 3;
+
+ ((want = dns_rr_copy(a))->next = dns_rr_copy(b))->next = dns_rr_copy(c);
+
+ got = dns_rr_append(a, dns_rr_append(b, c));
+
+ return (eq_dns_rr_free(got, want));
+}
+
+ /*
+ * The test cases.
+ */
+static const TEST_CASE test_cases[] = {
+
+ /*
+ * Test eq_dns_rr; TODO: move to testing/dns_rr_testers_test.c
+ */
+ "eq_dns_rr qname differ", eq_dns_rr_qname_differ,
+ "eq_dns_rr reply differ", eq_dns_rr_reply_differ,
+ "eq_dns_rr flags differ", eq_dns_rr_flags_differ,
+
+ /*
+ * Test dns_rr_append() without truncation.
+ */
+ "append to null from null", append_to_null_from_null,
+ "append to null from element", appent_to_null_from_elem,
+ "append to element from null", append_to_elem_from_null,
+ "append to element from element", append_to_elem_from_elem,
+ "append to element from list", append_to_elem_from_list,
+ "append to list from element", append_to_list_from_elem,
+ "append to list from list", append_to_list_from_list,
+
+ /*
+ * Test dns_rr_append() flag propagation.
+ */
+ "append propagates flags", append_propagates_flags,
+
+ /*
+ * Test dns_rr_append() with truncation.
+ */
+ "append to list from list truncate", append_to_list_from_list_truncate,
+ "append to list from element element truncate", append_to_list_from_elem_elem_truncate,
+ "append to list from element truncate", append_to_list_from_elem_truncate,
+ "append to element from list truncate", append_to_elem_from_list_truncate,
+ "append to list from element exact fit", append_to_list_from_elem_exact_fit,
+ "append to element from list exact fit", append_to_elem_from_list_exact_fit,
+
+ /*
+ * TODO: tests dns_rr_sort(), dns_rr_srv_sort(), dns_rr_remove(),
+ * dns_rr_shuffle(), etc.
+ */
+ 0,
+};
+
+int main(int argc, char **argv)
+{
+ const TEST_CASE *tp;
+ int pass = 0;
+ int fail = 0;
+ VSTRING *res_buf = vstring_alloc(100);
+ int saved_limit = var_dns_rr_list_limit;
+
+ msg_vstream_init(sane_basename((VSTRING *) 0, argv[0]), VSTREAM_ERR);
+
+ for (tp = test_cases; tp->label != 0; tp++) {
+ msg_info("RUN %s", tp->label);
+ if (tp->fn() == 0) {
+ fail++;
+ msg_info("FAIL %s", tp->label);
+ } else {
+ msg_info("PASS %s", tp->label);
+ pass++;
+ }
+ var_dns_rr_list_limit = saved_limit;
+ }
+ msg_info("PASS=%d FAIL=%d", pass, fail);
+ vstring_free(res_buf);
+ exit(fail != 0);
+}
diff --git a/src/dns/mxonly_test.ref b/src/dns/mxonly_test.ref
index 44f22d6..e1e4bad 100644
--- a/src/dns/mxonly_test.ref
+++ b/src/dns/mxonly_test.ref
@@ -6,6 +6,6 @@
./test_dns_lookup: lookup porcupine.org type A flags RES_USE_DNSSEC
./test_dns_lookup: dns_query: porcupine.org (A): Host found but no data record of requested type
ad: 0, rr: porcupine.org. 3600 IN MX 10 spike.porcupine.org.
-ad: 0, rr: porcupine.org. 3600 IN MX 30 m1.porcupine.org.
ad: 0, rr: porcupine.org. 3600 IN MX 30 vz.porcupine.org.
+ad: 0, rr: porcupine.org. 3600 IN MX 40 m1.porcupine.org.
porcupine.org: fqdn: porcupine.org
diff --git a/src/dns/no-mx.ref b/src/dns/no-mx.ref
index 5adc7bf..527e0b8 100644
--- a/src/dns/no-mx.ref
+++ b/src/dns/no-mx.ref
@@ -1,15 +1,15 @@
./test_dns_lookup: dict_regexp_lookup: no-mx.reg: porcupine.org. 3600 IN MX 10 spike.porcupine.org.
-./test_dns_lookup: dict_regexp_lookup: no-mx.reg: porcupine.org. 3600 IN MX 30 m1.porcupine.org.
./test_dns_lookup: dict_regexp_lookup: no-mx.reg: porcupine.org. 3600 IN MX 30 vz.porcupine.org.
+./test_dns_lookup: dict_regexp_lookup: no-mx.reg: porcupine.org. 3600 IN MX 40 m1.porcupine.org.
./test_dns_lookup: dns_get_answer: type MX for porcupine.org
./test_dns_lookup: dns_get_answer: type MX for porcupine.org
./test_dns_lookup: dns_get_answer: type MX for porcupine.org
./test_dns_lookup: dns_query: porcupine.org (MX): OK
./test_dns_lookup: ignoring DNS RR: porcupine.org. 3600 IN MX 10 spike.porcupine.org.
-./test_dns_lookup: ignoring DNS RR: porcupine.org. 3600 IN MX 30 m1.porcupine.org.
./test_dns_lookup: ignoring DNS RR: porcupine.org. 3600 IN MX 30 vz.porcupine.org.
+./test_dns_lookup: ignoring DNS RR: porcupine.org. 3600 IN MX 40 m1.porcupine.org.
./test_dns_lookup: lookup porcupine.org type MX flags RES_USE_DNSSEC
./test_dns_lookup: maps_find: DNS reply filter: regexp:no-mx.reg(0,lock|fold_fix): porcupine.org. 3600 IN MX 10 spike.porcupine.org. = ignore
-./test_dns_lookup: maps_find: DNS reply filter: regexp:no-mx.reg(0,lock|fold_fix): porcupine.org. 3600 IN MX 30 m1.porcupine.org. = ignore
./test_dns_lookup: maps_find: DNS reply filter: regexp:no-mx.reg(0,lock|fold_fix): porcupine.org. 3600 IN MX 30 vz.porcupine.org. = ignore
+./test_dns_lookup: maps_find: DNS reply filter: regexp:no-mx.reg(0,lock|fold_fix): porcupine.org. 3600 IN MX 40 m1.porcupine.org. = ignore
./test_dns_lookup: warning: Error looking up name=porcupine.org type=MX: DNS reply filter drops all results (rcode=0)
diff --git a/src/dns/test_dns_lookup.c b/src/dns/test_dns_lookup.c
index f07c3ef..6970124 100644
--- a/src/dns/test_dns_lookup.c
+++ b/src/dns/test_dns_lookup.c
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
var_dnssec_probe = "";
msg_vstream_init(argv[0], VSTREAM_ERR);
- while ((ch = GETOPT(argc, argv, "f:npvs")) > 0) {
+ while ((ch = GETOPT(argc, argv, "f:l:npvs")) > 0) {
switch (ch) {
case 'v':
msg_verbose++;
@@ -88,6 +88,9 @@ int main(int argc, char **argv)
case 'f':
dns_rr_filter_compile("DNS reply filter", optarg);
break;
+ case 'l':
+ var_dns_rr_list_limit = atoi(optarg);
+ break;
case 'n':
lflags |= DNS_REQ_FLAG_NCACHE_TTL;
break;
diff --git a/src/dnsblog/dnsblog.c b/src/dnsblog/dnsblog.c
index bc87c4b..7a4a446 100644
--- a/src/dnsblog/dnsblog.c
+++ b/src/dnsblog/dnsblog.c
@@ -43,7 +43,8 @@
/* How much time a Postfix daemon process may take to handle a
/* request before it is terminated by a built-in watchdog timer.
/* .IP "\fBpostscreen_dnsbl_sites (empty)\fR"
-/* Optional list of DNS allow/denylist domains, filters and weight
+/* Optional list of patterns with DNS allow/denylist domains, filters
+/* and weight
/* factors.
/* .IP "\fBipc_timeout (3600s)\fR"
/* The time limit for sending or receiving information over an internal