chiark / gitweb /
Fix typo in changelog entry for 1.6.1 master
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 5 May 2024 21:47:54 +0000 (22:47 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 5 May 2024 21:47:54 +0000 (22:47 +0100)
78 files changed:
.gitignore
INSTALL
Makefile.in
NEWS
README
README.html
RELEASE-CHECKLIST
acconfig.h
aclocal.m4
autogen.sh [new file with mode: 0755]
changelog
client/Makefile.in
client/addrtext.c
client/adh-main.c
client/adh-opts.c
client/adh-query.c
client/adnsheloex.c
client/adnshost.h
client/adnslogres.c
client/adnsresfilter.c
client/adnstest.c
client/client.h
client/fanftest.c
common.make.in
configure
configure.in
dynamic/Makefile.in
regress/Makefile.in
regress/addcases
regress/case-adh-reverse-pipe.err [new file with mode: 0644]
regress/case-adh-reverse-pipe.out [new file with mode: 0644]
regress/case-adh-reverse-pipe.sys [new file with mode: 0644]
regress/case-monotonic.err [new file with mode: 0644]
regress/case-monotonic.out [new file with mode: 0644]
regress/case-monotonic.sys [new file with mode: 0644]
regress/categorisefuzz [new file with mode: 0755]
regress/check1fuzz [new file with mode: 0755]
regress/checkall
regress/harness.h [deleted file]
regress/harness.h.m4
regress/hcommon.c [deleted file]
regress/hcommon.c.m4
regress/hfuzz.c [new file with mode: 0644]
regress/hfuzzraw.c.m4 [new file with mode: 0644]
regress/hmacros.i4
regress/hnonfuzz.c [new file with mode: 0644]
regress/hplayback.c [deleted file]
regress/hplayback.c.m4
regress/hrecord.c [deleted file]
regress/hrecord.c.m4
regress/hredirect.h [deleted file]
regress/hredirect.h.m4
regress/hsyscalls.h [deleted file]
regress/hsyscalls.h.m4
regress/hsyscalls.i4
regress/m1test
regress/make1fuzz [new file with mode: 0755]
regress/r1test
regress/shlib [new file with mode: 0644]
settings.make.in
src/Makefile.in
src/addrfam.c
src/adns.h
src/adns.make
src/check.c
src/config.h.in
src/dlist.h
src/event.c
src/general.c
src/internal.h
src/parse.c
src/poll.c
src/query.c
src/reply.c
src/setup.c
src/transmit.c
src/tvarith.h
src/types.c

index 973a4806991b50d0f0b54a650773f6c8905ecd48..89b05ff5d108521ba6ff594eed7f07a3fcad4a62 100644 (file)
@@ -29,12 +29,24 @@ client/adnsresfilter
 client/adnsresfilter_s
 dynamic/Makefile
 dynamic/libadns.so.*
 client/adnsresfilter_s
 dynamic/Makefile
 dynamic/libadns.so.*
+regress/fuzzcat.d
 regress/Makefile
 regress/*_record
 regress/*_playback
 regress/Makefile
 regress/*_record
 regress/*_playback
+regress/*_fuzz
+regress/*_fuzzraw
 regress/output-*.*
 regress/output-*.*
+regress/fuzz-*
+regress/fuzzraw-*
 regress/pipe.out
 regress/pipe.err
 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
 src/Makefile
 src/config.h
 web
diff --git a/INSTALL b/INSTALL
index c4bdbf92feee891531b751996e55210d8f72befd..1b99d036053b2779859fa91a3c5f85a9accd1db2 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -67,7 +67,8 @@ containing tsearch, such as the GNU C library.  It is best if tsearch
 uses an automatically-balancing tree algorithm, like the glibc version
 does.  Simple binary trees may perform badly.
 
 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.
 
 You will probably find that GNU Make is required.
 Please do not report this as a bug; install GNU Make instead.
@@ -97,11 +98,11 @@ DNSSEC cryptographic signature checking.
 COPYRIGHT
 
 This file, INSTALL, contains installation instructions and other
 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
 
 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]
  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]
index 9510b7b7e510ca24ba0d3b16f7d356fe934badab..bc1a0b2bd1a321ce58984aabddd27a4362f848c9 100644 (file)
@@ -1,11 +1,7 @@
 # Makefile[.in] - top-level Makefile
 #  
 # 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
 # 
 #  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
@@ -24,7 +20,7 @@ include               ./common.make
 
 # Remember to change ADNS_VERSION_STRING in client/client.h too, and
 # possibly library soname (MAJOR and MINOR in common.make.in).
 
 # 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@
 
 srcdir=                @srcdir@
 VPATH=         @srcdir@
@@ -75,10 +71,10 @@ adnshost.txt: all
 
 web-install: adnshost.txt
        test -e $(WEBDIR) || mkdir $(WEBDIR)
 
 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
 
 check:                 all
        $(MAKE) -C regress check
diff --git a/NEWS b/NEWS
index 4cb96303684cdf586426bc4935963f32bcfbfac0..ce0e44eea99355b1b052124851f1294f26b3f8c3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+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.
 Changes in adns 1.5.1, since adns 1.5.0, are:
 
  Bugfixes.  See changelog.
diff --git a/README b/README
index c045cae644944dd40a76f1fc39e77f295e2e40b5..da6108ac835ed1af4b7d3339d0e592073b3cd3d6 100644 (file)
--- a/README
+++ b/README
@@ -120,9 +120,8 @@ References and related projects
 
 Copyright and licensing
 
 
 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
 
    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
@@ -148,23 +147,23 @@ Copyright and licensing
 
 References
 
 
 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:///
   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
index 07123cd49c010279e9e5b40af4858baeac8e712f..f0d4560f719afa5d6e6778129cf9e60d51059437 100644 (file)
@@ -11,7 +11,7 @@ library and utilities.</strong>
 <!--      Note: this file must contain portable HTML !            -->
 <!--                                                              -->
 <!--  It is served on the GNU site and also from my own system,   -->
 <!--      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.                            -->
 <!--                                                              -->
 <!--  Please ensure that all links continine to be correct        -->
 <!--  both for www.gnu.org and chiark.                            -->
 <!--                                                              -->
@@ -87,7 +87,7 @@ which can be used easily in from the command line and from shell
 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
 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>
 usage message</A> for a summary of its capabilities.
 
 </ul>
@@ -96,7 +96,7 @@ usage message</A> for a summary of its capabilities.
 
 I'm afraid there is no manual yet.  However, competent C programmers
 should be able to use the library based on the
 
 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.
 
 adns.h header file</A>, and the usage messages for the programs should
 be sufficient.
 
@@ -108,7 +108,7 @@ your project, and what you think of it.
 <p>
 
 Bug reports should be reported to the
 <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>
 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>
@@ -131,7 +131,7 @@ will contain only announcements of important bugs, new versions, etc.
 <p>
 
 There are
 <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
 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
@@ -140,26 +140,26 @@ containing the word `subscribe' to
 <h2>Documentation</h2>
 
 <ul>
 <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>
     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>
     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.
     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).
     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
     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>Installation note</h2>
 
@@ -175,21 +175,21 @@ replies to adns's queries.
 <h2>References and related projects</h2>
 
 <ul>
 <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.
    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. -->
    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.
    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>
 
    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>
 
 
 <p>
 
@@ -204,14 +204,14 @@ This program and documentation is distributed in the hope that it will
 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
 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,
 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>
 or email <code>ijackson@chiark.greenend.org.uk</code>.
 
 <p>
@@ -220,13 +220,13 @@ or email <code>ijackson@chiark.greenend.org.uk</code>.
 Ian Jackson / <tt>ijackson@chiark.greenend.org.uk</tt>.
 <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="/">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>
 
 </body>
 </html>
index cdd3461a9de1fd5e4e792de25f55d58f2d4b9602..e38d55c2c1a9316632501e3050c8db6b00e3b8e0 100755 (executable)
@@ -3,7 +3,6 @@
 #
 #  * Maybe rerun autoconf
 #  * Ensure changelog reflects changes
 #
 #  * 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
 #  * Maybe update copyright dates
 #  * Maybe update MAJOR and/or MINOR in common.make.in
 #  * Update DISTVERSION in Makefile.in
index c3ed43d8d49c5172770f26a48e4d3d7a307f8ed2..c5ea93ec58c6c2c6bda530b3a14a4ef13ce5fd8c 100644 (file)
@@ -3,12 +3,8 @@
  * input file for autoheader/autoconf/configure: extra stuff for config.h
  */
 /*
  * 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
  *  
  *  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
index 4a4d074376ab27669041fa9418e98f8f88c8c993..cb8d92fd6af9595fd481baba5013073f48fe6615 100644 (file)
@@ -1,11 +1,7 @@
 # aclocal.m4 - package-specific macros for autoconf
 #  
 # 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
 #
 #  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
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..14efa37
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -e
+autoheader
+autoconf
index f4886ea5d92a40e69b7e28fe68de2bcdb625b6c9..b48004eab7fa54363f93de218f4217a880ba1aec 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,4 +1,100 @@
-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
 
   * Portability fix for systems where socklen_t is bigger than int.
   * Fix for malicious optimisation of memcpy in test suite, which
@@ -17,7 +113,7 @@ adns (1.5.1~~) UPSTREAM; urgency=low
   * Properly include harness.h in adnstest.c in regress/.  Suppresses
     a couple of compiler warnings (implicit declaration of Texit, etc.)
 
   * 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
 
 
 adns (1.5.0) UPSTREAM; urgency=low
 
index fa3a0029c32f5af6934d366abf92e11e0fb60126..36c8b74617f7751be822784505297dc658885f5b 100644 (file)
@@ -1,11 +1,7 @@
 # client/Makefile - client program(s) Makefile
 # 
 # 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
 #  
 #  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
@@ -58,9 +54,9 @@ ALL_OBJS=     $(ADH_OBJS) $(TARG_OBJS)
 all:           $(TARGETS)
 
 install:       $(TARG_INSTALL)
 all:           $(TARGETS)
 
 install:       $(TARG_INSTALL)
-               mkdir -p $(bindir)
+               $(INSTALL_DIR) $(DESTDIR)$(bindir)
                set -xe; for f in $(TARG_INSTALL); \
                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
 
 uninstall:
                for f in $(TARGETS); do rm -f $(bindir)/$$f; done
index 212dece00b965e1354667703d55a7220c7465851..e02bb5a1fe98d566da52d7d415d67d3148da2d13 100644 (file)
  * - test program for address<->string conversion, not part of the library
  */
 /*
  * - 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
  *  
  *  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
index 9709be225d331ceb1a50c8fce532694516668ae4..a2dc5fe31b5730fdef15587743b7f6c1713cbe8f 100644 (file)
@@ -4,12 +4,8 @@
  *   main program and useful subroutines
  */
 /*
  *   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
  *  
  *  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
@@ -129,7 +125,7 @@ void of_type(const struct optioninfo *oi, const char *arg, const char *arg2) {
 
 static void process_optarg(const char *arg,
                           const char *const **argv_p,
 
 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;
   const struct optioninfo *oip;
   const char *arg2;
   int invert;
@@ -148,9 +144,17 @@ static void process_optarg(const char *arg,
        if (!arg) usageerr("option --%s requires a value argument",oip->lopt);
        arg2= 0;
       } else if (oip->type == ot_funcarg2) {
        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 (!arg || !arg2)
          usageerr("option --%s requires two more arguments", oip->lopt);
       } else {
@@ -206,7 +210,7 @@ static void read_stdin(void) {
       if (r == 0) {
        if (used) {
          /* fake up final newline */
       if (r == 0) {
        if (used) {
          /* fake up final newline */
-         buf[used++]= '\n';
+         buf[used]= '\n';
          r= 1;
        } else {
          ov_pipe= 0;
          r= 1;
        } else {
          ov_pipe= 0;
index 2f1f1836379ae7f2ba77324dad271edf248a9e28..deea7d483eb7cc15f5635d036b610aa3118d78b9 100644 (file)
@@ -4,12 +4,8 @@
  *   option handling tables etc.
  */
 /*
  *   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
  *  
  *  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
@@ -32,6 +28,7 @@ int ov_verbose= 0;
 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;
 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 };
 
 char *ov_id= 0;
 struct perqueryflags_remember ov_pqfr = { 1,1,1, tm_none };
 
@@ -45,11 +42,11 @@ static const struct optioninfo global_options[]= {
     "a", "asynch",         &ov_asynch, 1 },
   
   { ot_desconly, "answer/error output format and destination (see below):" },
     "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 },
     "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 },
     "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:" },
     "Fa", "fmt-asynch",    &ov_format, fmt_asynch },
                         
   { ot_desconly, "global verbosity level:" },
@@ -59,6 +56,13 @@ static const struct optioninfo global_options[]= {
     "Vn", "no-quiet",      &ov_verbose, 0 },
   { ot_value,            "Debugging mode",
     "Vd", "debug",         &ov_verbose, adns_if_debug },
     "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, "other global options:" },
   { ot_funcarg,          "Configuration to use instead of /etc/resolv.conf",
@@ -127,7 +131,7 @@ static const struct optioninfo perquery_options[]= {
   { 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_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 }
     0, "cancel-id",        0,0, &of_cancel_id, "id" },
 
   { ot_end }
index 03f97b170a62a4977cee97a6e3b9f9eb9f75689b..479fe3c0b56b711fde4e211447f7c22ec21f8177 100644 (file)
@@ -4,12 +4,8 @@
  *   make queries and print answers
  */
 /*
  *   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
  *  
  *  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
@@ -40,7 +36,7 @@ void ensure_adns_init(void) {
 
   if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) sysfail("ignore SIGPIPE",errno);
 
 
   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) {
   if (!ov_env) initflags |= adns_if_noenv;
 
   if (config_text) {
index 5c0befe2b431e38bb2a133dac57b7a7cff305903..3ac1cba7254bd3a87b66508db54fd6763080f0b6 100644 (file)
@@ -3,15 +3,8 @@
  * - look up the A record of hosts in an Exim log that failed HELO verification
  */
 /*
  * - 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
  *  
  *  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
index e68ecb7bf06987bd61cbf5e8195d74149b762f4b..35d7811521c243cea529d7339a1adeb031486fc8 100644 (file)
@@ -3,12 +3,8 @@
  * - useful general-purpose resolver client program, header file
  */
 /*
  * - 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
  *  
  *  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
@@ -82,6 +78,7 @@ extern int ov_verbose;
 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 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;
 
 extern char *ov_id;
 extern struct perqueryflags_remember ov_pqfr;
 
index 4ab81eedcdb24574d7033f3898f35e5a37beac4e..3ce05ffa021661f6dae6a6040814b6fd1f5d3602 100644 (file)
@@ -3,16 +3,8 @@
  * - a replacement for the Apache logresolve program using adns
  */
 /*
  * - 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
  *  
  *  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
@@ -61,6 +53,7 @@
 /* option flags */
 #define OPT_DEBUG 1
 #define OPT_POLL 2
 /* 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;
 
 static const char *const progname= "adnslogres";
 static const char *config_text;
@@ -170,7 +163,8 @@ static void proclog(FILE *inf, FILE *outf, int maxpending, int opts) {
   logline *head, *tail, *line;
   adns_initflags initflags;
 
   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 {
   if (config_text) {
     errno= adns_init_strcfg(&adns, initflags, stderr, config_text);
   } else {
@@ -238,6 +232,13 @@ int main(int argc, char *argv[]) {
   extern char *optarg;
   FILE *inf;
 
   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);
   if (argv[1] && !strncmp(argv[1],"--",2)) {
     if (!strcmp(argv[1],"--help")) {
       printhelp(stdout);
@@ -251,7 +252,6 @@ int main(int argc, char *argv[]) {
   }
 
   maxpending= DEFMAXPENDING;
   }
 
   maxpending= DEFMAXPENDING;
-  opts= 0;
   while ((c= getopt(argc, argv, "c:C:dp")) != -1)
     switch (c) {
     case 'c':
   while ((c= getopt(argc, argv, "c:C:dp")) != -1)
     switch (c) {
     case 'c':
index f3244b901e329ce075a088622076b8c30c170f58..038b3ad8bad8ee0a3c0340760ad53725fe8222e5 100644 (file)
@@ -3,12 +3,8 @@
  * - filter which does resolving, not part of the library
  */
 /*
  * - 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
  *  
  *  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
@@ -171,6 +167,10 @@ static void parseargs(const char *const *argv) {
        config_text= arg;
       } else if (!strcmp(arg,"--debug")) {
        initflags |= adns_if_debug;
        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")) {
       } else if (!strcmp(arg,"--help")) {
        usage(); quitnow(0);
       } else if (!strcmp(arg,"--version")) {
index faba1bc57ce6082ceba13cdac1aa28cd6ff47875..0984399ed7be627af0b4fdda7e79c845b8aa80c8 100644 (file)
@@ -3,12 +3,8 @@
  * - simple test program, not part of the library
  */
 /*
  * - 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
  *  
  *  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
index 6e6fd8c70c78d9c514033ace14a6be630629db69..76d021902092910db0e7208eb7417e889cf01b84 100644 (file)
@@ -3,12 +3,8 @@
  * - useful declarations and definitions for adns client programs
  */
 /*
  * - 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
  *  
  *  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
 
 #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 \
 
 #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"
 
  "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"
 
index 6d6964b57b636f78617c23830c79085f1d17fb9b..d1cb2c79bbbdc77aa44e8c83a1569a80d078a453 100644 (file)
@@ -3,16 +3,8 @@
  * - a small test program from Tony Finch
  */
 /*
  * - 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
  *  
  *  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
index baced41bcbf6af42007d8cd29342b2f3b79a2a2b..5a5ba4d6ff30db095dc87907c62f0c465da1553a 100644 (file)
@@ -1,12 +1,8 @@
 #  common.make[.in] - common configuration settings for Makefiles,
 #  used by autoconf/configure to generate settings.make
 #  
 #  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
 #  
 #  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
@@ -22,7 +18,7 @@
 #  along with this program; if not, write to the Free Software Foundation.
 
 MAJOR=         1
 #  along with this program; if not, write to the Free Software Foundation.
 
 MAJOR=         1
-MINOR=         5
+MINOR=         6
 SHLIBFILE=     @SHLIBFILE@
 SHLIBSONAME=   @SHLIBSONAME@
 SHLIBFORLINK=  @SHLIBFORLINK@
 SHLIBFILE=     @SHLIBFILE@
 SHLIBSONAME=   @SHLIBSONAME@
 SHLIBFORLINK=  @SHLIBFORLINK@
@@ -33,7 +29,7 @@ LDFLAGS=      $(AUTOLDFLAGS) $(DIRLDFLAGS) $(XLDFLAGS)
 LDLIBS=                @LIBS@ $(XLIBS)
 AUTOCFLAGS=    @CFLAGS@
 AUTOLDFLAGS=   @LDFLAGS@
 LDLIBS=                @LIBS@ $(XLIBS)
 AUTOCFLAGS=    @CFLAGS@
 AUTOLDFLAGS=   @LDFLAGS@
-WARNS=         @WARNS@
+WARNS=         @WARNS@ -Wno-unused-value
 #WERROR=       -Werror
 
 M4=            m4
 #WERROR=       -Werror
 
 M4=            m4
@@ -45,11 +41,22 @@ MKSHLIB_1=  @MKSHLIB_1@
 MKSHLIB_2=     @MKSHLIB_2@
 MKSHLIB_3=     @MKSHLIB_3@
 
 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)
 
 AC_INSTALL=    @INSTALL@
 ifeq ($(AC_INSTALL),./install-sh -c)
@@ -60,4 +67,4 @@ endif
 
 INSTALL_PROGRAM=       $(INSTALL) -m 755 $(INSTALL_PROGRAM_FLAGS)
 INSTALL_DATA=          $(INSTALL) -m 644
 
 INSTALL_PROGRAM=       $(INSTALL) -m 755 $(INSTALL_PROGRAM_FLAGS)
 INSTALL_DATA=          $(INSTALL) -m 644
-
+INSTALL_DIR=           $(INSTALL) -d 755
index 825233cdb3801f74c7719203f380b6829dce17e0..b229e687f1988cac5cf551c69a9d06d1a18cee94 100755 (executable)
--- a/configure
+++ b/configure
@@ -664,6 +664,7 @@ infodir
 docdir
 oldincludedir
 includedir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -735,6 +736,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE}'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE}'
@@ -987,6 +989,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
   | -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=* \
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1124,7 +1135,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 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.
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1277,6 +1288,7 @@ Fine tuning of the installation directories:
   --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]
   --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]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
index 712572e22baac1e5cbe4b058fc3320a2a612ce99..b753a5bb3e235b30d61b50e9a57dad25f384995b 100644 (file)
@@ -1,11 +1,7 @@
 # configure.in - input to autoconf
 #  
 # 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
 #  
 #  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
index 0784e6aedfc938408cc6decc8979bd07e8494db6..d9151bd92ca6889e6e5dc0fe34ea0531f1ac279f 100644 (file)
@@ -1,11 +1,7 @@
 # dynamic/Makefile - dynamic library Makefile
 # 
 # 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
 #  
 #  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
@@ -31,9 +27,9 @@ ALLOBJS=      $(addsuffix _p.o, $(basename $(LIBOBJS)))
 
 install:
                mkdir -p $(libdir)
 
 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)
 
 uninstall:
                rm -f $(libdir)/$(SHLIBFILE) $(libdir)/$(SHLIBSONAME)
index 21e71563aab89da9937b274fd895fdcc2d046580..eb63a20442521eaa3678811aaae44cd782d63af6 100644 (file)
@@ -1,11 +1,7 @@
 # regress/Makefile[.in] - regression test Makefile
 # 
 # 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
 #  
 #  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
@@ -27,19 +23,23 @@ PROGS_SYSDEP=       @PROGS_HAVE_TSEARCH@
 
 CLIENTS=       adnstest adnshost adnslogres $(PROGS_SYSDEP)
 AUTOCHDRS=     harness.h hsyscalls.h hredirect.h
 
 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.
 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)
 
 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
 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)
 
 
 .PRECIOUS:     $(AUTOCSRCS) $(AUTOCHDRS)
 
@@ -51,15 +51,53 @@ check:              $(TARGETS) $(addprefix check-,$(ALL_TESTS))
                @echo
                @echo 'all tests passed or maybe skipped.'
 
                @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
 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 $@
 
 
 LINK_CMD=      $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
 
-%_record:      %_c.o hrecord.o $(HARNLOBJS)
+%_record:      %_c.o hrecord.o hnonfuzz.o $(HARNLOBJS)
                $(LINK_CMD)
 
                $(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)))
                $(LINK_CMD)
 
 .SECONDARY: $(addsuffix _c.o, $(filter-out adnshost, $(CLIENTS)))
@@ -72,13 +110,19 @@ LINK_CMD=  $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
 #
 # See also Savannah #29620, http://savannah.gnu.org/bugs/index.php?29620
 
 #
 # 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)
 
                $(LINK_CMD)
 
-%_d.o:         $(srcdir)/../src/%.c hredirect.h
+%_d.o:         $(srcdir)/../src/%.c hredirect.h hsyscalls.h
                $(CC) $(CFLAGS) $(HCPPFLAGS) -c -g -o $@ $<
 
                $(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
                $(CC) $(CFLAGS) $(HCPPFLAGS) -I $(srcdir)/../src -c -g -o $@ $<
 
 $(ALL_OBJS):   $(srcdir)/../src/adns.h $(srcdir)/../src/internal.h
index 3da3aa3aa6ec0984bddf7c609bb699683e1e2b18..ad41a4865d76e386c96dc21df72216f5d045dba6 100755 (executable)
@@ -1,12 +1,8 @@
 #!/bin/sh
 # usage: ./addcases <casename> ...
 #
 #!/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
 #  
 #  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
diff --git a/regress/case-adh-reverse-pipe.err b/regress/case-adh-reverse-pipe.err
new file mode 100644 (file)
index 0000000..e2a64b2
--- /dev/null
@@ -0,0 +1,4 @@
+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
diff --git a/regress/case-adh-reverse-pipe.out b/regress/case-adh-reverse-pipe.out
new file mode 100644 (file)
index 0000000..3d19c6a
--- /dev/null
@@ -0,0 +1,2 @@
+1.0.0.127.in-addr.arpa PTR localhost
+rc=0
diff --git a/regress/case-adh-reverse-pipe.sys b/regress/case-adh-reverse-pipe.sys
new file mode 100644 (file)
index 0000000..128817c
--- /dev/null
@@ -0,0 +1,136 @@
+./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
diff --git a/regress/case-monotonic.err b/regress/case-monotonic.err
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/regress/case-monotonic.out b/regress/case-monotonic.out
new file mode 100644 (file)
index 0000000..a55f101
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/regress/case-monotonic.sys b/regress/case-monotonic.sys
new file mode 100644 (file)
index 0000000..ff56db1
--- /dev/null
@@ -0,0 +1,219 @@
+./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
diff --git a/regress/categorisefuzz b/regress/categorisefuzz
new file mode 100755 (executable)
index 0000000..2208906
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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
diff --git a/regress/check1fuzz b/regress/check1fuzz
new file mode 100755 (executable)
index 0000000..5f1a0b2
--- /dev/null
@@ -0,0 +1,52 @@
+#!/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
index a404fa87a06bef857b912dbae5f0aa430c8ec7cc..a6cb2298bd9f7aa5a0daa9c32b29d1414f646506 100755 (executable)
@@ -2,12 +2,8 @@
 # usage: checkall
 # runs all test cases
 #
 # 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
 #  
 #  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
diff --git a/regress/harness.h b/regress/harness.h
deleted file mode 100644 (file)
index 85a936b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#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
index 5d17ca358780c35f83029dfdef1483faae9c66eb..1f24f2255fe0afee4e3432aea4777bd1698466f7 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl harness.h.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - function and other declarations
 
 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_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
@@ -39,6 +35,7 @@ hm_create_proto_q
 m4_define(`hm_syscall', `void Q$1(hm_args_massage($3,void));')
 m4_define(`hm_specsyscall', `')
 m4_include(`hsyscalls.i4')
 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 Q_vb(void);
 
@@ -50,7 +47,7 @@ void Tfailed(const char *why);
 void Toutputerr(void);
 void Tnomem(void);
 void Tfsyscallr(const char *fmt, ...) PRINTFFORMAT(1,2);
 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);
 void Tmust(const char *call, const char *arg, int cond);
 
 void Tvbf(const char *fmt, ...) PRINTFFORMAT(1,2);
@@ -67,9 +64,15 @@ void Tvba(const char *str);
 extern vbuf vb;
 extern struct timeval currenttime;
 extern const struct Terrno { const char *n; int v; } Terrnos[];
 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;
 
 
 /* Special cases */
   
 void Texit(int rv) NONRETURNING;
 
+void Tcommonshutdown(void);
+void Tmallocshutdown(void);
+int Ttestinputfd(void);
+void T_gettimeofday_hook(void);
+
 #endif
 #endif
diff --git a/regress/hcommon.c b/regress/hcommon.c
deleted file mode 100644 (file)
index 0aa3ffb..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-#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 */
-}
index 6f29b41a15abc594d8f3ce2a0424f85abfea528d..3fd2a103865b56bdc837faa4e6b76cb8a52d7166 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hcommon.c
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - routines used for both record and playback
 
 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
 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
@@ -36,6 +32,7 @@ m4_include(hmacros.i4)
 
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <time.h>
 
 #include "harness.h"
 #include "internal.h"
 
 #include "harness.h"
 #include "internal.h"
@@ -64,14 +61,28 @@ const struct Terrno Terrnos[]= {
   {  0,                          0                            }
 };
 
   {  0,                          0                            }
 };
 
+const int Tnerrnos= sizeof(Terrnos)/sizeof(Terrnos[0]) - 1;
+
 static vbuf vbw;
 
 int Hgettimeofday(struct timeval *tv, struct timezone *tz) {
 static vbuf vbw;
 
 int Hgettimeofday(struct timeval *tv, struct timezone *tz) {
-  Tensurerecordfile();
+  Tensuresetup();
   Tmust("gettimeofday","tz",!tz);
   Tmust("gettimeofday","tz",!tz);
+  T_gettimeofday_hook();
   *tv= currenttime;
   return 0;
 }
   *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;
 
 int Hwritev(int fd, const struct iovec *vector, size_t count) {
   size_t i;
@@ -132,6 +143,8 @@ m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
 
 
 m4_include(`hsyscalls.i4')
 
+hm_stdsyscall_close
+
 void Tvbaddr(const struct sockaddr *addr, int len) {
   char buf[ADNS_ADDR2TEXT_BUFLEN];
   int err, port;
 void Tvbaddr(const struct sockaddr *addr, int len) {
   char buf[ADNS_ADDR2TEXT_BUFLEN];
   int err, port;
@@ -250,84 +263,8 @@ void Toutputerr(void) {
   Tfailed("write error on test harness output");
 }
 
   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) {
 void Hexit(int rv) {
+  Tensuresetup();
   vb.used= 0;
   Tvbf("exit %d", rv);
   Q_vb();
   vb.used= 0;
   Tvbf("exit %d", rv);
   Q_vb();
@@ -338,3 +275,9 @@ pid_t Hgetpid(void) {
   return 2264; /* just some number */
 }
 
   return 2264; /* just some number */
 }
 
+void Tcommonshutdown(void) {
+  Tshutdown();
+  adns__vbuf_free(&vb);
+  adns__vbuf_free(&vbw);
+  Tmallocshutdown();
+}
diff --git a/regress/hfuzz.c b/regress/hfuzz.c
new file mode 100644 (file)
index 0000000..5d23368
--- /dev/null
@@ -0,0 +1,138 @@
+/* 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); }
diff --git a/regress/hfuzzraw.c.m4 b/regress/hfuzzraw.c.m4
new file mode 100644 (file)
index 0000000..fa54c53
--- /dev/null
@@ -0,0 +1,349 @@
+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, &currenttime, &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();
+}
index 123b8a3bcc63e5c5d21cca2bdd72456ea4b595bb..8aaf7a6b61c8def933f9eb8323c97931fe1aa8c6 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hmacros.h.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - common macros
 
 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_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
@@ -54,6 +50,15 @@ m4_define(`hm_create_nothing', `
  m4_define(`hm_arg_bytes_in', `')
  m4_define(`hm_arg_bytes_out', `')
  m4_define(`hm_arg_addr_out', `')
  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_create_proto_h',`
@@ -103,7 +108,7 @@ m4_define(`hm_create_hqcall_init',`
  m4_define(`hm_arg_fcntl_cmd_arg',`
   Tmust("$1","$'`1",$'`1==F_SETFL || $'`1==F_GETFL);
   if ($'`1 == F_SETFL) {
  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;
   }')
   } else {
     $'`2= 0;
   }')
@@ -138,3 +143,7 @@ m4_define(`hm_create_hqcall_args',`
  m4_define(`hm_arg_bytes_out', `$'`4')
  m4_define(`hm_arg_addr_out', `*$'`2')
 ')
  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";
+')
diff --git a/regress/hnonfuzz.c b/regress/hnonfuzz.c
new file mode 100644 (file)
index 0000000..eff569e
--- /dev/null
@@ -0,0 +1,116 @@
+/* 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);
+  }
+}
diff --git a/regress/hplayback.c b/regress/hplayback.c
deleted file mode 100644 (file)
index ed23542..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-#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;
-}
index ad27a9aee0bb8da04c4be0725e94dbc0ba352b3f..7e688bf1eac04f7ca2c5937ab17b16d87f7933e8 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hplayback.c.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - playback routines
 
 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
 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
@@ -37,17 +33,15 @@ m4_include(hmacros.i4)
 
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <limits.h>
+
 
 #include "harness.h"
 
 
 #include "harness.h"
 
-static FILE *Tinputfile, *Treportfile;
+static FILE *Tinputfile, *Tfuzzrawfile, *Treportfile;
 static vbuf vb2;
 
 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;
 
   const char *fdstr;
   int fd;
 
@@ -58,6 +52,36 @@ static void Tensurereportfile(void) {
   Treportfile= fdopen(fd,"a"); if (!Treportfile) Tfailed("fdopen ADNS_TEST_REPORT_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);
 static void Psyntax(const char *where) {
   fprintf(stderr,"adns test harness: syntax error in test log input file: %s\n",where);
   exit(-1);
@@ -68,17 +92,27 @@ static void Pcheckinput(void) {
   if (feof(Tinputfile)) Psyntax("eof at syscall reply");
 }
 
   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(&currenttime, &previously, &delta);
+  previously = currenttime;
+  FR_WRITE(delta);
+}
+
+void Tensuresetup(void) {
   int fd;
   int chars;
   unsigned long sec, usec;
 
   int fd;
   int chars;
   unsigned long sec, usec;
 
+  Tensure_reportfile();
+  Tensure_fuzzrawfile();
+
   if (Tinputfile) return;
   Tinputfile= stdin;
   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);
     Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD");
   }
   setvbuf(Tinputfile,0,_IONBF,0);
@@ -126,29 +160,37 @@ static int Perrno(const char *stuff) {
   if (te->n) return te->v;
   r= strtoul(stuff+2,&ep,10);
   if (*ep) Psyntax("errno value not recognised, not numeric");
   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;
   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;
 
   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;
   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_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) {
   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) {
   char *ep;
 
   if (!set) {
@@ -158,16 +200,33 @@ static void Pfdset(fd_set *set, int max) {
   
   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) 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++;
   }
 }
 
   }
 }
 
@@ -200,12 +259,15 @@ static void Ppollfds(struct pollfd *fds, int nfds) {
   if (vb2.buf[vb2.used++] != hm_squote[hm_squote) Psyntax("pollfds start not [");
   for (i=0; i<nfds; i++) {
     Pstring("{fd=","{fd= in pollfds");
   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");
     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();
     Pstring(", revents=",", revents= in pollfds");
     fds->revents= Ppollfdevents();
+    if (gotevents) FR_WRITE(fds->revents);
     Pstring("}","} in pollfds");
     Pstring(comma,"separator in pollfds");
     comma= ", ";
     Pstring("}","} in pollfds");
     Pstring(comma,"separator in pollfds");
     comma= ", ";
@@ -237,6 +299,14 @@ static void Paddr(struct sockaddr *addr, int *lenr) {
   if (*ep && *ep != ' ') Psyntax("invalid port (bad syntax)");
   if (ul >= 65536) Psyntax("port too large");
 
   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");
   a.len= sizeof(a.addr);
   err= adns_text2addr(p, (int)ul, 0, &a.addr.sa,&a.len);
   if (err) Psyntax("invalid address");
@@ -276,7 +346,7 @@ static int Pbytes(byte *buf, int maxlen) {
 void Q_vb(void) {
   const char *nl;
 
 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)) {
   if (!adns__vbuf_ensure(&vb2,vb.used+2)) Tnomem();
   fread(vb2.buf,1,vb.used+2,Tinputfile);
   if (feof(Tinputfile)) {
@@ -294,7 +364,6 @@ void Q_vb(void) {
             vb.used,vb.buf, vb.used,vb2.buf+1);
     exit(1);
   }
             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);
 }
   nl= memchr(vb.buf,'\n',vb.used);
   fprintf(Treportfile," %.*s\n", (int)(nl ? nl - (const char*)vb.buf : vb.used), vb.buf);
 }
@@ -303,12 +372,9 @@ m4_define(`hm_syscall', `
  hm_create_proto_h
 int H$1(hm_args_massage($3,void)) {
  int r, amtread;
  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_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
  $2
 
  hm_create_hqcall_vars
@@ -324,7 +390,7 @@ int H$1(hm_args_massage($3,void)) {
  if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
  fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
 
  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)
  fprintf(Treportfile,"%s",vb2.buf);
  amtread= strlen(vb2.buf);
  if (amtread<=0 || vb2.buf[--amtread]!=hm_squote\nhm_squote)
@@ -332,27 +398,56 @@ int H$1(hm_args_massage($3,void)) {
  vb2.buf[amtread]= 0;
  if (memcmp(vb2.buf," $1=",hm_r_offset)) Psyntax("syscall reply mismatch");
 
  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;
  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;
  }
   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;
  ')
   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;
  ')
   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_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) {
  m4_define(`hm_rv_fcntl',`
   r= 0;
   if (cmd == F_GETFL) {
@@ -365,7 +460,7 @@ int H$1(hm_args_massage($3,void)) {
       Psyntax("fcntl flags not O_NONBLOCK|... or ~O_NONBLOCK&...");
     }
   } else if (cmd == F_SETFL) {
       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");
   }
   } else {
     Psyntax("fcntl not F_GETFL or F_SETFL");
   }
@@ -381,7 +476,11 @@ int H$1(hm_args_massage($3,void)) {
  if (vb2.used != amtread) Psyntax("junk at end of line");
 
  hm_create_nothing
  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();
  $3
 
  P_updatetime();
@@ -392,3 +491,5 @@ int H$1(hm_args_massage($3,void)) {
 m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
 m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
+
+hm_stdsyscall_close
diff --git a/regress/hrecord.c b/regress/hrecord.c
deleted file mode 100644 (file)
index dec099b..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-#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(&currenttime,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;
-}
index b9d5a73e412f455bf1fef34f3da1778fef58da45..94e661760a1e57a369b2dad89d2031e71ec1e6f8 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hrecord.c.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - recording routines
 
 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
 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
@@ -44,7 +40,7 @@ static void R_recordtime(void) {
   int r;
   struct timeval tv, tvrel;
 
   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;
   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;
@@ -53,7 +49,9 @@ static void R_recordtime(void) {
   currenttime= tv;
 }
 
   currenttime= tv;
 }
 
-void Tensurerecordfile(void) {
+void T_gettimeofday_hook(void) { }
+
+void Tensuresetup(void) {
   const char *fdstr;
   int fd, r;
 
   const char *fdstr;
   int fd, r;
 
@@ -73,7 +71,7 @@ void Tensurerecordfile(void) {
 
 void Q_vb(void) {
   if (!adns__vbuf_append(&vb,"",1)) Tnomem();
 
 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();
 }
   if (fprintf(Toutputfile," %s\n",vb.buf) == EOF) Toutputerr();
   if (fflush(Toutputfile)) Toutputerr();
 }
@@ -112,7 +110,7 @@ int H$1(hm_args_massage($3,void)) {
  m4_define(`hm_rv_must',`Tmust("$1","return",!r); Tvba("OK");')
  m4_define(`hm_rv_len',`
   if (r==-1) { Tvberrno(e); goto x_error; }
  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; }
   Tvba("OK");')
  m4_define(`hm_rv_fcntl',`
   if (r==-1) { Tvberrno(e); goto x_error; }
@@ -138,6 +136,7 @@ int H$1(hm_args_massage($3,void)) {
  m4_define(`hm_arg_bytes_out',`Tvbbytes($'`2,r);')
  $3
 
  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_rv_any',`x_error:')
  m4_define(`hm_rv_fd',`x_error:')
  m4_define(`hm_rv_succfail',`x_error:')
@@ -156,3 +155,5 @@ int H$1(hm_args_massage($3,void)) {
 m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
 m4_define(`hm_specsyscall', `')
 
 m4_include(`hsyscalls.i4')
+
+hm_stdsyscall_close
diff --git a/regress/hredirect.h b/regress/hredirect.h
deleted file mode 100644 (file)
index 7bff129..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#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
index ccb48f0d2bb8d126d49a430d2361bac535df350e..f2d5618e2c25607789e5344ec51dbfcb4bffd187 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hredirect.h.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - redefinitions of system calls
 
 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
 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
@@ -36,4 +32,7 @@ m4_define(`hm_specsyscall',`#undef $2
 #define $2 H$2')
 m4_include(`hsyscalls.i4')
 
 #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
 #endif
diff --git a/regress/hsyscalls.h b/regress/hsyscalls.h
deleted file mode 100644 (file)
index 6dc9edc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#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
index 74008950c4a7cdef344fe213485f4e9d90d1aa4b..53c5ef645804c31945d00b4a41b8ba0ec4af31cd 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hsyscalls.h.m4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - prototypes of redefinitions of system calls
 
 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  
 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
index a480e6a253cf3cbc0ae6de5c920070c5d053548d..852cc93b263c6efe0c6cc8194b51cd0821467edd 100644 (file)
@@ -2,12 +2,8 @@ m4_dnl hsyscalls.i4
 m4_dnl (part of complex test harness, not of the library)
 m4_dnl - list of syscalls to override/log and their args
 
 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  
 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
@@ -29,8 +25,11 @@ m4_dnl  hm_rv_must       must succeed and return 0
 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_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_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 <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
@@ -53,7 +52,7 @@ m4_dnl   return value from syscall is supposed to be returned length
 m4_dnl  hm_arg_addr_out(<arg>,<lenptr>) struct sockaddr*, length io at <lenptr> (an int*)
 
 hm_syscall(
 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
        hm_arg_int(max) hm_na
        hm_arg_fdset_io(rfds,max) hm_na
        hm_arg_fdset_io(wfds,max) hm_na
@@ -63,7 +62,7 @@ hm_syscall(
 
 #ifdef HAVE_POLL
 hm_syscall(
 
 #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_arg_pollfds_io(fds,nfds) hm_na
        hm_arg_int(timeout) hm_na
 ')
@@ -101,12 +100,7 @@ hm_syscall(
 ')
 
 hm_syscall(
 ')
 
 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_arg_fd(fd) hm_na
        hm_arg_bytes_in(void,msg,int,msglen) hm_na
        hm_arg_must(unsigned int,flags,0) hm_na
@@ -128,16 +122,27 @@ hm_syscall(
 ')
 
 hm_syscall(
 ')
 
 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_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(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(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')
index e5411dcf355e31845cf07ff25da085c9eb15c40c..37fab254f7c1dc2403e8b1d07fb70dc42afb5be0 100755 (executable)
@@ -2,12 +2,8 @@
 # usage: m1test <name> <initfile> [<initflags>] <queryargs>'
 # test recording script
 #
 # 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
 #  
 #  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
@@ -67,7 +63,7 @@ queryargs="$*"
 
 initstring="`cat $srcdir/init-$initfile.text`"
 xinitflagsf=$srcdir/$program-xinitflags.text
 
 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
 then
        useinitflags="$initflags $(cat $xinitflagsf)";
 else
diff --git a/regress/make1fuzz b/regress/make1fuzz
new file mode 100755 (executable)
index 0000000..e121094
--- /dev/null
@@ -0,0 +1,62 @@
+#!/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
index e03ba0216c628dd268dad487874adc31a94e1152..f61089af2d01b78c9ff66d2b0be81a4738ba7789 100755 (executable)
@@ -2,12 +2,8 @@
 # usage: r1test <testcasename>
 # test execution script, for running one test
 #
 # 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
 #  
 #  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=.}
 
 set -e
 : ${srcdir=.}
+. "$srcdir"/shlib
 mrc=1
 trap 'exit $mrc' 0
 
 casename="$1"
 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
 
 
 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
 
 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
 
 if [ "$rc" = 5 ]
 then
diff --git a/regress/shlib b/regress/shlib
new file mode 100644 (file)
index 0000000..eabe631
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- 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
+}
index 47eaaa71570a3e4ad68889da928a31917240179b..dfba4eaf71006eabec18590add0979e383fc4f73 100644 (file)
@@ -1,12 +1,8 @@
 # settings.make[.in] - main configuration settings for Makefiles,
 #  used by autoconf/configure to generate settings.make
 #  
 # 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
 #  
 #  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
@@ -26,14 +22,15 @@ include             ../common.make
 all:                   $(TARGETS)
 
 clean mostlyclean:
 all:                   $(TARGETS)
 
 clean mostlyclean:
+               rm -f $(TARGETS) $(AUTOCSRCS) $(AUTOCHDRS)
                rm -f *.o *.tmp* *.so *.so.* pipe.*
                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
 
 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
 
 maintainer-clean:      distclean
-               -rm -f $(AUTOCSRCS) $(AUTOCHDRS)
index 449289b3097f2bebbe69796b5a5416e462e0c4f1..559257985b5f0cbb6259fc22868a4fe2bf695001 100644 (file)
@@ -1,11 +1,7 @@
 # src/Makefile[.in] - library main Makefile
 # 
 # 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
 #  
 #  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
@@ -32,8 +28,10 @@ DIRCFLAGS=   -I. -I$(srcdir)
 install:
                mkdir -p $(libdir) $(includedir)
                set -xe; for f in $(TARGETS); \
 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
 
 uninstall:
                for f in $(TARGETS); do rm -f $(libdir)/$$f; done
index 0ba204920529b980927374a75feca4bae51b389a..dece6e3d1ce1efeb578d314ed520cd7219e509da 100644 (file)
@@ -3,12 +3,8 @@
  * - address-family specific code
  */
 /*
  * - 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 program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
index a6599f6db3cb13e8e5e1c4b1cc754b706bdb1e99..ba44b06c972add406a5c565d6aae008f1c1bb244 100644 (file)
@@ -4,11 +4,8 @@
  */
 /*
  *
  */
 /*
  *
- *  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
  *
  *    Copyright (C) 1999-2000,2003,2006 Tony Finch
  *    Copyright (C) 1991 Massachusetts Institute of Technology
  *
@@ -103,6 +100,7 @@ typedef enum { /* In general, or together the desired flags: */
  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_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!) */
 
  adns_if_checkc_entex=0x0100,/* consistency checks on entry/exit to adns fns */
  adns_if_checkc_freq= 0x0300,/* consistency checks very frequently (slow!) */
 
@@ -488,6 +486,21 @@ typedef struct {
  *   these approaches has optimal performance.
  */
 
  *   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*/);
 
 int adns_init(adns_state *newstate_r, adns_initflags flags,
              FILE *diagfile /*0=>stderr*/);
 
@@ -822,6 +835,8 @@ int adns_processexceptional(adns_state ads, int fd, const struct timeval *now);
  * use that fd and only in the manner specified, regardless of whether
  * adns_if_noautosys was specified.
  *
  * 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.
  *
  * adns_processexceptional should be called when select(2) reports an
  * exceptional condition, or poll(2) reports POLLPRI.
  *
@@ -837,15 +852,19 @@ void adns_processtimeouts(adns_state ads, const struct timeval *now);
 /* Gives adns flow-of-control so that it can process any timeouts
  * which might have happened.  Very like _processreadable/writeable.
  *
 /* 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
  */
 
 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
  * 
  * 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
@@ -869,8 +888,9 @@ void adns_globalsystemfailure(adns_state ads);
  * adns_s_systemfail, and adns will close any stream sockets it has
  * open.
  *
  * 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.
  */
  *
  * This call will never block.
  */
@@ -886,9 +906,11 @@ void adns_beforeselect(adns_state ads, int *maxfd, fd_set *readfds,
 /* 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
 /* 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.
  *
  * 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
  * 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
@@ -902,6 +924,8 @@ void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds,
  * 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.
  * 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.
  */
 
 /*
  */
 
 /*
@@ -965,6 +989,8 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds,
  * descriptors, and use _firsttimeout is used to find out when adns
  * might want to time something out.)
  *
  * 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).
  *
  * adns_beforepoll will return 0 on success, and will not fail for any
  * reason other than the fds buffer being too small (ERANGE).
  *
@@ -987,6 +1013,8 @@ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds,
 /* 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.
 /* 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.
  */
 
 
  */
 
 
@@ -1057,8 +1085,13 @@ const char *adns_errtypeabbrev(adns_status st);
  * 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
  * 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
  */
 
 #ifdef __cplusplus
index 076df8bf59e25bf16bf371ac8bcee7b5ba931e93..64a42f2dc433d8d8df5d5bd63997c9bb763425c8 100644 (file)
@@ -1,11 +1,7 @@
 # src/adns.make - library definitions, including list of object files
 # 
 # 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
 #  
 #  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
index fcf1995e31db188566c90d22e5791907f2fe4485..ead1249971000678ddd5db2429e10882966692e1 100644 (file)
@@ -3,12 +3,8 @@
  * - consistency checks
  */
 /*
  * - 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
  *  
  *  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
@@ -136,14 +132,19 @@ static void checkc_queue_tcpw(adns_state ads) {
 }
 
 static void checkc_queue_childw(adns_state ads) {
 }
 
 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);
 
   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);
     });
     checkc_query(ads,parent);
     checkc_query_alloc(ads,parent);
@@ -182,7 +183,10 @@ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) {
   switch (cc) {
   case cc_user:
     break;
   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;
     if (!(ads->iflags & adns_if_checkc_entex)) return;
     assert(!ads->intdone.head);
     break;
index bd36686d648b7b6ea9007a10a1c3c4c7dc5ea351..e48c7ea470739346ccbc58720e1cf81b82a86308 100644 (file)
@@ -1,4 +1,25 @@
-/* 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 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 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
 
 #undef HAVE_LIBNSL
 
-/* Define if you have the socket library (-lsocket).  */
+/* Define to 1 if you have the `socket' library (-lsocket). */
 #undef HAVE_LIBSOCKET
 
 #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
 /* Use the definitions: */
 
 #ifndef HAVE_INLINE
index 8d83af283bd34f1e340d3d071e248ef368ca4b40..0efb3101d6e5d9874ca711f531630670bf0983b1 100644 (file)
@@ -3,12 +3,8 @@
  * - macros for handling doubly linked lists
  */
 /*
  * - 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
  *  
  *  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
index dcc49e9cc72b0562d0ec42d8ca6dab57e11ede5e..14c9ee9caee46cee23c0e80c66eae61cb29c6419 100644 (file)
@@ -5,12 +5,8 @@
  * - user-visible check/wait and event-loop-related functions
  */
 /*
  * - 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
  *  
  *  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
@@ -36,6 +32,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <time.h>
 
 #include "internal.h"
 #include "tvarith.h"
 
 #include "internal.h"
 #include "tvarith.h"
@@ -149,6 +146,19 @@ void adns__tcp_tryconnect(adns_state ads, struct timeval now) {
 
 /* Timeout handling functions. */
 
 
 /* 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;
 void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
                             struct timeval *tv_buf) {
   const struct timeval *now;
@@ -156,8 +166,9 @@ void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
 
   now= *now_io;
   if (now) return;
 
   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;
 }
   adns_globalsystemfailure(ads);
   return;
 }
@@ -209,11 +220,16 @@ static void timeouts_queue(adns_state ads, int act,
                           struct timeval **tv_io, struct timeval *tvbuf,
                           struct timeval now, struct query_queue *queue) {
   adns_query qu, nqu;
                           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;
   
   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);
     } else {
       if (!act) { inter_immed(tv_io,tvbuf); return; }
       LIST_UNLINK(*queue,qu);
@@ -284,7 +300,7 @@ void adns__timeouts(adns_state ads, int act,
 void adns_firsttimeout(adns_state ads,
                       struct timeval **tv_io, struct timeval *tvbuf,
                       struct timeval now) {
 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);
 }
   adns__timeouts(ads, 0, tv_io,tvbuf, now);
   adns__returning(ads,0);
 }
@@ -292,7 +308,7 @@ void adns_firsttimeout(adns_state ads,
 void adns_processtimeouts(adns_state ads, const struct timeval *now) {
   struct timeval tv_buf;
 
 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);
   adns__must_gettimeofday(ads,&now,&tv_buf);
   if (now) adns__timeouts(ads, 1, 0,0, *now);
   adns__returning(ads,0);
@@ -346,7 +362,7 @@ int adns_processreadable(adns_state ads, int fd, const struct timeval *now) {
   struct udpsocket *udp;
   adns_sockaddr udpaddr;
   
   struct udpsocket *udp;
   adns_sockaddr udpaddr;
   
-  adns__consistency(ads,0,cc_entex);
+  adns__consistency(ads,0,cc_enter);
 
   switch (ads->tcpstate) {
   case server_disconnected:
 
   switch (ads->tcpstate) {
   case server_disconnected:
@@ -433,7 +449,7 @@ xit:
 int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) {
   int r;
   
 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:
 
   switch (ads->tcpstate) {
   case server_disconnected:
@@ -461,7 +477,7 @@ int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) {
       }
       assert(FD_ISSET(ads->tcpsocket,&writeable));
       if (!adns__vbuf_ensure(&ads->tcprecv,1)) { r= ENOMEM; goto xit; }
       }
       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;
       if (r==0 || (r<0 && (errno==EAGAIN || errno==EWOULDBLOCK))) {
        tcp_connected(ads,*now);
        r= 0; goto xit;
@@ -488,6 +504,7 @@ int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) {
        adns__tcp_broken(ads,"write",strerror(errno));
        r= 0; goto xit;
       } else if (r>0) {
        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);
       }
        ads->tcpsend.used -= r;
        memmove(ads->tcpsend.buf,ads->tcpsend.buf+r,ads->tcpsend.used);
       }
@@ -505,7 +522,7 @@ xit:
   
 int adns_processexceptional(adns_state ads, int fd,
                            const struct timeval *now) {
   
 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:
   switch (ads->tcpstate) {
   case server_disconnected:
   case server_broken:
@@ -574,7 +591,7 @@ void adns_beforeselect(adns_state ads, int *maxfd_io, fd_set *readfds_io,
   struct pollfd pollfds[MAX_POLLFDS];
   int i, fd, maxfd, npollfds;
   
   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. */
 
   if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) {
     /* The caller is planning to sleep. */
@@ -605,7 +622,7 @@ void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds,
   struct pollfd pollfds[MAX_POLLFDS];
   int npollfds, i;
 
   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);
   adns__must_gettimeofday(ads,&now,&tv_buf);
   if (!now) goto xit;
   adns_processtimeouts(ads,now);
@@ -623,10 +640,24 @@ xit:
 /* General helpful functions. */
 
 void adns_globalsystemfailure(adns_state ads) {
 /* 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:
   
   switch (ads->tcpstate) {
   case server_connecting:
@@ -648,9 +679,9 @@ int adns_processany(adns_state ads) {
   struct pollfd pollfds[MAX_POLLFDS];
   int npollfds;
 
   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.
   if (!r) adns_processtimeouts(ads,&now);
 
   /* We just use adns__fdevents to loop over the fd's trying them.
@@ -707,7 +738,7 @@ int adns_wait(adns_state ads,
   fd_set readfds, writefds, exceptfds;
   struct timeval tvbuf, *tvp;
   
   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;
   for (;;) {
     r= adns__internal_check(ads,query_io,answer_r,context_r);
     if (r != EAGAIN) break;
@@ -739,8 +770,8 @@ int adns_check(adns_state ads,
   struct timeval now;
   int r;
   
   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);
   if (!r) adns__autosys(ads,now);
 
   r= adns__internal_check(ads,query_io,answer_r,context_r);
index c4d1f5573774b6089688b6c22e0e4d2e2d301ff5..183c4877ecdfdf24272407ee00f4c74f5b9444e4 100644 (file)
@@ -4,12 +4,8 @@
  * - vbuf handling
  */
 /*
  * - 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
  *  
  *  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
@@ -219,7 +215,7 @@ adns_status adns_rr_info(adns_rrtype type,
   if (!datap) return adns_s_ok;
   
   adns__vbuf_init(&vb);
   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);
   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);
@@ -288,14 +284,14 @@ const char *adns_strerror(adns_status st) {
   const struct sinfo *si;
 
   si= findsinfo(st);
   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);
 }
 
 const char *adns_errabbrev(adns_status st) {
   const struct sinfo *si;
 
   si= findsinfo(st);
-  return si->abbrev;
+  return si ? si->abbrev : 0;
 }
 
 
 }
 
 
@@ -332,7 +328,7 @@ const char *adns_errtypeabbrev(adns_status st) {
 
   sti= bsearch(&st,stinfos, sizeof(stinfos)/sizeof(*stinfos),
               sizeof(*stinfos), sti_compar);
 
   sti= bsearch(&st,stinfos, sizeof(stinfos)/sizeof(*stinfos),
               sizeof(*stinfos), sti_compar);
-  return sti->abbrev;
+  return sti ? sti->abbrev : 0;
 }
 
 
 }
 
 
index 00cf8258b7b6849382d923e002200cafc2c2c719..083f429f4adbdb80dd24e4b2750d5f2651d34322 100644 (file)
@@ -5,12 +5,8 @@
  * - comments regarding library data structures
  */
 /*
  * - 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
  *
  *  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
@@ -53,7 +49,7 @@ typedef unsigned char byte;
 
 /* Configuration and constants */
 
 
 /* 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
 #define MAXSORTLIST 15
 #define UDPMAXRETRIES 15
 #define UDPRETRYMS 2000
@@ -95,7 +91,8 @@ typedef unsigned char byte;
 
 typedef enum {
   cc_user,
 
 typedef enum {
   cc_user,
-  cc_entex,
+  cc_enter,
+  cc_exit,
   cc_freq
 } consistency_checks;
 
   cc_freq
 } consistency_checks;
 
@@ -170,7 +167,7 @@ typedef struct typeinfo {
    * Previously, used alloc_interim, now use alloc_final.
    */
 
    * 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.
   /* 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.
@@ -246,7 +243,7 @@ union maxalign {
   void *p;
   void (*fp)(void);
   union maxalign *up;
   void *p;
   void (*fp)(void);
   union maxalign *up;
-} data;
+};
 
 struct adns__query {
   adns_state ads;
 
 struct adns__query {
   adns_state ads;
@@ -297,7 +294,8 @@ struct adns__query {
   int id, flags, retries;
   int udpnextserver;
   unsigned long udpsent; /* bitmap indexed by server */
   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;
   time_t expires; /* Earliest expiry time of any record we used. */
 
   qcontext ctx;
@@ -371,7 +369,8 @@ struct adns__state {
   int configerrno;
   struct query_queue udpw, tcpw, childw, output, intdone;
   adns_query forallnext;
   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;
   struct udpsocket { int af; int fd; } udpsockets[MAXUDP];
   int nudpsockets;
   vbuf tcpsend, tcprecv;
@@ -719,6 +718,8 @@ void adns__returning(adns_state ads, adns_query qu);
  * external-faciing functions which call adns__returning should
  * normally be avoided in internal code. */
 
  * 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,
 /* From reply.c: */
 
 void adns__procdgram(adns_state ads, const byte *dgram, int len,
@@ -881,6 +882,17 @@ void adns__autosys(adns_state ads, struct timeval now);
  * lest we end up in recursive descent !
  */
 
  * 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! */
 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! */
@@ -934,7 +946,7 @@ static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; }
   (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) )        \
    * sizeof(union maxalign) )
 
   (( ((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,                         \
 #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,                         \
index 07d0614afcbf6d002849e99c1940bbda64a3cd06..3652b323632e94026a63246a48618e68527e5f20 100644 (file)
@@ -3,12 +3,8 @@
  * - parsing assistance functions (mainly for domains inside datagrams)
  */
 /*
  * - 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
  *  
  *  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
@@ -71,6 +67,7 @@ adns_status adns__findlabel_next(findlabel_state *fls,
                                 int *lablen_r, int *labstart_r) {
   int lablen, jumpto;
   const char *dgram;
                                 int *lablen_r, int *labstart_r) {
   int lablen, jumpto;
   const char *dgram;
+  int had_pointer= 0;
 
   dgram= fls->dgram;
   for (;;) {
 
   dgram= fls->dgram;
   for (;;) {
@@ -81,6 +78,7 @@ adns_status adns__findlabel_next(findlabel_state *fls,
     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 ((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;
     GET_B(fls->cbyte,jumpto);
     jumpto |= (lablen&0x3f)<<8;
     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
@@ -107,7 +105,12 @@ adns_status adns__findlabel_next(findlabel_state *fls,
 
  x_badresponse: 
   adns__diag(fls->ads,fls->serv,fls->qu,
 
  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;
 }
 
   return adns_s_invalidresponse;
 }
 
index 75bc19219ff705548785ded29bb430cd5a7d2fcc..54d7a2fb3fd6a95b37a261001cc6f994272c0c50 100644 (file)
@@ -3,12 +3,8 @@
  * - wrappers for poll(2)
  */
 /*
  * - 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
  *  
  *  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
@@ -37,7 +33,7 @@ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io,
   int space, found, timeout_ms, r;
   struct pollfd fds_tmp[MAX_POLLFDS];
 
   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);
 
   if (timeout_io) {
     adns__must_gettimeofday(ads,&now,&tv_nowbuf);
@@ -85,10 +81,11 @@ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds,
                    const struct timeval *now) {
   struct timeval tv_buf;
 
                    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__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);
     adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0);
   }
   adns__returning(ads,0);
@@ -101,7 +98,7 @@ int adns_wait_poll(adns_state ads,
   int r, nfds, to;
   struct pollfd fds[MAX_POLLFDS];
   
   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);
 
   for (;;) {
     r= adns__internal_check(ads,query_io,answer_r,context_r);
index 480cbf557ebafce2d88fc2aa0d3273975fecfc7d..7d537d54be4dd86e1f90042269eda12f3893db36 100644 (file)
@@ -5,12 +5,8 @@
  * - query submission and cancellation (user-visible and internal)
  */
 /*
  * - 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
  *  
  *  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
@@ -72,7 +68,7 @@ static adns_query query_alloc(adns_state ads,
   qu->retries= 0;
   qu->udpnextserver= 0;
   qu->udpsent= 0;
   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));
   qu->expires= now.tv_sec + MAXTTLBELIEVE;
 
   memset(&qu->ctx,0,sizeof(qu->ctx));
@@ -273,7 +269,7 @@ int adns_submit(adns_state ads,
   adns_query qu;
   const char *p;
 
   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
 
   if (flags & ~(adns_queryflags)0x4009ffff)
     /* 0x40080000 are reserved for `harmless' future expansion
@@ -284,7 +280,7 @@ int adns_submit(adns_state ads,
   typei= adns__findtype(type);
   if (!typei) return ENOSYS;
 
   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;
   qu= query_alloc(ads,typei,type,flags,now); if (!qu) goto x_errno;
   
   qu->ctx.ext= context;
@@ -431,10 +427,10 @@ void adns__free_interim(adns_query qu, void *p) {
 
   if (!an) return;
   assert(!qu->final_allocspace);
 
   if (!an) return;
   assert(!qu->final_allocspace);
+  qu->interim_allocd -= sz;
+  assert(qu->interim_allocd >= 0);
   LIST_UNLINK(qu->allocations, an);
   free(an);
   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) {
 }
 
 void *adns__alloc_mine(adns_query qu, size_t sz) {
@@ -504,7 +500,7 @@ static void free_query_allocs(adns_query qu) {
   qu->query_dgram= 0;
 }
 
   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;
   while (ads->intdone.head) {
     adns_query iq= ads->intdone.head;
     adns_query parent= iq->parent;
@@ -516,7 +512,11 @@ void adns__returning(adns_state ads, adns_query qu_for_caller) {
     free(iq->answer);
     free(iq);
   }
     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) {
 }
 
 void adns__cancel(adns_query qu) {
@@ -554,7 +554,7 @@ void adns_cancel(adns_query qu) {
 
   assert(!qu->parent);
   ads= qu->ads;
 
   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);
 }
   adns__cancel(qu);
   adns__returning(ads,0);
 }
index bd2d0e8efc6f99ec19a54a3d4641caaf31498550..e538674494662a50c65d1295ad9e685a54717c79 100644 (file)
@@ -3,12 +3,8 @@
  * - main handling and parsing routine for received datagrams
  */
 /*
  * - 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
  *  
  *  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
@@ -35,7 +31,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
   int flg_ra, flg_rd, flg_tc, flg_qr, opcode;
   int rrtype, rrclass, rdlength, rdstart;
   int anstart, nsstart;
   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;
   unsigned long ttl, soattl;
   const typeinfo *typei;
   adns_query qu, nqu;
@@ -162,6 +158,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
    * If it has any CNAMEs we stuff them in the answer.
    */
   wantedrrs= 0;
    * 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;
   cbyte= anstart;
   for (rri= 0; rri<ancount; rri++) {
     rrstart= cbyte;
@@ -229,6 +226,7 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
         */
       }
     } else if (rrtype == (qu->answer->type & adns_rrt_typemask)) {
         */
       }
     } else if (rrtype == (qu->answer->type & adns_rrt_typemask)) {
+      if (restartfrom==-1) restartfrom= rri;
       wantedrrs++;
     } else {
       adns__debug(ads,serv,qu,"ignoring answer RR"
       wantedrrs++;
     } else {
       adns__debug(ads,serv,qu,"ignoring answer RR"
@@ -331,13 +329,15 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
   pai.arcount= arcount;
   pai.now= now;
 
   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);
   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) ||
        rrtype != (qu->answer->type & adns_rrt_typemask) ||
+       rrclass != DNS_CLASS_IN ||
        !ownermatched)
       continue;
     adns__update_expires(qu,ttl,now);
        !ownermatched)
       continue;
     adns__update_expires(qu,ttl,now);
@@ -366,6 +366,11 @@ void adns__procdgram(adns_state ads, const byte *dgram, int dglen,
     adns__query_fail(qu,adns_s_invalidresponse);
     return;
   }
     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:
   qu->flags |= adns_qf_usevc;
   
  x_restartquery:
index 8ff92d284e5bf4a89955f336795479417d28ade1..a10cbf8087f03bbe4e00a53c18d689d85bf02d18 100644 (file)
@@ -4,12 +4,8 @@
  * - management of global state
  */
 /*
  * - 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
  *  
  *  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
@@ -147,11 +143,17 @@ static void ccf_search(adns_state ads, const char *fn,
   tl= 0;
   while (nextword(&bufp,&word,&l)) { count++; tl += l+1; }
 
   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;
 
   bufp= buf;
   pp= newptrs;
@@ -222,11 +224,12 @@ static void ccf_sortlist(adns_state ads, const char *fn,
        }
       } else {
        maskwhat = "prefix length";
        }
       } 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;
        }
          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);
       }
        sl->mask.sa.sa_family= sl->base.sa.sa_family;
        adns__prefix_mask(&sl->mask, initial);
       }
@@ -341,6 +344,8 @@ static void ccf_options(adns_state ads, const char *fn,
        /* adns normally does IPv6 if the application wants it; control
         * this with the adns_af: option if you like */
        WORD_IS("inet6") ||
        /* 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;
        /* adns does not do edns0 and this is not a problem */
        WORD_IS("edns0"))
       continue;
@@ -735,7 +740,7 @@ static int init_files(adns_state *ads_r, adns_initflags flags,
   r= init_finish(ads);
   if (r) return r;
 
   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;
 }
   *ads_r= ads;
   return 0;
 }
@@ -761,7 +766,7 @@ static int init_strcfg(adns_state *ads_r, adns_initflags flags,
   }
 
   r= init_finish(ads);  if (r) return r;
   }
 
   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;
 }
   *ads_r= ads;
   return 0;
 }
@@ -785,15 +790,20 @@ int adns_init_logfn(adns_state *newstate_r, adns_initflags flags,
     return init_files(newstate_r, flags, logfn, logfndata);
 }
 
     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;
 void adns_finish(adns_state ads) {
   int i;
-  adns__consistency(ads,0,cc_entex);
+  adns__consistency(ads,0,cc_enter);
   for (;;) {
   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);
     else break;
   }
   for (i=0; i<ads->nudpsockets; i++) close(ads->udpsockets[i].fd);
@@ -805,7 +815,7 @@ void adns_finish(adns_state ads) {
 }
 
 void adns_forallqueries_begin(adns_state ads) {
 }
 
 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 :
   ads->forallnext=
     ads->udpw.head ? ads->udpw.head :
     ads->tcpw.head ? ads->tcpw.head :
@@ -816,7 +826,7 @@ void adns_forallqueries_begin(adns_state ads) {
 adns_query adns_forallqueries_next(adns_state ads, void **context_r) {
   adns_query qu, nqu;
 
 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;
   nqu= ads->forallnext;
   for (;;) {
     qu= nqu;
index 33c33297c8b248329f212a91ce987be7d84f79dd..f18f8d8fbdac4e34339d5c7951bb02d770b56aa3 100644 (file)
@@ -4,12 +4,8 @@
  * - send queries
  */
 /*
  * - 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
  *  
  *  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
@@ -87,6 +83,7 @@ static adns_status qdparselabel(adns_state ads,
   while (p!=pe && (c= *p++)!='.') {
     if (c=='\\') {
       if (!(flags & adns_qf_quoteok_query)) return adns_s_querydomaininvalid;
   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])) {
       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])) {
@@ -233,8 +230,7 @@ void adns__querysend_tcp(adns_query qu, struct timeval now) {
 
 static void query_usetcp(adns_query qu, struct timeval now) {
   qu->state= query_tcpw;
 
 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);
   LIST_LINK_TAIL(qu->ads->tcpw,qu);
   adns__querysend_tcp(qu,now);
   adns__tcp_tryconnect(qu->ads,now);
@@ -280,8 +276,7 @@ void adns__query_send(adns_query qu, struct timeval now) {
   if (r<0 && errno != EAGAIN)
     adns__warn(ads,serv,0,"sendto failed: %s",strerror(errno));
   
   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++;
   qu->udpsent |= (1<<serv);
   qu->udpnextserver= (serv+1)%ads->nservers;
   qu->retries++;
index fe3b78ddfa5a90e46011851657339a5717eebf24..eb9be9b5ca8332bfb89d4c01e4ae41dab93fc72b 100644 (file)
@@ -3,12 +3,8 @@
  * - static inline functions for doing arithmetic on timevals
  */
 /*
  * - 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
  *
  *  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
index a4478fa369831a482e0e5a480bcf78d226c1fb39..d79f4a07045e99f197b83b6aaaac34e0e7156f3a 100644 (file)
@@ -3,12 +3,8 @@
  * - RR-type-specific code, and the machinery to call it
  */
 /*
  * - 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
  *  
  *  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
@@ -221,7 +217,7 @@ static adns_status pa_txt(const parseinfo *pai, int cbyte,
   return adns_s_ok;
 }
 
   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;
   const adns_rr_intstr *const *rrp= datap;
   const adns_rr_intstr *current;
   adns_status st;
@@ -238,7 +234,7 @@ static adns_status cs_txt(vbuf *vb, const void *datap) {
  * _hinfo   (cs)
  */
 
  * _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;
 
   const adns_rr_intstrpair *rrp= datap;
   adns_status st;
 
@@ -316,7 +312,7 @@ static adns_status csp_genaddr(vbuf *vb, int af, const void *p) {
   return adns_s_ok;
 }
 
   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 csp_genaddr(vb, AF_INET,datap);
 }
 
@@ -338,7 +334,7 @@ static int di_in6addr(adns_state ads,
   return dip_genaddr(ads,AF_INET6,datap_a,datap_b);
 }
 
   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 csp_genaddr(vb,AF_INET6,datap);
 }
 
@@ -499,7 +495,7 @@ static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) {
   return adns_s_ok;
 }
 
   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);
   const adns_rr_addr *rrp= datap;
 
   return csp_addr(vb,rrp);
@@ -691,7 +687,7 @@ static void icb_addr(adns_query parent, adns_query child) {
      * settled on.
      */
     adns__cancel_children(parent);
      * 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);
     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);
@@ -712,7 +708,7 @@ static void icb_addr(adns_query parent, adns_query child) {
     adns__cancel_children(parent);
     adns__free_interim(parent, pans->rrs.bytes);
     pans->rrs.bytes= 0; pans->nrrs= 0;
     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;
   }
     adns__search_next(ads, parent, now);
     return;
   }
@@ -737,7 +733,8 @@ x_gtod:
   /* We have our own error handling, because adns__must_gettimeofday
    * handles errors by calling adns_globalsystemfailure, which would
    * reenter the query processing logic. */
   /* 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;
 
   err= adns_s_systemfail;
   goto x_err;
 
@@ -785,7 +782,7 @@ static adns_status csp_domain(vbuf *vb, const char *domain) {
   return adns_s_ok;
 }
 
   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);
 }
   const char *const *domainp= datap;
   return csp_domain(vb,*domainp);
 }
@@ -838,6 +835,7 @@ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha,
                            &type, &class, &ttl, &rdlen, &rdstart,
                            pai->dgram, pai->dglen, dmstart, &ownermatched);
     if (st) return st;
                            &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;
     if (!ownermatched || class != DNS_CLASS_IN) continue;
     typef= addr_rrtypeflag(type);
     if (!(want & typef)) continue;
@@ -1000,11 +998,13 @@ static void mf_hostaddr(adns_query qu, void *datap) {
   mfp_hostaddr(qu,rrp);
 }
 
   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;
   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;
 
 
   st= csp_domain(vb,rrp->host);  if (st) return st;
 
@@ -1024,7 +1024,7 @@ static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) {
     CSP_ADDSTR(" (");
     for (i=0; i<rrp->naddrs; i++) {
       CSP_ADDSTR(" ");
     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 {
     }
     CSP_ADDSTR(" )");
   } else {
@@ -1033,10 +1033,10 @@ static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) {
   return adns_s_ok;
 }
 
   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;
 
   const adns_rr_hostaddr *rrp= datap;
 
-  return csp_hostaddr(vb,rrp);
+  return csp_hostaddr(vb,rrt,rrp);
 }
 
 /*
 }
 
 /*
@@ -1108,26 +1108,35 @@ static void mf_inthostaddr(adns_query qu, void *datap) {
   mfp_hostaddr(qu,&rrp->ha);
 }
 
   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];
 
   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);
   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)
  */
 
 }
 
 /*
  * _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;
   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);
 }
 
   return csp_domain(vb,rrp->str);
 }
 
@@ -1278,6 +1287,7 @@ static adns_status pap_mailbox822(const parseinfo *pai,
                        pai->dgram, pai->dglen, max,
                        *cbyte_io, cbyte_io);
   st= adns__findlabel_next(&fls,&lablen,&labstart);
                        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;
   if (!lablen) {
     adns__vbuf_appendstr(vb,".");
     goto x_ok;
@@ -1350,7 +1360,7 @@ static adns_status pa_rp(const parseinfo *pai, int cbyte,
   return adns_s_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;
 
   const adns_rr_strpair *rrp= datap;
   adns_status st;
 
@@ -1370,7 +1380,7 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte,
   adns_rr_soa *rrp= datap;
   const byte *dgram= pai->dgram;
   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);
 
   st= pap_domain(pai, &cbyte, max, &rrp->mname,
                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
@@ -1382,9 +1392,8 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte,
   if (cbyte+20 != max) return adns_s_invaliddata;
   
   for (i=0; i<5; i++) {
   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;
   }
 
   return adns_s_ok;
@@ -1397,7 +1406,7 @@ static void mf_soa(adns_query qu, void *datap) {
   adns__makefinal_str(qu,&rrp->rname);
 }
 
   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;
   const adns_rr_soa *rrp= datap;
   char buf[20];
   int i;
@@ -1408,6 +1417,8 @@ static adns_status cs_soa(vbuf *vb, const void *datap) {
   st= csp_mailbox(vb,rrp->rname);  if (st) return st;
 
   for (i=0; i<5; 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);
   }
     sprintf(buf," %lu",(&rrp->serial)[i]);
     CSP_ADDSTR(buf);
   }
@@ -1496,12 +1507,16 @@ static int di_srv(adns_state ads, const void *datap_a, const void *datap_b) {
 static adns_status csp_srv_begin(vbuf *vb, const adns_rr_srvha *rrp
                                   /* might be adns_rr_srvraw* */) {
   char buf[30];
 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;
 }
 
   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;
   
   const adns_rr_srvraw *rrp= datap;
   adns_status st;
   
@@ -1509,12 +1524,12 @@ static adns_status cs_srvraw(vbuf *vb, const void *datap) {
   return csp_domain(vb,rrp->host);
 }
 
   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;
   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,
 }
 
 static void postsort_srv(adns_state ads, void *array, int nrrs,int rrsz,
@@ -1605,12 +1620,15 @@ static adns_status pa_opaque(const parseinfo *pai, int cbyte,
   return adns_s_ok;
 }
 
   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;
 
   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);
   
   sprintf(buf,"\\# %d",rrp->len);
   CSP_ADDSTR(buf);