client/adnsresfilter_s
dynamic/Makefile
dynamic/libadns.so.*
+regress/fuzzcat.d
regress/Makefile
regress/*_record
regress/*_playback
+regress/*_fuzz
+regress/*_fuzzraw
regress/output-*.*
+regress/fuzz-*
+regress/fuzzraw-*
regress/pipe.out
regress/pipe.err
+regress/harness.h
+regress/hcommon.c
+regress/hplayback.c
+regress/hrecord.c
+regress/hfuzzraw.c
+regress/hredirect.h
+regress/hsyscalls.h
src/Makefile
src/config.h
web
uses an automatically-balancing tree algorithm, like the glibc version
does. Simple binary trees may perform badly.
-If you change the m4 input files in regress/ you may need GNU m4.
+You will need an m4 that supports: -P, -I, patsubst, ifelse, include,
+translit, and len.
You will probably find that GNU Make is required.
Please do not report this as a bug; install GNU Make instead.
COPYRIGHT
This file, INSTALL, contains installation instructions and other
-details for adns. It is
- Copyright (C) 1997-2000 Ian Jackson <ijackson@chiark.greenend.org.uk>
+details for adns.
adns is
- Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+ Copyright (C) 1997-2000,2003,2006,2014-2016,2020,2024 Ian Jackson
+ Copyright (C) 2024 Sergey Poznyakoff
Copyright (C) 2014 Mark Wooding
Copyright (C) 1999-2000,2003,2006 Tony Finch <dot@dotat.at> [1]
Copyright (C) 1991 Massachusetts Institute of Technology [2]
# Makefile[.in] - top-level Makefile
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# Remember to change ADNS_VERSION_STRING in client/client.h too, and
# possibly library soname (MAJOR and MINOR in common.make.in).
-DISTVERSION= 1.5.0
+DISTVERSION= 1.6.1
srcdir= @srcdir@
VPATH= @srcdir@
web-install: adnshost.txt
test -e $(WEBDIR) || mkdir $(WEBDIR)
- $(INSTALL_DATA) $(srcdir)/README.html $(WEBDIR)/
- $(INSTALL_DATA) $(srcdir)/src/adns.h $(WEBDIR)/adns.h.txt
- $(INSTALL_DATA) COPYING $(WEBDIR)/COPYING.txt
- $(INSTALL_DATA) adnshost.txt $(WEBDIR)/
+ $(INSTALL_DATA) $(srcdir)/README.html $(DESTDIR)$(WEBDIR)/
+ $(INSTALL_DATA) $(srcdir)/src/adns.h $(DESTDIR)$(WEBDIR)/adns.h.txt
+ $(INSTALL_DATA) COPYING $(DESTDIR)$(WEBDIR)/COPYING.txt
+ $(INSTALL_DATA) adnshost.txt $(DESTDIR)$(WEBDIR)/
check: all
$(MAKE) -C regress check
+For later changes, please see the file `changelog' in the
+source code toplevel.
+
+
+
+Changes in adns 1.5.2, since adns 1.5.1, are:
+
+ Important security fixes, and other bugfixes. See changelog.
+
Changes in adns 1.5.1, since adns 1.5.0, are:
Bugfixes. See changelog.
Copyright and licensing
- adns is Copyright 1997-2000,2003,2006,2014-2016 Ian Jackson, Copyright
- 2014 Mark Wooding, Copyright 1999-2000,2003,2006 Tony Finch, and
- Copyright (C) 1991 Massachusetts Institute of Technology.
+ adns is Copyright Ian Jackson and contributors. (See the file INSTALL
+ for a full list.)
adns is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
References
- 1. http://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt
- 2. http://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt
- 3. http://debbugs.gnu.org/
- 4. http://www.chiark.greenend.org.uk/mailman/listinfo
- 5. http://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt
- 6. http://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt
- 7. http://www.chiark.greenend.org.uk/~ian/adns/adns.tar.gz
- 8. http://www.chiark.greenend.org.uk/~ian/adns/ftp/
- 9. http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git/adns.git/
- 10. http://www.gnu.org/
- 11. http://www.gnu.org/order/ftp.html
- 12. http://code.google.com/p/adns-python
- 13. http://www.lysator.liu.se/liboop/
- 14. http://adns.jgaa.com/
- 15. http://www.chiark.greenend.org.uk/~ian/adns/docs/COPYING.txt
- 16. http://www.fsf.org/
- 17. http://www.gnu.org/
- 18. http://www.chiark.greenend.org.uk/
+ 1. https://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt
+ 2. https://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt
+ 3. https://debbugs.gnu.org/
+ 4. https://www.chiark.greenend.org.uk/mailman/listinfo
+ 5. https://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt
+ 6. https://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt
+ 7. https://www.chiark.greenend.org.uk/~ian/adns/adns.tar.gz
+ 8. https://www.chiark.greenend.org.uk/~ian/adns/ftp/
+ 9. https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git/adns.git/
+ 10. https://www.gnu.org/
+ 11. https://www.gnu.org/order/ftp.html
+ 12. https://code.google.com/p/adns-python
+ 13. https://www.lysator.liu.se/liboop/
+ 14. https://adns.jgaa.com/
+ 15. https://www.chiark.greenend.org.uk/~ian/adns/docs/COPYING.txt
+ 16. https://www.fsf.org/
+ 17. https://www.gnu.org/
+ 18. https://www.chiark.greenend.org.uk/
19. file:///
- 20. http://www.chiark.greenend.org.uk/~ian/sw-www-copy.html
+ 20. https://www.chiark.greenend.org.uk/~ian/sw-www-copy.html
<!-- Note: this file must contain portable HTML ! -->
<!-- -->
<!-- It is served on the GNU site and also from my own system, -->
-<!-- under the URL http://www.chiark.greenend.org.uk/adns/ -->
+<!-- under the URL https://www.chiark.greenend.org.uk/adns/ -->
<!-- Please ensure that all links continine to be correct -->
<!-- both for www.gnu.org and chiark. -->
<!-- -->
scripts to do simple lookups. In a more advanced mode it can be used
as a general-purpose DNS helper program for scripting languages which
can invoke and communicate with subprocesses. See the
-<A href="http://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt">adnshost
+<A href="https://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt">adnshost
usage message</A> for a summary of its capabilities.
</ul>
I'm afraid there is no manual yet. However, competent C programmers
should be able to use the library based on the
-<A href="http://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt">commented
+<A href="https://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt">commented
adns.h header file</A>, and the usage messages for the programs should
be sufficient.
<p>
Bug reports should be reported to the
-<a href="http://debbugs.gnu.org/">GNU Debbugs</a>. Send an email
+<a href="https://debbugs.gnu.org/">GNU Debbugs</a>. Send an email
to <code>submit@debbugs.gnu.org</code> and at the top of your email,
in a paragraph of its own, write the single line
<pre>
<p>
There are
-<A href="http://www.chiark.greenend.org.uk/mailman/listinfo">archives
+<A href="https://www.chiark.greenend.org.uk/mailman/listinfo">archives
and subscription web pages</A>, or you can subscribe by sending mail
containing the word `subscribe' to
<code>adns-announce-REQUEST@chiark.greenend.org.uk</code> or
<h2>Documentation</h2>
<ul>
-<li><A href="http://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt">adns.h
+<li><A href="https://www.chiark.greenend.org.uk/~ian/adns/docs/adns.h.txt">adns.h
API header file with documentation comments</A>
-<li><A href="http://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt">usage
+<li><A href="https://www.chiark.greenend.org.uk/~ian/adns/docs/adnshost.txt">usage
message for adnshost</A>
</ul>
<h2>Download and source code</h2>
<ul>
-<li>The <A href="http://www.chiark.greenend.org.uk/~ian/adns/adns.tar.gz">current
+<li>The <A href="https://www.chiark.greenend.org.uk/~ian/adns/adns.tar.gz">current
release</A> as a gzipped tarfile.
-<li><A href="http://www.chiark.greenend.org.uk/~ian/adns/ftp/">Previous
+<li><A href="https://www.chiark.greenend.org.uk/~ian/adns/ftp/">Previous
versions</A> and other files (including OpenPGP signatures).
-<li><A href="http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git/adns.git/">master
+<li><A href="https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git/adns.git/">master
git (version control) repository browser</a>.
</ul>
adns is also available from the
-<A href="http://www.gnu.org/">GNU Project</A> FTP servers and their
-<A href="http://www.gnu.org/order/ftp.html">mirrors</A>.
+<A href="https://www.gnu.org/">GNU Project</A> FTP servers and their
+<A href="https://www.gnu.org/order/ftp.html">mirrors</A>.
<h2>Installation note</h2>
<h2>References and related projects</h2>
<ul>
-<li><a href="http://code.google.com/p/adns-python">Python bindings</a>
+<li><a href="https://code.google.com/p/adns-python">Python bindings</a>
by Andy Dustman.
-<!-- <li><a href="http://cryp.to/hsdns/">Haskell bindings</a>
+<!-- <li><a href="https://cryp.to/hsdns/">Haskell bindings</a>
by Peter Simons. -->
-<li><a href="http://www.lysator.liu.se/liboop/">liboop event loop library</a>
+<li><a href="https://www.lysator.liu.se/liboop/">liboop event loop library</a>
has a built-in binding for adns.
-<li><a href="http://adns.jgaa.com/">port to MS Visual Studio 6 C++</a>
+<li><a href="https://adns.jgaa.com/">port to MS Visual Studio 6 C++</a>
by Jarle Aase.
</ul>
<h2>Copyright and licensing</h2>
-<kbd>adns</kbd> is Copyright 1997-2000,2003,2006,2014-2016 Ian Jackson,
-Copyright 2014 Mark Wooding, Copyright 1999-2000,2003,2006 Tony Finch,
-and Copyright (C) 1991 Massachusetts Institute of Technology.
+<kbd>adns</kbd> is
+Copyright Ian Jackson and contributors.
+(See the file INSTALL for a full list.)
<p>
be useful, but <em>without any warranty</em>; without even the implied
warranty of <em>merchantability</em> or <em>fitness for a particular
purpose</em>. See the
-<A href="http://www.chiark.greenend.org.uk/~ian/adns/docs/COPYING.txt">GNU
+<A href="https://www.chiark.greenend.org.uk/~ian/adns/docs/COPYING.txt">GNU
General Public License</A> for more details.
<p>
You should have received a copy of the GNU General Public License
along with <kbd>adns</kbd>, or one should be available above; if not,
-write to the <A href="http://www.fsf.org/">Free Software Foundation</A>
+write to the <A href="https://www.fsf.org/">Free Software Foundation</A>
or email <code>ijackson@chiark.greenend.org.uk</code>.
<p>
Ian Jackson / <tt>ijackson@chiark.greenend.org.uk</tt>.
<p>
-<A href="http://www.gnu.org/">GNU home page</A>;
-<A href="http://www.chiark.greenend.org.uk/">chiark home page</A>;
+<A href="https://www.gnu.org/">GNU home page</A>;
+<A href="https://www.chiark.greenend.org.uk/">chiark home page</A>;
<A href="/">site or mirror home page</A>
<p>
This web page is Copyright (C)1996-2005,2014-2016 Ian Jackson. See the
-<A href="http://www.chiark.greenend.org.uk/~ian/sw-www-copy.html">Copyright/acknowledgements</A>.
+<A href="https://www.chiark.greenend.org.uk/~ian/sw-www-copy.html">Copyright/acknowledgements</A>.
</body>
</html>
#
# * Maybe rerun autoconf
# * Ensure changelog reflects changes
-# * Ensure NEWS reflects changes
# * Maybe update copyright dates
# * Maybe update MAJOR and/or MINOR in common.make.in
# * Update DISTVERSION in Makefile.in
* input file for autoheader/autoconf/configure: extra stuff for config.h
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
# aclocal.m4 - package-specific macros for autoconf
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
--- /dev/null
+#!/bin/sh
+set -e
+autoheader
+autoconf
-adns (1.5.1~~) UPSTREAM; urgency=low
+adns (1.6.1) UPSTREAM; urgency=low
+
+ Minor bugfix:
+ * Suppress warning about `trust-ad` in resolv.conf. Debian #1028112.
+
+ Build system:
+ * Honour DESTDIR, avoiding need for prefix= workaround.
+ [Contribution from Sergey Poznyakoff]
+ * regression tests: Add missing dependency on hsyscalls.h.
+ GNU #51329. [Report from Sergei Trofimovich]
+ * regression tests: build with 64-bit time_t on 32-bit systems.
+ Debian #1065725, Ubuntu Launchpad #2057735.
+ [Report from Sebastian Ramacher]
+
+ Documentation:
+ * Fix all http: URLs in docs to be https: instead.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Sun, 05 May 2024 22:39:28 +0100
+
+adns (1.6.0) UPSTREAM; urgency=medium
+
+ Bugfixes:
+ * adnshost: Support --reverse in -f mode input stream
+ * timeout robustness against clock skew: track query start time and
+ duration. Clock instability may now only cause spurious timeouts
+ rather than indefinite hangs or even assertion failures.
+
+ New features:
+ * adnshost: Offer ability to set adns checkc flags
+ * adnslogres: Honour --checkc-freq (if it comes first)
+ * adnsresfilter: Honour --checkc-freq and --checkc-entex
+ * time handling: Support use of CLOCK_MONOTONIC via an init flag.
+ * adns_str* etc.: Improve robustness; more allowable inputs values.
+
+ Build system improvements:
+ * clean targets: Delete $(TARGETS) too!
+ * Remove all m4 output files from the distributed source tree.
+ * Support DESTDIR=/some/absolute/path on `make install'.
+ * Provide autogen.sh.
+ * Rerun autoheader and autoconf (2.69).
+
+ Internal changes:
+ * adnshost: adh-opts.c: Whitespace adjustments to option table
+
+ Tests:
+ * New tests for fixes in 1.5.3.
+ * Fixes to test harness to avoid false positives during fuzzing.
+ * Other changes to support use with AFL.
+ * Many supporting improvements and refactorings.
+ * Fix skipped tests ($$ reference in Makefile)
+
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Thu, 11 Jun 2020 15:49:39 +0100
+
+adns (1.5.2) UPSTREAM; urgency=medium
+
+ * Important security fixes:
+ CVE-2017-9103 CVE-2017-9104 CVE-2017-9105 CVE-2017-9109:
+ Vulnerable applications: all adns callers.
+ Exploitable by: the local recursive resolver.
+ Likely worst case: Remote code execution.
+ CVE-2017-9106:
+ Vulnerable applications: those that make SOA queries.
+ Exploitable by: upstream DNS data sources.
+ Likely worst case: DoS (crash of the adns-using application)
+ CVE-2017-9107:
+ Vulnerable applications: those that use adns_qf_quoteok_query.
+ Exploitable by: sources of query domain names.
+ Likely worst case: DoS (crash of the adns-using application)
+ CVE-2017-9108:
+ Vulnerable applications: adnshost.
+ Exploitable by: code responsible for framing the input.
+ Likely worst case: DoS (adnshost crashes at EOF).
+ All found by AFL 2.35b. Thanks to the University of Cambridge
+ Department of Applied Mathematics for computing facilities.
+
+ Bugfixes:
+ * Do not include spurious external symbol `data' (fixes GCC10 build).
+ * If server sends TC flag over TCP, bail rather than retrying.
+ * Do not crash on certain strange resolv.conf contents.
+ * Fix various crashes if a global system failure occurs, or
+ adns_finish is called with outstanding queries.
+ * Correct a parsing error message very slightly.
+ * DNS packet parsing: Slight fix when packet is truncated.
+ * Fix ABI compatibility in string conversion of certain RR types.
+ * internal.h: Use `unsigned' for nextid; fixes theoretical C UB.
+
+ Portability fix:
+ * common.make.in: add -Wno-unused-value. Fixes build with GCC9.
+
+ Internal changes:
+ * Additional comments describing some internal code restrions.
+ * Robustness assert() against malfunctioning write() system call.
+
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Thu, 11 Jun 2020 15:48:12 +0100
+
+adns (1.5.1) UPSTREAM; urgency=medium
* Portability fix for systems where socklen_t is bigger than int.
* Fix for malicious optimisation of memcpy in test suite, which
* Properly include harness.h in adnstest.c in regress/. Suppresses
a couple of compiler warnings (implicit declaration of Texit, etc.)
- --
+ -- Ian Jackson <ijackson@chiark.greenend.org.uk> Fri, 12 Aug 2016 22:53:59 +0100
adns (1.5.0) UPSTREAM; urgency=low
# client/Makefile - client program(s) Makefile
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
all: $(TARGETS)
install: $(TARG_INSTALL)
- mkdir -p $(bindir)
+ $(INSTALL_DIR) $(DESTDIR)$(bindir)
set -xe; for f in $(TARG_INSTALL); \
- do $(INSTALL_PROGRAM) $$f $(bindir)/$$f; done
+ do $(INSTALL_PROGRAM) $$f $(DESTDIR)$(bindir)/$$f; done
uninstall:
for f in $(TARGETS); do rm -f $(bindir)/$$f; done
* - test program for address<->string conversion, not part of the library
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* main program and useful subroutines
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
static void process_optarg(const char *arg,
const char *const **argv_p,
- const char *value) {
+ char *value) {
const struct optioninfo *oip;
const char *arg2;
int invert;
if (!arg) usageerr("option --%s requires a value argument",oip->lopt);
arg2= 0;
} else if (oip->type == ot_funcarg2) {
- assert(argv_p);
- arg= *++(*argv_p);
- arg2= arg ? *++(*argv_p) : 0;
+ if (argv_p) {
+ arg= *++(*argv_p);
+ arg2= arg ? *++(*argv_p) : 0;
+ } else if (value) {
+ arg= value;
+ char *space= strchr(value,' ');
+ if (space) *space++= 0;
+ arg2= space;
+ } else {
+ arg= 0;
+ }
if (!arg || !arg2)
usageerr("option --%s requires two more arguments", oip->lopt);
} else {
if (r == 0) {
if (used) {
/* fake up final newline */
- buf[used++]= '\n';
+ buf[used]= '\n';
r= 1;
} else {
ov_pipe= 0;
* option handling tables etc.
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
adns_rrtype ov_type= adns_r_none;
int ov_search=0, ov_qc_query=0, ov_qc_anshost=0, ov_qc_cname=1;
int ov_tcp=0, ov_cname=0, ov_afflags=0, ov_v6map=0, ov_format=fmt_default;
+int ov_checkc=0;
char *ov_id= 0;
struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none };
"a", "asynch", &ov_asynch, 1 },
{ ot_desconly, "answer/error output format and destination (see below):" },
- { ot_value, "Answers to stdout, errors as messages to stderr (default)",
+ { ot_value, "Answers to stdout, errors as messages to stderr (default)",
"Fs", "fmt-simple", &ov_format, fmt_simple },
- { ot_value, "Answers and errors both to stdout in parseable format",
+ { ot_value, "Answers and errors both to stdout in parseable format",
"Fi", "fmt-inline", &ov_format, fmt_inline },
- { ot_value, "Fully-parseable output format (default for --asynch)",
+ { ot_value, "Fully-parseable output format (default for --asynch)",
"Fa", "fmt-asynch", &ov_format, fmt_asynch },
{ ot_desconly, "global verbosity level:" },
"Vn", "no-quiet", &ov_verbose, 0 },
{ ot_value, "Debugging mode",
"Vd", "debug", &ov_verbose, adns_if_debug },
+
+ { ot_value, "Do not do for-developer consistency checks",
+ 0, "no-checkc", &ov_checkc, 0 },
+ { ot_value, "Do for-developer consistency checks",
+ 0, "checkc", &ov_checkc, adns_if_checkc_freq },
+ { ot_value, "Do for-developer consistency checks very often",
+ 0, "checkc-freq", &ov_checkc, adns_if_checkc_freq },
{ ot_desconly, "other global options:" },
{ ot_funcarg, "Configuration to use instead of /etc/resolv.conf",
{ ot_desconly, "asynchronous/pipe mode options:" },
{ ot_funcarg, "Set <id>, default is decimal sequence starting 0",
0, "asynch-id", 0,0, &of_asynch_id, "id" },
- { ot_funcarg, "Cancel the query with id <id> (no error if not found)",
+ { ot_funcarg, "Cancel the query with id <id> (no error if not found)",
0, "cancel-id", 0,0, &of_cancel_id, "id" },
{ ot_end }
* make queries and print answers
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) sysfail("ignore SIGPIPE",errno);
- initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose;
+ initflags= adns_if_noautosys|adns_if_nosigpipe|ov_verbose|ov_checkc;
if (!ov_env) initflags |= adns_if_noenv;
if (config_text) {
* - look up the A record of hosts in an Exim log that failed HELO verification
*/
/*
- * This file is
- * Copyright (C) 2004 Tony Finch <dot@dotat.at>
- *
- * It is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* - useful general-purpose resolver client program, header file
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
extern adns_rrtype ov_type;
extern int ov_search, ov_qc_query, ov_qc_anshost, ov_qc_cname;
extern int ov_tcp, ov_cname, ov_afflags, ov_v6map, ov_format;
+extern int ov_checkc;
extern char *ov_id;
extern struct perqueryflags_remember ov_pqfr;
* - a replacement for the Apache logresolve program using adns
*/
/*
- * This file is
- * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
- * Copyright (C) 1999-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *
- * It is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* option flags */
#define OPT_DEBUG 1
#define OPT_POLL 2
+#define OPT_CHECKC 4
static const char *const progname= "adnslogres";
static const char *config_text;
logline *head, *tail, *line;
adns_initflags initflags;
- initflags= (opts & OPT_DEBUG) ? adns_if_debug : 0;
+ initflags= (((opts & OPT_DEBUG) ? adns_if_debug : 0) |
+ ((opts & OPT_CHECKC) ? adns_if_checkc_entex : 0));
if (config_text) {
errno= adns_init_strcfg(&adns, initflags, stderr, config_text);
} else {
extern char *optarg;
FILE *inf;
+ opts= 0;
+
+ if (argv[1] && !strcmp(argv[1],"--checkc-freq")) {
+ opts|= OPT_CHECKC;
+ argv++; argc--;
+ }
+
if (argv[1] && !strncmp(argv[1],"--",2)) {
if (!strcmp(argv[1],"--help")) {
printhelp(stdout);
}
maxpending= DEFMAXPENDING;
- opts= 0;
while ((c= getopt(argc, argv, "c:C:dp")) != -1)
switch (c) {
case 'c':
* - filter which does resolving, not part of the library
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
config_text= arg;
} else if (!strcmp(arg,"--debug")) {
initflags |= adns_if_debug;
+ } else if (!strcmp(arg,"--checkc-freq")) {
+ initflags |= adns_if_checkc_freq;
+ } else if (!strcmp(arg,"--checkc-entex")) {
+ initflags |= adns_if_checkc_entex;
} else if (!strcmp(arg,"--help")) {
usage(); quitnow(0);
} else if (!strcmp(arg,"--version")) {
* - simple test program, not part of the library
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* - useful declarations and definitions for adns client programs
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#ifndef CLIENT_H_INCLUDED
#define CLIENT_H_INCLUDED
-#define ADNS_VERSION_STRING "1.5.0"
+#define ADNS_VERSION_STRING "1.6.1"
#define COPYRIGHT_MESSAGE \
- "Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson\n" \
- "Copyright (C) 2014 Mark Wooding\n" \
- "Copyright (C) 1999-2000,2003,2006 Tony Finch\n" \
- "Copyright (C) 1991 Massachusetts Institute of Technology\n" \
+ "Copyright Ian Jackson and contributors\n" \
"This is free software; see the source for copying conditions. There is NO\n" \
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
* - a small test program from Tony Finch
*/
/*
- * This file is
- * Copyright (C) 1999 Tony Finch <dot@dotat.at>
- * Copyright (C) 1999-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *
- * It is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
# common.make[.in] - common configuration settings for Makefiles,
# used by autoconf/configure to generate settings.make
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# along with this program; if not, write to the Free Software Foundation.
MAJOR= 1
-MINOR= 5
+MINOR= 6
SHLIBFILE= @SHLIBFILE@
SHLIBSONAME= @SHLIBSONAME@
SHLIBFORLINK= @SHLIBFORLINK@
LDLIBS= @LIBS@ $(XLIBS)
AUTOCFLAGS= @CFLAGS@
AUTOLDFLAGS= @LDFLAGS@
-WARNS= @WARNS@
+WARNS= @WARNS@ -Wno-unused-value
#WERROR= -Werror
M4= m4
MKSHLIB_2= @MKSHLIB_2@
MKSHLIB_3= @MKSHLIB_3@
-prefix= @prefix@
-exec_prefix= @exec_prefix@
-bindir= @bindir@
-libdir= @libdir@
-includedir= @includedir@
+prefix := @prefix@
+exec_prefix := @exec_prefix@
+bindir := @bindir@
+libdir := @libdir@
+includedir := @includedir@
+
+ifneq ($(DESTDIR),)
+# autoconf likes to define some of these in terms of each other
+# so if we want to add a prefix to each one we have to do it this way:
+destdir_prefix=$(DESTDIR)/
+prefix := ${destdir_prefix}${prefix}
+exec_prefix := ${destdir_prefix}${exec_prefix}
+bindir := ${destdir_prefix}${bindir}
+libdir := ${destdir_prefix}${libdir}
+includedir := ${destdir_prefix}${includedir}
+endif
AC_INSTALL= @INSTALL@
ifeq ($(AC_INSTALL),./install-sh -c)
INSTALL_PROGRAM= $(INSTALL) -m 755 $(INSTALL_PROGRAM_FLAGS)
INSTALL_DATA= $(INSTALL) -m 644
-
+INSTALL_DIR= $(INSTALL) -d 755
docdir
oldincludedir
includedir
+runstatedir
localstatedir
sharedstatedir
sysconfdir
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
+ | --runstate | --runstat | --runsta | --runst | --runs \
+ | --run | --ru | --r)
+ ac_prev=runstatedir ;;
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+ | --run=* | --ru=* | --r=*)
+ runstatedir=$ac_optarg ;;
+
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir
+ libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
# configure.in - input to autoconf
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# dynamic/Makefile - dynamic library Makefile
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
install:
mkdir -p $(libdir)
- $(INSTALL_PROGRAM) $(SHLIBFILE) $(libdir)/$(SHLIBFILE)
- ln -sf $(SHLIBFILE) $(libdir)/$(SHLIBSONAME)
- ln -sf $(SHLIBSONAME) $(libdir)/$(SHLIBFORLINK)
+ $(INSTALL_PROGRAM) $(SHLIBFILE) $(DESTDIR)$(libdir)/$(SHLIBFILE)
+ ln -sf $(SHLIBFILE) $(DESTDIR)$(libdir)/$(SHLIBSONAME)
+ ln -sf $(SHLIBSONAME) $(DESTDIR)$(libdir)/$(SHLIBFORLINK)
uninstall:
rm -f $(libdir)/$(SHLIBFILE) $(libdir)/$(SHLIBSONAME)
# regress/Makefile[.in] - regression test Makefile
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
CLIENTS= adnstest adnshost adnslogres $(PROGS_SYSDEP)
AUTOCHDRS= harness.h hsyscalls.h hredirect.h
-AUTOCSRCS= hrecord.c hplayback.c hcommon.c
+AUTOCSRCS= hrecord.c hplayback.c hcommon.c hfuzzraw.c
include ../settings.make
include $(srcdir)/../src/adns.make
DIRCFLAGS= -I../src -I$(srcdir) -I$(srcdir)/../src
HCPPFLAGS= -DADNS_REGRESS_TEST -I.
+#HCPPFLAGS+= -DFUZZRAW_SYNC
REDIRLIBOBJS= $(addsuffix _d.o, $(basename $(LIBOBJS)))
HARNLOBJS= hcommon.o $(REDIRLIBOBJS)
-TARGETS= $(addsuffix _record, $(CLIENTS)) $(addsuffix _playback, $(CLIENTS))
+TARGETS= $(addsuffix _record, $(CLIENTS)) \
+ $(addsuffix _playback, $(CLIENTS)) \
+ $(addsuffix _fuzz, $(CLIENTS)) \
+ $(addsuffix _fuzzraw, $(CLIENTS))
ADH_OBJS= adh-main_c.o adh-opts_c.o adh-query_c.o
-ALL_OBJS= $(HARNLOBJS) dtest.o hrecord.o hplayback.o
+ALL_OBJS= $(HARNLOBJS) dtest.o hrecord.o hplayback.o hnonfuzz.o hfuzz.o
.PRECIOUS: $(AUTOCSRCS) $(AUTOCHDRS)
@echo
@echo 'all tests passed or maybe skipped.'
+checkfuzz: $(TARGETS) \
+ $(addprefix checkfuzz-,$(ALL_TESTS)) \
+ $(addprefix checkfuzzraw-,$(ALL_TESTS))
+ @echo
+ @echo 'all fuzzes passed or maybe skipped.'
+# this target is mostly useful as prep work for running the fuzzer;
+# it doesn't really test any of adns
+
+fuzzcat.d: checkfuzz
+ $(srcdir)/categorisefuzz $(ALL_TESTS)
+ perl -ne 'print $$1,"\n" while m/\"([^"% ]{2,})\"/g' \
+ $(srcdir)/../src/*.[ch] $(srcdir)/../client/*.[ch] \
+ | sort -u >fuzzcat.d/dictionary
+ perl -p -e 'chomp;' \
+ -e 's/[^0-9a-z-_]/sprintf "\\x%02x", ord $$&/ige;' \
+ -e 's/^/l$$.="/; ' \
+ -e 's/$$/"\n/;' \
+ fuzzcat.d/dictionary >fuzzcat.d/dictionary.afl
+
check-%: case-%.sys
- @srcdir=$(srcdir) $(srcdir)/r1test $* || test $? = 5
+ @srcdir=$(srcdir) $(srcdir)/r1test $* || test $$? = 5
+
+fuzz-%: case-%.sys $(TARGETS) make1fuzz shlib
+ srcdir=$(srcdir) $(srcdir)/make1fuzz $*
+
+fuzzraw-%: fuzz-%
+
+.PRECIOUS: fuzz-%
+
+checkfuzz-%: fuzz-% $(TARGETS)
+ @srcdir=$(srcdir) $(srcdir)/check1fuzz $<
+
+checkfuzzraw-%: fuzz-% $(TARGETS)
+ @srcdir=$(srcdir) $(srcdir)/check1fuzz $<
LINK_CMD= $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
-%_record: %_c.o hrecord.o $(HARNLOBJS)
+%_record: %_c.o hrecord.o hnonfuzz.o $(HARNLOBJS)
$(LINK_CMD)
-%_playback: %_c.o hplayback.o $(HARNLOBJS)
+%_playback: %_c.o hplayback.o hnonfuzz.o $(HARNLOBJS)
+ $(LINK_CMD)
+
+%_fuzz: %_c.o hplayback.o hfuzz.o $(HARNLOBJS)
+ $(LINK_CMD)
+
+%_fuzzraw: %_c.o hfuzzraw.o hfuzz.o $(HARNLOBJS)
$(LINK_CMD)
.SECONDARY: $(addsuffix _c.o, $(filter-out adnshost, $(CLIENTS)))
#
# See also Savannah #29620, http://savannah.gnu.org/bugs/index.php?29620
-adnshost_%: $(ADH_OBJS) h%.o $(HARNLOBJS)
+adnshost_%: $(ADH_OBJS) h%.o hnonfuzz.o $(HARNLOBJS)
+ $(LINK_CMD)
+
+adnshost_fuzz: $(ADH_OBJS) hplayback.o hfuzz.o $(HARNLOBJS)
+ $(LINK_CMD)
+
+adnshost_fuzzraw: $(ADH_OBJS) hfuzzraw.o hfuzz.o $(HARNLOBJS)
$(LINK_CMD)
-%_d.o: $(srcdir)/../src/%.c hredirect.h
+%_d.o: $(srcdir)/../src/%.c hredirect.h hsyscalls.h
$(CC) $(CFLAGS) $(HCPPFLAGS) -c -g -o $@ $<
-%_c.o: $(srcdir)/../client/%.c hredirect.h
+%_c.o: $(srcdir)/../client/%.c hredirect.h hsyscalls.h
$(CC) $(CFLAGS) $(HCPPFLAGS) -I $(srcdir)/../src -c -g -o $@ $<
$(ALL_OBJS): $(srcdir)/../src/adns.h $(srcdir)/../src/internal.h
#!/bin/sh
# usage: ./addcases <casename> ...
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
--- /dev/null
+adns debug: using nameserver 172.18.45.6
+1.0.0.127.in-addr.arpa has no TXT record
+Error during DNS PTR lookup for 1.0.0.127.zen.spamhaus.org: Domain invalid for particular DNS query type
+1.0.0.127.zen.spamhaus.org does not exist
--- /dev/null
+1.0.0.127.in-addr.arpa PTR localhost
+rc=0
--- /dev/null
+./adnshost default
+-f
+ start 1481332828.558221
+ socket domain=AF_INET type=SOCK_DGRAM
+ socket=6
+ +0.000159
+ fcntl fd=6 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000051
+ fcntl fd=6 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000035
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +12.-81227
+ read fd=0 buflen=40
+ read=OK
+ 2d2d7265 76657273 65203132 372e302e 302e3120 696e2d61 6464722e 61727061
+ 0a.
+ +0.000148
+ sendto fd=6 addr=172.18.45.6:53
+ 311f0100 00010000 00000000 01310130 01300331 32370769 6e2d6164 64720461
+ 72706100 00100001.
+ sendto=40
+ +0.000190
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=1.999810
+ select=1 rfds=[6] wfds=[] efds=[]
+ +1.-429555
+ recvfrom fd=6 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 311f8580 00010000 00010000 01310130 01300331 32370769 6e2d6164 64720461
+ 72706100 00100001 c0120006 00010009 3a800026 096c6f63 616c686f 73740004
+ 726f6f74 c0340000 00010009 3a800001 51800024 ea000009 3a80.
+ +0.000152
+ recvfrom fd=6 buflen=512
+ recvfrom=EAGAIN
+ +0.000032
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +5.124113
+ read fd=0 buflen=40
+ read=OK
+ 2d742070 74720a.
+ +0.000126
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +1.658805
+ read fd=0 buflen=40
+ read=OK
+ 2d2d7265 76657273 65203132 372e302e 302e3120 696e2d61 6464722e 61727061
+ 0a.
+ +0.000135
+ sendto fd=6 addr=172.18.45.6:53
+ 31200100 00010000 00000000 01310130 01300331 32370769 6e2d6164 64720461
+ 72706100 000c0001.
+ sendto=40
+ +0.000207
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=1.999793
+ select=1 rfds=[6] wfds=[] efds=[]
+ +0.010520
+ recvfrom fd=6 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31208580 00010001 00010001 01310130 01300331 32370769 6e2d6164 64720461
+ 72706100 000c0001 c00c000c 00010009 3a80000b 096c6f63 616c686f 737400c0
+ 12000200 0100093a 800002c0 34c03400 01000100 093a8000 047f0000 01.
+ +0.000147
+ sendto fd=6 addr=172.18.45.6:53
+ 31210100 00010000 00000000 096c6f63 616c686f 73740000 010001.
+ sendto=27
+ +0.000109
+ recvfrom fd=6 buflen=512
+ recvfrom=EAGAIN
+ +0.000035
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=1.999709
+ select=1 rfds=[6] wfds=[] efds=[]
+ +0.003062
+ recvfrom fd=6 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31218580 00010001 00010000 096c6f63 616c686f 73740000 010001c0 0c000100
+ 0100093a 8000047f 000001c0 0c000200 0100093a 800002c0 0c.
+ +0.000130
+ recvfrom fd=6 buflen=512
+ recvfrom=EAGAIN
+ +0.000035
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +7.-587512
+ read fd=0 buflen=40
+ read=OK
+ 2d2d7265 76657273 65203132 372e302e 302e3120 7a656e2e 7370616d 68617573
+ 2e6f7267 0a.
+ +0.000112
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +2.190400
+ read fd=0 buflen=40
+ read=OK
+ 2d742070 74722d0a.
+ +0.000091
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +1.091179
+ read fd=0 buflen=40
+ read=OK
+ 2d2d7265 76657273 65203132 372e302e 302e3120 7a656e2e 7370616d 68617573
+ 2e6f7267 0a.
+ +0.000125
+ sendto fd=6 addr=172.18.45.6:53
+ 31230100 00010000 00000000 01310130 01300331 3237037a 656e0873 70616d68
+ 61757303 6f726700 000c0001.
+ sendto=44
+ +0.000157
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=1.999843
+ select=1 rfds=[6] wfds=[] efds=[]
+ +0.084632
+ recvfrom fd=6 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31238183 00010000 00010000 01310130 01300331 3237037a 656e0873 70616d68
+ 61757303 6f726700 000c0001 c0160006 00010000 000a0034 046e6565 6402746f
+ 046b6e6f 77046f6e 6c79000a 686f7374 6d617374 6572c01a 6016b217 00000e10
+ 00000258 00069780 0000000a.
+ +0.000163
+ recvfrom fd=6 buflen=512
+ recvfrom=EAGAIN
+ +0.000032
+ select max=7 rfds=[0,6] wfds=[] efds=[] to=null
+ select=1 rfds=[0] wfds=[] efds=[]
+ +10.-109673
+ read fd=0 buflen=40
+ read=OK
+ .
+ +0.000095
+ close fd=6
+ close=OK
+ +0.000060
+ exit 6
--- /dev/null
+adns debug [2264]: using nameserver 172.18.45.6
+v4.chiark.greenend.org.uk flags 0 type 1 A(-) submitted
+v4.chiark.greenend.org.uk flags 0 type 2 NS(raw) submitted
+v4.chiark.greenend.org.uk flags 0 type 5 CNAME(-) submitted
+v4.chiark.greenend.org.uk flags 0 type 6 SOA(raw) submitted
+v4.chiark.greenend.org.uk flags 0 type 12 PTR(raw) submitted
+v4.chiark.greenend.org.uk flags 0 type 13 HINFO(-) submitted
+v4.chiark.greenend.org.uk flags 0 type 15 MX(raw) submitted
+v4.chiark.greenend.org.uk flags 0 type 16 TXT(-) submitted
+v4.chiark.greenend.org.uk flags 0 type 17 RP(raw) submitted
+v4.chiark.greenend.org.uk flags 0 type 65537 A(addr) submitted
+v4.chiark.greenend.org.uk flags 0 type 65538 NS(+addr) submitted
+v4.chiark.greenend.org.uk flags 0 type 65548 PTR(checked) submitted
+v4.chiark.greenend.org.uk flags 0 type 65551 MX(+addr) submitted
+v4.chiark.greenend.org.uk flags 0 type 131078 SOA(822) submitted
+v4.chiark.greenend.org.uk flags 0 type 131089 RP(822) submitted
+v4.chiark.greenend.org.uk flags 0 type PTR(checked): Domain invalid for particular DNS query type; nrrs=0; cname=$; owner=$; ttl=-1499395200
+v4.chiark.greenend.org.uk flags 0 type A(-): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type NS(raw): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type CNAME(-): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type SOA(raw): No such domain; nrrs=0; cname=$; owner=$; ttl=-1500000000
+v4.chiark.greenend.org.uk flags 0 type PTR(raw): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type HINFO(-): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type MX(raw): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type TXT(-): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type RP(raw): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type MX(+addr): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type NS(+addr): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type RP(822): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+v4.chiark.greenend.org.uk flags 0 type SOA(822): No such domain; nrrs=0; cname=$; owner=$; ttl=-1500000000
+v4.chiark.greenend.org.uk flags 0 type A(addr): No such domain; nrrs=0; cname=$; owner=$; ttl=-1499999700
+rc=0
--- /dev/null
+./adnstest default -0x0080
+v4.chiark.greenend.org.uk
+ start 1590336601.672124
+ socket domain=AF_INET type=SOCK_DGRAM
+ socket=7
+ +0.000038
+ fcntl fd=7 cmd=F_GETFL
+ fcntl=~O_NONBLOCK&...
+ +0.000013
+ fcntl fd=7 cmd=F_SETFL O_NONBLOCK|...
+ fcntl=OK
+ +0.000009
+ sendto fd=7 addr=172.18.45.6:53
+ 311f0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 010001.
+ sendto=43
+ +0.000084
+ sendto fd=7 addr=172.18.45.6:53
+ 31200100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 020001.
+ sendto=43
+ +0.000068
+ sendto fd=7 addr=172.18.45.6:53
+ 31210100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 050001.
+ sendto=43
+ +0.000055
+ sendto fd=7 addr=172.18.45.6:53
+ 31220100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 060001.
+ sendto=43
+ +0.000041
+ sendto fd=7 addr=172.18.45.6:53
+ 31230100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0c0001.
+ sendto=43
+ +0.000041
+ sendto fd=7 addr=172.18.45.6:53
+ 31240100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0d0001.
+ sendto=43
+ +0.000070
+ sendto fd=7 addr=172.18.45.6:53
+ 31250100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0f0001.
+ sendto=43
+ +0.000053
+ sendto fd=7 addr=172.18.45.6:53
+ 31260100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 100001.
+ sendto=43
+ +0.000042
+ sendto fd=7 addr=172.18.45.6:53
+ 31270100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 110001.
+ sendto=43
+ +0.000041
+ sendto fd=7 addr=172.18.45.6:53
+ 31290100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 010001.
+ sendto=43
+ +0.000045
+ sendto fd=7 addr=172.18.45.6:53
+ 312a0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 1c0001.
+ sendto=43
+ +0.000026
+ sendto fd=7 addr=172.18.45.6:53
+ 312b0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 020001.
+ sendto=43
+ +0.000041
+ sendto fd=7 addr=172.18.45.6:53
+ 312d0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0f0001.
+ sendto=43
+ +0.000055
+ sendto fd=7 addr=172.18.45.6:53
+ 312e0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 060001.
+ sendto=43
+ +0.000040
+ sendto fd=7 addr=172.18.45.6:53
+ 312f0100 00010000 00000000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 110001.
+ sendto=43
+ +0.000040
+ select max=8 rfds=[7] wfds=[] efds=[] to=1.999258
+ select=1 rfds=[7] wfds=[] efds=[]
+ +0.003052
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 311f8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 010001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000055
+ recvfrom fd=7 buflen=512
+ recvfrom=EAGAIN
+ +0.000011
+ select max=8 rfds=[7] wfds=[] efds=[] to=1.996224
+ select=1 rfds=[7] wfds=[] efds=[]
+ +0.001024
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31208583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 020001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000049
+ recvfrom fd=7 buflen=512
+ recvfrom=EAGAIN
+ +0.000030
+ select max=8 rfds=[7] wfds=[] efds=[] to=1.995189
+ select=1 rfds=[7] wfds=[] efds=[]
+ +0.000586
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31218583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 050001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000036
+ recvfrom fd=7 buflen=512
+ recvfrom=EAGAIN
+ +0.000010
+ select max=8 rfds=[7] wfds=[] efds=[] to=1.994612
+ select=1 rfds=[7] wfds=[] efds=[]
+ +0.002366
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31228583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 060001c0 16000600 01000000 00002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000037
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31238583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0c0001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31248583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0d0001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31258583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0f0001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31268583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 100001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000027
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31278583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 110001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 31298583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 010001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000029
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 312d8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 0f0001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000027
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 312b8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 020001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 312a8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 1c0001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 312f8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 110001c0 16000600 01000001 2c002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000028
+ recvfrom fd=7 buflen=512
+ recvfrom=OK addr=172.18.45.6:53
+ 312e8583 00010000 00010000 02763406 63686961 726b0867 7265656e 656e6403
+ 6f726702 756b0000 060001c0 16000600 01000000 00002a03 736f6102 6e73c00f
+ 0a686f73 746d6173 746572c0 16ee6b28 85000070 8000001c 2000093a 80000151
+ 80.
+ +0.000027
+ recvfrom fd=7 buflen=512
+ recvfrom=EAGAIN
+ +0.000022
+ close fd=7
+ close=OK
+ +0.000114
--- /dev/null
+#!/bin/sh
+set -e
+
+out=fuzzcat.d
+
+rm -rf "$out"
+mkdir "$out"
+
+categ () {
+ fuzz=$1
+ exec <"$fuzz"
+ read nargs
+ read arg0len
+ read program
+ program="${program##*/}"
+ mkdir -p "$out/$program"
+ ln "$fuzz" "$out/$program"/.
+}
+
+for case in "$@"; do
+ categ "fuzz-$case"
+ categ "fuzzraw-$case"
+done
--- /dev/null
+#!/bin/sh
+# usage: check1fuzz <fuzzer stimulus file>
+# fuzz check script, for checking that one fuzz input works
+
+set -e
+: ${srcdir=.}
+. "$srcdir"/shlib
+
+fuzzfile="$1"
+
+exec <"$fuzzfile"
+
+case "$fuzzfile" in
+fuzz-*) kind=f; case="${fuzzfile#fuzz-}" ;;
+fuzzraw-*) kind=r; case="${fuzzfile#fuzzraw-}" ;;
+*) printf >&2 '\nWRONG-FUZZ-%s\n' $fuzzfile; exit 1 ;;
+esac
+
+desc="$case.$kind"
+
+read nargs
+if [ "$nargs" = 0 ]; then printf "SKIPPED-$desc "; exit 5; fi
+
+read arg1len
+read program
+
+case "$program" in
+*/*) ;;
+*) program="./$program" ;;
+esac
+
+exec 3>output-$desc.trouble
+
+set +e
+${program} <"$fuzzfile" >output-$desc.out.tmp 2>&3
+rc=$?
+set -e
+
+if [ $rc = 0 ]; then
+ set +e
+ diff -u output-$desc.out.tmp case-$case.out >&3
+ rc=$?
+ set -e
+fi
+
+if [ $rc != 0 ]; then
+ printf >&2 '\nFAIL-%s\n' $desc
+ exit $rc
+fi
+
+printf '%s ' "$desc"
+rm -f output-$desc.trouble
# usage: checkall
# runs all test cases
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
+++ /dev/null
-#ifndef HARNESS_H_INCLUDED
-#define HARNESS_H_INCLUDED
-#include "internal.h"
-#include "hsyscalls.h"
-/* There is a Q function (Q for Question) for each such syscall;
- * it constructs a string representing the call, and calls Q_str
- * on it, or constructs it in vb and calls Q_vb;
- */
-void Qselect( int max , const fd_set *rfds , const fd_set *wfds , const fd_set *efds , struct timeval *to );
-#ifdef HAVE_POLL
-void Qpoll( const struct pollfd *fds , int nfds , int timeout );
-#endif
-void Qsocket( int domain , int type );
-void Qfcntl( int fd , int cmd , long arg );
-void Qconnect( int fd , const struct sockaddr *addr , int addrlen );
-void Qbind( int fd , const struct sockaddr *addr , int addrlen );
-void Qlisten( int fd , int backlog );
-void Qclose( int fd );
-void Qsendto( int fd , const void *msg , int msglen , const struct sockaddr *addr , int addrlen );
-void Qrecvfrom( int fd , int buflen , int addrlen );
-void Qread( int fd , size_t buflen );
-void Qwrite( int fd , const void *buf , size_t len );
-void Q_vb(void);
-extern void Tshutdown(void);
-/* General help functions */
-void Tfailed(const char *why);
-void Toutputerr(void);
-void Tnomem(void);
-void Tfsyscallr(const char *fmt, ...) PRINTFFORMAT(1,2);
-void Tensurerecordfile(void);
-void Tmust(const char *call, const char *arg, int cond);
-void Tvbf(const char *fmt, ...) PRINTFFORMAT(1,2);
-void Tvbvf(const char *fmt, va_list al);
-void Tvbfdset(int max, const fd_set *set);
-void Tvbpollfds(const struct pollfd *fds, int nfds);
-void Tvbaddr(const struct sockaddr *addr, int addrlen);
-void Tvbbytes(const void *buf, int len);
-void Tvberrno(int e);
-void Tvba(const char *str);
-/* Shared globals */
-extern vbuf vb;
-extern struct timeval currenttime;
-extern const struct Terrno { const char *n; int v; } Terrnos[];
-/* Special cases */
-void Texit(int rv) NONRETURNING;
-#endif
m4_dnl (part of complex test harness, not of the library)
m4_dnl - function and other declarations
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
m4_define(`hm_syscall', `void Q$1(hm_args_massage($3,void));')
m4_define(`hm_specsyscall', `')
m4_include(`hsyscalls.i4')
+hm_stdsyscall_close
void Q_vb(void);
void Toutputerr(void);
void Tnomem(void);
void Tfsyscallr(const char *fmt, ...) PRINTFFORMAT(1,2);
-void Tensurerecordfile(void);
+void Tensuresetup(void);
void Tmust(const char *call, const char *arg, int cond);
void Tvbf(const char *fmt, ...) PRINTFFORMAT(1,2);
extern vbuf vb;
extern struct timeval currenttime;
extern const struct Terrno { const char *n; int v; } Terrnos[];
+extern const int Tnerrnos;
/* Special cases */
void Texit(int rv) NONRETURNING;
+void Tcommonshutdown(void);
+void Tmallocshutdown(void);
+int Ttestinputfd(void);
+void T_gettimeofday_hook(void);
+
#endif
+++ /dev/null
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include "harness.h"
-#include "internal.h"
-vbuf vb;
-FILE *Toutputfile= 0;
-struct timeval currenttime;
-const struct Terrno Terrnos[]= {
- { "EBADF", EBADF },
- { "EAGAIN", EAGAIN },
- { "EINPROGRESS", EINPROGRESS },
- { "EINTR", EINTR },
- { "EINVAL", EINVAL },
- { "EMSGSIZE", EMSGSIZE },
- { "ENOBUFS", ENOBUFS },
- { "ENOENT", ENOENT },
- { "ENOPROTOOPT", ENOPROTOOPT },
- { "ENOSPC", ENOSPC },
- { "EWOULDBLOCK", EWOULDBLOCK },
- { "EHOSTUNREACH", EHOSTUNREACH },
- { "ECONNRESET", ECONNRESET },
- { "ECONNREFUSED", ECONNREFUSED },
- { "EPIPE", EPIPE },
- { "ENOTSOCK", ENOTSOCK },
- { 0, 0 }
-};
-static vbuf vbw;
-int Hgettimeofday(struct timeval *tv, struct timezone *tz) {
- Tensurerecordfile();
- Tmust("gettimeofday","tz",!tz);
- *tv= currenttime;
- return 0;
-}
-int Hwritev(int fd, const struct iovec *vector, size_t count) {
- size_t i;
- vbw.used= 0;
- for (i=0; i<count; i++, vector++) {
- if (!adns__vbuf_append(&vbw,vector->iov_base,vector->iov_len)) Tnomem();
- }
- return Hwrite(fd,vbw.buf,vbw.used);
-}
-void Qselect( int max , const fd_set *rfds , const fd_set *wfds , const fd_set *efds , struct timeval *to ) {
- vb.used= 0;
- Tvba("select");
- Tvbf(" max=%d",max);
- Tvbf(" rfds="); Tvbfdset(max,rfds);
- Tvbf(" wfds="); Tvbfdset(max,wfds);
- Tvbf(" efds="); Tvbfdset(max,efds);
- if (to) Tvbf(" to=%ld.%06ld",(long)to->tv_sec,(long)to->tv_usec);
- else Tvba(" to=null");
- Q_vb();
-}
-#ifdef HAVE_POLL
-void Qpoll( const struct pollfd *fds , int nfds , int timeout ) {
- vb.used= 0;
- Tvba("poll");
- Tvbf(" fds="); Tvbpollfds(fds,nfds);
- Tvbf(" timeout=%d",timeout);
- Q_vb();
-}
-#endif
-void Qsocket( int domain , int type ) {
- vb.used= 0;
- Tvba("socket");
- Tvbf(domain==AF_INET ? " domain=AF_INET" :
- domain==AF_INET6 ? " domain=AF_INET6" :
- " domain=AF_???");
- Tvbf(type==SOCK_STREAM ? " type=SOCK_STREAM" : " type=SOCK_DGRAM");
- Q_vb();
-}
-void Qfcntl( int fd , int cmd , long arg ) {
- vb.used= 0;
- Tvba("fcntl");
- Tvbf(" fd=%d",fd);
- if (cmd == F_SETFL) {
- Tvbf(" cmd=F_SETFL %s",arg & O_NONBLOCK ? "O_NONBLOCK|..." : "~O_NONBLOCK&...");
- } else if (cmd == F_GETFL) {
- Tvba(" cmd=F_GETFL");
- } else {
- Tmust("cmd","F_GETFL/F_SETFL",0);
- }
- Q_vb();
-}
-void Qconnect( int fd , const struct sockaddr *addr , int addrlen ) {
- vb.used= 0;
- Tvba("connect");
- Tvbf(" fd=%d",fd);
- Tvba(" addr="); Tvbaddr(addr,addrlen);
- Q_vb();
-}
-void Qbind( int fd , const struct sockaddr *addr , int addrlen ) {
- vb.used= 0;
- Tvba("bind");
- Tvbf(" fd=%d",fd);
- Tvba(" addr="); Tvbaddr(addr,addrlen);
- Q_vb();
-}
-void Qlisten( int fd , int backlog ) {
- vb.used= 0;
- Tvba("listen");
- Tvbf(" fd=%d",fd);
- Tvbf(" backlog=%d",backlog);
- Q_vb();
-}
-void Qclose( int fd ) {
- vb.used= 0;
- Tvba("close");
- Tvbf(" fd=%d",fd);
- Q_vb();
-}
-void Qsendto( int fd , const void *msg , int msglen , const struct sockaddr *addr , int addrlen ) {
- vb.used= 0;
- Tvba("sendto");
- Tvbf(" fd=%d",fd);
- Tvba(" addr="); Tvbaddr(addr,addrlen);
- Tvbbytes(msg,msglen);
- Q_vb();
-}
-void Qrecvfrom( int fd , int buflen , int addrlen ) {
- vb.used= 0;
- Tvba("recvfrom");
- Tvbf(" fd=%d",fd);
- Tvbf(" buflen=%lu",(unsigned long)buflen);
- Q_vb();
-}
-void Qread( int fd , size_t buflen ) {
- vb.used= 0;
- Tvba("read");
- Tvbf(" fd=%d",fd);
- Tvbf(" buflen=%lu",(unsigned long)buflen);
- Q_vb();
-}
-void Qwrite( int fd , const void *buf , size_t len ) {
- vb.used= 0;
- Tvba("write");
- Tvbf(" fd=%d",fd);
- Tvbbytes(buf,len);
- Q_vb();
-}
-void Tvbaddr(const struct sockaddr *addr, int len) {
- char buf[ADNS_ADDR2TEXT_BUFLEN];
- int err, port;
- int sz= sizeof(buf);
- err= adns_addr2text(addr, 0, buf,&sz, &port);
- assert(!err);
- Tvbf(strchr(buf, ':') ? "[%s]:%d" : "%s:%d", buf,port);
-}
-void Tvbbytes(const void *buf, int len) {
- const byte *bp;
- int i;
- if (!len) { Tvba("\n ."); return; }
- for (i=0, bp=buf; i<len; i++, bp++) {
- if (!(i&31)) Tvba("\n ");
- else if (!(i&3)) Tvba(" ");
- Tvbf("%02x",*bp);
- }
- Tvba(".");
-}
-void Tvbfdset(int max, const fd_set *fds) {
- int i;
- const char *comma= "";
- if (!fds) {
- Tvba("null");
- return;
- }
- Tvba("[");
- for (i=0; i<max; i++) {
- if (!FD_ISSET(i,fds)) continue;
- Tvba(comma);
- Tvbf("%d",i);
- comma= ",";
- }
- Tvba("]");
-}
-static void Tvbpollevents(int events) {
- const char *delim= "";
- events &= (POLLIN|POLLOUT|POLLPRI);
- if (!events) { Tvba("0"); return; }
- if (events & POLLIN) { Tvba("POLLIN"); delim= "|"; }
- if (events & POLLOUT) { Tvba(delim); Tvba("POLLOUT"); delim= "|"; }
- if (events & POLLPRI) { Tvba(delim); Tvba("POLLPRI"); }
-}
-void Tvbpollfds(const struct pollfd *fds, int nfds) {
- const char *comma= "";
- Tvba("[");
- while (nfds>0) {
- Tvba(comma);
- Tvbf("{fd=%d, events=",fds->fd);
- Tvbpollevents(fds->events);
- Tvba(", revents=");
- Tvbpollevents(fds->revents);
- Tvba("}");
- comma= ", ";
- nfds--; fds++;
- }
- Tvba("]");
-}
-void Tvberrno(int e) {
- const struct Terrno *te;
- for (te= Terrnos; te->n && te->v != e; te++);
- assert(te->n);
- Tvba(te->n);
-}
-void Tvba(const char *str) {
- if (!adns__vbuf_appendstr(&vb,str)) Tnomem();
-}
-void Tvbvf(const char *fmt, va_list al) {
- char buf[1000];
- buf[sizeof(buf)-2]= '\t';
- vsnprintf(buf,sizeof(buf),fmt,al);
- assert(buf[sizeof(buf)-2] == '\t');
- Tvba(buf);
-}
-void Tvbf(const char *fmt, ...) {
- va_list al;
- va_start(al,fmt);
- Tvbvf(fmt,al);
- va_end(al);
-}
-void Tmust(const char *call, const char *arg, int cond) {
- if (cond) return;
- fprintf(stderr,"adns test harness: case not handled: system call %s, arg %s",call,arg);
- exit(-1);
-}
-void Tfailed(const char *why) {
- fprintf(stderr,"adns test harness: failure: %s: %s\n",why,strerror(errno));
- exit(-1);
-}
-void Tnomem(void) {
- Tfailed("unable to malloc/realloc");
-}
-void Toutputerr(void) {
- Tfailed("write error on test harness output");
-}
-struct malloced {
- struct malloced *next, *back;
- size_t sz;
- unsigned long count;
- struct { double d; long ul; void *p; void (*fp)(void); } data;
-};
-static unsigned long malloccount, mallocfailat;
-static struct { struct malloced *head, *tail; } mallocedlist;
-#define MALLOCHSZ ((char*)&mallocedlist.head->data - (char*)mallocedlist.head)
-void *Hmalloc(size_t sz) {
- struct malloced *newnode;
- const char *mfavar;
- char *ep;
- assert(sz);
- newnode= malloc(MALLOCHSZ + sz); if (!newnode) Tnomem();
- LIST_LINK_TAIL(mallocedlist,newnode);
- newnode->sz= sz;
- newnode->count= ++malloccount;
- if (!mallocfailat) {
- mfavar= getenv("ADNS_REGRESS_MALLOCFAILAT");
- if (mfavar) {
- mallocfailat= strtoul(mfavar,&ep,10);
- if (!mallocfailat || *ep) Tfailed("ADNS_REGRESS_MALLOCFAILAT bad value");
- } else {
- mallocfailat= ~0UL;
- }
- }
- assert(newnode->count != mallocfailat);
- memset(&newnode->data,0xc7,sz);
- return &newnode->data;
-}
-void Hfree(void *ptr) {
- struct malloced *oldnode;
- if (!ptr) return;
- oldnode= (void*)((char*)ptr - MALLOCHSZ);
- LIST_UNLINK(mallocedlist,oldnode);
- memset(&oldnode->data,0x38,oldnode->sz);
- free(oldnode);
-}
-void *Hrealloc(void *op, size_t nsz) {
- struct malloced *oldnode;
- void *np;
- size_t osz;
- if (op) { oldnode= (void*)((char*)op - MALLOCHSZ); osz= oldnode->sz; } else { osz= 0; }
- np= Hmalloc(nsz);
- if (osz) memcpy(np,op, osz>nsz ? nsz : osz);
- Hfree(op);
- return np;
-}
-void Texit(int rv) {
- struct malloced *loopnode;
- Tshutdown();
- adns__vbuf_free(&vb);
- adns__vbuf_free(&vbw);
- if (mallocedlist.head) {
- fprintf(stderr,"adns test harness: memory leaked:");
- for (loopnode=mallocedlist.head; loopnode; loopnode=loopnode->next)
- fprintf(stderr," %lu",loopnode->count);
- putc('\n',stderr);
- if (ferror(stderr)) exit(-1);
- }
- exit(rv);
-}
-void Hexit(int rv) {
- vb.used= 0;
- Tvbf("exit %d", rv);
- Q_vb();
- Texit(0);
-}
-pid_t Hgetpid(void) {
- return 2264; /* just some number */
-}
m4_dnl (part of complex test harness, not of the library)
m4_dnl - routines used for both record and playback
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
#include <unistd.h>
#include <fcntl.h>
+#include <time.h>
#include "harness.h"
#include "internal.h"
{ 0, 0 }
};
+const int Tnerrnos= sizeof(Terrnos)/sizeof(Terrnos[0]) - 1;
+
static vbuf vbw;
int Hgettimeofday(struct timeval *tv, struct timezone *tz) {
- Tensurerecordfile();
+ Tensuresetup();
Tmust("gettimeofday","tz",!tz);
+ T_gettimeofday_hook();
*tv= currenttime;
return 0;
}
+int Hclock_gettime(clockid_t clk, struct timespec *ts) {
+ Tensuresetup();
+ ts->tv_sec = currenttime.tv_sec;
+ ts->tv_nsec = currenttime.tv_usec * 1000 + 666;
+ switch (clk) {
+ case CLOCK_MONOTONIC: ts->tv_sec -= 1500000000; break;
+ case CLOCK_REALTIME: break;
+ default: Tmust("clock_gettime","clk",0);
+ }
+ return 0;
+}
int Hwritev(int fd, const struct iovec *vector, size_t count) {
size_t i;
m4_include(`hsyscalls.i4')
+hm_stdsyscall_close
+
void Tvbaddr(const struct sockaddr *addr, int len) {
char buf[ADNS_ADDR2TEXT_BUFLEN];
int err, port;
Tfailed("write error on test harness output");
}
-struct malloced {
- struct malloced *next, *back;
- size_t sz;
- unsigned long count;
- struct { double d; long ul; void *p; void (*fp)(void); } data;
-};
-
-static unsigned long malloccount, mallocfailat;
-static struct { struct malloced *head, *tail; } mallocedlist;
-
-#define MALLOCHSZ ((char*)&mallocedlist.head->data - (char*)mallocedlist.head)
-
-void *Hmalloc(size_t sz) {
- struct malloced *newnode;
- const char *mfavar;
- char *ep;
-
- assert(sz);
-
- newnode= malloc(MALLOCHSZ + sz); if (!newnode) Tnomem();
-
- LIST_LINK_TAIL(mallocedlist,newnode);
- newnode->sz= sz;
- newnode->count= ++malloccount;
- if (!mallocfailat) {
- mfavar= getenv("ADNS_REGRESS_MALLOCFAILAT");
- if (mfavar) {
- mallocfailat= strtoul(mfavar,&ep,10);
- if (!mallocfailat || *ep) Tfailed("ADNS_REGRESS_MALLOCFAILAT bad value");
- } else {
- mallocfailat= ~0UL;
- }
- }
- assert(newnode->count != mallocfailat);
- memset(&newnode->data,0xc7,sz);
- return &newnode->data;
-}
-
-void Hfree(void *ptr) {
- struct malloced *oldnode;
-
- if (!ptr) return;
-
- oldnode= (void*)((char*)ptr - MALLOCHSZ);
- LIST_UNLINK(mallocedlist,oldnode);
- memset(&oldnode->data,0x38,oldnode->sz);
- free(oldnode);
-}
-
-void *Hrealloc(void *op, size_t nsz) {
- struct malloced *oldnode;
- void *np;
- size_t osz;
-
- if (op) { oldnode= (void*)((char*)op - MALLOCHSZ); osz= oldnode->sz; } else { osz= 0; }
- np= Hmalloc(nsz);
- if (osz) memcpy(np,op, osz>nsz ? nsz : osz);
- Hfree(op);
- return np;
-}
-
-void Texit(int rv) {
- struct malloced *loopnode;
-
- Tshutdown();
- adns__vbuf_free(&vb);
- adns__vbuf_free(&vbw);
- if (mallocedlist.head) {
- fprintf(stderr,"adns test harness: memory leaked:");
- for (loopnode=mallocedlist.head; loopnode; loopnode=loopnode->next)
- fprintf(stderr," %lu",loopnode->count);
- putc('\n',stderr);
- if (ferror(stderr)) exit(-1);
- }
- exit(rv);
-}
-
void Hexit(int rv) {
+ Tensuresetup();
vb.used= 0;
Tvbf("exit %d", rv);
Q_vb();
return 2264; /* just some number */
}
+void Tcommonshutdown(void) {
+ Tshutdown();
+ adns__vbuf_free(&vb);
+ adns__vbuf_free(&vbw);
+ Tmallocshutdown();
+}
--- /dev/null
+/* nfuzz.c
+ * (part of complex test harness, not of the library)
+ * - routines used for fuzzing (a kind of playback)
+ *
+ * This file is part of adns, which is
+ * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+ * Copyright (C) 2014 Mark Wooding
+ * Copyright (C) 1999-2000,2003,2006 Tony Finch
+ * Copyright (C) 1991 Massachusetts Institute of Technology
+ * (See the file INSTALL for full details.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation.
+ *
+ */
+/*
+ * We read from stdin:
+ * - command line arguments
+ * - syscall stream
+ * - stdin
+ */
+
+#include <stdio.h>
+
+#include "harness.h"
+
+extern int Hmain(int argc, char **argv);
+
+FILE *Hfopen(const char *path, const char *mode) {
+ /* we do not allow adns to open any files */
+ errno = EPERM;
+ return 0;
+}
+
+static int t_argc;
+static char **t_argv;
+
+static FILE *t_stdin, *stdoutcopy;
+static int t_sys_fd;
+
+static int bail(const char *msg) {
+ fprintf(stderr,"adns fuzz client: %s\n", msg);
+ exit(-1);
+}
+static int baile(const char *msg) {
+ fprintf(stderr,"adns fuzz client: %s: %s\n", msg, strerror(errno));
+ exit(-1);
+}
+
+static void chkin(void) {
+ if (ferror(stdin)) baile("read stdin");
+ if (feof(stdin)) bail("eof on stdin");
+}
+
+static int getint(int max) {
+ int val;
+ char c;
+ chkin();
+ int r = scanf("%d%c", &val, &c);
+ chkin();
+ if (r != 2 || c != '\n') bail("bad input format: not integer");
+ if (val < 0 || val > max) bail("bad input format: wrong value");
+ return val;
+}
+
+static void getnl(void) {
+ chkin();
+ int c = getchar();
+ chkin();
+ if (c != '\n') bail("bad input format: expected newline");
+}
+
+int Ttestinputfd(void) {
+ return t_sys_fd;
+}
+
+void Texit(int rv) {
+ fprintf(stdoutcopy,"rc=%d\n",rv);
+ if (ferror(stdoutcopy) || fclose(stdoutcopy)) baile("flush rc msg");
+ Tcommonshutdown();
+ exit(0);
+}
+
+int main(int argc, char **argv) {
+ int i, l;
+
+ if (argc!=1)
+ bail("usage: *_fuzz (no arguments)");
+
+ int stdoutcopyfd= dup(1);
+ if (stdoutcopyfd<0) baile("dup 1 again");
+ stdoutcopy= fdopen(stdoutcopyfd,"w");
+ if (!stdoutcopy) baile("fdopen 1 again");
+
+ t_argc = getint(50);
+ if (!t_argc) bail("too few arguments");
+ t_argv = calloc(t_argc+1, sizeof(*t_argv));
+ for (i=0; i<t_argc; i++) {
+ l = getint(1000);
+ t_argv[i] = calloc(1, l+1);
+ fread(t_argv[i], 1,l, stdin);
+ t_argv[i][l] = 0;
+ getnl();
+ }
+
+ t_stdin = tmpfile();
+ l = getint(100000);
+ while (l>0) {
+ int c = getchar();
+ if (c==EOF) break;
+ fputc(c, t_stdin);
+ l--;
+ }
+ getnl();
+ if (ferror(t_stdin) || fflush(t_stdin)) baile("write/flush t_stdin");
+ if (fseek(stdin, 0, SEEK_CUR)) baile("seek-flush stdin");
+ t_sys_fd = dup(0); if (t_sys_fd < 0) baile("dup stdin");
+ if (dup2(fileno(t_stdin), 0)) baile("dup2 t_stdin");
+ if (fseek(stdin, 0, SEEK_SET)) baile("rewind t_stdin");
+
+ int estatus = Hmain(t_argc, t_argv);
+ Texit(estatus);
+}
+
+void Tmallocshutdown(void) { }
+void *Hmalloc(size_t s) { assert(s); return malloc(s); }
+void *Hrealloc(void *p, size_t s) { assert(s); return realloc(p,s); }
+void Hfree(void *p) { free(p); }
--- /dev/null
+m4_dnl hfuzzraw.c.m4
+m4_dnl (part of complex test harness, not of the library)
+m4_dnl - routines for fuzzing
+
+m4_dnl This file is part of adns, which is
+m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+m4_dnl Copyright (C) 2014 Mark Wooding
+m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
+m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
+m4_dnl (See the file INSTALL for full details.)
+m4_dnl
+m4_dnl This program is free software; you can redistribute it and/or modify
+m4_dnl it under the terms of the GNU General Public License as published by
+m4_dnl the Free Software Foundation; either version 3, or (at your option)
+m4_dnl any later version.
+m4_dnl
+m4_dnl This program is distributed in the hope that it will be useful,
+m4_dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+m4_dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+m4_dnl GNU General Public License for more details.
+m4_dnl
+m4_dnl You should have received a copy of the GNU General Public License
+m4_dnl along with this program; if not, write to the Free Software Foundation.
+
+m4_include(hmacros.i4)
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+
+
+#include "harness.h"
+
+static vbuf fdtab;
+#define FDF_OPEN 001u
+#define FDF_NONBLOCK 002u
+
+static FILE *Tinputfile, *traceout;
+static int traceprint;
+
+static void Tflushtrace( void) {
+ if (fflush(traceout)) Toutputerr();
+}
+
+void Tensuresetup(void) {
+ static int done;
+
+ if (done) return;
+ done++;
+
+ int fd;
+
+ fd = Ttestinputfd();
+ assert(fd >= 0);
+ Tinputfile= fdopen(fd,"rb");
+ if (!Tinputfile) Tfailed("fdopen record fd");
+
+ while (fdtab.used < 3) {
+ const char fdfstd = FDF_OPEN;
+ if (!adns__vbuf_append(&fdtab,&fdfstd,1)) Tnomem();
+ }
+
+ const char *traceprintstr= getenv("ADNS_TEST_FUZZRAW_TRACEPRINT");
+ if (traceprintstr) {
+ traceprint= atoi(traceprintstr);
+ int tracefd= dup(2);
+ if (tracefd<0) Tfailed("dup for tracefd");
+ traceout= fdopen(tracefd,"w");
+ if (!traceout) Tfailed("fdopen for traceout");
+ }
+}
+
+void Q_vb(void) {
+ if (!traceprint) return; /* hcommon.c.m4 can call Q_vb directly */
+ if (!adns__vbuf_append(&vb,"",1)) Tnomem();
+ if (fprintf(traceout," %s\n",vb.buf) == EOF) Toutputerr();
+ Tflushtrace();
+}
+
+static void Pformat(const char *what) {
+ fprintf(stderr,"adns test harness: format error in raw log input file: %s\n",what);
+ exit(-1);
+}
+
+extern void Tshutdown(void) {
+ if (!Tinputfile) return;
+ int c= fgetc(Tinputfile);
+ if (c!=EOF) Pformat("unwanted additional syscall reply data");
+ if (ferror(Tinputfile)) Tfailed("read test log input (at end)");
+}
+
+static void Pcheckinput(void) {
+ if (ferror(Tinputfile)) Tfailed("read test log input file");
+ if (feof(Tinputfile)) Pformat("eof at syscall reply");
+}
+
+static void P_read_dump(const unsigned char *p0, size_t count, ssize_t d) {
+ fputs(" | ",traceout);
+ while (count) {
+ fprintf(traceout,"%02x", *p0);
+ p0 += d;
+ count--;
+ }
+}
+
+static void P_read(void *p, size_t sz, const char *what) {
+ long pos = ftell(Tinputfile);
+ ssize_t got = fread(p,1,sz,Tinputfile);
+ Pcheckinput();
+ assert(got==sz);
+ if (traceprint>1 && sz) {
+ fprintf(traceout,"%8lx %8s:",pos,what);
+ P_read_dump(p, sz, +1);
+ if (sz<=16) {
+ P_read_dump((const unsigned char *)p+sz-1, sz, -1);
+ }
+ fputs(" |\n",traceout);
+ Tflushtrace();
+ }
+}
+
+#define P_READ(x) (P_read(&(x), sizeof((x)), #x))
+
+static unsigned P_fdf(int fd) {
+ assert(fd>=0 && fd<fdtab.used);
+ return fdtab.buf[fd];
+}
+
+void T_gettimeofday_hook(void) {
+ struct timeval delta, sum;
+ P_READ(delta);
+ timeradd(&delta, ¤ttime, &sum);
+ sum.tv_usec %= 1000000;
+ currenttime= sum;
+}
+
+static void Paddr(struct sockaddr *addr, int *lenr) {
+ int al, r;
+ uint16_t port;
+ char buf[512];
+ socklen_t sl = *lenr;
+
+ P_READ(al);
+ if (al<0 || al>=sizeof(buf)-1) Pformat("bad addr len");
+ P_read(buf,al,"addrtext");
+ buf[al]= 0;
+ P_READ(port);
+ r= adns_text2addr(buf,port, adns_qf_addrlit_scope_numeric, addr, &sl);
+ if (r==EINVAL) Pformat("bad addr text");
+ assert(r==0 || r==ENOSPC);
+ *lenr = sl;
+}
+
+static int Pbytes(byte *buf, int maxlen) {
+ int bl;
+ P_READ(bl);
+ if (bl<0 || bl>maxlen) Pformat("bad byte block len");
+ P_read(buf, bl, "bytes");
+ return bl;
+}
+
+static void Pfdset(fd_set *set, int max, int *r_io) {
+ uint16_t fdmap;
+ int fd, nfdmap=0;
+
+ if (!set)
+ return;
+
+ for (fd=max-1; fd>=0; fd--) {
+ if (nfdmap==0) {
+ P_READ(fdmap);
+ nfdmap= 16;
+ }
+ _Bool y = fdmap & 1u;
+ fdmap >>= 1;
+ nfdmap--;
+
+ if (!FD_ISSET(fd,set)) continue;
+
+ P_fdf(fd);
+
+ if (y) {
+ (*r_io)++;
+ } else {
+ FD_CLR(fd,set);
+ }
+ }
+}
+
+#ifdef FUZZRAW_SYNC
+static void Psync(const char *exp, char *got, size_t sz, const char *what) {
+ P_read(got,sz,"syscall");
+ if (memcmp(exp,got,sz)) Pformat(what);
+}
+#endif
+m4_define(`syscall_sync',`
+#ifdef FUZZRAW_SYNC
+ hm_fr_syscall_ident($'`1)
+ static char sync_got[sizeof(sync_expect)];
+ Psync(sync_expect, sync_got, sizeof(sync_got), "sync lost: program did $1");
+#endif
+')
+
+#ifdef HAVE_POLL
+static void Ppollfds(struct pollfd *fds, int nfds, int *r_io) {
+ int fd;
+ for (fd=0; fd<nfds; fd++) {
+ if (!fds[fd].events) continue;
+ P_fdf(fd);
+ P_READ(fds[fd].revents);
+ if (fds[fd].revents)
+ (*r_io)++;
+ }
+}
+#endif
+
+static int P_succfail(void) {
+ int e;
+ P_READ(e);
+ if (e>0) {
+ errno= e;
+ return -1;
+ } else if (e) {
+ Pformat("wrong errno value");
+ }
+ return 0;
+}
+
+m4_define(`hm_syscall', `
+ hm_create_proto_h
+int H$1(hm_args_massage($3,void)) {
+ int r;
+ hm_create_nothing
+ $2
+
+ hm_create_hqcall_vars
+ $3
+
+ hm_create_hqcall_init($1)
+ $3
+
+ Tensuresetup();
+
+ if (traceprint) {
+ hm_create_hqcall_args
+ Q$1(hm_args_massage($3));
+ }
+
+ syscall_sync($'`1)
+
+ m4_define(`hm_rv_succfail',`
+ r= P_succfail();
+ if (r<0) return r;
+ ')
+
+ m4_define(`hm_rv_any',`
+ hm_rv_succfail
+ if (!r) {
+ P_READ(r);
+ if (r<0) Pformat("negative nonerror syscall return");
+ }
+ ')
+ m4_define(`hm_rv_len',`
+ hm_rv_succfail
+ ')
+ m4_define(`hm_rv_must',`
+ r= 0;
+ ')
+ m4_define(`hm_rv_select',`hm_rv_succfail')
+ m4_define(`hm_rv_poll',`hm_rv_succfail')
+ m4_define(`hm_rv_fcntl',`
+ unsigned flg = P_fdf(fd);
+ if (cmd == F_GETFL) {
+ r= (flg & FDF_NONBLOCK) ? O_NONBLOCK : 0;
+ } else if (cmd == F_SETFL) {
+ flg &= ~FDF_NONBLOCK;
+ if (arg & O_NONBLOCK)
+ flg |= FDF_NONBLOCK;
+ fdtab.buf[fd]= flg;
+ r= 0;
+ } else {
+ abort();
+ }
+ ')
+ m4_define(`hm_rv_fd',`
+ hm_rv_succfail
+ if (!r) {
+ int newfd;
+ P_READ(newfd);
+ if (newfd<0 || newfd>1000) Pformat("new fd out of range");
+ adns__vbuf_ensure(&fdtab, newfd+1);
+ if (fdtab.used <= newfd) {
+ memset(fdtab.buf+fdtab.used, 0, newfd+1-fdtab.used);
+ fdtab.used= newfd+1;
+ }
+ if (fdtab.buf[newfd]) Pformat("new fd already in use");
+ fdtab.buf[newfd] |= FDF_OPEN;
+ r= newfd;
+ }
+ ')
+ m4_define(`hm_rv_wlen',`
+ hm_rv_any
+ if (r>$'`1) Pformat("write return value too large");
+ ')
+ $2
+
+ hm_create_nothing
+ m4_define(`hm_arg_fdset_io',`Pfdset($'`1,$'`2,&r);')
+ m4_define(`hm_arg_pollfds_io',`Ppollfds($'`1,$'`2,&r);')
+ m4_define(`hm_arg_addr_out',`Paddr($'`1,$'`2);')
+ $3
+
+ hm_create_nothing
+ m4_define(`hm_arg_bytes_out',`r= Pbytes($'`2,$'`4);')
+ $3
+
+ hm_create_nothing
+ m4_define(`hm_rv_selectpoll',`
+ if (($'`1) && !r) Pformat("select/poll returning 0 but infinite timeout");
+ ')
+ m4_define(`hm_rv_select',`hm_rv_selectpoll(!to)')
+ m4_define(`hm_rv_poll',`hm_rv_selectpoll(timeout<0)')
+ $2
+
+ return r;
+}
+')
+
+m4_define(`hm_specsyscall', `')
+
+m4_include(`hsyscalls.i4')
+
+int Hclose(int fd) {
+ syscall_sync(close)
+ P_fdf(fd);
+ fdtab.buf[fd]= 0;
+ return P_succfail();
+}
m4_dnl (part of complex test harness, not of the library)
m4_dnl - common macros
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
m4_define(`hm_arg_bytes_in', `')
m4_define(`hm_arg_bytes_out', `')
m4_define(`hm_arg_addr_out', `')
+ m4_define(`hm_rv_must', `')
+ m4_define(`hm_rv_any', `')
+ m4_define(`hm_rv_fd', `')
+ m4_define(`hm_rv_succfail', `')
+ m4_define(`hm_rv_len', `')
+ m4_define(`hm_rv_wlen', `hm_rv_any')
+ m4_define(`hm_rv_fcntl', `')
+ m4_define(`hm_rv_select', `hm_rv_any')
+ m4_define(`hm_rv_poll', `hm_rv_any')
')
m4_define(`hm_create_proto_h',`
m4_define(`hm_arg_fcntl_cmd_arg',`
Tmust("$1","$'`1",$'`1==F_SETFL || $'`1==F_GETFL);
if ($'`1 == F_SETFL) {
- va_start(al,$'`1); $'`2= va_arg(al,long); va_end(al);
+ va_start(al,$'`1); $'`2= va_arg(al,int); va_end(al);
} else {
$'`2= 0;
}')
m4_define(`hm_arg_bytes_out', `$'`4')
m4_define(`hm_arg_addr_out', `*$'`2')
')
+
+m4_define(`hm_fr_syscall_ident',`
+ static const char sync_expect[sizeof("$1")]= "$1\xee";
+')
--- /dev/null
+/* nhonfuzz.c
+ * (part of complex test harness, not of the library)
+ * - routines used for record and playback but not for fuzzing
+ *
+ * This file is part of adns, which is
+ * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
+ * Copyright (C) 2014 Mark Wooding
+ * Copyright (C) 1999-2000,2003,2006 Tony Finch
+ * Copyright (C) 1991 Massachusetts Institute of Technology
+ * (See the file INSTALL for full details.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation.
+ */
+
+#include <stdio.h>
+
+#include "harness.h"
+
+extern int Hmain(int argc, char **argv);
+int main(int argc, char **argv) { return Hmain(argc, argv); }
+
+FILE *Hfopen(const char *path, const char *mode) { return fopen(path,mode); }
+
+void Texit(int rv) {
+ Tcommonshutdown();
+ exit(rv);
+}
+
+int Ttestinputfd(void) {
+ const char *fdstr= getenv("ADNS_TEST_IN_FD");
+ if (!fdstr) return -1;
+ return atoi(fdstr);
+}
+
+struct malloced {
+ struct malloced *next, *back;
+ size_t sz;
+ unsigned long count;
+ struct { double d; long ul; void *p; void (*fp)(void); } data;
+};
+
+static unsigned long malloccount, mallocfailat;
+static struct { struct malloced *head, *tail; } mallocedlist;
+
+#define MALLOCHSZ ((char*)&mallocedlist.head->data - (char*)mallocedlist.head)
+
+void *Hmalloc(size_t sz) {
+ struct malloced *newnode;
+ const char *mfavar;
+ char *ep;
+
+ assert(sz);
+
+ newnode= malloc(MALLOCHSZ + sz); if (!newnode) Tnomem();
+
+ LIST_LINK_TAIL(mallocedlist,newnode);
+ newnode->sz= sz;
+ newnode->count= ++malloccount;
+ if (!mallocfailat) {
+ mfavar= getenv("ADNS_REGRESS_MALLOCFAILAT");
+ if (mfavar) {
+ mallocfailat= strtoul(mfavar,&ep,10);
+ if (!mallocfailat || *ep) Tfailed("ADNS_REGRESS_MALLOCFAILAT bad value");
+ } else {
+ mallocfailat= ~0UL;
+ }
+ }
+ assert(newnode->count != mallocfailat);
+ memset(&newnode->data,0xc7,sz);
+ return &newnode->data;
+}
+
+void Hfree(void *ptr) {
+ struct malloced *oldnode;
+
+ if (!ptr) return;
+
+ oldnode= (void*)((char*)ptr - MALLOCHSZ);
+ LIST_UNLINK(mallocedlist,oldnode);
+ memset(&oldnode->data,0x38,oldnode->sz);
+ free(oldnode);
+}
+
+void *Hrealloc(void *op, size_t nsz) {
+ struct malloced *oldnode;
+ void *np;
+ size_t osz;
+
+ if (op) { oldnode= (void*)((char*)op - MALLOCHSZ); osz= oldnode->sz; } else { osz= 0; }
+ np= Hmalloc(nsz);
+ if (osz) memcpy(np,op, osz>nsz ? nsz : osz);
+ Hfree(op);
+ return np;
+}
+
+void Tmallocshutdown(void) {
+ struct malloced *loopnode;
+ if (mallocedlist.head) {
+ fprintf(stderr,"adns test harness: memory leaked:");
+ for (loopnode=mallocedlist.head; loopnode; loopnode=loopnode->next)
+ fprintf(stderr," %lu",loopnode->count);
+ putc('\n',stderr);
+ if (ferror(stderr)) exit(-1);
+ }
+}
+++ /dev/null
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include "harness.h"
-static FILE *Tinputfile, *Treportfile;
-static vbuf vb2;
-extern void Tshutdown(void) {
- adns__vbuf_free(&vb2);
-}
-static void Tensurereportfile(void) {
- const char *fdstr;
- int fd;
- if (Treportfile) return;
- Treportfile= stderr;
- fdstr= getenv("ADNS_TEST_REPORT_FD"); if (!fdstr) return;
- fd= atoi(fdstr);
- Treportfile= fdopen(fd,"a"); if (!Treportfile) Tfailed("fdopen ADNS_TEST_REPORT_FD");
-}
-static void Psyntax(const char *where) {
- fprintf(stderr,"adns test harness: syntax error in test log input file: %s\n",where);
- exit(-1);
-}
-static void Pcheckinput(void) {
- if (ferror(Tinputfile)) Tfailed("read test log input file");
- if (feof(Tinputfile)) Psyntax("eof at syscall reply");
-}
-void Tensurerecordfile(void) {
- const char *fdstr;
- int fd;
- int chars;
- unsigned long sec, usec;
- if (Tinputfile) return;
- Tinputfile= stdin;
- fdstr= getenv("ADNS_TEST_IN_FD");
- if (fdstr) {
- fd= atoi(fdstr);
- Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD");
- }
- setvbuf(Tinputfile,0,_IONBF,0);
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- chars= -1;
- sscanf(vb2.buf," start %lu.%lu%n",&sec,&usec,&chars);
- if (chars==-1) Psyntax("start time invalid");
- currenttime.tv_sec= sec;
- currenttime.tv_usec= usec;
- if (vb2.buf[chars] != '\n') Psyntax("not newline after start time");
-}
-static void Parg(const char *argname) {
- int l;
- if (vb2.buf[vb2.used++] != ' ') Psyntax("not a space before argument");
- l= strlen(argname);
- if (memcmp(vb2.buf+vb2.used,argname,l)) Psyntax("argument name wrong");
- vb2.used+= l;
- if (vb2.buf[vb2.used++] != '=') Psyntax("not = after argument name");
-}
-static int Pstring_maybe(const char *string) {
- int l;
- l= strlen(string);
- if (memcmp(vb2.buf+vb2.used,string,l)) return 0;
- vb2.used+= l;
- return 1;
-}
-static void Pstring(const char *string, const char *emsg) {
- if (Pstring_maybe(string)) return;
- Psyntax(emsg);
-}
-static int Perrno(const char *stuff) {
- const struct Terrno *te;
- int r;
- char *ep;
- for (te= Terrnos; te->n && strcmp(te->n,stuff); te++);
- if (te->n) return te->v;
- r= strtoul(stuff+2,&ep,10);
- if (*ep) Psyntax("errno value not recognised, not numeric");
- return r;
-}
-static void P_updatetime(void) {
- int chars;
- unsigned long sec, usec;
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- chars= -1;
- sscanf(vb2.buf," +%lu.%lu%n",&sec,&usec,&chars);
- if (chars==-1) Psyntax("update time invalid");
- currenttime.tv_sec+= sec;
- currenttime.tv_usec+= usec;
- if (currenttime.tv_usec > 1000000) {
- currenttime.tv_sec++;
- currenttime.tv_usec -= 1000000;
- }
- if (vb2.buf[chars] != '\n') Psyntax("not newline after update time");
-}
-static void Pfdset(fd_set *set, int max) {
- int r, c;
- char *ep;
- if (!set) {
- Pstring("null","null fdset pointer");
- return;
- }
- if (vb2.buf[vb2.used++] != '[') Psyntax("fd set start not [");
- FD_ZERO(set);
- if (vb2.buf[vb2.used] == ']') { vb2.used++; return; }
- for (;;) {
- r= strtoul(vb2.buf+vb2.used,&ep,10);
- if (r>=max) Psyntax("fd set member > max");
- if (ep == (char*)vb2.buf+vb2.used) Psyntax("empty entry in fd set");
- FD_SET(r,set);
- vb2.used= ep - (char*)vb2.buf;
- c= vb2.buf[vb2.used++];
- if (c == ']') break;
- if (c != ',') Psyntax("fd set separator not ,");
- }
-}
-#ifdef HAVE_POLL
-static int Ppollfdevents(void) {
- int events;
- if (Pstring_maybe("0")) return 0;
- events= 0;
- if (Pstring_maybe("POLLIN")) {
- events |= POLLIN;
- if (!Pstring_maybe("|")) return events;
- }
- if (Pstring_maybe("POLLOUT")) {
- events |= POLLOUT;
- if (!Pstring_maybe("|")) return events;
- }
- Pstring("POLLPRI","pollfdevents PRI?");
- return events;
-}
-static void Ppollfds(struct pollfd *fds, int nfds) {
- int i;
- char *ep;
- const char *comma= "";
- if (vb2.buf[vb2.used++] != '[') Psyntax("pollfds start not [");
- for (i=0; i<nfds; i++) {
- Pstring("{fd=","{fd= in pollfds");
- fds->fd= strtoul(vb2.buf+vb2.used,&ep,10);
- vb2.used= ep - (char*)vb2.buf;
- Pstring(", events=",", events= in pollfds");
- fds->events= Ppollfdevents();
- Pstring(", revents=",", revents= in pollfds");
- fds->revents= Ppollfdevents();
- Pstring("}","} in pollfds");
- Pstring(comma,"separator in pollfds");
- comma= ", ";
- }
- if (vb2.buf[vb2.used++] != ']') Psyntax("pollfds end not ]");
-}
-#endif
-static void Paddr(struct sockaddr *addr, int *lenr) {
- adns_rr_addr a;
- char *p, *q, *ep;
- int err;
- unsigned long ul;
- p= vb2.buf+vb2.used;
- if (*p!='[') {
- q= strchr(p,':');
- if (!q) Psyntax("missing :");
- *q++= 0;
- } else {
- p++;
- q= strchr(p,']');
- if (!q) Psyntax("missing ]");
- *q++= 0;
- if (*q!=':') Psyntax("expected : after ]");
- q++;
- }
- ul= strtoul(q,&ep,10);
- if (*ep && *ep != ' ') Psyntax("invalid port (bad syntax)");
- if (ul >= 65536) Psyntax("port too large");
- a.len= sizeof(a.addr);
- err= adns_text2addr(p, (int)ul, 0, &a.addr.sa,&a.len);
- if (err) Psyntax("invalid address");
- assert(*lenr >= a.len);
- memcpy(addr, &a.addr, a.len);
- *lenr= a.len;
- vb2.used= ep - (char*)vb2.buf;
-}
-static int Pbytes(byte *buf, int maxlen) {
- static const char hexdigits[]= "0123456789abcdef";
- int c, v, done;
- const char *pf;
- done= 0;
- for (;;) {
- c= getc(Tinputfile); Pcheckinput();
- if (c=='\n' || c==' ' || c=='\t') continue;
- if (c=='.') break;
- pf= strchr(hexdigits,c); if (!pf) Psyntax("invalid first hex digit");
- v= (pf-hexdigits)<<4;
- c= getc(Tinputfile); Pcheckinput();
- pf= strchr(hexdigits,c); if (!pf) Psyntax("invalid second hex digit");
- v |= (pf-hexdigits);
- if (maxlen<=0) Psyntax("buffer overflow in bytes");
- *buf++= v;
- maxlen--; done++;
- }
- for (;;) {
- c= getc(Tinputfile); Pcheckinput();
- if (c=='\n') return done;
- }
-}
-void Q_vb(void) {
- const char *nl;
- Tensurerecordfile();
- if (!adns__vbuf_ensure(&vb2,vb.used+2)) Tnomem();
- fread(vb2.buf,1,vb.used+2,Tinputfile);
- if (feof(Tinputfile)) {
- fprintf(stderr,"adns test harness: input ends prematurely; program did:\n %.*s\n",
- vb.used,vb.buf);
- exit(-1);
- }
- Pcheckinput();
- if (vb2.buf[0] != ' ') Psyntax("not space before call");
- if (memcmp(vb.buf,vb2.buf+1,vb.used) ||
- vb2.buf[vb.used+1] != '\n') {
- fprintf(stderr,
- "adns test harness: program did unexpected:\n %.*s\n"
- "was expecting:\n %.*s\n",
- vb.used,vb.buf, vb.used,vb2.buf+1);
- exit(1);
- }
- Tensurereportfile();
- nl= memchr(vb.buf,'\n',vb.used);
- fprintf(Treportfile," %.*s\n", (int)(nl ? nl - (const char*)vb.buf : vb.used), vb.buf);
-}
-int Hselect( int max , fd_set *rfds , fd_set *wfds , fd_set *efds , struct timeval *to ) {
- int r, amtread;
- char *ep;
- Qselect( max , rfds , wfds , efds , to );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," select=",8)) Psyntax("syscall reply mismatch");
- if (vb2.buf[8] == 'E') {
- int e;
- e= Perrno(vb2.buf+8);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= strtoul(vb2.buf+8,&ep,10);
- if (*ep && *ep!=' ') Psyntax("return value not E* or positive number");
- vb2.used= ep - (char*)vb2.buf;
- Parg("rfds"); Pfdset(rfds,max);
- Parg("wfds"); Pfdset(wfds,max);
- Parg("efds"); Pfdset(efds,max);
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-#ifdef HAVE_POLL
-int Hpoll( struct pollfd *fds , int nfds , int timeout ) {
- int r, amtread;
- char *ep;
- Qpoll( fds , nfds , timeout );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," poll=",6)) Psyntax("syscall reply mismatch");
- if (vb2.buf[6] == 'E') {
- int e;
- e= Perrno(vb2.buf+6);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= strtoul(vb2.buf+6,&ep,10);
- if (*ep && *ep!=' ') Psyntax("return value not E* or positive number");
- vb2.used= ep - (char*)vb2.buf;
- Parg("fds"); Ppollfds(fds,nfds);
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-#endif
-int Hsocket( int domain , int type , int protocol ) {
- int r, amtread;
- char *ep;
- Tmust("socket","domain",domain==AF_INET || domain==AF_INET6);
- Tmust("socket","type",type==SOCK_STREAM || type==SOCK_DGRAM);
- Qsocket( domain , type );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," socket=",8)) Psyntax("syscall reply mismatch");
- if (vb2.buf[8] == 'E') {
- int e;
- e= Perrno(vb2.buf+8);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= strtoul(vb2.buf+8,&ep,10);
- if (*ep && *ep!=' ') Psyntax("return value not E* or positive number");
- vb2.used= ep - (char*)vb2.buf;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hfcntl( int fd , int cmd , ... ) {
- int r, amtread;
- va_list al; long arg;
- Tmust("fcntl","cmd",cmd==F_SETFL || cmd==F_GETFL);
- if (cmd == F_SETFL) {
- va_start(al,cmd); arg= va_arg(al,long); va_end(al);
- } else {
- arg= 0;
- }
- Qfcntl( fd , cmd , arg );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," fcntl=",7)) Psyntax("syscall reply mismatch");
- if (vb2.buf[7] == 'E') {
- int e;
- e= Perrno(vb2.buf+7);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= 0;
- if (cmd == F_GETFL) {
- if (!memcmp(vb2.buf+7,"O_NONBLOCK|...",14)) {
- r= O_NONBLOCK;
- vb2.used= 7+14;
- } else if (!memcmp(vb2.buf+7,"~O_NONBLOCK&...",15)) {
- vb2.used= 7+15;
- } else {
- Psyntax("fcntl flags not O_NONBLOCK|... or ~O_NONBLOCK&...");
- }
- } else if (cmd == F_SETFL) {
- if (memcmp(vb2.buf+7,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 7+2;
- r= 0;
- } else {
- Psyntax("fcntl not F_GETFL or F_SETFL");
- }
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hconnect( int fd , const struct sockaddr *addr , int addrlen ) {
- int r, amtread;
- Qconnect( fd , addr , addrlen );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," connect=",9)) Psyntax("syscall reply mismatch");
- if (vb2.buf[9] == 'E') {
- int e;
- e= Perrno(vb2.buf+9);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+9,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 9+2;
- r= 0;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hbind( int fd , const struct sockaddr *addr , int addrlen ) {
- int r, amtread;
- Qbind( fd , addr , addrlen );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," bind=",6)) Psyntax("syscall reply mismatch");
- if (vb2.buf[6] == 'E') {
- int e;
- e= Perrno(vb2.buf+6);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+6,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 6+2;
- r= 0;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hlisten( int fd , int backlog ) {
- int r, amtread;
- Qlisten( fd , backlog );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," listen=",8)) Psyntax("syscall reply mismatch");
- if (vb2.buf[8] == 'E') {
- int e;
- e= Perrno(vb2.buf+8);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+8,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 8+2;
- r= 0;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hclose( int fd ) {
- int r, amtread;
- Qclose( fd );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," close=",7)) Psyntax("syscall reply mismatch");
- if (vb2.buf[7] == 'E') {
- int e;
- e= Perrno(vb2.buf+7);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+7,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 7+2;
- r= 0;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hsendto( int fd , const void *msg , int msglen , unsigned int flags , const struct sockaddr *addr , int addrlen ) {
- int r, amtread;
- char *ep;
- Tmust("sendto","flags",flags==0);
- Qsendto( fd , msg , msglen , addr , addrlen );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," sendto=",8)) Psyntax("syscall reply mismatch");
- if (vb2.buf[8] == 'E') {
- int e;
- e= Perrno(vb2.buf+8);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= strtoul(vb2.buf+8,&ep,10);
- if (*ep && *ep!=' ') Psyntax("return value not E* or positive number");
- vb2.used= ep - (char*)vb2.buf;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
-int Hrecvfrom( int fd , void *buf , int buflen , unsigned int flags , struct sockaddr *addr , int *addrlen ) {
- int r, amtread;
- Tmust("recvfrom","flags",flags==0);
- Tmust("recvfrom","*addrlen",*addrlen>=sizeof(struct sockaddr_in));
- Qrecvfrom( fd , buflen , *addrlen );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," recvfrom=",10)) Psyntax("syscall reply mismatch");
- if (vb2.buf[10] == 'E') {
- int e;
- e= Perrno(vb2.buf+10);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+10,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 10+2;
- r= 0;
- Parg("addr"); Paddr(addr,addrlen);
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- r= Pbytes(buf,buflen);
- P_updatetime();
- return r;
-}
-int Hread( int fd , void *buf , size_t buflen ) {
- int r, amtread;
- Qread( fd , buflen );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," read=",6)) Psyntax("syscall reply mismatch");
- if (vb2.buf[6] == 'E') {
- int e;
- e= Perrno(vb2.buf+6);
- P_updatetime();
- errno= e;
- return -1;
- }
- if (memcmp(vb2.buf+6,"OK",2)) Psyntax("success/fail not E* or OK");
- vb2.used= 6+2;
- r= 0;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- r= Pbytes(buf,buflen);
- P_updatetime();
- return r;
-}
-int Hwrite( int fd , const void *buf , size_t len ) {
- int r, amtread;
- char *ep;
- Qwrite( fd , buf , len );
- if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
- fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
- fprintf(Treportfile,"%s",vb2.buf);
- amtread= strlen(vb2.buf);
- if (amtread<=0 || vb2.buf[--amtread]!='\n')
- Psyntax("badly formed line");
- vb2.buf[amtread]= 0;
- if (memcmp(vb2.buf," write=",7)) Psyntax("syscall reply mismatch");
- if (vb2.buf[7] == 'E') {
- int e;
- e= Perrno(vb2.buf+7);
- P_updatetime();
- errno= e;
- return -1;
- }
- r= strtoul(vb2.buf+7,&ep,10);
- if (*ep && *ep!=' ') Psyntax("return value not E* or positive number");
- vb2.used= ep - (char*)vb2.buf;
- assert(vb2.used <= amtread);
- if (vb2.used != amtread) Psyntax("junk at end of line");
- P_updatetime();
- return r;
-}
m4_dnl (part of complex test harness, not of the library)
m4_dnl - playback routines
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
#include <unistd.h>
#include <fcntl.h>
+#include <limits.h>
+
#include "harness.h"
-static FILE *Tinputfile, *Treportfile;
+static FILE *Tinputfile, *Tfuzzrawfile, *Treportfile;
static vbuf vb2;
-extern void Tshutdown(void) {
- adns__vbuf_free(&vb2);
-}
-
-static void Tensurereportfile(void) {
+static void Tensure_reportfile(void) {
const char *fdstr;
int fd;
Treportfile= fdopen(fd,"a"); if (!Treportfile) Tfailed("fdopen ADNS_TEST_REPORT_FD");
}
+static void Tensure_fuzzrawfile(void) {
+ static int done;
+
+ if (done) return;
+ done++;
+
+ const char *fdstr= getenv("ADNS_TEST_FUZZRAW_DUMP_FD");
+ if (!fdstr) return;
+
+ int fd= atoi(fdstr);
+ Tfuzzrawfile= fdopen(fd,"ab");
+ if (!Tfuzzrawfile) Tfailed("fdopen ADNS_TEST_FUZZRAW_DUMP_FD");
+}
+
+static void FR_write(const void *p, size_t sz) {
+ if (!Tfuzzrawfile) return;
+ ssize_t got = fwrite(p,1,sz,Tfuzzrawfile);
+ if (ferror(Tfuzzrawfile)) Tfailed("write fuzzraw output file");
+ assert(got==sz);
+}
+
+#define FR_WRITE(x) (FR_write(&(x), sizeof((x))))
+
+extern void Tshutdown(void) {
+ adns__vbuf_free(&vb2);
+ if (Tfuzzrawfile) {
+ if (fclose(Tfuzzrawfile)) Tfailed("close fuzzraw output file");
+ }
+}
+
static void Psyntax(const char *where) {
fprintf(stderr,"adns test harness: syntax error in test log input file: %s\n",where);
exit(-1);
if (feof(Tinputfile)) Psyntax("eof at syscall reply");
}
-void Tensurerecordfile(void) {
- const char *fdstr;
+void T_gettimeofday_hook(void) {
+ static struct timeval previously;
+ struct timeval delta;
+ memset(&delta,0,sizeof(delta));
+ timersub(¤ttime, &previously, &delta);
+ previously = currenttime;
+ FR_WRITE(delta);
+}
+
+void Tensuresetup(void) {
int fd;
int chars;
unsigned long sec, usec;
+ Tensure_reportfile();
+ Tensure_fuzzrawfile();
+
if (Tinputfile) return;
Tinputfile= stdin;
- fdstr= getenv("ADNS_TEST_IN_FD");
- if (fdstr) {
- fd= atoi(fdstr);
+ fd = Ttestinputfd();
+ if (fd >= 0) {
Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD");
}
setvbuf(Tinputfile,0,_IONBF,0);
if (te->n) return te->v;
r= strtoul(stuff+2,&ep,10);
if (*ep) Psyntax("errno value not recognised, not numeric");
+ if (r==0 || r>255) Psyntax("numeric errno out of range 1..255");
return r;
}
static void P_updatetime(void) {
int chars;
- unsigned long sec, usec;
+ unsigned long sec;
+ long usec;
if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
chars= -1;
- sscanf(vb2.buf," +%lu.%lu%n",&sec,&usec,&chars);
+ sscanf(vb2.buf," +%lu.%ld%n",&sec,&usec,&chars);
if (chars==-1) Psyntax("update time invalid");
currenttime.tv_sec+= sec;
- currenttime.tv_usec+= usec;
- if (currenttime.tv_usec > 1000000) {
+ usec = (long)currenttime.tv_usec + usec;
+ while (usec < 0) {
+ currenttime.tv_sec--;
+ usec += 1000000;
+ }
+ while (usec > 1000000) {
currenttime.tv_sec++;
- currenttime.tv_usec -= 1000000;
+ usec -= 1000000;
}
+ currenttime.tv_usec = usec;
if (vb2.buf[chars] != hm_squote\nhm_squote) Psyntax("not newline after update time");
}
static void Pfdset(fd_set *set, int max) {
- int r, c;
+ int c;
+ unsigned long ul;
char *ep;
if (!set) {
if (vb2.buf[vb2.used++] != hm_squote[hm_squote) Psyntax("fd set start not [");
FD_ZERO(set);
- if (vb2.buf[vb2.used] == hm_squote]hm_squote) { vb2.used++; return; }
- for (;;) {
- r= strtoul(vb2.buf+vb2.used,&ep,10);
- if (r>=max) Psyntax("fd set member > max");
- if (ep == (char*)vb2.buf+vb2.used) Psyntax("empty entry in fd set");
- FD_SET(r,set);
- vb2.used= ep - (char*)vb2.buf;
- c= vb2.buf[vb2.used++];
- if (c == hm_squote]hm_squote) break;
- if (c != hm_squote,hm_squote) Psyntax("fd set separator not ,");
+ if (vb2.buf[vb2.used] == hm_squote]hm_squote) {
+ vb2.used++;
+ } else {
+ for (;;) {
+ ul= strtoul(vb2.buf+vb2.used,&ep,10);
+ if (ul>=max) Psyntax("fd set member > max");
+ if (ep == (char*)vb2.buf+vb2.used) Psyntax("empty entry in fd set");
+ FD_SET(ul,set);
+ vb2.used= ep - (char*)vb2.buf;
+ c= vb2.buf[vb2.used++];
+ if (c == hm_squote]hm_squote) break;
+ if (c != hm_squote,hm_squote) Psyntax("fd set separator not ,");
+ }
+ }
+
+ uint16_t accum;
+ int inaccum=0, fd;
+ for (fd=0; ; fd++) {
+ if (fd>=max || inaccum==16) {
+ FR_WRITE(accum);
+ inaccum= 0;
+ }
+ if (fd>=max)
+ break;
+ accum <<= 1;
+ accum |= !!FD_ISSET(fd,set);
+ inaccum++;
}
}
if (vb2.buf[vb2.used++] != hm_squote[hm_squote) Psyntax("pollfds start not [");
for (i=0; i<nfds; i++) {
Pstring("{fd=","{fd= in pollfds");
- fds->fd= strtoul(vb2.buf+vb2.used,&ep,10);
+ int gotfd= strtoul(vb2.buf+vb2.used,&ep,10);
+ if (gotfd != fds->fd) Psyntax("poll fds[].fd changed");
vb2.used= ep - (char*)vb2.buf;
Pstring(", events=",", events= in pollfds");
- fds->events= Ppollfdevents();
+ int gotevents= Ppollfdevents();
+ if (gotevents != fds->events) Psyntax("poll fds[].events changed");
Pstring(", revents=",", revents= in pollfds");
fds->revents= Ppollfdevents();
+ if (gotevents) FR_WRITE(fds->revents);
Pstring("}","} in pollfds");
Pstring(comma,"separator in pollfds");
comma= ", ";
if (*ep && *ep != ' ') Psyntax("invalid port (bad syntax)");
if (ul >= 65536) Psyntax("port too large");
+ if (Tfuzzrawfile) {
+ int tl = strlen(p);
+ FR_WRITE(tl);
+ FR_write(p,tl);
+ uint16_t port16 = ul;
+ FR_WRITE(port16);
+ }
+
a.len= sizeof(a.addr);
err= adns_text2addr(p, (int)ul, 0, &a.addr.sa,&a.len);
if (err) Psyntax("invalid address");
void Q_vb(void) {
const char *nl;
- Tensurerecordfile();
+ Tensuresetup();
if (!adns__vbuf_ensure(&vb2,vb.used+2)) Tnomem();
fread(vb2.buf,1,vb.used+2,Tinputfile);
if (feof(Tinputfile)) {
vb.used,vb.buf, vb.used,vb2.buf+1);
exit(1);
}
- Tensurereportfile();
nl= memchr(vb.buf,'\n',vb.used);
fprintf(Treportfile," %.*s\n", (int)(nl ? nl - (const char*)vb.buf : vb.used), vb.buf);
}
hm_create_proto_h
int H$1(hm_args_massage($3,void)) {
int r, amtread;
+ hm_create_nothing
m4_define(`hm_rv_fd',`char *ep;')
m4_define(`hm_rv_any',`char *ep;')
- m4_define(`hm_rv_len',`')
- m4_define(`hm_rv_must',`')
- m4_define(`hm_rv_succfail',`')
- m4_define(`hm_rv_fcntl',`')
$2
hm_create_hqcall_vars
if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
- Tensurereportfile();
+ Tensuresetup();
fprintf(Treportfile,"%s",vb2.buf);
amtread= strlen(vb2.buf);
if (amtread<=0 || vb2.buf[--amtread]!=hm_squote\nhm_squote)
vb2.buf[amtread]= 0;
if (memcmp(vb2.buf," $1=",hm_r_offset)) Psyntax("syscall reply mismatch");
+#ifdef FUZZRAW_SYNC
+ hm_fr_syscall_ident($1)
+ FR_WRITE(sync_expect);
+#endif
+
+ m4_define(`hm_rv_check_errno',`
if (vb2.buf[hm_r_offset] == hm_squoteEhm_squote) {
int e;
e= Perrno(vb2.buf+hm_r_offset);
P_updatetime();
errno= e;
+ FR_WRITE(e);
return -1;
}
-
- m4_define(`hm_rv_succfail',`
+ r= 0;
+ FR_WRITE(r);
+ ')
+ m4_define(`hm_rv_check_success',`
if (memcmp(vb2.buf+hm_r_offset,"OK",2)) Psyntax("success/fail not E* or OK");
vb2.used= hm_r_offset+2;
r= 0;
')
- m4_define(`hm_rv_len',`hm_rv_succfail')
- m4_define(`hm_rv_must',`hm_rv_succfail')
- m4_define(`hm_rv_any',`
- r= strtoul(vb2.buf+hm_r_offset,&ep,10);
- if (*ep && *ep!=hm_squote hm_squote) Psyntax("return value not E* or positive number");
+ m4_define(`hm_rv_any_nowrite',`
+ hm_rv_check_errno
+ unsigned long ul_r= strtoul(vb2.buf+hm_r_offset,&ep,10);
+ if (ul_r < 0 || ul_r > INT_MAX ||
+ (*ep && *ep!=hm_squote hm_squote))
+ Psyntax("return value not E* or positive number");
+ r= ul_r;
vb2.used= ep - (char*)vb2.buf;
')
+
+ m4_define(`hm_rv_succfail',`
+ hm_rv_check_errno
+ hm_rv_check_success
+ ')
+ m4_define(`hm_rv_len',`
+ hm_rv_check_errno
+ hm_rv_check_success
+ ')
+ m4_define(`hm_rv_must',`
+ hm_rv_check_success
+ ')
+ m4_define(`hm_rv_any',`
+ hm_rv_any_nowrite
+ FR_WRITE(r);
+ ')
m4_define(`hm_rv_fd',`hm_rv_any')
+ m4_define(`hm_rv_select',`hm_rv_any_nowrite')
+ m4_define(`hm_rv_poll',`hm_rv_any_nowrite')
m4_define(`hm_rv_fcntl',`
r= 0;
if (cmd == F_GETFL) {
Psyntax("fcntl flags not O_NONBLOCK|... or ~O_NONBLOCK&...");
}
} else if (cmd == F_SETFL) {
- hm_rv_succfail
+ hm_rv_check_success
} else {
Psyntax("fcntl not F_GETFL or F_SETFL");
}
if (vb2.used != amtread) Psyntax("junk at end of line");
hm_create_nothing
- m4_define(`hm_arg_bytes_out',`r= Pbytes($'`2,$'`4);')
+ m4_define(`hm_arg_bytes_out',`
+ r= Pbytes($'`2,$'`4);
+ FR_WRITE(r);
+ FR_write(buf,r);
+ ')
$3
P_updatetime();
m4_define(`hm_specsyscall', `')
m4_include(`hsyscalls.i4')
+
+hm_stdsyscall_close
+++ /dev/null
-#include <assert.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include "harness.h"
-static FILE *Toutputfile;
-void Tshutdown(void) {
-}
-static void R_recordtime(void) {
- int r;
- struct timeval tv, tvrel;
- Tensurerecordfile();
- r= gettimeofday(&tv,0); if (r) Tfailed("gettimeofday syscallbegin");
- tvrel.tv_sec= tv.tv_sec - currenttime.tv_sec;
- tvrel.tv_usec= tv.tv_usec - currenttime.tv_usec;
- if (tv.tv_usec < 0) { tvrel.tv_usec += 1000000; tvrel.tv_sec--; }
- Tvbf("\n +%ld.%06ld",(long)tvrel.tv_sec,(long)tvrel.tv_usec);
- currenttime= tv;
-}
-void Tensurerecordfile(void) {
- const char *fdstr;
- int fd, r;
- if (Toutputfile) return;
- Toutputfile= stdout;
- fdstr= getenv("ADNS_TEST_OUT_FD");
- if (fdstr) {
- fd= atoi(fdstr);
- Toutputfile= fdopen(fd,"a"); if (!Toutputfile) Tfailed("fdopen ADNS_TEST_OUT_FD");
- }
- r= gettimeofday(¤ttime,0); if (r) Tfailed("gettimeofday syscallbegin");
- if (fprintf(Toutputfile," start %ld.%06ld\n",
- (long)currenttime.tv_sec,(long)currenttime.tv_usec) == EOF) Toutputerr();
-}
-void Q_vb(void) {
- if (!adns__vbuf_append(&vb,"",1)) Tnomem();
- Tensurerecordfile();
- if (fprintf(Toutputfile," %s\n",vb.buf) == EOF) Toutputerr();
- if (fflush(Toutputfile)) Toutputerr();
-}
-static void R_vb(void) {
- Q_vb();
-}
-int Hselect( int max , fd_set *rfds , fd_set *wfds , fd_set *efds , struct timeval *to ) {
- int r, e;
- Qselect( max , rfds , wfds , efds , to );
- r= select( max , rfds , wfds , efds , to );
- e= errno;
- vb.used= 0;
- Tvba("select=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tvbf("%d",r);
- Tvba(" rfds="); Tvbfdset(max,rfds);
- Tvba(" wfds="); Tvbfdset(max,wfds);
- Tvba(" efds="); Tvbfdset(max,efds);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-#ifdef HAVE_POLL
-int Hpoll( struct pollfd *fds , int nfds , int timeout ) {
- int r, e;
- Qpoll( fds , nfds , timeout );
- r= poll( fds , nfds , timeout );
- e= errno;
- vb.used= 0;
- Tvba("poll=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tvbf("%d",r);
- Tvba(" fds="); Tvbpollfds(fds,nfds);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-#endif
-int Hsocket( int domain , int type , int protocol ) {
- int r, e;
- Tmust("socket","domain",domain==AF_INET || domain==AF_INET6);
- Tmust("socket","type",type==SOCK_STREAM || type==SOCK_DGRAM);
- Qsocket( domain , type );
- r= socket( domain , type , protocol );
- e= errno;
- vb.used= 0;
- Tvba("socket=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tvbf("%d",r);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hfcntl( int fd , int cmd , ... ) {
- int r, e;
- va_list al; long arg;
- Tmust("fcntl","cmd",cmd==F_SETFL || cmd==F_GETFL);
- if (cmd == F_SETFL) {
- va_start(al,cmd); arg= va_arg(al,long); va_end(al);
- } else {
- arg= 0;
- }
- Qfcntl( fd , cmd , arg );
- r= fcntl( fd , cmd , arg );
- e= errno;
- vb.used= 0;
- Tvba("fcntl=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- if (cmd == F_GETFL) {
- Tvbf(r & O_NONBLOCK ? "O_NONBLOCK|..." : "~O_NONBLOCK&...");
- } else {
- if (cmd == F_SETFL) {
- Tmust("fcntl","return",!r);
- } else {
- Tmust("cmd","F_GETFL/F_SETFL",0);
- }
- Tvba("OK");
- }
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hconnect( int fd , const struct sockaddr *addr , int addrlen ) {
- int r, e;
- Qconnect( fd , addr , addrlen );
- r= connect( fd , addr , addrlen );
- e= errno;
- vb.used= 0;
- Tvba("connect=");
- if (r) { Tvberrno(e); goto x_error; }
- Tvba("OK");
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hbind( int fd , const struct sockaddr *addr , int addrlen ) {
- int r, e;
- Qbind( fd , addr , addrlen );
- r= bind( fd , addr , addrlen );
- e= errno;
- vb.used= 0;
- Tvba("bind=");
- if (r) { Tvberrno(e); goto x_error; }
- Tvba("OK");
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hlisten( int fd , int backlog ) {
- int r, e;
- Qlisten( fd , backlog );
- r= listen( fd , backlog );
- e= errno;
- vb.used= 0;
- Tvba("listen=");
- if (r) { Tvberrno(e); goto x_error; }
- Tvba("OK");
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hclose( int fd ) {
- int r, e;
- Qclose( fd );
- r= close( fd );
- e= errno;
- vb.used= 0;
- Tvba("close=");
- if (r) { Tvberrno(e); goto x_error; }
- Tvba("OK");
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hsendto( int fd , const void *msg , int msglen , unsigned int flags , const struct sockaddr *addr , int addrlen ) {
- int r, e;
- Tmust("sendto","flags",flags==0);
- Qsendto( fd , msg , msglen , addr , addrlen );
- r= sendto( fd , msg , msglen , flags , addr , addrlen );
- e= errno;
- vb.used= 0;
- Tvba("sendto=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tvbf("%d",r);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hrecvfrom( int fd , void *buf , int buflen , unsigned int flags , struct sockaddr *addr , int *addrlen ) {
- int r, e;
- Tmust("recvfrom","flags",flags==0);
- Tmust("recvfrom","*addrlen",*addrlen>=sizeof(struct sockaddr_in));
- Qrecvfrom( fd , buflen , *addrlen );
- r= recvfrom( fd , buf , buflen , flags , addr , addrlen );
- e= errno;
- vb.used= 0;
- Tvba("recvfrom=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tmust("recvfrom","return",r<=buflen);
- Tvba("OK");
- Tvba(" addr="); Tvbaddr(addr,*addrlen);
- Tvbbytes(buf,r);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hread( int fd , void *buf , size_t buflen ) {
- int r, e;
- Qread( fd , buflen );
- r= read( fd , buf , buflen );
- e= errno;
- vb.used= 0;
- Tvba("read=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tmust("read","return",r<=buflen);
- Tvba("OK");
- Tvbbytes(buf,r);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
-int Hwrite( int fd , const void *buf , size_t len ) {
- int r, e;
- Qwrite( fd , buf , len );
- r= write( fd , buf , len );
- e= errno;
- vb.used= 0;
- Tvba("write=");
- if (r==-1) { Tvberrno(e); goto x_error; }
- Tvbf("%d",r);
- x_error:
- R_recordtime();
- R_vb();
- errno= e;
- return r;
-}
m4_dnl (part of complex test harness, not of the library)
m4_dnl - recording routines
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
int r;
struct timeval tv, tvrel;
- Tensurerecordfile();
+ Tensuresetup();
r= gettimeofday(&tv,0); if (r) Tfailed("gettimeofday syscallbegin");
tvrel.tv_sec= tv.tv_sec - currenttime.tv_sec;
tvrel.tv_usec= tv.tv_usec - currenttime.tv_usec;
currenttime= tv;
}
-void Tensurerecordfile(void) {
+void T_gettimeofday_hook(void) { }
+
+void Tensuresetup(void) {
const char *fdstr;
int fd, r;
void Q_vb(void) {
if (!adns__vbuf_append(&vb,"",1)) Tnomem();
- Tensurerecordfile();
+ Tensuresetup();
if (fprintf(Toutputfile," %s\n",vb.buf) == EOF) Toutputerr();
if (fflush(Toutputfile)) Toutputerr();
}
m4_define(`hm_rv_must',`Tmust("$1","return",!r); Tvba("OK");')
m4_define(`hm_rv_len',`
if (r==-1) { Tvberrno(e); goto x_error; }
- Tmust("$1","return",r<=$'`1);
+ Tmust("$'`1","return",r<=$'`1);
Tvba("OK");')
m4_define(`hm_rv_fcntl',`
if (r==-1) { Tvberrno(e); goto x_error; }
m4_define(`hm_arg_bytes_out',`Tvbbytes($'`2,r);')
$3
+ hm_create_nothing
m4_define(`hm_rv_any',`x_error:')
m4_define(`hm_rv_fd',`x_error:')
m4_define(`hm_rv_succfail',`x_error:')
m4_define(`hm_specsyscall', `')
m4_include(`hsyscalls.i4')
+
+hm_stdsyscall_close
+++ /dev/null
-#ifndef HREDIRECT_H_INCLUDED
-#define HREDIRECT_H_INCLUDED
-#include "hsyscalls.h"
-#undef select
-#define select Hselect
-#ifdef HAVE_POLL
-#undef poll
-#define poll Hpoll
-#endif
-#undef socket
-#define socket Hsocket
-#undef fcntl
-#define fcntl Hfcntl
-#undef connect
-#define connect Hconnect
-#undef bind
-#define bind Hbind
-#undef listen
-#define listen Hlisten
-#undef close
-#define close Hclose
-#undef sendto
-#define sendto Hsendto
-#undef recvfrom
-#define recvfrom Hrecvfrom
-#undef read
-#define read Hread
-#undef write
-#define write Hwrite
-#undef writev
-#define writev Hwritev
-#undef gettimeofday
-#define gettimeofday Hgettimeofday
-#undef getpid
-#define getpid Hgetpid
-#undef malloc
-#define malloc Hmalloc
-#undef free
-#define free Hfree
-#undef realloc
-#define realloc Hrealloc
-#undef exit
-#define exit Hexit
-#endif
m4_dnl (part of complex test harness, not of the library)
m4_dnl - redefinitions of system calls
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
#define $2 H$2')
m4_include(`hsyscalls.i4')
+m4_dnl only usage site is definition of main
+#define main(C, V) Hmain(C, V); int Hmain(C, V)
+
#endif
+++ /dev/null
-#ifndef HSYSCALLS_H_INCLUDED
-#define HSYSCALLS_H_INCLUDED
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-int Hselect( int max , fd_set *rfds , fd_set *wfds , fd_set *efds , struct timeval *to );
-#ifdef HAVE_POLL
-int Hpoll( struct pollfd *fds , int nfds , int timeout );
-#endif
-int Hsocket( int domain , int type , int protocol );
-int Hfcntl( int fd , int cmd , ... );
-int Hconnect( int fd , const struct sockaddr *addr , int addrlen );
-int Hbind( int fd , const struct sockaddr *addr , int addrlen );
-int Hlisten( int fd , int backlog );
-int Hclose( int fd );
-int Hsendto( int fd , const void *msg , int msglen , unsigned int flags , const struct sockaddr *addr , int addrlen );
-int Hrecvfrom( int fd , void *buf , int buflen , unsigned int flags , struct sockaddr *addr , int *addrlen );
-int Hread( int fd , void *buf , size_t buflen );
-int Hwrite( int fd , const void *buf , size_t len );
-int Hwritev(int fd, const struct iovec *vector, size_t count);
-int Hgettimeofday(struct timeval *tv, struct timezone *tz);
-pid_t Hgetpid(void);
-void* Hmalloc(size_t sz);
-void Hfree(void *ptr);
-void* Hrealloc(void *op, size_t nsz);
-void Hexit(int rv)NONRETURNING;
-#endif
m4_dnl (part of complex test harness, not of the library)
m4_dnl - prototypes of redefinitions of system calls
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
m4_dnl (part of complex test harness, not of the library)
m4_dnl - list of syscalls to override/log and their args
-m4_dnl This file is part of adns, which is
-m4_dnl Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-m4_dnl Copyright (C) 2014 Mark Wooding
-m4_dnl Copyright (C) 1999-2000,2003,2006 Tony Finch
-m4_dnl Copyright (C) 1991 Massachusetts Institute of Technology
-m4_dnl (See the file INSTALL for full details.)
+m4_dnl This file is part of adns, which is Copyright Ian Jackson
+m4_dnl and contributors (see the file INSTALL for full details).
m4_dnl
m4_dnl This program is free software; you can redistribute it and/or modify
m4_dnl it under the terms of the GNU General Public License as published by
m4_dnl hm_rv_any any nonnegative return allowed, -1 means see errno
m4_dnl hm_rv_fd file descriptor is returned, -1 means see errno
m4_dnl hm_rv_succfail returns 0 (ok) or -1 (see errno)
-m4_dnl hm_rv_len(<max>) returns length read/written, must be <=max, -1 => errno
+m4_dnl hm_rv_len(<max>) returns length read, must be <=max, -1 => errno
+m4_dnl hm_rv_wlen(<max>) returns length written, must be <=max, -1 => errno
m4_dnl hm_rv_fcntl syscall is fcntl, do special processing
+m4_dnl hm_rv_select select, do special processing } default is _any
+m4_dnl hm_rv_poll poll, do special processing } after create_nothing
m4_dnl <args> is list of macros for arguments, each followed by hm_na
m4_dnl hm_arg_nullptr(<type>,<arg>) pointer of type type, must be null
m4_dnl hm_arg_int(<arg>) signed integer
m4_dnl hm_arg_addr_out(<arg>,<lenptr>) struct sockaddr*, length io at <lenptr> (an int*)
hm_syscall(
- select, `hm_rv_any', `
+ select, `hm_rv_select', `
hm_arg_int(max) hm_na
hm_arg_fdset_io(rfds,max) hm_na
hm_arg_fdset_io(wfds,max) hm_na
#ifdef HAVE_POLL
hm_syscall(
- poll, `hm_rv_any', `
+ poll, `hm_rv_poll', `
hm_arg_pollfds_io(fds,nfds) hm_na
hm_arg_int(timeout) hm_na
')
')
hm_syscall(
- close, `hm_rv_succfail', `
- hm_arg_fd(fd) hm_na
-')
-
-hm_syscall(
- sendto, `hm_rv_any', `
+ sendto, `hm_rv_wlen(msglen)', `
hm_arg_fd(fd) hm_na
hm_arg_bytes_in(void,msg,int,msglen) hm_na
hm_arg_must(unsigned int,flags,0) hm_na
')
hm_syscall(
- write, `hm_rv_any', `
+ write, `hm_rv_wlen(len)', `
hm_arg_fd(fd) hm_na
hm_arg_bytes_in(void,buf,size_t,len) hm_na
')
hm_specsyscall(int, writev, `int fd, const struct iovec *vector, size_t count')
hm_specsyscall(int, gettimeofday, `struct timeval *tv, struct timezone *tz')
+hm_specsyscall(int, clock_gettime, `clockid_t clk, struct timespec *ts')
hm_specsyscall(pid_t, getpid, `void')
+hm_specsyscall(int, close, `int fd')
+
+m4_define(hm_stdsyscall_close,`
+hm_syscall(
+ close, `hm_rv_succfail', `
+ hm_arg_fd(fd) hm_na
+')
+')
hm_specsyscall(void*, malloc, `size_t sz')
hm_specsyscall(void, free, `void *ptr')
hm_specsyscall(void*, realloc, `void *op, size_t nsz')
hm_specsyscall(void, exit, `int rv', NONRETURNING)
+
+hm_specsyscall(FILE*, fopen, `const char *path, const char *mode')
# usage: m1test <name> <initfile> [<initflags>] <queryargs>'
# test recording script
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
initstring="`cat $srcdir/init-$initfile.text`"
xinitflagsf=$srcdir/$program-xinitflags.text
-if test -f $xinitflagsf
+if test -e $xinitflagsf
then
useinitflags="$initflags $(cat $xinitflagsf)";
else
--- /dev/null
+#!/bin/sh
+set -e
+
+: ${srcdir=.}
+. "$srcdir"/shlib
+
+casename="$1"
+
+playback_prepare
+
+ofuzz="fuzz-$casename"
+ofuzzraw="fuzzraw-$casename"
+
+rm -f "$ofuzz.tmp"
+rm -f "$ofuzzraw.tmp"
+exec >"$ofuzz.tmp"
+exec 6>"$ofuzzraw.tmp"
+
+fuzzout_complete () {
+ mv "$ofuzz.tmp" "$ofuzz"
+ mv "$ofuzzraw.tmp" "$ofuzzraw"
+ exit 0
+}
+
+if test ! -e $playback; then
+ echo 0
+ echo 0 >&6
+ fuzzout_complete
+fi
+
+dump_args () {
+ printf "%d\n" "$#"
+ for a in "$@"; do
+ printf "%d\n" "${#a}"
+ printf "%s\n" "$a"
+ done
+
+ if test -e "$case.in"
+ then
+ inputsz=$(stat -c'%s' -L "$case.in")
+ printf "%d\n" "$inputsz"
+ cat "$case.in"
+ else
+ echo 0
+ fi
+
+ echo
+}
+
+playback_execute_hook () {
+ dump_args "${program}_fuzz" "$@"
+ dump_args "${program}_fuzzraw" "$@" >&6
+ cat <&4 >"$ofuzz.sys.tmp"
+ exec 4<$ofuzz.sys.tmp
+ ADNS_TEST_FUZZRAW_DUMP_FD=6
+ export ADNS_TEST_FUZZRAW_DUMP_FD
+}
+playback_execute
+
+cat $ofuzz.sys.tmp
+
+fuzzout_complete
# usage: r1test <testcasename>
# test execution script, for running one test
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
set -e
: ${srcdir=.}
+. "$srcdir"/shlib
mrc=1
trap 'exit $mrc' 0
casename="$1"
-case="$srcdir/case-$casename"
-ocase="output-$casename"
-exec 4<"$case.sys"
-read <&4 program initfile initflags
-read <&4 queryargs
-
-initstring="`cat $srcdir/init-$initfile.text`"
-xinitflagsf=$srcdir/$program-xinitflags.text
-if test -f $xinitflagsf
-then
- initflags="$initflags `cat $xinitflagsf`";
-else
- initflags="$initflags /"
-fi
+playback_prepare
rm -f $ocase.*
EF_DISABLE_BANNER=1
export EF_DISABLE_BANNER
-if test -f "$case.in"
-then
- exec <"$case.in"
-else
- exec </dev/null
-fi
-
-playback=./${program}_playback
-if test ! -f $playback
+if test ! -e $playback
then
printf "SKIPPED-$casename "
mrc=5
exit
fi
-set +e
-ADNS_TEST_REPORT_FD=3 ADNS_TEST_IN_FD=4 \
- 3>>"$ocase.report" 4<&4 >"$ocase.out" 2>"$ocase.err" \
- $ADNS_TEST_DEBUG $playback $initflags"$initstring" $queryargs
-rc=$?
-set -e
+playback_execute_hook () { :; }
+playback_execute
if [ "$rc" = 5 ]
then
--- /dev/null
+# -*- shell -*-
+
+playback_prepare () {
+ case="$srcdir/case-$casename"
+ ocase="output-$casename"
+
+ if test -e "$case.in"
+ then
+ exec <"$case.in"
+ else
+ exec </dev/null
+ fi
+
+ exec 4<"$case.sys"
+ read <&4 program initfile initflags
+ read <&4 queryargs
+
+ initstring="`cat $srcdir/init-$initfile.text`"
+ xinitflagsf=$srcdir/$program-xinitflags.text
+ if test -e $xinitflagsf
+ then
+ initflags="$initflags `cat $xinitflagsf`";
+ else
+ initflags="$initflags /"
+ fi
+
+ playback=./${program}_playback
+}
+
+playback_execute_core () {
+ playback_execute_hook "$@"
+ set +e
+ ADNS_TEST_REPORT_FD=3 ADNS_TEST_IN_FD=4 \
+ 3>>"$ocase.report" 4<&4 >"$ocase.out" 2>"$ocase.err" \
+ $ADNS_TEST_DEBUG $playback "$@"
+ rc=$?
+ set -e
+}
+
+playback_execute () {
+ playback_execute_core $initflags"$initstring" $queryargs
+}
# settings.make[.in] - main configuration settings for Makefiles,
# used by autoconf/configure to generate settings.make
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
all: $(TARGETS)
clean mostlyclean:
+ rm -f $(TARGETS) $(AUTOCSRCS) $(AUTOCHDRS)
rm -f *.o *.tmp* *.so *.so.* pipe.*
- rm -f output-*.err output-*.leftover
- rm -f output-*.out output-*.report
+ rm -f output-*.err output-*.leftover output-*.trouble
+ rm -f output-*.out output-*.report fuzz-* fuzzraw-*
+ rm -rf fuzzcat.d
distclean: clean
- rm -f $(TARGETS) *~ ./#*# core *.orig *.rej Makefile config.h
+ rm -f *~ ./#*# core *.orig *.rej Makefile config.h
-distprep: $(AUTOCSRCS) $(AUTOCHDRS)
+distprep:
maintainer-clean: distclean
- -rm -f $(AUTOCSRCS) $(AUTOCHDRS)
# src/Makefile[.in] - library main Makefile
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
install:
mkdir -p $(libdir) $(includedir)
set -xe; for f in $(TARGETS); \
- do $(INSTALL_DATA) $$f $(libdir)/$$f; done
- $(INSTALL_DATA) $(srcdir)/../src/adns.h $(includedir)/adns.h
+ do $(INSTALL_DIR) $(DESTDIR)$(libdir); \
+ $(INSTALL_DATA) $$f $(DESTDIR)$(libdir)/$$f; done
+ $(INSTALL_DIR) $(DESTDIR)$(includedir)
+ $(INSTALL_DATA) $(srcdir)/../src/adns.h $(DESTDIR)$(includedir)/adns.h
uninstall:
for f in $(TARGETS); do rm -f $(libdir)/$$f; done
* - address-family specific code
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
/*
*
- * This file is
- * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson
- *
- * It is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014 Ian Jackson
+ * This file is part of adns, which is
+ * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
* Copyright (C) 1999-2000,2003,2006 Tony Finch
* Copyright (C) 1991 Massachusetts Institute of Technology
*
adns_if_noautosys= 0x0010,/* do not make syscalls at every opportunity */
adns_if_eintr= 0x0020,/* allow _wait and _synchronous to return EINTR */
adns_if_nosigpipe= 0x0040,/* applic has SIGPIPE ignored, do not protect */
+ adns_if_monotonic= 0x0080,/* enable if you can; see adns_processtimeouts */
adns_if_checkc_entex=0x0100,/* consistency checks on entry/exit to adns fns */
adns_if_checkc_freq= 0x0300,/* consistency checks very frequently (slow!) */
* these approaches has optimal performance.
*/
+/*
+ * Use of time:
+ *
+ * adns needs to manipulate timeouts. For API compatibility reasons
+ * (adns predates clock_gettime) the default is to use wall clock time
+ * from gettimeofday. This will malfunction if the system clock is
+ * not suitably stable. To avoid this, you should set
+ * adns_if_monotonic
+ *
+ * If you specify adns_if_monotonic then all `now' values passed to
+ * adns must be from clock_gettime(CLOCK_MONOTONIC). clock_gettime
+ * returns a struct timespec; you must convert it to a struct timeval
+ * by dividing the nsec by 1000 to make usec, rounding down.
+ */
+
int adns_init(adns_state *newstate_r, adns_initflags flags,
FILE *diagfile /*0=>stderr*/);
* use that fd and only in the manner specified, regardless of whether
* adns_if_noautosys was specified.
*
+ * now is as for adns_processtimeouts.
+ *
* adns_processexceptional should be called when select(2) reports an
* exceptional condition, or poll(2) reports POLLPRI.
*
/* Gives adns flow-of-control so that it can process any timeouts
* which might have happened. Very like _processreadable/writeable.
*
- * now may be 0; if it isn't, *now must be the current time, recently
- * obtained from gettimeofday.
+ * now may be 0; if it isn't, *now must be the current time from
+ * gettimeofday, or iff adns_if_monotonic it must be converted
+ * from the results of clock_gettime(CLOCK_MONOTONIC) (with the
+ * timespec.tv_nsec rounded down to make timeval.tv_usec).
*/
void adns_firsttimeout(adns_state ads,
struct timeval **tv_mod, struct timeval *tv_buf,
struct timeval now);
/* Asks adns when it would first like the opportunity to time
- * something out. now must be the current time, from gettimeofday.
+ * something out.
+ *
+ * now must be the current time, as for adns_processtimeouts.
*
* If tv_mod points to 0 then tv_buf must be non-null, and
* _firsttimeout will fill in *tv_buf with the time until the first
* adns_s_systemfail, and adns will close any stream sockets it has
* open.
*
- * This is used by adns, for example, if gettimeofday() fails.
- * Without this the program's event loop might start to spin !
+ * This is used by adns, for example, if gettimeofday() or
+ * clock_gettime fails. Without this the program's event loop might
+ * start to spin !
*
* This call will never block.
*/
/* Find out file descriptors adns is interested in, and when it would
* like the opportunity to time something out. If you do not plan to
* block then tv_mod may be 0. Otherwise, tv_mod and tv_buf are as
- * for adns_firsttimeout. readfds, writefds, exceptfds and maxfd_io may
+ * for adns_processtimeouts. readfds, writefds, exceptfds and maxfd_io may
* not be 0.
*
+ * now is as for adns_processtimeouts.
+ *
* If tv_mod is 0 on entry then this will never actually do any I/O,
* or change the fds that adns is using or the timeouts it wants. In
* any case it won't block, and it will set the timeout to zero if a
* select. This is just a fancy way of calling adns_processreadable/
* writeable/timeouts as appropriate, as if select had returned the
* data being passed. Always succeeds.
+ *
+ * now is as for adns_processtimeouts.
*/
/*
* descriptors, and use _firsttimeout is used to find out when adns
* might want to time something out.)
*
+ * now is as for adns_processtimeouts.
+ *
* adns_beforepoll will return 0 on success, and will not fail for any
* reason other than the fds buffer being too small (ERANGE).
*
/* Gives adns flow-of-control for a bit; intended for use after
* poll(2). fds and nfds should be the results from poll(). pollfd
* structs mentioning fds not belonging to adns will be ignored.
+ *
+ * now is as for adns_processtimeouts.
*/
* the abbreviation of the error - eg, for adns_s_timeout it returns
* "timeout". adns_errtypeabbrev returns the abbreviation of the
* error class: ie, for values up to adns_s_max_XXX it will return the
- * string XXX. You MUST NOT call these functions with status values
- * not returned by the same adns library.
+ * string XXX.
+ *
+ * If you call these functions with status values not actually
+ * returned from other functions in the same adns library, the
+ * returned information may be NULL. (You are also guaranteed
+ * that the return value will not be NULL for values in the
+ * adns_status enum, *except* for adns_s_max_XXXX.)
*/
#ifdef __cplusplus
# src/adns.make - library definitions, including list of object files
#
-# This file is part of adns, which is
-# Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
-# Copyright (C) 2014 Mark Wooding
-# Copyright (C) 1999-2000,2003,2006 Tony Finch
-# Copyright (C) 1991 Massachusetts Institute of Technology
-# (See the file INSTALL for full details.)
+# This file is part of adns, which is Copyright Ian Jackson
+# and contributors (see the file INSTALL for full details).
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
* - consistency checks
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
static void checkc_queue_childw(adns_state ads) {
- adns_query parent, child;
+ adns_query parent, child, search;
DLIST_CHECK(ads->childw, parent, , {
assert(parent->state == query_childw);
assert(parent->children.head);
DLIST_CHECK(parent->children, child, siblings., {
assert(child->parent == parent);
- assert(child->state != query_done);
+ if (child->state == query_done) {
+ for (search= ads->intdone.head; search; search= search->next)
+ if (search==child) goto child_done_ok;
+ assert(!"done child not on intdone");
+ child_done_ok:;
+ }
});
checkc_query(ads,parent);
checkc_query_alloc(ads,parent);
switch (cc) {
case cc_user:
break;
- case cc_entex:
+ case cc_enter:
+ if (!(ads->iflags & adns_if_checkc_entex)) return;
+ break;
+ case cc_exit:
if (!(ads->iflags & adns_if_checkc_entex)) return;
assert(!ads->intdone.head);
break;
-/* src/config.h.in. Generated automatically from configure.in by autoheader 2.13. */
+/* src/config.h.in. Generated from configure.in by autoheader. */
+/*
+ * acconfig.h
+ * input file for autoheader/autoconf/configure: extra stuff for config.h
+ */
+/*
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation.
+ */
/* Define if inline functions a la GCC are available. */
#undef HAVE_INLINE
/* Define if we want to include rpc/types.h. Crap BSDs put INADDR_LOOPBACK there. */
#undef HAVEUSE_RPCTYPES_H
-/* Define if you have the poll function. */
-#undef HAVE_POLL
-/* Define if you have the nsl library (-lnsl). */
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
-/* Define if you have the socket library (-lsocket). */
+/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
/* Use the definitions: */
#ifndef HAVE_INLINE
* - macros for handling doubly linked lists
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* - user-visible check/wait and event-loop-related functions
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <time.h>
#include "internal.h"
#include "tvarith.h"
/* Timeout handling functions. */
+int adns__gettimeofday(adns_state ads, struct timeval *tv) {
+ if (!(ads->iflags & adns_if_monotonic))
+ return gettimeofday(tv,0);
+
+ struct timespec ts;
+ int r = clock_gettime(CLOCK_MONOTONIC,&ts);
+ if (r) return r;
+
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ return 0;
+}
+
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
struct timeval *tv_buf) {
const struct timeval *now;
now= *now_io;
if (now) return;
- r= gettimeofday(tv_buf,0); if (!r) { *now_io= tv_buf; return; }
- adns__diag(ads,-1,0,"gettimeofday failed: %s",strerror(errno));
+ r= adns__gettimeofday(ads,tv_buf); if (!r) { *now_io= tv_buf; return; }
+ adns__diag(ads,-1,0,"gettimeofday/clock_gettime failed: %s",
+ strerror(errno));
adns_globalsystemfailure(ads);
return;
}
struct timeval **tv_io, struct timeval *tvbuf,
struct timeval now, struct query_queue *queue) {
adns_query qu, nqu;
+ struct timeval expires;
for (qu= queue->head; qu; qu= nqu) {
nqu= qu->next;
- if (!timercmp(&now,&qu->timeout,>)) {
- inter_maxtoabs(tv_io,tvbuf,now,qu->timeout);
+ if (timercmp(&now,&qu->timeout_started,<)) /* clock rewound */
+ qu->timeout_started= now;
+ expires= qu->timeout_started;
+ timevaladd(&expires, qu->timeout_ms);
+ if (!timercmp(&now,&expires,>)) {
+ inter_maxtoabs(tv_io,tvbuf,now,expires);
} else {
if (!act) { inter_immed(tv_io,tvbuf); return; }
LIST_UNLINK(*queue,qu);
void adns_firsttimeout(adns_state ads,
struct timeval **tv_io, struct timeval *tvbuf,
struct timeval now) {
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
adns__timeouts(ads, 0, tv_io,tvbuf, now);
adns__returning(ads,0);
}
void adns_processtimeouts(adns_state ads, const struct timeval *now) {
struct timeval tv_buf;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (now) adns__timeouts(ads, 1, 0,0, *now);
adns__returning(ads,0);
struct udpsocket *udp;
adns_sockaddr udpaddr;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
switch (ads->tcpstate) {
case server_disconnected:
int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) {
int r;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
switch (ads->tcpstate) {
case server_disconnected:
}
assert(FD_ISSET(ads->tcpsocket,&writeable));
if (!adns__vbuf_ensure(&ads->tcprecv,1)) { r= ENOMEM; goto xit; }
- r= read(ads->tcpsocket,&ads->tcprecv.buf,1);
+ r= read(ads->tcpsocket,ads->tcprecv.buf,1);
if (r==0 || (r<0 && (errno==EAGAIN || errno==EWOULDBLOCK))) {
tcp_connected(ads,*now);
r= 0; goto xit;
adns__tcp_broken(ads,"write",strerror(errno));
r= 0; goto xit;
} else if (r>0) {
+ assert(r <= ads->tcpsend.used);
ads->tcpsend.used -= r;
memmove(ads->tcpsend.buf,ads->tcpsend.buf+r,ads->tcpsend.used);
}
int adns_processexceptional(adns_state ads, int fd,
const struct timeval *now) {
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
switch (ads->tcpstate) {
case server_disconnected:
case server_broken:
struct pollfd pollfds[MAX_POLLFDS];
int i, fd, maxfd, npollfds;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) {
/* The caller is planning to sleep. */
struct pollfd pollfds[MAX_POLLFDS];
int npollfds, i;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (!now) goto xit;
adns_processtimeouts(ads,now);
/* General helpful functions. */
void adns_globalsystemfailure(adns_state ads) {
- adns__consistency(ads,0,cc_entex);
+ /* Must not be called by adns during actual processing of a
+ * particular query, since it reenters adns. Only safe to call in
+ * situations where it would be safe to call adns_returning. */
+ adns__consistency(ads,0,cc_enter);
- while (ads->udpw.head) adns__query_fail(ads->udpw.head, adns_s_systemfail);
- while (ads->tcpw.head) adns__query_fail(ads->tcpw.head, adns_s_systemfail);
+ for (;;) {
+ adns_query qu;
+#define GSF_QQ(QQ) \
+ if ((qu= ads->QQ.head)) { \
+ LIST_UNLINK(ads->QQ,qu); \
+ adns__query_fail(qu, adns_s_systemfail); \
+ continue; \
+ }
+ GSF_QQ(udpw);
+ GSF_QQ(tcpw);
+#undef GSF_QQ
+ break;
+ }
switch (ads->tcpstate) {
case server_connecting:
struct pollfd pollfds[MAX_POLLFDS];
int npollfds;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
- r= gettimeofday(&now,0);
+ r= adns__gettimeofday(ads,&now);
if (!r) adns_processtimeouts(ads,&now);
/* We just use adns__fdevents to loop over the fd's trying them.
fd_set readfds, writefds, exceptfds;
struct timeval tvbuf, *tvp;
- adns__consistency(ads,*query_io,cc_entex);
+ adns__consistency(ads,*query_io,cc_enter);
for (;;) {
r= adns__internal_check(ads,query_io,answer_r,context_r);
if (r != EAGAIN) break;
struct timeval now;
int r;
- adns__consistency(ads,*query_io,cc_entex);
- r= gettimeofday(&now,0);
+ adns__consistency(ads,*query_io,cc_enter);
+ r= adns__gettimeofday(ads,&now);
if (!r) adns__autosys(ads,now);
r= adns__internal_check(ads,query_io,answer_r,context_r);
* - vbuf handling
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
if (!datap) return adns_s_ok;
adns__vbuf_init(&vb);
- st= typei->convstring(&vb,datap);
+ st= typei->convstring(&vb,type,datap);
if (st) goto x_freevb;
if (!adns__vbuf_append(&vb,"",1)) { st= adns_s_nomemory; goto x_freevb; }
assert(strlen(vb.buf) == vb.used-1);
const struct sinfo *si;
si= findsinfo(st);
- return si->string;
+ return si ? si->string : 0;
}
const char *adns_errabbrev(adns_status st) {
const struct sinfo *si;
si= findsinfo(st);
- return si->abbrev;
+ return si ? si->abbrev : 0;
}
sti= bsearch(&st,stinfos, sizeof(stinfos)/sizeof(*stinfos),
sizeof(*stinfos), sti_compar);
- return sti->abbrev;
+ return sti ? sti->abbrev : 0;
}
* - comments regarding library data structures
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* Configuration and constants */
-#define MAXSERVERS 5
+#define MAXSERVERS 5 /* do not increase beyond no. of bits in `unsigned'! */
#define MAXSORTLIST 15
#define UDPMAXRETRIES 15
#define UDPRETRYMS 2000
typedef enum {
cc_user,
- cc_entex,
+ cc_enter,
+ cc_exit,
cc_freq
} consistency_checks;
* Previously, used alloc_interim, now use alloc_final.
*/
- adns_status (*convstring)(vbuf *vb, const void *data);
+ adns_status (*convstring)(vbuf *vb, adns_rrtype, const void *data);
/* Converts the RR data to a string representation in vbuf.
* vbuf will be appended to (it must have been initialised),
* and will not be null-terminated by convstring.
void *p;
void (*fp)(void);
union maxalign *up;
-} data;
+};
struct adns__query {
adns_state ads;
int id, flags, retries;
int udpnextserver;
unsigned long udpsent; /* bitmap indexed by server */
- struct timeval timeout;
+ int timeout_ms;
+ struct timeval timeout_started;
time_t expires; /* Earliest expiry time of any record we used. */
qcontext ctx;
int configerrno;
struct query_queue udpw, tcpw, childw, output, intdone;
adns_query forallnext;
- int nextid, tcpsocket;
+ unsigned nextid;
+ int tcpsocket;
struct udpsocket { int af; int fd; } udpsockets[MAXUDP];
int nudpsockets;
vbuf tcpsend, tcprecv;
* external-faciing functions which call adns__returning should
* normally be avoided in internal code. */
+void adns__intdone_process(adns_state ads);
+
/* From reply.c: */
void adns__procdgram(adns_state ads, const byte *dgram, int len,
* lest we end up in recursive descent !
*/
+static inline void
+adns__timeout_set(adns_query qu, struct timeval now, long ms)
+ { qu->timeout_ms= ms; qu->timeout_started= now; }
+
+static inline void
+adns__timeout_clear(adns_query qu)
+ { qu->timeout_ms= 0; timerclear(&qu->timeout_started); }
+
+
+int adns__gettimeofday(adns_state ads, struct timeval *tv_buf);
+
void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
struct timeval *tv_buf);
/* Call with care - might reentrantly cause queries to be completed! */
(( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \
* sizeof(union maxalign) )
-#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff)
+#define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ffu)
#define GET_B(cb,tv) ((tv)= GETIL_B((cb)))
#define GET_W(cb,tv) ((tv)=0,(tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv))
#define GET_L(cb,tv) ( (tv)=0, \
* - parsing assistance functions (mainly for domains inside datagrams)
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int *lablen_r, int *labstart_r) {
int lablen, jumpto;
const char *dgram;
+ int had_pointer= 0;
dgram= fls->dgram;
for (;;) {
if ((lablen & 0x0c0) != 0x0c0) return adns_s_unknownformat;
if (fls->cbyte >= fls->dglen) goto x_truncated;
if (fls->cbyte >= fls->max) goto x_badresponse;
+ if (had_pointer++ >= 2) goto x_loop;
GET_B(fls->cbyte,jumpto);
jumpto |= (lablen&0x3f)<<8;
if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
x_badresponse:
adns__diag(fls->ads,fls->serv,fls->qu,
- "label in domain runs beyond end of domain");
+ "label in domain runs or points outside of packet");
+ return adns_s_invalidresponse;
+
+ x_loop:
+ adns__diag(fls->ads,fls->serv,fls->qu,
+ "compressed label pointer chain");
return adns_s_invalidresponse;
}
* - wrappers for poll(2)
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int space, found, timeout_ms, r;
struct pollfd fds_tmp[MAX_POLLFDS];
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
if (timeout_io) {
adns__must_gettimeofday(ads,&now,&tv_nowbuf);
const struct timeval *now) {
struct timeval tv_buf;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (now) {
adns__timeouts(ads, 1, 0,0, *now);
+ adns__intdone_process(ads); /* fdevents calls adns_processwriteable */
adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0);
}
adns__returning(ads,0);
int r, nfds, to;
struct pollfd fds[MAX_POLLFDS];
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
for (;;) {
r= adns__internal_check(ads,query_io,answer_r,context_r);
* - query submission and cancellation (user-visible and internal)
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
qu->retries= 0;
qu->udpnextserver= 0;
qu->udpsent= 0;
- timerclear(&qu->timeout);
+ adns__timeout_clear(qu);
qu->expires= now.tv_sec + MAXTTLBELIEVE;
memset(&qu->ctx,0,sizeof(qu->ctx));
adns_query qu;
const char *p;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
if (flags & ~(adns_queryflags)0x4009ffff)
/* 0x40080000 are reserved for `harmless' future expansion
typei= adns__findtype(type);
if (!typei) return ENOSYS;
- r= gettimeofday(&now,0); if (r) goto x_errno;
+ r= adns__gettimeofday(ads,&now); if (r) goto x_errno;
qu= query_alloc(ads,typei,type,flags,now); if (!qu) goto x_errno;
qu->ctx.ext= context;
if (!an) return;
assert(!qu->final_allocspace);
+ qu->interim_allocd -= sz;
+ assert(qu->interim_allocd >= 0);
LIST_UNLINK(qu->allocations, an);
free(an);
- qu->interim_allocd -= sz;
- assert(!qu->interim_allocd >= 0);
}
void *adns__alloc_mine(adns_query qu, size_t sz) {
qu->query_dgram= 0;
}
-void adns__returning(adns_state ads, adns_query qu_for_caller) {
+void adns__intdone_process(adns_state ads) {
while (ads->intdone.head) {
adns_query iq= ads->intdone.head;
adns_query parent= iq->parent;
free(iq->answer);
free(iq);
}
- adns__consistency(ads,qu_for_caller,cc_entex);
+}
+
+void adns__returning(adns_state ads, adns_query qu_for_caller) {
+ adns__intdone_process(ads);
+ adns__consistency(ads,qu_for_caller,cc_exit);
}
void adns__cancel(adns_query qu) {
assert(!qu->parent);
ads= qu->ads;
- adns__consistency(ads,qu,cc_entex);
+ adns__consistency(ads,qu,cc_enter);
adns__cancel(qu);
adns__returning(ads,0);
}
* - main handling and parsing routine for received datagrams
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int flg_ra, flg_rd, flg_tc, flg_qr, opcode;
int rrtype, rrclass, rdlength, rdstart;
int anstart, nsstart;
- int ownermatched, l, nrrs;
+ int ownermatched, l, nrrs, restartfrom;
unsigned long ttl, soattl;
const typeinfo *typei;
adns_query qu, nqu;
* If it has any CNAMEs we stuff them in the answer.
*/
wantedrrs= 0;
+ restartfrom= -1;
cbyte= anstart;
for (rri= 0; rri<ancount; rri++) {
rrstart= cbyte;
*/
}
} else if (rrtype == (qu->answer->type & adns_rrt_typemask)) {
+ if (restartfrom==-1) restartfrom= rri;
wantedrrs++;
} else {
adns__debug(ads,serv,qu,"ignoring answer RR"
pai.arcount= arcount;
pai.now= now;
+ assert(restartfrom>=0);
for (rri=0, nrrs=0; rri<ancount; rri++) {
st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
&rrtype,&rrclass,&ttl, &rdlength,&rdstart,
&ownermatched);
assert(!st); assert(rrtype != -1);
- if (rrclass != DNS_CLASS_IN ||
+ if (rri < restartfrom ||
rrtype != (qu->answer->type & adns_rrt_typemask) ||
+ rrclass != DNS_CLASS_IN ||
!ownermatched)
continue;
adns__update_expires(qu,ttl,now);
adns__query_fail(qu,adns_s_invalidresponse);
return;
}
+ if (qu->flags & adns_qf_usevc) {
+ adns__diag(ads,serv,qu,"server sent datagram with TC over TCP");
+ adns__query_fail(qu,adns_s_invalidresponse);
+ return;
+ }
qu->flags |= adns_qf_usevc;
x_restartquery:
* - management of global state
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
tl= 0;
while (nextword(&bufp,&word,&l)) { count++; tl += l+1; }
- newptrs= malloc(sizeof(char*)*count);
- if (!newptrs) { saveerr(ads,errno); return; }
+ if (count) {
+ newptrs= malloc(sizeof(char*)*count);
+ if (!newptrs) { saveerr(ads,errno); return; }
- newchars= malloc(tl);
- if (!newchars) { saveerr(ads,errno); free(newptrs); return; }
+ newchars= malloc(tl);
+ if (!newchars) { saveerr(ads,errno); free(newptrs); return; }
+ } else {
+ assert(!tl);
+ newptrs= 0;
+ newchars= 0;
+ }
bufp= buf;
pp= newptrs;
}
} else {
maskwhat = "prefix length";
- initial= strtoul(slash,&ep,10);
- if (*ep || initial>adns__addr_width(sl->base.sa.sa_family)) {
+ unsigned long prefixlen = strtoul(slash,&ep,10);
+ if (*ep || prefixlen>adns__addr_width(sl->base.sa.sa_family)) {
configparseerr(ads,fn,lno,"mask length `%s' invalid",slash);
continue;
}
+ initial= prefixlen;
sl->mask.sa.sa_family= sl->base.sa.sa_family;
adns__prefix_mask(&sl->mask, initial);
}
/* adns normally does IPv6 if the application wants it; control
* this with the adns_af: option if you like */
WORD_IS("inet6") ||
+ /* adns trusts the resolver anyway */
+ WORD_IS("trust-ad") ||
/* adns does not do edns0 and this is not a problem */
WORD_IS("edns0"))
continue;
r= init_finish(ads);
if (r) return r;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_exit);
*ads_r= ads;
return 0;
}
}
r= init_finish(ads); if (r) return r;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_exit);
*ads_r= ads;
return 0;
}
return init_files(newstate_r, flags, logfn, logfndata);
}
+static void cancel_all(adns_query qu) {
+ if (!qu->parent) adns__cancel(qu);
+ else cancel_all(qu->parent);
+}
+
void adns_finish(adns_state ads) {
int i;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
for (;;) {
- if (ads->udpw.head) adns__cancel(ads->udpw.head);
- else if (ads->tcpw.head) adns__cancel(ads->tcpw.head);
- else if (ads->childw.head) adns__cancel(ads->childw.head);
- else if (ads->output.head) adns__cancel(ads->output.head);
- else if (ads->intdone.head) adns__cancel(ads->output.head);
+ if (ads->udpw.head) cancel_all(ads->udpw.head);
+ else if (ads->tcpw.head) cancel_all(ads->tcpw.head);
+ else if (ads->childw.head) cancel_all(ads->childw.head);
+ else if (ads->output.head) cancel_all(ads->output.head);
+ else if (ads->intdone.head) cancel_all(ads->output.head);
else break;
}
for (i=0; i<ads->nudpsockets; i++) close(ads->udpsockets[i].fd);
}
void adns_forallqueries_begin(adns_state ads) {
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
ads->forallnext=
ads->udpw.head ? ads->udpw.head :
ads->tcpw.head ? ads->tcpw.head :
adns_query adns_forallqueries_next(adns_state ads, void **context_r) {
adns_query qu, nqu;
- adns__consistency(ads,0,cc_entex);
+ adns__consistency(ads,0,cc_enter);
nqu= ads->forallnext;
for (;;) {
qu= nqu;
* - send queries
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
while (p!=pe && (c= *p++)!='.') {
if (c=='\\') {
if (!(flags & adns_qf_quoteok_query)) return adns_s_querydomaininvalid;
+ if (p==pe) return adns_s_querydomaininvalid;
if (ctype_digit(p[0])) {
if (p+1==pe || p+2==pe) return adns_s_querydomaininvalid;
if (ctype_digit(p[1]) && ctype_digit(p[2])) {
static void query_usetcp(adns_query qu, struct timeval now) {
qu->state= query_tcpw;
- qu->timeout= now;
- timevaladd(&qu->timeout,TCPWAITMS);
+ adns__timeout_set(qu,now,TCPWAITMS);
LIST_LINK_TAIL(qu->ads->tcpw,qu);
adns__querysend_tcp(qu,now);
adns__tcp_tryconnect(qu->ads,now);
if (r<0 && errno != EAGAIN)
adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno));
- qu->timeout= now;
- timevaladd(&qu->timeout,UDPRETRYMS);
+ adns__timeout_set(qu, now, UDPRETRYMS);
qu->udpsent |= (1<<serv);
qu->udpnextserver= (serv+1)%ads->nservers;
qu->retries++;
* - static inline functions for doing arithmetic on timevals
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* - RR-type-specific code, and the machinery to call it
*/
/*
- * This file is part of adns, which is
- * Copyright (C) 1997-2000,2003,2006,2014-2016 Ian Jackson
- * Copyright (C) 2014 Mark Wooding
- * Copyright (C) 1999-2000,2003,2006 Tony Finch
- * Copyright (C) 1991 Massachusetts Institute of Technology
- * (See the file INSTALL for full details.)
+ * This file is part of adns, which is Copyright Ian Jackson
+ * and contributors (see the file INSTALL for full details).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
return adns_s_ok;
}
-static adns_status cs_txt(vbuf *vb, const void *datap) {
+static adns_status cs_txt(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_intstr *const *rrp= datap;
const adns_rr_intstr *current;
adns_status st;
* _hinfo (cs)
*/
-static adns_status cs_hinfo(vbuf *vb, const void *datap) {
+static adns_status cs_hinfo(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_intstrpair *rrp= datap;
adns_status st;
return adns_s_ok;
}
-static adns_status cs_inaddr(vbuf *vb, const void *datap) {
+static adns_status cs_inaddr(vbuf *vb, adns_rrtype rrt, const void *datap) {
return csp_genaddr(vb, AF_INET,datap);
}
return dip_genaddr(ads,AF_INET6,datap_a,datap_b);
}
-static adns_status cs_in6addr(vbuf *vb, const void *datap) {
+static adns_status cs_in6addr(vbuf *vb, adns_rrtype rrt, const void *datap) {
return csp_genaddr(vb,AF_INET6,datap);
}
return adns_s_ok;
}
-static adns_status cs_addr(vbuf *vb, const void *datap) {
+static adns_status cs_addr(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_addr *rrp= datap;
return csp_addr(vb,rrp);
* settled on.
*/
adns__cancel_children(parent);
- r= gettimeofday(&now, 0); if (r) goto x_gtod;
+ r= adns__gettimeofday(ads,&now); if (r) goto x_gtod;
qf= adns__qf_addr_cname;
if (!(parent->flags & adns_qf_cname_loose)) qf |= adns_qf_cname_forbid;
addr_subqueries(parent, now, qf, child->vb.buf, child->vb.used);
adns__cancel_children(parent);
adns__free_interim(parent, pans->rrs.bytes);
pans->rrs.bytes= 0; pans->nrrs= 0;
- r= gettimeofday(&now, 0); if (r) goto x_gtod;
+ r= adns__gettimeofday(ads,&now); if (r) goto x_gtod;
adns__search_next(ads, parent, now);
return;
}
/* We have our own error handling, because adns__must_gettimeofday
* handles errors by calling adns_globalsystemfailure, which would
* reenter the query processing logic. */
- adns__diag(ads, -1, parent, "gettimeofday failed: %s", strerror(errno));
+ adns__diag(ads, -1, parent, "gettimeofday/clock_gettime failed: %s",
+ strerror(errno));
err= adns_s_systemfail;
goto x_err;
return adns_s_ok;
}
-static adns_status cs_domain(vbuf *vb, const void *datap) {
+static adns_status cs_domain(vbuf *vb, adns_rrtype rrt, const void *datap) {
const char *const *domainp= datap;
return csp_domain(vb,*domainp);
}
&type, &class, &ttl, &rdlen, &rdstart,
pai->dgram, pai->dglen, dmstart, &ownermatched);
if (st) return st;
+ if (type==-1) continue;
if (!ownermatched || class != DNS_CLASS_IN) continue;
typef= addr_rrtypeflag(type);
if (!(want & typef)) continue;
mfp_hostaddr(qu,rrp);
}
-static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) {
+static adns_status csp_hostaddr(vbuf *vb, adns_rrtype rrt,
+ const adns_rr_hostaddr *rrp) {
const char *errstr;
adns_status st;
char buf[20];
int i;
+ size_t addrsz= gsz_addr(0, rrt);
st= csp_domain(vb,rrp->host); if (st) return st;
CSP_ADDSTR(" (");
for (i=0; i<rrp->naddrs; i++) {
CSP_ADDSTR(" ");
- st= csp_addr(vb,&rrp->addrs[i]);
+ st= csp_addr(vb, (const void*)((const char*)rrp->addrs + addrsz*i));
}
CSP_ADDSTR(" )");
} else {
return adns_s_ok;
}
-static adns_status cs_hostaddr(vbuf *vb, const void *datap) {
+static adns_status cs_hostaddr(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_hostaddr *rrp= datap;
- return csp_hostaddr(vb,rrp);
+ return csp_hostaddr(vb,rrt,rrp);
}
/*
mfp_hostaddr(qu,&rrp->ha);
}
-static adns_status cs_inthostaddr(vbuf *vb, const void *datap) {
- const adns_rr_inthostaddr *rrp= datap;
+static adns_status csp_intofinthost(vbuf *vb, int i) {
char buf[10];
- sprintf(buf,"%u ",rrp->i);
+ if (i < 0 || i > 0xffff)
+ /* currently only used for MX whose priorities are 16-bit */
+ return adns_s_invaliddata;
+
+ sprintf(buf,"%u ",i);
CSP_ADDSTR(buf);
+ return adns_s_ok;
+}
+
+static adns_status cs_inthostaddr(vbuf *vb, adns_rrtype rrt, const void *datap) {
+ const adns_rr_inthostaddr *rrp= datap;
+ adns_status st;
- return csp_hostaddr(vb,&rrp->ha);
+ st = csp_intofinthost(vb,rrp->i); if (st) return st;
+ return csp_hostaddr(vb,rrt,&rrp->ha);
}
/*
* _inthost (cs)
*/
-static adns_status cs_inthost(vbuf *vb, const void *datap) {
+static adns_status cs_inthost(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_intstr *rrp= datap;
- char buf[10];
+ adns_status st;
- sprintf(buf,"%u ",rrp->i);
- CSP_ADDSTR(buf);
+ st = csp_intofinthost(vb,rrp->i); if (st) return st;
return csp_domain(vb,rrp->str);
}
pai->dgram, pai->dglen, max,
*cbyte_io, cbyte_io);
st= adns__findlabel_next(&fls,&lablen,&labstart);
+ if (st) return st;
if (!lablen) {
adns__vbuf_appendstr(vb,".");
goto x_ok;
return adns_s_ok;
}
-static adns_status cs_rp(vbuf *vb, const void *datap) {
+static adns_status cs_rp(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_strpair *rrp= datap;
adns_status st;
adns_rr_soa *rrp= datap;
const byte *dgram= pai->dgram;
adns_status st;
- int msw, lsw, i;
+ int i;
st= pap_domain(pai, &cbyte, max, &rrp->mname,
pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
if (cbyte+20 != max) return adns_s_invaliddata;
for (i=0; i<5; i++) {
- GET_W(cbyte,msw);
- GET_W(cbyte,lsw);
- (&rrp->serial)[i]= (msw<<16) | lsw;
+ unsigned long v;
+ (&rrp->serial)[i]= GET_L(cbyte, v);
}
return adns_s_ok;
adns__makefinal_str(qu,&rrp->rname);
}
-static adns_status cs_soa(vbuf *vb, const void *datap) {
+static adns_status cs_soa(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_soa *rrp= datap;
char buf[20];
int i;
st= csp_mailbox(vb,rrp->rname); if (st) return st;
for (i=0; i<5; i++) {
+ if (rrp->serial > 0xffffffffUL)
+ return adns_s_invaliddata;
sprintf(buf," %lu",(&rrp->serial)[i]);
CSP_ADDSTR(buf);
}
static adns_status csp_srv_begin(vbuf *vb, const adns_rr_srvha *rrp
/* might be adns_rr_srvraw* */) {
char buf[30];
+ if (rrp->priority < 0 || rrp->priority > 0xffff ||
+ rrp->weight < 0 || rrp->weight > 0xffff ||
+ rrp->port < 0 || rrp->port > 0xffff)
+ return adns_s_invaliddata;
sprintf(buf,"%u %u %u ", rrp->priority, rrp->weight, rrp->port);
CSP_ADDSTR(buf);
return adns_s_ok;
}
-static adns_status cs_srvraw(vbuf *vb, const void *datap) {
+static adns_status cs_srvraw(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_srvraw *rrp= datap;
adns_status st;
return csp_domain(vb,rrp->host);
}
-static adns_status cs_srvha(vbuf *vb, const void *datap) {
+static adns_status cs_srvha(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_srvha *rrp= datap;
adns_status st;
st= csp_srv_begin(vb,(const void*)datap); if (st) return st;
- return csp_hostaddr(vb,&rrp->ha);
+ return csp_hostaddr(vb,rrt,&rrp->ha);
}
static void postsort_srv(adns_state ads, void *array, int nrrs,int rrsz,
return adns_s_ok;
}
-static adns_status cs_opaque(vbuf *vb, const void *datap) {
+static adns_status cs_opaque(vbuf *vb, adns_rrtype rrt, const void *datap) {
const adns_rr_byteblock *rrp= datap;
char buf[10];
int l;
unsigned char *p;
+ if (rrp->len < 0 || rrp->len > 0xffff)
+ return adns_s_invaliddata;
+
sprintf(buf,"\\# %d",rrp->len);
CSP_ADDSTR(buf);