From: Ryan Dahl Date: Thu, 8 Apr 2010 01:25:37 +0000 (-0700) Subject: Remove udns X-Git-Tag: v0.1.90~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d923c94a0ca6ca4aa23318013de443dbb83398cb;p=platform%2Fupstream%2Fnodejs.git Remove udns --- diff --git a/LICENSE b/LICENSE index 7a3e96b..532a7d1 100644 --- a/LICENSE +++ b/LICENSE @@ -15,10 +15,6 @@ are: - The SCONS build system, located at tools/scons. Copyrighted by the SCONS Foundation. Released under an MIT license. - - UDNS, an asynchronous DNS client, located at deps/udns. Copyrighted by - Michael Tokarev . Released under the GNU Lesser General - Public License version 2.1. - - C-Ares, an asynchronous DNS client, located at deps/c-ares. Copyright by the Massachusetts Institute of Technology; authored by Greg Hudson, Daniel Stenberg and others. Released under an MIT license. diff --git a/deps/udns/.cvsignore b/deps/udns/.cvsignore deleted file mode 100644 index 81946db..0000000 --- a/deps/udns/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -udns*.tar.gz -udns_codes.c -udns.3.html -*.lo -*_s -libudns.so.* -dnsget -ex-rdns -rblcheck -Makefile -config.h -config.status -config.log -build-stamp diff --git a/deps/udns/COPYING.LGPL b/deps/udns/COPYING.LGPL deleted file mode 100644 index b1e3f5a..0000000 --- a/deps/udns/COPYING.LGPL +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/deps/udns/Makefile.in b/deps/udns/Makefile.in deleted file mode 100644 index 4e0e56e..0000000 --- a/deps/udns/Makefile.in +++ /dev/null @@ -1,198 +0,0 @@ -#! /usr/bin/make -rf -# $Id: Makefile.in,v 1.11 2007/01/15 21:19:08 mjt Exp $ -# libudns Makefile -# -# Copyright (C) 2005 Michael Tokarev -# This file is part of UDNS library, an async DNS stub resolver. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library, in file named COPYING.LGPL; if not, -# write to the Free Software Foundation, Inc., 59 Temple Place, -# Suite 330, Boston, MA 02111-1307 USA - -NAME = udns -VERS = 0.0.9 -SRCS = udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \ - udns_misc.c udns_XtoX.c \ - udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \ - udns_rr_srv.c udns_rr_naptr.c udns_codes.c -USRCS = dnsget.c rblcheck.c ex-rdns.c -DEB = debian/copyright debian/changelog debian/control debian/rules -DIST = COPYING.LGPL udns.h udns.3 dnsget.1 rblcheck.1 $(SRCS) $(USRCS) \ - NEWS TODO NOTES Makefile.in configure configure.lib \ - inet_XtoX.c getopt.c - -OBJS = $(SRCS:.c=.o) $(GEN:.c=.o) -LIB = lib$(NAME).a -LIBFL = -L. -l$(NAME) - -SOVER = 0 -SOBJS = $(OBJS:.o=.lo) -SOLIB = lib$(NAME)_s.so -SOLIBV = lib$(NAME).so.$(SOVER) -SOLIBFL= -L. -l$(NAME)_s - -LIBS = $(LIB) $(SOLIBV) - -UTILS = $(USRCS:.c=) -UOBJS = $(USRCS:.c=.o) -SOUTILS = $(USRCS:.c=_s) - -NAMEPFX = $(NAME)-$(VERS) - -CC = @CC@ -RANLIB = @RANLIB@ -CFLAGS = @CFLAGS@ -CDEFS = @CDEFS@ -PICFLAGS = -fPIC -AWK = awk - -all: staticlib - -.SUFFIXES: .c .o .lo - -static: $(LIB) $(UTILS) -staticlib: $(LIB) -$(LIB): $(OBJS) - -rm -f $@ - $(AR) rv $@ $(OBJS) - $(RANLIB) $(LIB) -.c.o: - $(CC) $(CFLAGS) $(CDEFS) -c $< - -shared: $(SOLIBV) $(SOUTILS) -sharedlib: $(SOLIBV) - -$(SOLIBV): $(SOBJS) - $(CC) -shared -Wl,--soname,$(SOLIBV) -o $@ $(SOBJS) -$(SOLIB): $(SOLIBV) - rm -f $@ - ln -s $(SOLIBV) $@ -.c.lo: - $(CC) $(CFLAGS) $(PICFLAGS) $(CDEFS) -o $@ -c $< - -# udns_codes.c is generated from udns.h -udns_codes.c: udns.h - @echo Generating $@ - @set -e; exec >$@.tmp; \ - set T type C class R rcode; \ - echo "/* Automatically generated. */"; \ - echo "#include \"udns.h\""; \ - while [ "$$1" ]; do \ - echo; \ - echo "const struct dns_nameval dns_$${2}tab[] = {"; \ - $(AWK) "/^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \ - { printf \" {%s,\\\"%s\\\"},\\n\", \$$1, substr(\$$1,7) }" \ - udns.h ; \ - echo " {0,0}};"; \ - echo "const char *dns_$${2}name(enum dns_$${2} code) {"; \ - echo " static char nm[20];"; \ - echo " switch(code) {"; \ - $(AWK) "BEGIN{i=0} \ - /^ DNS_$${1}_[A-Z0-9_]+[ ]*=/ \ - {printf \" case %s: return dns_$${2}tab[%d].name;\\n\",\$$1,i++}\ - " udns.h ; \ - echo " }"; \ - echo " return _dns_format_code(nm,\"$$2\",code);"; \ - echo "}"; \ - shift 2; \ - done - @mv $@.tmp $@ - -udns.3.html: udns.3 - groff -man -Thtml udns.3 > $@.tmp - mv $@.tmp $@ - -dist: $(NAMEPFX).tar.gz -$(NAMEPFX).tar.gz: $(DIST) $(DEB) - mkdir $(NAMEPFX) $(NAMEPFX)/debian - ln $(DIST) $(NAMEPFX) - ln $(DEB) $(NAMEPFX)/debian - tar cvfz $@ $(NAMEPFX) - rm -rf $(NAMEPFX) -subdist: - cp -p $(DIST) $(TARGET)/ - -clean: - rm -f $(OBJS) - rm -f $(SOBJS) - rm -f $(UOBJS) - rm -f build-stamp config.log -distclean: clean - rm -f $(LIBS) $(SOLIB) udns.3.html - rm -f $(UTILS) $(SOUTILS) - rm -f config.status config.h Makefile - - -Makefile: configure configure.lib Makefile.in - ./configure - @echo - @echo Please rerun make >&2 - @exit 1 - -.PHONY: all static staticlib shared sharedlib dist clean distclean subdist \ - depend dep deps - -depend dep deps: $(SRCS) $(USRC) - @echo Generating deps for: - @echo \ $(SRCS) - @echo \ $(USRCS) - @sed '/^# depend/q' Makefile.in > Makefile.tmp - @set -e; \ - for f in $(SRCS) $(USRCS); do \ - echo $${f%.c}.o $${f%.c}.lo: $$f \ - `sed -n 's/^#[ ]*include[ ]*"\(.*\)".*/\1/p' $$f`; \ - done >> Makefile.tmp; \ - for f in $(USRCS:.c=.o); do \ - echo "$${f%.?}: $$f \$$(LIB)"; \ - echo " \$$(CC) \$$(CFLAGS) -o \$$@ $$f \$$(LIBFL)"; \ - echo "$${f%.?}_s: $$f \$$(SOLIB)"; \ - echo " \$$(CC) \$$(CFLAGS) -o \$$@ $$f \$$(SOLIBFL)"; \ - done >> Makefile.tmp ; \ - if cmp Makefile.tmp Makefile.in >/dev/null 2>&1 ; then \ - echo Makefile.in unchanged; rm -f Makefile.tmp; \ - else \ - echo Updating Makfile.in; mv -f Makefile.tmp Makefile.in ; \ - fi - -# depend -udns_dn.o udns_dn.lo: udns_dn.c udns.h -udns_dntosp.o udns_dntosp.lo: udns_dntosp.c udns.h -udns_parse.o udns_parse.lo: udns_parse.c udns.h -udns_resolver.o udns_resolver.lo: udns_resolver.c config.h udns.h -udns_init.o udns_init.lo: udns_init.c config.h udns.h -udns_misc.o udns_misc.lo: udns_misc.c udns.h -udns_XtoX.o udns_XtoX.lo: udns_XtoX.c config.h udns.h inet_XtoX.c -udns_rr_a.o udns_rr_a.lo: udns_rr_a.c udns.h -udns_rr_ptr.o udns_rr_ptr.lo: udns_rr_ptr.c udns.h -udns_rr_mx.o udns_rr_mx.lo: udns_rr_mx.c udns.h -udns_rr_txt.o udns_rr_txt.lo: udns_rr_txt.c udns.h -udns_bl.o udns_bl.lo: udns_bl.c udns.h -udns_rr_srv.o udns_rr_srv.lo: udns_rr_srv.c udns.h -udns_rr_naptr.o udns_rr_naptr.lo: udns_rr_naptr.c udns.h -udns_codes.o udns_codes.lo: udns_codes.c udns.h -dnsget.o dnsget.lo: dnsget.c config.h udns.h getopt.c -rblcheck.o rblcheck.lo: rblcheck.c udns.h getopt.c -ex-rdns.o ex-rdns.lo: ex-rdns.c udns.h -dnsget: dnsget.o $(LIB) - $(CC) $(CFLAGS) -o $@ dnsget.o $(LIBFL) -dnsget_s: dnsget.o $(SOLIB) - $(CC) $(CFLAGS) -o $@ dnsget.o $(SOLIBFL) -rblcheck: rblcheck.o $(LIB) - $(CC) $(CFLAGS) -o $@ rblcheck.o $(LIBFL) -rblcheck_s: rblcheck.o $(SOLIB) - $(CC) $(CFLAGS) -o $@ rblcheck.o $(SOLIBFL) -ex-rdns: ex-rdns.o $(LIB) - $(CC) $(CFLAGS) -o $@ ex-rdns.o $(LIBFL) -ex-rdns_s: ex-rdns.o $(SOLIB) - $(CC) $(CFLAGS) -o $@ ex-rdns.o $(SOLIBFL) diff --git a/deps/udns/NEWS b/deps/udns/NEWS deleted file mode 100644 index 3234a6b..0000000 --- a/deps/udns/NEWS +++ /dev/null @@ -1,85 +0,0 @@ -$Id: NEWS,v 1.11 2007/01/15 21:19:08 mjt Exp $ - -User-visible changes in udns library. Recent changes on top. - -0.0.9 (16 Jan 2007) - - - incompat: minor API changes in dns_init() &friends. dns_init() - now requires extra `struct dns_ctx *' argument. Not bumped - soversion yet - I only expect one "release" with this change, - 0.1 will have more changes and will increment so version - - - many small bugfixes, here and there - - - more robust FORMERR replies handling - not only such replies are now - recognized, but udns retries queries without EDNS0 extensions if tried - with, but server reported FORMERR - - - portability changes, udns now includes getopt() implementation fo - the systems lacking it (mostly windows), and dns_ntop()&dns_pton(), - which are either just wrappers for system functions or reimplementations. - - - build is now based on autoconf-like configuration - - - NAPTR (RFC3403) RR decoding support - - - new file NOTES which complements TODO somewhat, and includes some - important shortcomings - - - many internal cleanups, including some preparations for better error - recovery, security and robustness (and thus API changes) - - - removed some #defines which are now unused (like DNS_MAXSRCH) - - - changed WIN32 to WINDOWS everywhere in preprocessor tests, - to be able to build it on win64 as well - -0.0.8 (12 Sep 2005) - - - added SRV records (rfc2782) parsing, - thanks to Thadeu Lima de Souza Cascardo for implementation. - - - bugfixes: - o use uninitialized value when no reply, library died with assertion: - assert((status < 0 && result == 0) || (status >= 0 && result != 0)). - o on some OSes, struct sockaddr_in has additional fields, so - memcmp'ing two sockaddresses does not work. - - - rblcheck(.1) - -0.0.7 (20 Apr 2005) - - - dnsget.1 manpage and several enhancements to dnsget. - - - allow nameserver names for -n option of dnsget. - - - API change: all dns_submit*() routines now does not expect - last `now' argument, since requests aren't sent immediately - anymore. - - - API change: different application timer callback mechanism. - Udns now uses single per-context timer instead of per-query. - - - don't assume DNS replies only contain backward DN pointers, - allow forward pointers too. Change parsing API. - - - debianize - -0.0.6 (08 Apr 2005) - - - use double sorted list for requests (sorted by deadline). - This should significantly speed up timeout processing for - large number of requests. - - - changed debugging interface, so it is finally useable - (still not documented). - - - dnsget routine is now Officially Useable, and sometimes - even more useable than `host' from BIND distribution - (and sometimes not - dnsget does not have -C option - and TCP mode) - - - Debian packaging in debian/ -- udns is now maintained as a - native Debian package. - - - alot (and I really mean alot) of code cleanups all over. diff --git a/deps/udns/NOTES b/deps/udns/NOTES deleted file mode 100644 index 6c24682..0000000 --- a/deps/udns/NOTES +++ /dev/null @@ -1,222 +0,0 @@ -Assorted notes about udns (library). - -UDP-only mode -~~~~~~~~~~~~~ - -First of all, since udns is (currently) UDP-only, there are some -shortcomings. - -It assumes that a reply will fit into a UDP buffer. With adoption of EDNS0, -and general robustness of IP stacks, in most cases it's not an issue. But -in some cases there may be problems: - - - if an RRset is "very large" so it does not fit even in buffer of size - requested by the library (current default is 4096; some servers limits - it further), we will not see the reply, or will only see "damaged" - reply (depending on the server). - - - many DNS servers ignores EDNS0 option requests. In this case, no matter - which buffer size udns library will request, such servers reply is limited - to 512 bytes (standard pre-EDNS0 DNS packet size). (Udns falls back to - non-EDNO0 query if EDNS0-enabled one received FORMERR or NOTIMPL error). - -The problem is that with this, udns currently will not consider replies with -TC (truncation) bit set, and will treat such replies the same way as it -treats SERVFAIL replies, thus trying next server, or temp-failing the query -if no more servers to try. In other words, if the reply is really large, or -if the servers you're using don't support EDNS0, your application will be -unable to resolve a given name. - -Yet it's not common situation - in practice, it's very rare. - -Implementing TCP mode isn't difficult, but it complicates API significantly. -Currently udns uses only single UDP socket (or - maybe in the future - two, -see below), but in case of TCP, it will need to open and close sockets for -TCP connections left and right, and that have to be integrated into an -application's event loop in an easy and efficient way. Plus all the -timeouts - different for connect(), write, and several stages of read. - -IPv6 vs IPv4 usage -~~~~~~~~~~~~~~~~~~ - -This is only relevant for nameservers reachable over IPv6, NOT for IPv6 -queries. I.e., if you've IPv6 addresses in 'nameservers' line in your -/etc/resolv.conf file. Even more: if you have BOTH IPv6 AND IPv4 addresses -there. Or pass them to udns initialization routines. - -Since udns uses a single UDP socket to communicate with all nameservers, -it should support both v4 and v6 communications. Most current platforms -supports this mode - using PF_INET6 socket and V4MAPPED addresses, i.e, -"tunnelling" IPv4 inside IPv6. But not all systems supports this. And -more, it has been said that such mode is deprecated. - -So, list only IPv4 or only IPv6 addresses, but don't mix them, in your -/etc/resolv.conf. - -An alternative is to use two sockets instead of 1 - one for IPv6 and one -for IPv4. For now I'm not sure if it's worth the complexity - again, of -the API, not the library itself (but this will not simplify library either). - -Single socket for all queries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Using single UDP socket for sending queries to all nameservers has obvious -advantages. First it's, again, trivial, simple to use API. And simple -library too. Also, after sending queries to all nameservers (in case first -didn't reply in time), we will be able to receive late reply from first -nameserver and accept it. - -But this mode has disadvantages too. Most important is that it's much easier -to send fake reply to us, as the UDP port where we expects the reply to come -to is constant during the whole lifetime of an application. More secure -implementations uses random port for every single query. While port number -(16 bits integer) can not hold much randomness, it's still of some help. -Ok, udns is a stub resolver, so it expects sorta friendly environment, but -on LAN it's usually much easier to fire an attack, due to the speed of local -network, where a bad guy can generate alot of packets in a short time. - -Choosing of DNS QueryID -~~~~~~~~~~~~~~~~~~~~~~~ - -Currently, udns uses sequential number for query IDs. Which simplifies -attacks even more (c.f. the previous item about single UDP port), making -them nearly trivial. The library should use random number for query ID. -But there's no portable way to get random numbers, even on various flavors -of Unix. It's possible to use low bits from tv_nsec field returned by -gettimeofday() (current time, nanoseconds), but I wrote the library in -a way to avoid making system calls where possible, because many syscalls -means many context switches and slow processes as a result. Maybe use some -application-supplied callback to get random values will be a better way, -defaulting to gettimeofday() method. - -Note that a single query - even if (re)sent to different nameservers, several -times (due to no reply received in time), uses the same qID assigned when it -was first dispatched. So we have: single UDP socket (fixed port number), -sequential (= trivially predictable) qIDs, and long lifetime of those qIDs. -This all makes (local) attacks against the library really trivial. - -See also comments in udns_resolver.c, udns_newid(). - -And note that at least some other stub resolvers out there (like c-ares -for example) also uses sequential qID. - -Assumptions about RRs returned -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Currently udns processes records in the reply it received sequentially. -This means that order of the records is significant. For example, if -we asked for foo.bar A, but the server returned that foo.bar is a CNAME -(alias) for bar.baz, and bar.baz, in turn, has address 1.2.3.4, when -the CNAME should come first in reply, followed by A. While DNS specs -does not say anything about order of records - it's an rrSET - unordered, - -I think an implementation which returns the records in "wrong" order is -somewhat insane... - -CNAME recursion -~~~~~~~~~~~~~~~ - -Another interesting point is the handling of CNAMEs returned as replies -to non-CNAME queries. If we asked for foo.bar A, but it's a CNAME, udns -expects BOTH the CNAME itself and the target DN to be present in the reply. -In other words, udns DOES NOT RECURSE CNAMES. If we asked for foo.bar A, -but only record in reply was that foo.bar is a CNAME for bar.baz, udns will -return no records to an application (NXDOMAIN). Strictly speaking, udns -should repeat the query asking for bar.baz A, and recurse. But since it's -stub resolver, recursive resolver should recurse for us instead. - -It's not very difficult to implement, however. Probably with some (global?) -flag to en/dis-able the feature. Provided there's some demand for it. - -To clarify: udns handles CNAME recursion in a single reply packet just fine. - -Note also that standard gethostbyname() routine does not recurse in this -situation, too. - -Error reporting -~~~~~~~~~~~~~~~ - -Too many places in the code (various failure paths) sets generic "TEMPFAIL" -error condition. For example, if no nameserver replied to our query, an -application will get generic TEMPFAIL, instead of something like TIMEDOUT. -This probably should be fixed, but most applications don't care about the -exact reasons of failure - 4 common cases are already too much: - - query returned some valid data - - NXDOMAIN - - valid domain but no data of requested type - =NXDOMAIN in most cases - - temporary error - this one sometimes (incorrectly!) treated as NXDOMAIN - by (naive) applications. -DNS isn't yes/no, it's at least 3 variants, temp err being the 3rd important -case! And adding more variations for the temp error case is complicating things -even more - again, from an application writer standpoint. For diagnostics, -such more specific error cases are of good help. - -Planned API changes -~~~~~~~~~~~~~~~~~~~ - -At least one thing I want to change for 0.1 version is a way how queries are -submitted and how replies are handled. - -I want to made dns_query object to be owned by an application. So that instead -of udns library allocating it for the lifetime of query, it will be pre- -allocated by an application. This simplifies and enhances query submitting -interface, and complicates it a bit too, in simplest cases. - -Currently, we have: - -dns_submit_dn(dn, cls, typ, flags, parse, cbck, data) -dns_submit_p(name, cls, typ, flags, parse, cbck, data) -dns_submit_a4(ctx, name, flags, cbck, data) - -and so on -- with many parameters missed for type-specific cases, but generic -cases being too complex for most common usage. - -Instead, with dns_query being owned by an app, we will be able to separately -set up various parts of the query - domain name (various forms), type&class, -parser, flags, callback... and even change them at runtime. And we will also -be able to reuse query structures, instead of allocating/freeing them every -time. So the whole thing will look something like: - - q = dns_alloc_query(); - dns_submit(dns_q_flags(dns_q_a4(q, name, cbck), DNS_F_NOSRCH), data); - -The idea is to have a set of functions accepting struct dns_query* and -returning it (so the calls can be "nested" like the above), to set up -relevant parts of the query - specific type of callback, conversion from -(type-specific) query parameters into a domain name (this is for type- -specific query initializers), and setting various flags and options and -type&class things. - -One example where this is almost essential - if we want to support -per-query set of nameservers (which isn't at all useless: imagine a -high-volume mail server, were we want to direct DNSBL queries to a separate -set of nameservers, and rDNS queries to their own set and so on). Adding -another argument (set of nameservers to use) to EVERY query submitting -routine is.. insane. Especially since in 99% cases it will be set to -default NULL. But with such "nesting" of query initializers, it becomes -trivial. - -Another way to do the same is to manipulate query object right after a -query has been submitted, but before any events processing (during this -time, query object is allocated and initialized, but no actual network -packets were sent - it will happen on the next event processing). But -this way it become impossible to perform syncronous resolver calls, since -those calls hide query objects they use internally. - -Speaking of replies handling - the planned change is to stop using dynamic -memory (malloc) inside the library. That is, instead of allocating a buffer -for a reply dynamically in a parsing routine (or memdup'ing the raw reply -packet if no parsing routine is specified), I want udns to return the packet -buffer it uses internally, and change parsing routines to expect a buffer -for result. When parsing, a routine will return true amount of memory it -will need to place the result, regardless of whenever it has enough room -or not, so that an application can (re)allocate properly sized buffer and -call a parsing routine again. - -Another modification I plan to include is to have an ability to work in -terms of domain names (DNs) as used with on-wire DNS packets, not only -with asciiz representations of them. For this to work, the above two -changes (query submission and result passing) have to be completed first -(esp. the query submission part), so that it will be possible to specify -some additional query flags (for example) to request domain names instead -of the text strings, and to allow easy query submissions with either DNs -or text strings. diff --git a/deps/udns/TODO b/deps/udns/TODO deleted file mode 100644 index 41299bc..0000000 --- a/deps/udns/TODO +++ /dev/null @@ -1,69 +0,0 @@ -$Id: TODO,v 1.13 2007/01/15 21:19:08 mjt Exp $ - -The following is mostly an internal, not user-visible stuff. - -* rearrange an API to make dns_query object owned by application, - so that it'll look like this: - struct dns_query *q; - q = udns_query_alloc(ctx); - udns_query_set(q, options, domain_name, flags, ...); - udns_query_submit(ctx, q); - or - udns_query_resolve(ctx, q); - -* allow NULL callbacks? Or provide separate resolver - context list of queries which are done but wich did not - have callback, and dns_pick() routine to retrieve results - from this query, i.e. allow non-callback usage? The - non-callback usage may be handy sometimes (any *good* - example?), but it will be difficult to provide type-safe - non-callback interface due to various RR-specific types - in use. - -* DNS_OPT_FLAGS should be DNS_OPT_ADDFLAGS and DNS_OPT_SETFLAGS. - Currently one can't add a single flag bit but preserve - existing bits... at least not without retrieving all current - flags before, which isn't that bad anyway. - -* dns_set_opts() may process flags too (such as aaonly etc) - -* a way to disable $NSCACHEIP et al processing? - (with now separate dns_init() and dns_reset(), it has finer - control, but still no way to init from system files but ignore - environment variables and the like) - -* initialize/open the context automatically, and be more - liberal about initialization in general? - -* dns_init(ctx, do_open) - make the parameter opposite, aka - dns_init(ctx, skip_open) ? - -* allow TCP queue? - -* And oh, qID should really be random. Or... not. - See notes in udns_resolver.c, dns_newid(). - -* more accurate error reporting. Currently, udns always returns TEMPFAIL, - but don't specify why it happened (ENOMEM, timeout, etc). - -* check the error value returned by recvfrom() and - sendto() and determine which errors to ignore. - -* maybe merge dns_timeouts() and dns_ioevent(), to have - only one entry point for everything? For traditional - select-loop-based eventloop it may be easier, but for - callback-driven event loops the two should be separate. - Provide an option, or a single dns_events() entry point - for select-loop approach, or just call dns_ioevent() - from within dns_timeouts() (probably after renaming - it to be dns_events()) ? - -* implement /etc/hosts lookup too, ala [c-]ares?? - -* sortlist support? - -* windows port? Oh no please!.. At least, I can't do it myself - because of the lack of platform. - Ok ok, the Windows port is in progress. Christian Prahauser - from cosy.sbg.ac.at is helping with that. - Other folks done some more work in this area. diff --git a/deps/udns/configure b/deps/udns/configure deleted file mode 100755 index 14e1b70..0000000 --- a/deps/udns/configure +++ /dev/null @@ -1,168 +0,0 @@ -#! /bin/sh -# $Id: configure,v 1.4 2007/01/07 23:19:40 mjt Exp $ -# autoconf-style configuration script -# - -set -e - -name=udns - -if [ -f udns.h -a -f udns_resolver.c ] ; then : -else - echo "configure: error: sources not found at `pwd`" >&2 - exit 1 -fi - -options="ipv6" - -for opt in $options; do - eval enable_$opt= -done - -if [ -f config.status ]; then - . ./config.status -fi - -enable() { - opt=`echo "$1" | sed 's/^--[^-]*-//'` - case "$opt" in - ipv6|stats|master_dump|zlib|dso) ;; - master-dump) opt=master_dump ;; - *) echo "configure: unrecognized option \`$1'" >&2; exit 1;; - esac - eval enable_$opt=$2 -} - -while [ $# -gt 0 ]; do - case "$1" in - --disable-*|--without-*|--no-*) enable "$1" n;; - --enable-*|--with-*) enable "$1" y;; - --help | --hel | --he | --h | -help | -hel | -he | -h ) - cat <&2; exit 1 ;; - esac - shift -done - -. ./configure.lib - -ac_msg "configure" -ac_result "$name package" - -ac_prog_c_compiler_v -ac_prog_ranlib_v - -ac_ign ac_yesno "for getopt()" ac_have GETOPT ac_link < -extern int optind; -extern char *optarg; -extern int getopt(int, char **, char *); -int main(int argc, char **argv) { - getopt(argc, argv, "abc"); - return optarg ? optind : 0; -} -EOF - -ac_ign \ - ac_yesno "for inet_pton() && inet_ntop()" \ - ac_have INET_PTON_NTOP \ - ac_link < -#include -#include -#include -int main() { - char buf[64]; - long x = 0; - inet_pton(AF_INET, &x, buf); - return inet_ntop(AF_INET, &x, buf, sizeof(buf)); -} -EOF - -if ac_yesno "for socklen_t" ac_compile < -#include -int foo() { socklen_t len; len = 0; return len; } -EOF -then : -else - ac_define socklen_t int -fi - -if ac_library_find_v 'socket and connect' "" "-lsocket -lnsl" < -#include -#include -int main() { - struct sockaddr_in6 sa; - sa.sin6_family = AF_INET6; - return 0; -} -EOF -then : -elif [ "$enable_ipv6" ]; then - ac_fatal "IPv6 is requested but not available" -fi -fi # !disable_ipv6? - -if ac_yesno "for poll()" ac_have POLL ac_link < -#include -int main() { - struct pollfd pfd[2]; - return poll(pfd, 2, 10); -} -EOF -then : -else - ac_ign ac_yesno "for sys/select.h" ac_have SYS_SELECT_H ac_cpp < -#include -EOF -fi - -ac_config_h -ac_output Makefile -ac_msg "creating config.status" -rm -f config.status -{ -echo "# automatically generated by configure to hold command-line options" -echo -found= -for opt in $options; do - eval val=\$enable_$opt - if [ -n "$val" ]; then - echo enable_$opt=$val - found=y - fi -done -if [ ! "$found" ]; then - echo "# (no options encountered)" -fi -} > config.status -ac_result ok - -ac_result "all done." -exit 0 diff --git a/deps/udns/configure.lib b/deps/udns/configure.lib deleted file mode 100644 index 541177a..0000000 --- a/deps/udns/configure.lib +++ /dev/null @@ -1,268 +0,0 @@ -# configure.lib -# a library of shell routines for simple autoconf system -# - -set -e -ac_substitutes= -rm -f conftest* config.log -exec 5>config.log -cat <&5 -This file contains any messages produced by compilers etc while -running configure, to aid debugging if configure script makes a mistake. - -EOF - -case `echo "a\c"` in - *c*) ac_en=-n ac_ec= ;; - *) ac_en= ac_ec='\c' ;; -esac - -##### Messages -ac_msg() { - echo $ac_en "$*... $ac_ec" - echo ">>> $*" >&5 -} -ac_checking() { - echo $ac_en "checking $*... $ac_ec" - echo ">>> checking $*" >&5 -} -ac_result() { - echo "$1" - echo "=== $1" >&5 -} -ac_fatal() { - echo "configure: fatal: $*" >&2 - echo "=== FATAL: $*" >&5 - exit 1 -} -ac_warning() { - echo "configure: warning: $*" >&2 - echo "=== WARNING: $*" >&5 -} -ac_ign() { - "$@" || : -} - -# ac_run command... -# captures output in conftest.out -ac_run() { - # apparently UnixWare (for one) /bin/sh optimizes the following "if" - # "away", by checking if there's such a command BEFORE redirecting - # output. So error message (like "gcc: command not found") goes - # to stderr instead of to conftest.out, and `cat conftest.out' below - # fails. - if "$@" >conftest.out 2>&1; then - return 0 - else - echo "==== Command invocation failed. Command line was:" >&5 - echo "$*" >&5 - echo "==== compiler input was:" >&5 - cat conftest.c >&5 - echo "==== output was:" >&5 - cat conftest.out >&5 - echo "====" >&5 - return 1 - fi -} - -# common case for ac_verbose: yes/no result -ac_yesno() { - ac_checking "$1" - shift - if "$@"; then - ac_result yes - return 0 - else - ac_result no - return 1 - fi -} - -ac_subst() { - ac_substitutes="$ac_substitutes $*" -} - -ac_define() { - CDEFS="$CDEFS -D$1=${2:-1}" -} - -ac_have() { - ac_what=$1; shift - if "$@"; then - ac_define HAVE_$ac_what - eval ac_have_$ac_what=yes - return 0 - else - eval ac_have_$ac_what=no - return 1 - fi -} - -##### Compiling, linking - -# run a compiler -ac_run_compiler() { - rm -f conftest*; cat >conftest.c - ac_run $CC $CFLAGS $CDEFS "$@" conftest.c -} - -ac_compile() { - ac_run_compiler -c -} - -ac_link() { - ac_run_compiler -o conftest $LIBS "$@" -} - -ac_cpp() { - ac_run_compiler -E "$@" -} - -### check for C compiler. Set $CC, $CFLAGS etc -ac_prog_c_compiler_v() { - ac_checking "for C compiler" - rm -f conftest* - echo 'int main(int argc, char **argv) { return 0; }' >conftest.c - - if [ -n "$CC" ]; then - if ac_run $CC -o conftest conftest.c && ac_run ./conftest; then - ac_result "\$CC ($CC)" - else - ac_result no - ac_fatal "\$CC ($CC) is not a working compiler" - fi - else - for cc in gcc cc ; do - if ac_run $cc -o conftest conftest.c && ac_run ./conftest; then - ac_result "$cc" - CC=$cc - break - fi - done - if [ -z "$CC" ]; then - ac_result no - ac_fatal "no working C compiler found in \$PATH. please set \$CC variable" - fi - fi - if [ -z "$CFLAGS" ]; then - if ac_yesno "whenever C compiler ($CC) is GNU CC" \ - ac_grep_cpp yEs_mAsTeR <conftest.c - for lib in "$@"; do - if ac_run $CC $CFLAGS $LDFLAGS conftest.c -o conftest $LIBS $lib; then - found=y - break - fi - done - if [ ! "$found" ]; then - ac_result "not found" - return 1 - fi - if [ -z "$lib" ]; then - ac_result "ok (none needed)" - else - ac_result "ok ($lib)" - LIBS="$LIBS $lib" - fi -} - -ac_compile_run() { - ac_link "$@" && ac_run ./conftest -} - -ac_grep_cpp() { - pattern="$1"; shift - ac_cpp "$@" && grep "$pattern" conftest.out >/dev/null -} - -ac_output() { - for var in $ac_substitutes; do - eval echo "\"s|@$var@|\$$var|\"" - done >conftest.sed - for file in "$@"; do - ac_msg "creating $file" - if [ -f $file.in ]; then - sed -f conftest.sed $file.in > $file.tmp - mv -f $file.tmp $file - ac_result ok - else - ac_result failed - ac_fatal "$file.in not found" - fi - done - rm -f conftest* -} - -ac_config_h() { - h=${1:-config.h} - ac_msg "creating $h" - rm -f $1.tmp - echo "/* automatically generated by configure. */" > $h.tmp - echo "$CDEFS" | tr ' ' ' -' | sed -e 's/^-D/#define /' -e 's/=/ /' >> $h.tmp - if [ -f $h ] && cmp -s $h.tmp $h ; then - rm -f $h.tmp - ac_result unchanged - else - mv -f $h.tmp $h - ac_result ok - fi - CDEFS=-DHAVE_CONFIG_H -} diff --git a/deps/udns/debian/changelog b/deps/udns/debian/changelog deleted file mode 100644 index bd39c33..0000000 --- a/deps/udns/debian/changelog +++ /dev/null @@ -1,136 +0,0 @@ -udns (0.0.9) unstable; urgency=low - - * s/EOVERFLOW/ENFILE, partly to make win32 happy - - * several win32 fixes - - * don't use `class' in udns.h, to make C++ happy - (thanks Markus Koetter for pointing this out) - - * fixed CNAME handling in dnsget tool. Another Thank You! goes - to Markus Koetter. - - * NAPTR (RFC3403) support, thanks to Mikael Magnusson - for this. - - * more Win32 fixes from Mikael Magnusson. I have to admit - I never tried to compile it on Win32. - - * added NOTES file - - * reworked initialisation stuff. Minor API changes -- new dns_reset(), - dns_init() now has one more argument, corrections to dns_close(), - dns_open(), dns_free(). Cleaned up *_internal() routines. - - * moved dns_init() routine into separate file. - - * reworked dn suffix searching. As a result, query only has - dnsq_dn[] field -- no header and EDNS0 "suffix", and query - packet is now formatted in dns_send() - - * added inet_XtoX.c - public domain implementations of inet_pton() - and inet_ntop(), inet_aton() and inet_ntoa() routines. - - * added getopt.c - public domain implementation of getopt() routine. - - * switched to autoconf-style configuration - - * introduce dns_random16() to generate query IDs - (currently based on gettimeofday.tv_usec) - - * dnsget: fix printing of -t ANY and -c any records, - thanks to Jaroslaw Rafa - - * implement dns_ntop() and dns_pton() as either wrappers or - reimplementations (using inet_XtoX.c) of inet_ntop() and inet_pton(). - Too much troubles with portability - it was a complete mess, each - OS has its own problems with them. - And use those routines everywhere. - - * s/WIN32/WINDOWS/g to allow building on WIN64. Oh well. - - * try to find query by ID first, don't drop header-only replies early. - This is in order to support FORMERR replies from nameservers which - don't understand EDNS0. - - * retry queries w/o EDNS0 if sent with it and if - server reported FORMERR or NOTIMPL - - * fixed debian/copyright and debian/control - - * rblcheck revamp - - -- Michael Tokarev Tue, 16 Jan 2007 00:00:28 +0300 - -udns (0.0.8) unstable; urgency=low - - * don't compare sockaddr_in's, but individual parts only - (on some OSes, there are additional fields in this structure - so memcmp() does not quite work) - - * use dnsc_t instead of unsigned char for DNs everywhere - - * SRV records (rfc2782) parsing, thanks to - Thadeu Lima de Souza Cascardo. - - * manpage fixes - - -- Michael Tokarev Mon, 12 Sep 2005 16:06:45 +0400 - -udns (0.0.7) unstable; urgency=low - - * added dnsget.1 and rblcheck.1 manpages. - - * internal: use generic list implementation in udns_resolver.c - - * don't assume only backward DN pointers in replies, allow forward - pointers too. This is quite large change, involves changing - parsing API all over the places. - - * internal: typedef dnsc_t and dnscc_t for [const] unsigned char, to - make function prototypes shorter to better fit on a single line. - - * in parsing routines, verify (assert) that the query type - is the one we can handle. - - * recognize names (and resolve them) as nameservers in dnsget. - - * when new request is submitted, don't send it immediately, but - add it into the head of the active queue with deadline=0. - This will allow us to tweak some query settings before it will - be processed. - Note API change: removed `now' argument from all dns_submit_*() - routines. - - * use single per-context user timer, not per-query. - Note API change: different user timer callback - - * add dnsc_salen field -- length of the socket address used - - * fix dns_set_opt(DNS_OPT_FLAGS) which didn't work before - - * allow to set some options for a context wich is open but with no - active queries - - -- Michael Tokarev Thu, 5 May 2005 23:14:29 +0400 - -udns (0.0.6) unstable; urgency=low - - * 0.0.6 release. - ALOT of changes all over. Keep 'em in CVS logs! - - -- Michael Tokarev Fri, 8 Apr 2005 19:51:38 +0400 - -udns (0.0.5) unstable; urgency=low - - * Initial Release. - * Provides 3 packages: - libudns0 - shared library - libudns-dev - development files and static library - udns-utils - dnsget, rblcheck - - -- Michael Tokarev Thu, 7 Apr 2005 00:05:24 +0400 - -Local variables: -mode: debian-changelog -End: diff --git a/deps/udns/debian/control b/deps/udns/debian/control deleted file mode 100644 index 5ae3fa0..0000000 --- a/deps/udns/debian/control +++ /dev/null @@ -1,33 +0,0 @@ -Source: udns -Priority: optional -Maintainer: Michael Tokarev -Build-Depends: debhelper (>= 4.0.0) -Standards-Version: 3.7.2 - -Package: libudns0 -Section: libs -Architecture: any -Depends: ${shlibs:Depends} -Description: async-capable DNS stub resolver library - libudns0 package provides libudns shared library needed - to run programs using it - -Package: libudns-dev -Section: libdevel -Architecture: any -Depends: libudns0 (= ${Source-Version}) -Description: async-capable DNS stub resolver library, development files - This package provides development files needed - to build programs using udns library - -Package: udns-utils -Section: net -Architecture: any -Depends: ${shlibs:Depends} -Conflicts: rblcheck -Description: Several DNS-related utilities built on top of udns library - This package includes the following utilities: - dnsget - a simple DNS query tool, like `host' or `dig' for usage from - a command line, and dnsip, dnsname etc for usage in scripts - rblcheck - DNSBL (rbl) checker - All the utilities are built using udns library diff --git a/deps/udns/debian/copyright b/deps/udns/debian/copyright deleted file mode 100644 index 3d6c9c2..0000000 --- a/deps/udns/debian/copyright +++ /dev/null @@ -1,23 +0,0 @@ -This is udns, written and maintained by Michael Tokarev - -The original source can always be found at: - http://www.corpit.ru/mjt/udns.html - -Copyright (C) 2005,2006,2007 Michael Tokarev - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -On Debian systems, the complete text of the GNU Lesser General -Public License can be found in `/usr/share/common-licenses/LGPL'. diff --git a/deps/udns/debian/rules b/deps/udns/debian/rules deleted file mode 100755 index 6a5a46f..0000000 --- a/deps/udns/debian/rules +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 -export DH_COMPAT=4 - -CFLAGS = -Wall -W -Wmissing-prototypes -g -CDEFS = -DHAVE_POOL - -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -p -INSTALL_DATA = $(INSTALL) -p -m0644 - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif -ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) - INSTALL_PROGRAM += -s -endif -ifeq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) -# CDEFS += -DNDEBUG -endif - -SOVER = 0 - -config.h: ./configure Makefile.in - dh_testdir - ./configure --enable-ipv6 - -build: build-stamp -build-stamp: config.h - dh_testdir - $(MAKE) CFLAGS="$(CFLAGS)" SOVER=$(SOVER) \ - staticlib sharedlib rblcheck_s dnsget_s - mv -f dnsget_s dnsget - mv -f rblcheck_s rblcheck - mv -f libudns_s.so libudns.so - echo - touch $@ - -clean: - dh_testdir - rm -f build-stamp - if [ -f Makefile ]; then $(MAKE) distclean; fi - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean - dh_installdirs - dh_installdocs -A NEWS - -# libudns - dh_install -plibudns$(SOVER) libudns.so.$(SOVER) usr/lib - -# libudns-dev - dh_install -plibudns-dev libudns.a libudns.so usr/lib - dh_install -plibudns-dev udns.h usr/include - dh_installman -plibudns-dev udns.3 - dh_installdocs -plibudns-dev TODO NOTES - dh_installexamples -plibudns-dev ex-rdns.c - -# udns-utils - dh_install -pudns-utils dnsget rblcheck usr/bin - dh_installman -pudns-utils dnsget.1 rblcheck.1 - -binary-indep: build install - -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_strip - dh_compress - dh_fixperms - dh_makeshlibs -V - dh_installdeb - dh_shlibdeps -L libudns$(SOVER) -l . - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install diff --git a/deps/udns/dnsget.1 b/deps/udns/dnsget.1 deleted file mode 100644 index 711f297..0000000 --- a/deps/udns/dnsget.1 +++ /dev/null @@ -1,182 +0,0 @@ -.\" $Id: dnsget.1,v 1.3 2005/04/20 00:55:34 mjt Exp $ -.\" dnsget manpage -.\" -.\" Copyright (C) 2005 Michael Tokarev -.\" This file is part of UDNS library, an async DNS stub resolver. -.\" -.\" This library is free software; you can redistribute it and/or -.\" modify it under the terms of the GNU Lesser General Public -.\" License as published by the Free Software Foundation; either -.\" version 2.1 of the License, or (at your option) any later version. -.\" -.\" This library 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 -.\" Lesser General Public License for more details. -.\" -.\" You should have received a copy of the GNU Lesser General Public -.\" License along with this library, in file named COPYING.LGPL; if not, -.\" write to the Free Software Foundation, Inc., 59 Temple Place, -.\" Suite 330, Boston, MA 02111-1307 USA - -.TH dnsget 1 "Apr 2005" "User Utilities" - -.SH NAME -dnsget \- DNS lookup utility - -.SH SYNOPSYS -.B dnsget -.RB [\| \-v \||\| \-q \|] -.RB [\| \-c -.IR class \|] -.RB [\| \-t -.IR type \|] -.RB [\| \-o -.IR option : value \] -.IR name \|.\|.\|. - -.SH DESCRIPTION -.B dnsget -is a simple command-line to perform DNS lookups, similar to -.BR host (1) -and -.BR dig (1). -It is useable for both interactive/debugging scenarious and -in scripts. -The program is implemented using -.BR udns (3) -library. - -.PP -By default, -.B dnsget -produces a human-readable output, similar to -.RS -.nf -alias.example.com. CNAME www.example.com. -www.example.com. A 192.168.1.1 -www.example.com. MX 10 mx.example.com. -.fi -.RE -which is just sufficient to see how a given name resolves. -Output format is controllable with -.B \-v -and -.B \-q -options -- the former increases verbosity level up to printing -the whole DNS contents of all packets sent and received, which -is suitable for debugging DNS problems, while the latter reduces -the level, making output more quiet, up to bare result with no -error messages, which is good for scripts. - -.SH OPTIONS - -The following options are recognized by -.BR dnsget : - -.TP -.B \-v -produce more detailed output. More -.BR \-v 's -means more details will be produced. With single -.BR \-v , dnsget -will print contents of all received DNS packets (in a readable format), -while with -.BR \-vv , -it will output all outgoing DNS packets too. - -.TP -.B \-q -the opposite for \fB\-v\fR -- produce less detailed output. -With single -.BR \-q , dnsget -will only show (decoded) data from final DNS resource records (RR), -while -.B \-qq -also suppresses error messages. - -.TP -\fB\-t \fItype\fR -request record(s) of the given type \fItype\fR. By default, -.B dnsget -will ask for IPv4 address (A) record, or for PTR record if the -argument in question is an IPv4 or IPv6 address. Recognized -types include A, AAAA, MX, TXT, CNAME, PTR, NS, SOA, ANY and -others. - -.TP -\fB\-c \fIclass\fR -request DNS record(s) of the given class \fIclass\fR. By -default -.B dnsget -uses IN class. Valid classes include IN, CH, HS, ANY. - -.TP -.B \-a -(compatibility option). Equivalent to setting query type to -.B ANY -and increasing verbosity level -.RB ( \-v ). - -.TP -.B \-C -(planned) - -.TP -.B \-x -(planned) - -.TP -\fB\-o \fIoption\fR:\fIvalue\fR -Set resolver option \fIoption\fR to the value \fIvalue\fR -(may be specified several times). The same as setting -.RB $ RES_OPTIONS -environment variable. The following options are recognized: -.RS -.TP -\fBtimeout\fR:\fIsec\fR -Set initial query timeout to \fIsec\fR. -.TP -\fBattempts\fR:\fInum\fR -(re)try every query \fInum\fR times before failing. -.TP -\fBudpbuf\fR:\fIbytes\fR -set DNS UDP buffer size to \fIbytes\fR bytes. Valid values -are from 512 to 65535. If \fIbytes\fR is greather than 512, -EDNS0 (RFC 2671) extensions will be used. -.TP -\fBport\fR:\fInum\fR -Use given UDP port number \fInum\fR instead of the default port 53 (domain). -.RE - -.TP -\fB\-n \fInameserver\fR -Use the given nameserver(s) (may be specified more than once) -instead of the default. Using this option has the same same effect as -.RB $ NSCACHEIP -or -.RB $ NAMESERVERS -environment variables, with the only difference that only IPv4 addresses -are recognized for now, and it is possible to specify names (which will -be resolved using default settings) instead of IP addresses. - -.TP -.B \-h -print short help and exit. - -.SH "RETURN VALUE" -When all names where resovled successefully, -.B dnsget -exits with zero exit status. If at least one name was not found, -.B dnsget -will exit with return code 100. If some other error occured during -name resolution, it will exit with code 99. In case of usage or -initialization error, -.B dnsget -will return 1. - -.SH "SEE ALSO" -.BR host (1) -.BR dig (1) -.BR resolv.conf (5) -.BR udns (3). diff --git a/deps/udns/dnsget.c b/deps/udns/dnsget.c deleted file mode 100644 index 68c5295..0000000 --- a/deps/udns/dnsget.c +++ /dev/null @@ -1,726 +0,0 @@ -/* $Id: dnsget.c,v 1.31 2007/01/08 01:14:44 mjt Exp $ - simple host/dig-like application using UDNS library - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef WINDOWS -#include -#include -#else -#include -#include -#include -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include "udns.h" - -#ifndef HAVE_GETOPT -# include "getopt.c" -#endif - -#ifndef AF_INET6 -# define AF_INET6 10 -#endif - -static char *progname; -static int verbose = 1; -static int errors; -static int notfound; - -/* verbosity level: - * <0 - bare result - * 0 - bare result and error messages - * 1 - readable result - * 2 - received packet contents and `trying ...' stuff - * 3 - sent and received packet contents - */ - -static void die(int errnum, const char *fmt, ...) { - va_list ap; - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - if (errnum) fprintf(stderr, ": %s\n", strerror(errnum)); - else putc('\n', stderr); - fflush(stderr); - exit(1); -} - -static const char *dns_xntop(int af, const void *src) { - static char buf[6*5+4*4]; - return dns_ntop(af, src, buf, sizeof(buf)); -} - -struct query { - const char *name; /* original query string */ - unsigned char *dn; /* the DN being looked up */ - enum dns_type qtyp; /* type of the query */ -}; - -static void query_free(struct query *q) { - free(q->dn); - free(q); -} - -static struct query * -query_new(const char *name, const unsigned char *dn, enum dns_type qtyp) { - struct query *q = malloc(sizeof(*q)); - unsigned l = dns_dnlen(dn); - unsigned char *cdn = malloc(l); - if (!q || !cdn) die(0, "out of memory"); - memcpy(cdn, dn, l); - q->name = name; - q->dn = cdn; - q->qtyp = qtyp; - return q; -} - -static enum dns_class qcls = DNS_C_IN; - -static void -dnserror(struct query *q, int errnum) { - if (verbose >= 0) - fprintf(stderr, "%s: unable to lookup %s record for %s: %s\n", progname, - dns_typename(q->qtyp), dns_dntosp(q->dn), dns_strerror(errnum)); - if (errnum == DNS_E_NXDOMAIN || errnum == DNS_E_NODATA) - ++notfound; - else - ++errors; - query_free(q); -} - -static const unsigned char * -printtxt(const unsigned char *c) { - unsigned n = *c++; - const unsigned char *e = c + n; - if (verbose > 0) while(c < e) { - if (*c < ' ' || *c >= 127) printf("\\%02x", *c); - else if (*c == '\\' || *c == '"') printf("\\%c", *c); - else putchar(*c); - ++c; - } - else - fwrite(c, n, 1, stdout); - return e; -} - -static void -printhex(const unsigned char *c, const unsigned char *e) { - while(c < e) - printf("%02x", *c++); -} - -static unsigned char to_b64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static void -printb64(const unsigned char *c, const unsigned char *e) { - while(c < e) { - putchar(to_b64[c[0] >> 2]); - if (c+1 < e) { - putchar(to_b64[(c[0] & 0x3) << 4 | c[1] >> 4]); - if (c+2 < e) { - putchar(to_b64[(c[1] & 0xf) << 2 | c[2] >> 6]); - putchar(to_b64[c[2] & 0x3f]); - } - else { - putchar(to_b64[(c[1] & 0xf) << 2]); - putchar('='); - break; - } - } - else { - putchar(to_b64[(c[0] & 0x3) << 4]); - putchar('='); - putchar('='); - break; - } - c += 3; - } -} - -static void -printdate(time_t time) { - struct tm *tm = gmtime(&time); - printf("%04d%02d%02d%02d%02d%02d", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); -} - -static void -printrr(const struct dns_parse *p, struct dns_rr *rr) { - const unsigned char *pkt = p->dnsp_pkt; - const unsigned char *end = p->dnsp_end; - const unsigned char *dptr = rr->dnsrr_dptr; - const unsigned char *dend = rr->dnsrr_dend; - unsigned char *dn = rr->dnsrr_dn; - const unsigned char *c; - unsigned n; - - if (verbose > 0) { - if (verbose > 1) { - if (!p->dnsp_rrl && !rr->dnsrr_dn[0] && rr->dnsrr_typ == DNS_T_OPT) { - printf(";EDNS0 OPT record (UDPsize: %d): %d bytes\n", - rr->dnsrr_cls, rr->dnsrr_dsz); - return; - } - n = printf("%s.", dns_dntosp(rr->dnsrr_dn)); - printf("%s%u\t%s\t%s\t", - n > 15 ? "\t" : n > 7 ? "\t\t" : "\t\t\t", - rr->dnsrr_ttl, - dns_classname(rr->dnsrr_cls), - dns_typename(rr->dnsrr_typ)); - } - else - printf("%s. %s ", dns_dntosp(rr->dnsrr_dn), dns_typename(rr->dnsrr_typ)); - } - - switch(rr->dnsrr_typ) { - - case DNS_T_CNAME: - case DNS_T_PTR: - case DNS_T_NS: - case DNS_T_MB: - case DNS_T_MD: - case DNS_T_MF: - case DNS_T_MG: - case DNS_T_MR: - if (dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN) <= 0) goto xperr; - printf("%s.", dns_dntosp(dn)); - break; - - case DNS_T_A: - if (rr->dnsrr_dsz != 4) goto xperr; - printf("%d.%d.%d.%d", dptr[0], dptr[1], dptr[2], dptr[3]); - break; - - case DNS_T_AAAA: - if (rr->dnsrr_dsz != 16) goto xperr; - printf("%s", dns_xntop(AF_INET6, dptr)); - break; - - case DNS_T_MX: - c = dptr + 2; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr; - printf("%d %s.", dns_get16(dptr), dns_dntosp(dn)); - break; - - case DNS_T_TXT: - /* first verify it */ - for(c = dptr; c < dend; c += n) { - n = *c++; - if (c + n > dend) goto xperr; - } - c = dptr; n = 0; - while (c < dend) { - if (verbose > 0) printf(n++ ? "\" \"":"\""); - c = printtxt(c); - } - if (verbose > 0) putchar('"'); - break; - - case DNS_T_HINFO: /* CPU, OS */ - c = dptr; - n = *c++; if ((c += n) >= dend) goto xperr; - n = *c++; if ((c += n) != dend) goto xperr; - c = dptr; - if (verbose > 0) putchar('"'); - c = printtxt(c); - if (verbose > 0) printf("\" \""); else putchar(' '); - printtxt(c); - if (verbose > 0) putchar('"'); - break; - - case DNS_T_WKS: - c = dptr; - if (dptr + 4 + 2 >= end) goto xperr; - printf("%s %d", dns_xntop(AF_INET, dptr), dptr[4]); - c = dptr + 5; - for (n = 0; c < dend; ++c, n += 8) { - if (*c) { - unsigned b; - for (b = 0; b < 8; ++b) - if (*c & (1 << (7-b))) printf(" %d", n + b); - } - } - break; - - case DNS_T_SRV: /* prio weight port targetDN */ - c = dptr; - c += 2 + 2 + 2; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr; - c = dptr; - printf("%d %d %d %s.", - dns_get16(c+0), dns_get16(c+2), dns_get16(c+4), - dns_dntosp(dn)); - break; - - case DNS_T_NAPTR: /* order pref flags serv regexp repl */ - c = dptr; - c += 4; /* order, pref */ - for (n = 0; n < 3; ++n) - if (c >= dend) goto xperr; - else c += *c + 1; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || c != dend) goto xperr; - c = dptr; - printf("%u %u", dns_get16(c+0), dns_get16(c+2)); - c += 4; - for(n = 0; n < 3; ++n) { - putchar(' '); - if (verbose > 0) putchar('"'); - c = printtxt(c); - if (verbose > 0) putchar('"'); - } - printf(" %s.", dns_dntosp(dn)); - break; - - case DNS_T_KEY: /* flags(2) proto(1) algo(1) pubkey */ - c = dptr; - if (c + 2 + 1 + 1 > dend) goto xperr; - printf("%d %d %d", dns_get16(c), c[2], c[3]); - c += 2 + 1 + 1; - if (c < dend) { - putchar(' '); - printb64(c, dend); - } - break; - - case DNS_T_SIG: - /* type(2) algo(1) labels(1) ottl(4) sexp(4) sinc(4) tag(2) sdn sig */ - c = dptr; - c += 2 + 1 + 1 + 4 + 4 + 4 + 2; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr; - printf("%d %u %u %u ", - dns_get16(dptr), dptr[2], dptr[3], dns_get32(dptr+4)); - printdate(dns_get32(dptr+8)); - putchar(' '); - printdate(dns_get32(dptr+12)); - printf(" %d %s. ", dns_get16(dptr+10), dns_dntosp(dn)); - printb64(c, dend); - break; - -#if 0 /* unused RR types? */ - case DNS_T_DS: - c = dptr; - if (c + 2 + 2 >= dend) goto xperr; - printf("%u %u %u ", dns_get16(c), c[2], c[3]); - printhex(c + 4, dend); - break; - - case DNS_T_NSEC: - c = dptr; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0) goto xperr; - printf("%s.", dns_dntosp(dn)); - unfinished. - break; -#endif - - - case DNS_T_SOA: - c = dptr; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || - dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || - c + 4*5 != dend) - goto xperr; - dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN); - printf("%s. ", dns_dntosp(dn)); - dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN); - printf("%s. ", dns_dntosp(dn)); - printf("%u %u %u %u %u", - dns_get32(dptr), dns_get32(dptr+4), dns_get32(dptr+8), - dns_get32(dptr+12), dns_get32(dptr+16)); - break; - - case DNS_T_MINFO: - c = dptr; - if (dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || - dns_getdn(pkt, &c, end, dn, DNS_MAXDN) <= 0 || - c != dend) - goto xperr; - dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN); - printf("%s. ", dns_dntosp(dn)); - dns_getdn(pkt, &dptr, end, dn, DNS_MAXDN); - printf("%s.", dns_dntosp(dn)); - break; - - case DNS_T_NULL: - default: - printhex(dptr, dend); - break; - } - putchar('\n'); - return; - -xperr: - printf("\n"); - ++errors; -} - -static int -printsection(struct dns_parse *p, int nrr, const char *sname) { - struct dns_rr rr; - int r; - if (!nrr) return 0; - if (verbose > 1) printf("\n;; %s section (%d):\n", sname, nrr); - - p->dnsp_rrl = nrr; - while((r = dns_nextrr(p, &rr)) > 0) - printrr(p, &rr); - if (r < 0) printf("<>\n"); - return r; -} - -/* dbgcb will only be called if verbose > 1 */ -static void -dbgcb(int code, const struct sockaddr *sa, unsigned slen, - const unsigned char *pkt, int r, - const struct dns_query *unused_q, void *unused_data) { - struct dns_parse p; - const unsigned char *cur, *end; - int numqd; - - if (code > 0) { - printf(";; trying %s.\n", dns_dntosp(dns_payload(pkt))); - printf(";; sending %d bytes query to ", r); - } - else - printf(";; received %d bytes response from ", r); - if (sa->sa_family == AF_INET && slen >= sizeof(struct sockaddr_in)) - printf("%s port %d\n", - dns_xntop(AF_INET, &((struct sockaddr_in*)sa)->sin_addr), - htons(((struct sockaddr_in*)sa)->sin_port)); -#ifdef HAVE_IPv6 - else if (sa->sa_family == AF_INET6 && slen >= sizeof(struct sockaddr_in6)) - printf("%s port %d\n", - dns_xntop(AF_INET6, &((struct sockaddr_in6*)sa)->sin6_addr), - htons(((struct sockaddr_in6*)sa)->sin6_port)); -#endif - else - printf("<>\n", sa->sa_family); - if (code > 0 && verbose < 3) { - putchar('\n'); - return; - } - - if (code == -2) printf(";; reply from unexpected source\n"); - if (code == -5) printf(";; reply to a query we didn't sent (or old)\n"); - if (r < DNS_HSIZE) { - printf(";; short packet (%d bytes)\n", r); - return; - } - if (dns_opcode(pkt) != 0) - printf(";; unexpected opcode %d\n", dns_opcode(pkt)); - if (dns_tc(pkt) != 0) - printf(";; warning: TC bit set, probably incomplete reply\n"); - - printf(";; ->>HEADER<<- opcode: "); - switch(dns_opcode(pkt)) { - case 0: printf("QUERY"); break; - case 1: printf("IQUERY"); break; - case 2: printf("STATUS"); break; - default: printf("UNKNOWN(%u)", dns_opcode(pkt)); break; - } - printf(", status: %s, id: %d, size: %d\n;; flags:", - dns_rcodename(dns_rcode(pkt)), dns_qid(pkt), r); - if (dns_qr(pkt)) printf(" qr"); - if (dns_rd(pkt)) printf(" rd"); - if (dns_ra(pkt)) printf(" ra"); - if (dns_aa(pkt)) printf(" aa"); - if (dns_tc(pkt)) printf(" tc"); - numqd = dns_numqd(pkt); - printf("; QUERY: %d, ANSWER: %d, AUTHORITY: %d, ADDITIONAL: %d\n", - numqd, dns_numan(pkt), dns_numns(pkt), dns_numar(pkt)); - if (numqd != 1) - printf(";; unexpected number of entries in QUERY section: %d\n", - numqd); - printf("\n;; QUERY SECTION (%d):\n", numqd); - cur = dns_payload(pkt); - end = pkt + r; - while(numqd--) { - if (dns_getdn(pkt, &cur, end, p.dnsp_dnbuf, DNS_MAXDN) <= 0 || - cur + 4 > end) { - printf("; invalid query section\n"); - return; - } - r = printf(";%s.", dns_dntosp(p.dnsp_dnbuf)); - printf("%s%s\t%s\n", - r > 23 ? "\t" : r > 15 ? "\t\t" : r > 7 ? "\t\t\t" : "\t\t\t\t", - dns_classname(dns_get16(cur+2)), dns_typename(dns_get16(cur))); - cur += 4; - } - - p.dnsp_pkt = pkt; - p.dnsp_cur = p.dnsp_ans = cur; - p.dnsp_end = end; - p.dnsp_qdn = NULL; - p.dnsp_qcls = p.dnsp_qtyp = 0; - p.dnsp_ttl = 0xffffffffu; - p.dnsp_nrr = 0; - - r = printsection(&p, dns_numan(pkt), "ANSWER"); - if (r == 0) - r = printsection(&p, dns_numns(pkt), "AUTHORITY"); - if (r == 0) - r = printsection(&p, dns_numar(pkt), "ADDITIONAL"); - putchar('\n'); -} - -static void dnscb(struct dns_ctx *ctx, void *result, void *data) { - int r = dns_status(ctx); - struct query *q = data; - struct dns_parse p; - struct dns_rr rr; - unsigned nrr; - unsigned char dn[DNS_MAXDN]; - const unsigned char *pkt, *cur, *end; - if (!result) { - dnserror(q, r); - return; - } - pkt = result; end = pkt + r; cur = dns_payload(pkt); - dns_getdn(pkt, &cur, end, dn, sizeof(dn)); - dns_initparse(&p, NULL, pkt, cur, end); - p.dnsp_qcls = p.dnsp_qtyp = 0; - nrr = 0; - while((r = dns_nextrr(&p, &rr)) > 0) { - if (!dns_dnequal(dn, rr.dnsrr_dn)) continue; - if ((qcls == DNS_C_ANY || qcls == rr.dnsrr_cls) && - (q->qtyp == DNS_T_ANY || q->qtyp == rr.dnsrr_typ)) - ++nrr; - else if (rr.dnsrr_typ == DNS_T_CNAME && !nrr) { - if (dns_getdn(pkt, &rr.dnsrr_dptr, end, - p.dnsp_dnbuf, sizeof(p.dnsp_dnbuf)) <= 0 || - rr.dnsrr_dptr != rr.dnsrr_dend) { - r = DNS_E_PROTOCOL; - break; - } - else { - if (verbose == 1) { - printf("%s.", dns_dntosp(dn)); - printf(" CNAME %s.\n", dns_dntosp(p.dnsp_dnbuf)); - } - dns_dntodn(p.dnsp_dnbuf, dn, sizeof(dn)); - } - } - } - if (!r && !nrr) - r = DNS_E_NODATA; - if (r < 0) { - dnserror(q, r); - free(result); - return; - } - if (verbose < 2) { /* else it is already printed by dbgfn */ - dns_rewind(&p, NULL); - p.dnsp_qtyp = q->qtyp == DNS_T_ANY ? 0 : q->qtyp; - p.dnsp_qcls = qcls == DNS_C_ANY ? 0 : qcls; - while(dns_nextrr(&p, &rr)) - printrr(&p, &rr); - } - free(result); - query_free(q); -} - -int main(int argc, char **argv) { - int i; - int fd; - fd_set fds; - struct timeval tv; - time_t now; - char *ns[DNS_MAXSERV]; - int nns = 0; - struct query *q; - enum dns_type qtyp = 0; - struct dns_ctx *nctx = NULL; - - if (!(progname = strrchr(argv[0], '/'))) progname = argv[0]; - else argv[0] = ++progname; - - if (argc <= 1) - die(0, "try `%s -h' for help", progname); - - if (dns_init(NULL, 0) < 0 || !(nctx = dns_new(NULL))) - die(errno, "unable to initialize dns library"); - /* we keep two dns contexts: one may be needed to resolve - * nameservers if given as names, using default options. - */ - - while((i = getopt(argc, argv, "vqt:c:an:o:h")) != EOF) switch(i) { - case 'v': ++verbose; break; - case 'q': --verbose; break; - case 't': - if (optarg[0] == '*' && !optarg[1]) - i = DNS_T_ANY; - else if ((i = dns_findtypename(optarg)) <= 0) - die(0, "unrecognized query type `%s'", optarg); - qtyp = i; - break; - case 'c': - if (optarg[0] == '*' && !optarg[1]) - i = DNS_C_ANY; - else if ((i = dns_findclassname(optarg)) < 0) - die(0, "unrecognized query class `%s'", optarg); - qcls = i; - break; - case 'a': - qtyp = DNS_T_ANY; - ++verbose; - break; - case 'n': - if (nns >= DNS_MAXSERV) - die(0, "too many nameservers, %d max", DNS_MAXSERV); - ns[nns++] = optarg; - break; - case 'o': - if (dns_set_opts(NULL, optarg) != 0) - die(0, "invalid option string: `%s'", optarg); - break; - case 'h': - printf( -"%s: simple DNS query tool (using udns version %s)\n" -"Usage: %s [options] domain-name...\n" -"where options are:\n" -" -h - print this help and exit\n" -" -v - be more verbose\n" -" -q - be less verbose\n" -" -t type - set query type (A, AAA, PTR etc)\n" -" -c class - set query class (IN (default), CH, HS, *)\n" -" -a - equivalent to -t ANY -v\n" -" -n ns - use given nameserver(s) instead of default\n" -" (may be specified multiple times)\n" -" -o option:value - set resovler option (the same as setting $RES_OPTIONS):\n" -" timeout:sec - initial query timeout\n" -" attempts:num - number of attempt to resovle a query\n" -" ndots:num - if name has more than num dots, lookup it before search\n" -" port:num - port number for queries instead of default 53\n" -" udpbuf:num - size of UDP buffer (use EDNS0 if >512)\n" -" (may be specified more than once)\n" - , progname, dns_version(), progname); - return 0; - default: - die(0, "try `%s -h' for help", progname); - } - - argc -= optind; argv += optind; - if (!argc) - die(0, "no name(s) to query specified"); - - if (nns) { - /* if nameservers given as names, resolve them. - * We only allow IPv4 nameservers as names for now. - * Ok, it is easy enouth to try both AAAA and A, - * but the question is what to do by default. - */ - struct sockaddr_in sin; - int j, r = 0, opened = 0; - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(dns_set_opt(NULL, DNS_OPT_PORT, -1)); - dns_add_serv(NULL, NULL); - for(i = 0; i < nns; ++i) { - if (dns_pton(AF_INET, ns[i], &sin.sin_addr) <= 0) { - struct dns_rr_a4 *rr; - if (!opened) { - if (dns_open(nctx) < 0) - die(errno, "unable to initialize dns context"); - opened = 1; - } - rr = dns_resolve_a4(nctx, ns[i], 0); - if (!rr) - die(0, "unable to resolve nameserver %s: %s", - ns[i], dns_strerror(dns_status(nctx))); - for(j = 0; j < rr->dnsa4_nrr; ++j) { - sin.sin_addr = rr->dnsa4_addr[j]; - if ((r = dns_add_serv_s(NULL, (struct sockaddr *)&sin)) < 0) - break; - } - free(rr); - } - else - r = dns_add_serv_s(NULL, (struct sockaddr *)&sin); - if (r < 0) - die(errno, "unable to add nameserver %s", - dns_xntop(AF_INET, &sin.sin_addr)); - } - } - dns_free(nctx); - - fd = dns_open(NULL); - if (fd < 0) - die(errno, "unable to initialize dns context"); - - if (verbose > 1) - dns_set_dbgfn(NULL, dbgcb); - - for (i = 0; i < argc; ++i) { - char *name = argv[i]; - union { - struct in_addr addr; - struct in6_addr addr6; - } a; - unsigned char dn[DNS_MAXDN]; - enum dns_type l_qtyp = 0; - int abs; - if (dns_pton(AF_INET, name, &a.addr) > 0) { - dns_a4todn(&a.addr, 0, dn, sizeof(dn)); - l_qtyp = DNS_T_PTR; - abs = 1; - } -#ifdef HAVE_IPv6 - else if (dns_pton(AF_INET6, name, &a.addr6) > 0) { - dns_a6todn(&a.addr6, 0, dn, sizeof(dn)); - l_qtyp = DNS_T_PTR; - abs = 1; - } -#endif - else if (!dns_ptodn(name, strlen(name), dn, sizeof(dn), &abs)) - die(0, "invalid name `%s'\n", name); - else - l_qtyp = DNS_T_A; - if (qtyp) l_qtyp = qtyp; - q = query_new(name, dn, l_qtyp); - if (abs) abs = DNS_NOSRCH; - if (!dns_submit_dn(NULL, dn, qcls, l_qtyp, abs, 0, dnscb, q)) - dnserror(q, dns_status(NULL)); - } - - FD_ZERO(&fds); - now = 0; - while((i = dns_timeouts(NULL, -1, now)) > 0) { - FD_SET(fd, &fds); - tv.tv_sec = i; - tv.tv_usec = 0; - i = select(fd+1, &fds, 0, 0, &tv); - now = time(NULL); - if (i > 0) dns_ioevent(NULL, now); - } - - return errors ? 1 : notfound ? 100 : 0; -} diff --git a/deps/udns/ex-rdns.c b/deps/udns/ex-rdns.c deleted file mode 100644 index 4b176e7..0000000 --- a/deps/udns/ex-rdns.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $Id: ex-rdns.c,v 1.8 2007/01/07 22:46:47 mjt Exp $ - parallel rDNS resolver example - read IP addresses from stdin, - write domain names to stdout - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "udns.h" - -static int curq; - -static const char *n2ip(const unsigned char *c) { - static char b[sizeof("255.255.255.255")]; - sprintf(b, "%u.%u.%u.%u", c[0], c[1], c[2], c[3]); - return b; -} -static void dnscb(struct dns_ctx *ctx, struct dns_rr_ptr *rr, void *data) { - const char *ip = n2ip((unsigned char *)&data); - int i; - --curq; - if (rr) { - printf("%s", ip); - for(i = 0; i < rr->dnsptr_nrr; ++i) - printf(" %s", rr->dnsptr_ptr[i]); - putchar('\n'); - free(rr); - } - else - fprintf(stderr, "%s: %s\n", ip, dns_strerror(dns_status(ctx))); -} - -int main(int argc, char **argv) { - int c, t; - time_t now; - int maxq = 10; - struct pollfd pfd; - char linebuf[1024]; - char *eol; - int eof; - - if (dns_init(NULL, 1) < 0) { - fprintf(stderr, "unable to initialize dns library\n"); - return 1; - } - while((c = getopt(argc, argv, "m:r")) != EOF) switch(c) { - case 'm': maxq = atoi(optarg); break; - case 'r': - dns_set_opt(0, DNS_OPT_FLAGS, - dns_set_opt(0, DNS_OPT_FLAGS, -1) | DNS_NORD); - break; - default: return 1; - } - if (argc != optind) return 1; - - pfd.fd = dns_sock(0); - pfd.events = POLLIN; - now = time(NULL); - c = optind; - eof = 0; - while(curq || !eof) { - if (!eof && curq < maxq) { - union { struct in_addr a; void *p; } pa; - if (!fgets(linebuf, sizeof(linebuf), stdin)) { - eof = 1; - continue; - } - eol = strchr(linebuf, '\n'); - if (eol) *eol = '\0'; - if (!linebuf[0]) continue; - if (dns_pton(AF_INET, linebuf, &pa.a) <= 0) - fprintf(stderr, "%s: invalid address\n", linebuf); - else if (dns_submit_a4ptr(0, &pa.a, dnscb, pa.p) == 0) - fprintf(stderr, "%s: unable to submit query: %s\n", - linebuf, dns_strerror(dns_status(0))); - else - ++curq; - continue; - } - if (curq) { - t = dns_timeouts(0, -1, now); - t = poll(&pfd, 1, c * 1000); - now = time(NULL); - if (t) dns_ioevent(0, now); - } - } - return 0; -} diff --git a/deps/udns/getopt.c b/deps/udns/getopt.c deleted file mode 100644 index f5d476a..0000000 --- a/deps/udns/getopt.c +++ /dev/null @@ -1,165 +0,0 @@ -/* $Id: getopt.c,v 1.2 2007/01/07 23:19:19 mjt Exp $ - * Simple getopt() implementation. - * - * Standard interface: - * extern int getopt(int argc, char *const *argv, const char *opts); - * extern int optind; current index in argv[] - * extern char *optarg; argument for the current option - * extern int optopt; the current option - * extern int opterr; to control error printing - * - * Some minor extensions: - * ignores leading `+' sign in opts[] (unemplemented GNU extension) - * handles optional arguments, in form "x::" in opts[] - * if opts[] starts with `:', will return `:' in case of missing required - * argument, instead of '?'. - * - * Compile with -DGETOPT_NO_OPTERR to never print errors internally. - * Compile with -DGETOPT_NO_STDIO to use write() calls instead of fprintf() for - * error reporting (ignored with -DGETOPT_NO_OPTERR). - * Compile with -DGETOPT_CLASS=static to get static linkage. - * Compile with -DGETOPT_MY to redefine all visible symbols to be prefixed - * with "my_", like my_getopt instead of getopt. - * Compile with -DTEST to get a test executable. - * - * Written by Michael Tokarev. Public domain. - */ - -#include - -#ifndef GETOPT_CLASS -# define GETOPT_CLASS -#endif -#ifdef GETOPT_MY -# define optarg my_optarg -# define optind my_optind -# define opterr my_opterr -# define optopt my_optopt -# define getopt my_getopt -#endif - -GETOPT_CLASS char *optarg /* = NULL */; -GETOPT_CLASS int optind = 1; -GETOPT_CLASS int opterr = 1; -GETOPT_CLASS int optopt; - -static char *nextc /* = NULL */; - -#if defined(GETOPT_NO_OPTERR) - -#define printerr(argv, msg) - -#elif defined(GETOPT_NO_STDIO) - -extern int write(int, void *, int); - -static void printerr(char *const *argv, const char *msg) { - if (opterr) { - char buf[64]; - unsigned pl = strlen(argv[0]); - unsigned ml = strlen(msg); - char *p; - if (pl + /*": "*/2 + ml + /*" -- c\n"*/6 > sizeof(buf)) { - write(2, argv[0], pl); - p = buf; - } - else { - memcpy(buf, argv[0], ml); - p = buf + pl; - } - *p++ = ':'; *p++ = ' '; - memcpy(p, msg, ml); p += ml; - *p++ = ' '; *p++ = '-'; *p++ = '-'; *p++ = ' '; - *p++ = optopt; - *p++ = '\n'; - write(2, buf, p - buf); - } -} - -#else - -#include -static void printerr(char *const *argv, const char *msg) { - if (opterr) - fprintf(stderr, "%s: %s -- %c\n", argv[0], msg, optopt); -} - -#endif - -GETOPT_CLASS int getopt(int argc, char *const *argv, const char *opts) { - char *p; - - optarg = 0; - if (*opts == '+') /* GNU extension (permutation) - isn't supported */ - ++opts; - - if (!optind) { /* a way to reset things */ - nextc = 0; - optind = 1; - } - - if (!nextc || !*nextc) { /* advance to the next argv element */ - /* done scanning? */ - if (optind >= argc) - return -1; - /* not an optional argument */ - if (argv[optind][0] != '-') - return -1; - /* bare `-' */ - if (argv[optind][1] == '\0') - return -1; - /* special case `--' argument */ - if (argv[optind][1] == '-' && argv[optind][2] == '\0') { - ++optind; - return -1; - } - nextc = argv[optind] + 1; - } - - optopt = *nextc++; - if (!*nextc) - ++optind; - p = strchr(opts, optopt); - if (!p || optopt == ':') { - printerr(argv, "illegal option"); - return '?'; - } - if (p[1] == ':') { - if (*nextc) { - optarg = nextc; - nextc = NULL; - ++optind; - } - else if (p[2] != ':') { /* required argument */ - if (optind >= argc) { - printerr(argv, "option requires an argument"); - return *opts == ':' ? ':' : '?'; - } - else - optarg = argv[optind++]; - } - } - return optopt; -} - -#ifdef TEST - -#include - -int main(int argc, char **argv) { - int c; - while((c = getopt(argc, argv, "ab:c::")) != -1) switch(c) { - case 'a': - case 'b': - case 'c': - printf("option %c %s\n", c, optarg ? optarg : "(none)"); - break; - default: - return -1; - } - for(c = optind; c < argc; ++c) - printf("non-opt: %s\n", argv[c]); - return 0; -} - -#endif diff --git a/deps/udns/inet_XtoX.c b/deps/udns/inet_XtoX.c deleted file mode 100644 index 174b8ed..0000000 --- a/deps/udns/inet_XtoX.c +++ /dev/null @@ -1,327 +0,0 @@ -/* $Id: inet_XtoX.c,v 1.1 2006/12/04 01:55:39 mjt Exp $ - * Simple implementation of the following functions: - * inet_ntop(), inet_ntoa(), inet_pton(), inet_aton(). - * - * Differences from traditional implementaitons: - * o modifies destination buffers even on error return. - * o no fancy (hex, or 1.2) input support in inet_aton() - * o inet_aton() does not accept junk after an IP address. - * o inet_ntop(AF_INET) requires at least 16 bytes in dest, - * and inet_ntop(AF_INET6) at least 40 bytes - * (traditional inet_ntop() will try to fit anyway) - * - * Compile with -Dinet_XtoX_prefix=pfx_ to have pfx_*() instead of inet_*() - * Compile with -Dinet_XtoX_no_ntop or -Dinet_XtoX_no_pton - * to disable net2str or str2net conversions. - * - * #define inet_XtoX_prototypes and #include "this_file.c" - * to get function prototypes only (but not for inet_ntoa()). - * #define inet_XtoX_decl to be `static' for static visibility, - * or use __declspec(dllexport) or somesuch... - * - * Compile with -DTEST to test against stock implementation. - * - * Written by Michael Tokarev. Public domain. - */ - -#ifdef inet_XtoX_prototypes - -struct in_addr; - -#else - -#include - -#ifdef TEST - -# include -# include -# include -# include -# include -# include -# include -# undef inet_XtoX_prefix -# define inet_XtoX_prefix mjt_inet_ -# undef inet_XtoX_no_ntop -# undef inet_XtoX_no_pton - -#else /* !TEST */ - -struct in_addr { /* declare it here to avoid messing with headers */ - unsigned char x[4]; -}; - -#endif /* TEST */ - -#endif /* inet_XtoX_prototypes */ - -#ifndef inet_XtoX_prefix -# define inet_XtoX_prefix inet_ -#endif -#ifndef inet_XtoX_decl -# define inet_XtoX_decl /*empty*/ -#endif - -#define cc2_(x,y) cc2__(x,y) -#define cc2__(x,y) x##y -#define fn(x) cc2_(inet_XtoX_prefix,x) - -#ifndef inet_XtoX_no_ntop - -inet_XtoX_decl const char * -fn(ntop)(int af, const void *src, char *dst, unsigned size); - -#ifndef inet_XtoX_prototypes - -static int mjt_ntop4(const void *_src, char *dst, int size) { - unsigned i, x, r; - char *p; - const unsigned char *s = _src; - if (size < 4*4) /* for simplicity, disallow non-max-size buffer */ - return 0; - for (i = 0, p = dst; i < 4; ++i) { - if (i) *p++ = '.'; - x = r = s[i]; - if (x > 99) { *p++ = (char)(r / 100 + '0'); r %= 100; } - if (x > 9) { *p++ = (char)(r / 10 + '0'); r %= 10; } - *p++ = (char)(r + '0'); - } - *p = '\0'; - return 1; -} - -static char *hexc(char *p, unsigned x) { - static char hex[16] = "0123456789abcdef"; - if (x > 0x0fff) *p++ = hex[(x >>12) & 15]; - if (x > 0x00ff) *p++ = hex[(x >> 8) & 15]; - if (x > 0x000f) *p++ = hex[(x >> 4) & 15]; - *p++ = hex[x & 15]; - return p; -} - -static int mjt_ntop6(const void *_src, char *dst, int size) { - unsigned i; - unsigned short w[8]; - unsigned bs = 0, cs = 0; - unsigned bl = 0, cl = 0; - char *p; - const unsigned char *s = _src; - - if (size < 40) /* for simplicity, disallow non-max-size buffer */ - return 0; - - for(i = 0; i < 8; ++i, s += 2) { - w[i] = (((unsigned short)(s[0])) << 8) | s[1]; - if (!w[i]) { - if (!cl++) cs = i; - } - else { - if (cl > bl) bl = cl, bs = cs; - } - } - if (cl > bl) bl = cl, bs = cs; - p = dst; - if (bl == 1) - bl = 0; - if (bl) { - for(i = 0; i < bs; ++i) { - if (i) *p++ = ':'; - p = hexc(p, w[i]); - } - *p++ = ':'; - i += bl; - if (i == 8) - *p++ = ':'; - } - else - i = 0; - for(; i < 8; ++i) { - if (i) *p++ = ':'; - if (i == 6 && !bs && (bl == 6 || (bl == 5 && w[5] == 0xffff))) - return mjt_ntop4(s - 4, p, size - (p - dst)); - p = hexc(p, w[i]); - } - *p = '\0'; - return 1; -} - -inet_XtoX_decl const char * -fn(ntop)(int af, const void *src, char *dst, unsigned size) { - switch(af) { - /* don't use AF_*: don't mess with headers */ - case 2: /* AF_INET */ if (mjt_ntop4(src, dst, size)) return dst; break; - case 10: /* AF_INET6 */ if (mjt_ntop6(src, dst, size)) return dst; break; - default: errno = EAFNOSUPPORT; return (char*)0; - } - errno = ENOSPC; - return (char*)0; -} - -inet_XtoX_decl const char * -fn(ntoa)(struct in_addr addr) { - static char buf[4*4]; - mjt_ntop4(&addr, buf, sizeof(buf)); - return buf; -} - -#endif /* inet_XtoX_prototypes */ -#endif /* inet_XtoX_no_ntop */ - -#ifndef inet_XtoX_no_pton - -inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst); -inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr); - -#ifndef inet_XtoX_prototypes - -static int mjt_pton4(const char *c, void *dst) { - unsigned char *a = dst; - unsigned n, o; - for (n = 0; n < 4; ++n) { - if (*c < '0' || *c > '9') - return 0; - o = *c++ - '0'; - while(*c >= '0' && *c <= '9') - if ((o = o * 10 + (*c++ - '0')) > 255) - return 0; - if (*c++ != (n == 3 ? '\0' : '.')) - return 0; - *a++ = (unsigned char)o; - } - return 1; -} - -static int mjt_pton6(const char *c, void *dst) { - unsigned short w[8], *a = w, *z, *i; - unsigned v, o; - const char *sc; - unsigned char *d = dst; - if (*c != ':') z = (unsigned short*)0; - else if (*++c != ':') return 0; - else ++c, z = a; - i = 0; - for(;;) { - v = 0; - sc = c; - for(;;) { - if (*c >= '0' && *c <= '9') o = *c - '0'; - else if (*c >= 'a' && *c <= 'f') o = *c - 'a' + 10; - else if (*c >= 'A' && *c <= 'F') o = *c - 'A' + 10; - else break; - v = (v << 4) | o; - if (v > 0xffff) return 0; - ++c; - } - if (sc == c) { - if (z == a && !*c) - break; - else - return 0; - } - if (*c == ':') { - if (a >= w + 8) - return 0; - *a++ = v; - if (*++c == ':') { - if (z) - return 0; - z = a; - if (!*++c) - break; - } - } - else if (!*c) { - if (a >= w + 8) - return 0; - *a++ = v; - break; - } - else if (*c == '.') { - if (a > w + 6) - return 0; - if (!mjt_pton4(sc, d)) - return 0; - *a++ = ((unsigned)(d[0]) << 8) | d[1]; - *a++ = ((unsigned)(d[2]) << 8) | d[3]; - break; - } - else - return 0; - } - v = w + 8 - a; - if ((v && !z) || (!v && z)) - return 0; - for(i = w; ; ++i) { - if (i == z) - while(v--) { *d++ = '\0'; *d++ = '\0'; } - if (i >= a) - break; - *d++ = (unsigned char)((*i >> 8) & 255); - *d++ = (unsigned char)(*i & 255); - } - return 1; -} - -inet_XtoX_decl int fn(pton)(int af, const char *src, void *dst) { - switch(af) { - /* don't use AF_*: don't mess with headers */ - case 2 /* AF_INET */: return mjt_pton4(src, dst); - case 10 /* AF_INET6 */: return mjt_pton6(src, dst); - default: errno = EAFNOSUPPORT; return -1; - } -} - -inet_XtoX_decl int fn(aton)(const char *src, struct in_addr *addr) { - return mjt_pton4(src, addr); -} - -#endif /* inet_XtoX_prototypes */ - -#endif /* inet_XtoX_no_pton */ - -#ifdef TEST - -int main(int argc, char **argv) { - int i; - char n0[16], n1[16]; - char p0[64], p1[64]; - int af = AF_INET; - int pl = sizeof(p0); - int r0, r1; - const char *s0, *s1; - - while((i = getopt(argc, argv, "46a:p:")) != EOF) switch(i) { - case '4': af = AF_INET; break; - case '6': af = AF_INET6; break; - case 'a': case 'p': pl = atoi(optarg); break; - default: return 1; - } - for(i = optind; i < argc; ++i) { - char *a = argv[i]; - - printf("%s:\n", a); - r0 = inet_pton(af, a, n0); - printf(" p2n stock: %s\n", - (r0 < 0 ? "(notsupp)" : !r0 ? "(inval)" : fn(ntop)(af,n0,p0,sizeof(p0)))); - r1 = fn(pton)(af, a, n1); - printf(" p2n this : %s\n", - (r1 < 0 ? "(notsupp)" : !r1 ? "(inval)" : fn(ntop)(af,n1,p1,sizeof(p1)))); - - if ((r0 > 0) != (r1 > 0) || - (r0 > 0 && r1 > 0 && memcmp(n0, n1, af == AF_INET ? 4 : 16) != 0)) - printf(" DIFFER!\n"); - - s0 = inet_ntop(af, n1, p0, pl); - printf(" n2p stock: %s\n", s0 ? s0 : "(inval)"); - s1 = fn(ntop)(af, n1, p1, pl); - printf(" n2p this : %s\n", s1 ? s1 : "(inval)"); - if ((s0 != 0) != (s1 != 0) || - (s0 && s1 && strcmp(s0, s1) != 0)) - printf(" DIFFER!\n"); - - } - return 0; -} - -#endif /* TEST */ diff --git a/deps/udns/rblcheck.1 b/deps/udns/rblcheck.1 deleted file mode 100644 index 0e427e4..0000000 --- a/deps/udns/rblcheck.1 +++ /dev/null @@ -1,151 +0,0 @@ -.\" $Id: rblcheck.1,v 1.1 2005/04/24 23:14:23 mjt Exp $ -.\" rblckeck manpage -.\" -.\" Copyright (C) 2005 Michael Tokarev -.\" This file is part of UDNS library, an async DNS stub resolver. -.\" -.\" This library is free software; you can redistribute it and/or -.\" modify it under the terms of the GNU Lesser General Public -.\" License as published by the Free Software Foundation; either -.\" version 2.1 of the License, or (at your option) any later version. -.\" -.\" This library 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 -.\" Lesser General Public License for more details. -.\" -.\" You should have received a copy of the GNU Lesser General Public -.\" License along with this library, in file named COPYING.LGPL; if not, -.\" write to the Free Software Foundation, Inc., 59 Temple Place, -.\" Suite 330, Boston, MA 02111-1307 USA - -.TH rblckeck 1 "Apr 2005" "User Utilities" - -.SH NAME -rblckeck \- DNSBL lookup utility - -.SH SYNOPSYS -.B rblcheck -.RB [\| \-s -.IR zone \|] -.RB [\| \-S -.IR zone\-file \|] -.RB [\| \-c \|] -.RB [\| \-tmvq \|] -.RB [\| \-n -.IR nsaddr \|] -.IR address \|.\|.\|. - -.SH DESCRIPTION -.B rblcheck -is a simple command-line to perform DNSBL (DNS-based blocklists) lookups. -For every IP address (or a name, in which case it will be resolved to an -address first), the utility verifies whenever it is listed in a (list of) -DNS blocklists specified with -.B \-s -or -.B \-S -options, optionally obtains text assotiated with the listing (usually it -is either some description about the reason of the listing or an URL -referring to such a description), and displays results on standard output. -.PP -The program is implemented on top of -.BR udns (3) -library. - -.SH OPTIONS - -The following options are recognized by -.BR rblcheck : - -.TP -.B \-s \fIzone\fR -add the given \fIzone\fR DNSBL name to the list of active zones. -.TP -.B \-S \fIzone-file\fR -add list of zones from the named \fIzone-file\fR to the list of -active zones (the file specifies one zone as the first word on a -line, empty lines and lines starting with `#' character are ignored). -.TP -.B \-c -reset active zone list. -.TP -.B \-v -be more verbose, produce more detailed output. -.TP -.B \-q -the opposite for \fB\-v\fR -- produce less detailed output. -.TP -.B \-t -obtain text for listed addresses. -.TP -.B \-n \fInsaddr\fR -Use the given nameserver (given as IPv4 or IPv6 address) instead of the -default. The same effect may be achieved by setting $NSCACHEIP environment -variable. -.TP -.B \-m -stop after first hit, ie after the first address which is found to be -listed. - -.TP -.B \-h -print short help and exit. - -.PP -If no -.BR \-s , -.BR \-S -and -.B \-c -options are given, -.B rblcheck -will try to obtain list of zones using $RBLCHECK_ZONES environment variable, -or ~/.rblcheckrc, or /etc/rblckechrc files, in that order. If no zones are -found, it will exit unsuccessefully. - -.SH "RETURN VALUE" -When no addresses given are listed and no errors occured, -.B rblcheck -exits with code 0. If at least one address is listed, -.B rblcheck -returns 100. In case of DNS errors, -.B rblcheck -returns 2. - -.SH ENVIRONMENT - -.TP -.B $RBLCHECK_ZONES -if no -.BR \-s , -.B \-S -or -.B \-c -option is given, -.B rblcheck -tries this variable to obtain list of DNSBL zones to check against. - -.SH FILES - -.TP -$HOME/.rblcheckrc and /etc/rblcheckrc -if no -.BR \-s , -.B \-S -or -.B \-c -option is given, and no $RBLCHECK_ZONES environment variable is set, -.B rblcheck -will try the two files (the first one that exists) to obtain list of -DNSBL zones to check against. -Each line specifies one zone (only first word in each line is used). -Empty lines and lines starting with `#' character are ignored. - -.SH "SEE ALSO" -.BR dnsget (1) -.BR resolv.conf (5) -.BR udns (3). - -.SH AUTHOR -This program and manual pages are written by Michael Tokarev. diff --git a/deps/udns/rblcheck.c b/deps/udns/rblcheck.c deleted file mode 100644 index 1820d1c..0000000 --- a/deps/udns/rblcheck.c +++ /dev/null @@ -1,377 +0,0 @@ -/* $Id: rblcheck.c,v 1.14 2007/01/10 02:52:51 mjt Exp $ - dnsbl (rbl) checker application - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include -#include -#ifdef WINDOWS -# include -#else -# include -# include -# include -# include -#endif -#include -#include -#include -#include "udns.h" - -#ifndef HAVE_GETOPT -# include "getopt.c" -#endif - -static const char *version = "udns-rblcheck 0.2"; -static char *progname; - -static void error(int die, const char *fmt, ...) { - va_list ap; - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); - putc('\n', stderr); - fflush(stderr); - if (die) - exit(1); -} - -struct rblookup { - struct ipcheck *parent; - struct in_addr key; - const char *zone; - struct dns_rr_a4 *addr; - struct dns_rr_txt *txt; -}; - -struct ipcheck { - const char *name; - int naddr; - int listed; - struct rblookup *lookup; -}; - -#define notlisted ((void*)1) - -static int nzones, nzalloc; -static const char **zones; - -static int do_txt; -static int stopfirst; -static int verbose = 1; -/* verbosity level: - * <0 - only bare As/TXTs - * 0 - what RBL result - * 1(default) - what is listed by RBL: result - * 2 - what is[not ]listed by RBL: result, name lookups - */ - -static int listed; -static int failures; - -static void *ecalloc(int size, int cnt) { - void *t = calloc(size, cnt); - if (!t) - error(1, "out of memory"); - return t; -} - -static void addzone(const char *zone) { - if (nzones >= nzalloc) { - const char **zs = (const char**)ecalloc(sizeof(char*), (nzalloc += 16)); - if (zones) { - memcpy(zs, zones, nzones * sizeof(char*)); - free(zones); - } - zones = zs; - } - zones[nzones++] = zone; -} - -static int addzonefile(const char *fname) { - FILE *f = fopen(fname, "r"); - char linebuf[2048]; - if (!f) - return 0; - while(fgets(linebuf, sizeof(linebuf), f)) { - char *p = linebuf, *e; - while(*p == ' ' || *p == '\t') ++p; - if (*p == '#' || *p == '\n') continue; - e = p; - while(*e && *e != ' ' && *e != '\t' && *e != '\n') - ++e; - *e = '\0'; - addzone(p); - } - fclose(f); - return 1; -} - -static void dnserror(struct rblookup *ipl, const char *what) { - char buf[4*4]; - error(0, "unable to %s for %s (%s): %s", - what, dns_ntop(AF_INET, &ipl->key, buf, sizeof(buf)), - ipl->zone, dns_strerror(dns_status(0))); - ++failures; -} - -static void display_result(struct ipcheck *ipc) { - int j; - struct rblookup *l, *le; - char buf[4*4]; - if (!ipc->naddr) return; - for (l = ipc->lookup, le = l + nzones * ipc->naddr; l < le; ++l) { - if (!l->addr) continue; - if (verbose < 2 && l->addr == notlisted) continue; - if (verbose >= 0) { - dns_ntop(AF_INET, &l->key, buf, sizeof(buf)); - if (ipc->name) printf("%s[%s]", ipc->name, buf); - else printf("%s", buf); - } - if (l->addr == notlisted) { - printf(" is NOT listed by %s\n", l->zone); - continue; - } - else if (verbose >= 1) - printf(" is listed by %s: ", l->zone); - else if (verbose >= 0) - printf(" %s ", l->zone); - if (verbose >= 1 || !do_txt) - for (j = 0; j < l->addr->dnsa4_nrr; ++j) - printf("%s%s", j ? " " : "", - dns_ntop(AF_INET, &l->addr->dnsa4_addr[j], buf, sizeof(buf))); - if (!do_txt) ; - else if (l->txt) { - for(j = 0; j < l->txt->dnstxt_nrr; ++j) { - unsigned char *t = l->txt->dnstxt_txt[j].txt; - unsigned char *e = t + l->txt->dnstxt_txt[j].len; - printf("%s\"", verbose > 0 ? "\n\t" : j ? " " : ""); - while(t < e) { - if (*t < ' ' || *t >= 127) printf("\\x%02x", *t); - else if (*t == '\\' || *t == '"') printf("\\%c", *t); - else putchar(*t); - ++t; - } - putchar('"'); - } - free(l->txt); - } - else - printf("%s", verbose > 0 ? "\n\t" : ""); - free(l->addr); - putchar('\n'); - } - free(ipc->lookup); -} - -static void txtcb(struct dns_ctx *ctx, struct dns_rr_txt *r, void *data) { - struct rblookup *ipl = data; - if (r) { - ipl->txt = r; - ++ipl->parent->listed; - } - else if (dns_status(ctx) != DNS_E_NXDOMAIN) - dnserror(ipl, "lookup DNSBL TXT record"); -} - -static void a4cb(struct dns_ctx *ctx, struct dns_rr_a4 *r, void *data) { - struct rblookup *ipl = data; - if (r) { - ipl->addr = r; - ++listed; - if (do_txt) { - if (dns_submit_a4dnsbl_txt(0, &ipl->key, ipl->zone, txtcb, ipl)) - return; - dnserror(ipl, "submit DNSBL TXT record"); - } - ++ipl->parent->listed; - } - else if (dns_status(ctx) != DNS_E_NXDOMAIN) - dnserror(ipl, "lookup DNSBL A record"); - else - ipl->addr = notlisted; -} - -static int -submit_a_queries(struct ipcheck *ipc, - int naddr, const struct in_addr *addr) { - int z, a; - struct rblookup *rl = ecalloc(sizeof(*rl), nzones * naddr); - ipc->lookup = rl; - ipc->naddr = naddr; - for(a = 0; a < naddr; ++a) { - for(z = 0; z < nzones; ++z) { - rl->key = addr[a]; - rl->zone = zones[z]; - rl->parent = ipc; - if (!dns_submit_a4dnsbl(0, &rl->key, rl->zone, a4cb, rl)) - dnserror(rl, "submit DNSBL A query"); - ++rl; - } - } - return 0; -} - -static void namecb(struct dns_ctx *ctx, struct dns_rr_a4 *rr, void *data) { - struct ipcheck *ipc = data; - if (rr) { - submit_a_queries(ipc, rr->dnsa4_nrr, rr->dnsa4_addr); - free(rr); - } - else { - error(0, "unable to lookup `%s': %s", - ipc->name, dns_strerror(dns_status(ctx))); - ++failures; - } -} - -static int submit(struct ipcheck *ipc) { - struct in_addr addr; - if (dns_pton(AF_INET, ipc->name, &addr) > 0) { - submit_a_queries(ipc, 1, &addr); - ipc->name = NULL; - } - else if (!dns_submit_a4(0, ipc->name, 0, namecb, ipc)) { - error(0, "unable to submit name query for %s: %s\n", - ipc->name, dns_strerror(dns_status(0))); - ++failures; - } - return 0; -} - -static void waitdns(struct ipcheck *ipc) { - struct timeval tv; - fd_set fds; - int c; - int fd = dns_sock(NULL); - time_t now = 0; - FD_ZERO(&fds); - while((c = dns_timeouts(NULL, -1, now)) > 0) { - FD_SET(fd, &fds); - tv.tv_sec = c; - tv.tv_usec = 0; - c = select(fd+1, &fds, NULL, NULL, &tv); - now = time(NULL); - if (c > 0) - dns_ioevent(NULL, now); - if (stopfirst && ipc->listed) - break; - } -} - -int main(int argc, char **argv) { - int c; - struct ipcheck ipc; - char *nameserver = NULL; - int zgiven = 0; - - if (!(progname = strrchr(argv[0], '/'))) progname = argv[0]; - else argv[0] = ++progname; - - while((c = getopt(argc, argv, "hqtvms:S:cn:")) != EOF) switch(c) { - case 's': ++zgiven; addzone(optarg); break; - case 'S': - ++zgiven; - if (addzonefile(optarg)) break; - error(1, "unable to read zonefile `%s'", optarg); - case 'c': ++zgiven; nzones = 0; break; - case 'q': --verbose; break; - case 'v': ++verbose; break; - case 't': do_txt = 1; break; - case 'n': nameserver = optarg; break; - case 'm': ++stopfirst; break; - case 'h': - printf("%s: %s (udns library version %s).\n", - progname, version, dns_version()); - printf("Usage is: %s [options] address..\n", progname); - printf( -"Where options are:\n" -" -h - print this help and exit\n" -" -s service - add the service (DNSBL zone) to the serice list\n" -" -S service-file - add the DNSBL zone(s) read from the given file\n" -" -c - clear service list\n" -" -v - increase verbosity level (more -vs => more verbose)\n" -" -q - decrease verbosity level (opposite of -v)\n" -" -t - obtain and print TXT records if any\n" -" -m - stop checking after first address match in any list\n" -" -n ipaddr - use the given nameserver instead of the default\n" -"(if no -s or -S option is given, use $RBLCHECK_ZONES, ~/.rblcheckrc\n" -"or /etc/rblcheckrc in that order)\n" - ); - return 0; - default: - error(1, "use `%s -h' for help", progname); - } - - if (!zgiven) { - char *s = getenv("RBLCHECK_ZONES"); - if (s) { - char *k; - s = strdup(s); - for(k = strtok(s, " \t"); k; k = strtok(NULL, " \t")) - addzone(k); - free(s); - } - else { /* probably worthless on windows? */ - char *path; - char *home = getenv("HOME"); - if (!home) home = "."; - path = malloc(strlen(home) + 1 + sizeof(".rblcheckrc")); - sprintf(path, "%s/.rblcheckrc", home); - if (!addzonefile(path)) - addzonefile("/etc/rblcheckrc"); - free(path); - } - } - if (!nzones) - error(1, "no service (zone) list specified (-s or -S option)"); - - argv += optind; - argc -= optind; - - if (!argc) - return 0; - - if (dns_init(NULL, 0) < 0) - error(1, "unable to initialize DNS library: %s", strerror(errno)); - if (nameserver) { - dns_add_serv(NULL, NULL); - if (dns_add_serv(NULL, nameserver) < 0) - error(1, "wrong IP address for a nameserver: `%s'", nameserver); - } - if (dns_open(NULL) < 0) - error(1, "unable to initialize DNS library: %s", strerror(errno)); - - for (c = 0; c < argc; ++c) { - if (c && (verbose > 1 || (verbose == 1 && do_txt))) putchar('\n'); - memset(&ipc, 0, sizeof(ipc)); - ipc.name = argv[c]; - submit(&ipc); - waitdns(&ipc); - display_result(&ipc); - if (stopfirst > 1 && listed) break; - } - - return listed ? 100 : failures ? 2 : 0; -} diff --git a/deps/udns/udns.3 b/deps/udns/udns.3 deleted file mode 100644 index f580add..0000000 --- a/deps/udns/udns.3 +++ /dev/null @@ -1,1351 +0,0 @@ -.\" $Id: udns.3,v 1.32 2007/01/15 21:19:08 mjt Exp $ -.\" udns library manpage -.\" -.\" Copyright (C) 2005 Michael Tokarev -.\" This file is part of UDNS library, an async DNS stub resolver. -.\" -.\" This library is free software; you can redistribute it and/or -.\" modify it under the terms of the GNU Lesser General Public -.\" License as published by the Free Software Foundation; either -.\" version 2.1 of the License, or (at your option) any later version. -.\" -.\" This library 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 -.\" Lesser General Public License for more details. -.\" -.\" You should have received a copy of the GNU Lesser General Public -.\" License along with this library, in file named COPYING.LGPL; if not, -.\" write to the Free Software Foundation, Inc., 59 Temple Place, -.\" Suite 330, Boston, MA 02111-1307 USA - -.TH udns 3 "Jan 2007" "Library Functions" - -.SH NAME -udns \- stub DNS resolver library - -.SH SYNOPSYS -.nf -#include -struct \fBdns_ctx\fR; -struct \fBdns_query\fR; -extern struct dns_ctx \fBdns_defctx\fR; -struct dns_ctx *\fIctx\fR; -typedef void \fBdns_query_fn\fR(\fIctx\fR, void *\fIresult\fR, void *\fIdata\fR); -typedef int -\fBdns_parse_fn\fR(const unsigned char *\fIqnd\fR, - const unsigned char *\fIpkt\fR, - const unsigned char *\fIcur\fR, - const unsigned char *\fIend\fR, - void **\fIresultp\fR); - -\fBcc\fR ... -l\fBudns\fR -.fi - -.SH DESCRIPTION - -.PP -The DNS library, \fBudns\fR, implements thread-safe stub DNS resolver -functionality, which may be used both traditional, syncronous way -and asyncronously, with application-supplied event loop. - -.PP -While DNS works with both TCP and UDP, performing UDP query first and -if the result does not fit in UDP buffer (512 bytes max for original -DNS protocol), retrying the query over TCP, the library uses UDP only, -but uses EDNS0 (RFC2671) extensions which allows larger UDP buffers. - -.PP -The library uses single UDP socket to perform all operations even when -asking multiple nameservers. This way, it is very simple to use the -library in asyncronous event-loop applications: an application should -add only single socket to the set of filedescriptors it monitors for I/O. - -.PP -The library uses two main objects, \fIresolver context\fR of type -\fBstruct\ dns_ctx\fR, and \fIquery structure\fR of type -\fBstruct\ dns_query\fR, both are opaque for an application. -Resolver context holds global information about the resolver, -such as list of nameservers to use, list of active requests and the like. -Query objects holds information about a single DNS query in progress and -are allocated/processed/freed by the library. Pointer to query structure -may be treated as an identifier of an in-progress query and may be used -to cancel the asyncronous query or to wait for it to complete. - -.PP -Asyncronous interface works as follows. An application initializes -resolver context, submits any number of queries for it using one of -supplied \fBdns_submit_\fIXXX\fR() routines (each return the query -identifier as pointer to query structure), waits for input on the -UDP socket used by the library, and gives some control to the library -by calling \fBdns_ioevent\fR() and \fBdns_timeouts\fR() routines when -appropriate. The library performs all necessary processing and executes -application supplied callback routine when a query completes (either -successefully or not), giving it the result if any, pointer to the -resolver context (from which completion status may be obtained), and -the data pointer supplied by an application when the query has been -submitted. When submitting a query, an application requests how to -handle the reply -- to either return raw DNS reply packet for its -own low-level processing, or it may provide an address of \fIparsing -routine\fR of type \fBdns_parse_fn\fR to perform conversion of on-wire -format into easy to use data structure (the library provides parsing -routines for several commonly used resource record types, as well as -type-safe higher-level inteface that requests parsing automatically). -The I/O monitoring and timeout handling may be either traditional -select() or poll() based, or any callback-driven technique may be -used. - -.PP -Additionally, the library provides traditional syncronous interface, -which may be intermixed with asyncronous calls (during syncronous -query processing, other asyncronous queries for the same resolver -context continued to be processed as usual). An application uses -one of numerous \fBdns_resolve_\fIXXX\fR() routines provided by the -library to perform a query. As with asyncronous interface, an -application may either request to return raw DNS packet or type-specific -data structure by providing the parsing routine to handle the reply. -Every routine from \fBdns_resolve_\fIXXX\fR() series return pointer -to result or NULL in case of any error. Query completion status -(or length of the raw DNS packet) is available from the resolver -context using \fBdns_status\fR() routine, the same way as for the -asyncronous interface. - -.PP -Internally, library uses on-wire format of domain names, referred -to as \fIDN format\fR in this manual page. This is a series of domain -\fIlabels\fR whith preceeding length byte, terminated by zero-length -label wich is integral part of the DN format. There are several routines -provided to convert from traditional asciiz string to DN and back. -Higher-level type-specific query interface hides the DN format from -an application. - -.SH "COMMON DEFINITIONS" - -.PP -Every DNS Resource Record (RR) has a \fItype\fR and a \fIclass\fR. -The library defines several integer constants, \fBDNS_C_\fIXXX\fR and -\fBDNS_T_\fIXXX\fR, to use as symbolic names for RR classes and types, -such as \fBDNS_C_IN\fR for Internet class, \fBDNS_T_A\fR for IPv4 -address record type and so on. See udns.h header file for complete list -of all such constants. - -.PP -The following constants are defined in udns.h header file: -.IP "\fBDNS_MAXDN\fR (255 bytes)" -Maximum length of the domain name in internal (on-wire) DN format. -.IP "\fBDNS_MAXLABEL\fR (63 bytes)" -Maximum length of a single label in DN format. -.IP "\fBDNS_MAXNAME\fR (1024 bytes)" -Maximum length of asciiz format of a domain name. -.IP "\fBDNS_HSIZE\fR (12 bytes)" -Size of header in DNS packet. -.IP "\fBDNS_PORT\fR (53)" -Default port to use when contacting a DNS server. -.IP "\fBDNS_MAXSERV\fR (6 servers)" -Maximum number of DNS servers to use. -.IP "\fBDNS_MAXPACKET\fR (512 bytes)" -Maximum length of DNS UDP packet as specified by original DNS protocol -.IP "\fBDNS_EDNS0PACKET\fR (4096 bytes)" -Default length of DNS UDP packet (with EDNS0 extensions) the library uses. -Note that recursive nameservers usually resides near the client asking them -to resolve names, e.g. on the same LAN segment or even on the same host, so -UDP packet fragmentation isn't a problem in most cases. Note also that -the size of actual packets will be as many bytes as actual reply size requires, -which is smaller than this value in almost all cases. - -.PP -Additionally, several constants are defined to simplify work with raw DNS -packets, such as DNS response codes (\fBDNS_R_\fIXXX\fR), DNS header layout -(\fBDNS_H_\fIXXX\fR) and others. Again, see udns.h for complete list. -Library error codes (\fBDNS_E_\fIXXX\fR) are described later in this -manual page. - -.SH "RESOLVER CONTEXT" - -.PP -Resolver context, of type \fBstruct\ dns_ctx\fR, is an object which is -opaque to an application. Several routines provided by the library -to initialize, copy and free resolver contexts. Most other high-level -routines in this library expects a pointer to resolver context, \fIctx\fR, -as the first argument. There is a default resolver context available, -named \fBdns_defctx\fR. When the context pointer \fIctx\fR passed to -a routine is NULL, \fBdns_defctx\fR is used. Several resolver contexts -may be active at the same time, for example, when an application is -multi-threaded and each thread uses resolver. -.PP -In order to use the library, an application should initialize and open -one or more resolver context objects. These are two separate actions, -performed by \fBdns_init\fR() (or \fBdns_reset\fR()), and \fBdns_open\fR(). -Between the two calls, an application is free to pefrorm additional -initialisation, such as setting custom nameservers, options or domain search -lists. Optionally, in case no additional custom initialisation is required, -\fBdns_init\fR() may open the context if \fIdo_open\fR argument (see below) -is non-zero. -.PP -When initializing resolver context, the library uses information from -system file /etc/resolv.conf (see \fBresolv.conf\fR(5)), consults -environment variables \fB$LOCALDOMAIN\fR, \fB$DNSCACHEIP\fR, -\fB$NAMESERVERS\fR and \fB$RES_OPTIONS\fR, and local host name to obtain -list of local nameservers, domain name search list and various resolver -options. -.PP -The following routines to initialize resolver context are available: -.PP -.nf -void \fBdns_reset\fR(\fIctx\fR) -int \fBdns_init\fR(\fIctx\fR, int \fIdo_open\fR) -.fi -.RS -\fBdns_reset\fR() resets a given resolver context to default values, -preparing it to be opened by \fBdns_open\fR(). -It is ok to call this routine against opened and active context - all active -queries will be dropped, sockets will be closed and so on. This routine -does not initialize any parameters from system configuration files, use -\fBdns_init\fR() for this. There's no error return - operation always -succeeds. \fBdns_init\fR() does everything \fBdns_reset\fR() does, -plus initializes various parameters of the context according to system -configuration and process environment variables. If \fIdo_open\fR is -non-zero, \fBdns_init\fR() calls \fIdns_open\fR(), so that the whole -library initialisation is performed in a single step. -.RE -.PP -.nf -struct dns_ctx *\fBdns_new\fR(struct dns_ctx *\fIcopy\fR) -void \fBdns_free\fR(\fIctx\fR) -.fi -.RS -\fBdns_new\fR() allocates new resolver context and copies all parameters -for a given resolver context \fIcopy\fR, or default context if \fIcopy\fR -is NULL, and returns pointer to the newly allocated context. The context -being copied should be initialized. -\fBdns_new\fR() may fail if there's no memory available to make a copy -of \fIcopy\fR, in which case the routine will return NULL pointer. -\fBdns_free\fR() is used to close assotiated socket and free resolver -context resources and cancelling (abandoming) all active queries -assotiated with it. It's an error to free \fBdns_defctx\fR, only -dynamically allocated contexts returned by \fBdns_new\fR() are allowed -to be freed by \fBdns_free\fR(). -.RE -.PP -.nf -int \fBdns_add_serv\fR(\fIctx\fR, const char *\fIservaddr\fR) -int \fBdns_add_serv_s\fR(\fIctx\fR, const struct sockaddr *\fIsa\fR) -int \fBdns_add_srch\fR(\fIctx\fR, const char *\fIsrch\fR) -.fi -.RS -Add an element to list of nameservers (\fBdns_add_serv\fR(), as -asciiz-string \fIservaddr\fR with an IP address of the nameserver, -and \fBdns_add_serv_s\fR(), as initialized socket address \fIsa\fR), -or search list (\fBdns_add_srch\fR(), as a pointer to domain name) -for the given context \fIctx\fR. If the last argument is a NULL -pointer, the corresponding list (search or nameserver) is reset -instead. Upon successeful completion, each routine returns new -number of elements in the list in question. On error, negative -value is returned and global variable \fBerrno\fR is set appropriately. -It is an error to call any of this functions if the context is -opened (after \fBdns_open\fR() or \fBdns_init\fR() with non-zero argument). -.RE -.PP -.nf -int \fBdns_set_opts\fR(\fIctx\fR, const char *\fIopts\fR) -.fi -.RS -set resolver context options from \fIopts\fR string, in the same way as -processing \fBoptions\fR statement in resolv.conf and \fB$RES_OPTIONS\fR -environment variable. -.RE -.PP -.nf -void \fBdns_set_opt\fR(\fIctx\fR, int \fIopt\fR, \fIval\fR) -.fi -.RS -.B TODO -The \fIflags\fR argument is a bitmask with the following bits defined: -.IP \fBDNS_NOSRCH\fR -do not perform domain name search in search list. -.IP \fBDNS_NORD\fR -do not request recursion when performing queries -(i.e. don't set RD flag in querues). -.IP \fBDNS_AAONLY\fR -request authoritative answers only (i.e. set AA -flag in queries). -.RE - -.PP -.nf -int \fBdns_open\fR(\fIctx\fR) -int \fBdns_sock\fR(const \fIctx\fR) -void \fBdns_close\fR(\fIctx\fR) -.fi -.RS -\fBdns_open\fR() opens the UDP socket used for queries if not already -open, and return assotiated filedescriptor (or negative value in case -of error). Before any query can be submitted, the context should be -opened using this routine. And before opening, the context should be -initialized. -\fBdns_sock\fR() return the UDP socket if open, or -1 if not. -\fBdns_close\fR() closes the UDP socket if it was open, and drops all active -queries if any. -.RE - -.PP -.nf -int \fBdns_active\fR(const \fIctx\fR) -.fi -.RS -return number of active queries queued for the given context -\fIctx\fR, or zero if none. -.RE - -.PP -.nf -int \fBdns_status\fR(const \fIctx\fR) -.fi -.RS -return status code from last operation. When using syncronous -interface, this is the query completion status of the last query. -With asyncronous interface, from within the callback routine, -this is the query completion status of the query for which the -callback is being called. When query submission fails, this -is the error code indicating failure reason. All error codes -are negative and are represented by \fBDNS_E_\fIXXX\fR constants -described below. -.RE - -.PP -.nf -void \fBdns_ioevent\fR(\fIctx\fR, time_t \fInow\fR) -.fi -.RS -this routine may be called by an application to process I/O -events on the UDP socket used by the library, as returned -by \fBdns_sock\fR(). The routine tries to receive incoming -UDP datagram from the socket and process it. The socket is -set up to be non-blocking, so it is safe to call the routine -even if there's no data to read. The routine will process -as many datagrams as are queued for the socket, so it is -safe to use it with either level-triggered or edge-triggered -I/O monitoring model. The \fInow\fR argument is either a -current time as returned by \fBtime\fR(), or 0, in which -case the routine will obtain current time by it's own. -.RE - -.PP -.nf -int \fBdns_timeouts\fR(\fIctx\fR, int \fImaxwait\fR, time_t \fInow\fR) -.fi -.RS -process any pending timeouts and return number of secounds -from current time (\fInow\fR if it is not 0) to the time when -the library wants the application to pass it control to process -more queued requests. In case when there are no requests pending, -this time is -1. The routine will not request a time larger than -\fImaxwait\fR secounds if it is greather or equal to zero. If -\fInow\fR is 0, the routine will obtain current time by it's own; -when it is not 0, it should contain current time as returned by -\fBtime\fR(). -.RE - -.PP -.nf -typedef void \fBdns_utm_fn\fR(\fIctx\fR, int \fItimeout\fR, void *\fIdata\fR) -void \fBdns_set_cbck\fR(\fIctx\fR, dns_utm_fn *\fIutmfn\fR, void *\fIdata\fR) -.fi -.RS -An application may use custom callback-based I/O multiplexing mechanism. -Usually such a mechanism have concept of a \fItimer\fR, and an ability -to register a timer event in a form of a callback routine which will -be executed after certain amount of time. In order to use such an -event mechanism, udns provides an ability to register and de-register -timer events necessary for internal processing using whatever event -mechanism an application uses. For this to work, it is possible to -assotiate a pointer to a routine that will perform necessary work for -(de)registering timer events with a given resolver context, and -udns will call that routine at appropriate times. Prototype of -such a routine is shown by \fBdns_utm_fn\fR typedef above. Libudns -assotiates single timer with resolver context. User-supplied \fIutmfn\fR -routine will be called by the library with the following arguments: -.IP "\fIctx\fR == NULL" -delete user timer, at context free time or when an application changes -user timer request routine using \fBdns_set_cbck\fR(); -.IP "\fIctx\fR != NULL, \fItimeout\fR < 0" -don't fire timer anymore, when there are no active requests; -.IP "\fIctx\fR != NULL, \fItimeout\fR == 0" -fire timer at the next possibility, but not immediately; -.IP "\fIctx\fR != NULL, \fItimeout\fR > 0" -fire timer after \fItimeout\fR seconds after now. -.PP -The \fIdata\fR argument passed to the routine will be the same -as passed to \fBdns_set_cbck\fR(). -.PP -When a timer expires, an application should call \fBdns_tmeouts\fR() -routine (see below). Non-callback timer usage is provided too. -.RE - -.PP -.B XXXX TODO: some more resolver context routines, like dns_set_dbgfn() etc. - -.SH "QUERY INTERFACE" - -.PP -There are two ways to perform DNS queries: traditional syncronous -way, when udns performs all the necessary processing and return -control to the application only when the query completes, and -asyncronous way, when an application submits one or more queries -to the library using given resolver context, and waits for completion -by monitoring filedescriptor used by library and calling library -routines to process input on that filedescriptor. Asyncronous mode -works with callback routines: an application supplies an address of -a routine to execute when the query completes, and a data pointer, -which is passed to the callback routine. - -.PP -Queries are submitted to the library in a form of \fBstruct\ dns_query\fR. -To perform asyncronous query, an application calls one of the -\fBdns_submit_\fIXXX\fR() rounines, and provides necessary information -for a callback, together with all the query parameters. -When the query completes, library will call application-supplied callback -routine, giving it the resolver context (wich holds query completion status), -dynamically allocated result (which will be either raw DNS packet or, if -applicatin requested parsing the result by specifying non-NULL parse routine, -ready-to-use type-specific structure), and a data pointer provided by an -application when it submitted the query. It is the application who's -responsible for freeing the result memory. -.PP -Generic query callback routine looks like this: -.nf -typedef void -\fBdns_query_fn\fR(\fIctx\fR, void *\fIresult\fR, void *\fIdata\fR) -.fi -Type-specific query interface expects similar form of callback -routine with the only difference in type of \fBresult\fR argument, -which will be pointer to specific data structure (decoded reply) -instead of this void pointer to raw DNS packet data. - -.PP -Result parsing routine looks like this: -.nf -typedef int -\fBdns_parse_fn\fR(const unsigned char *\fIqdn\fR, - const unsigned char *\fIpkt\fR, - const unsigned char *\fIcur\fR, - const unsigned char *\fIend\fR, - void **\fIresultp\fR); -.fi -When called by the library, the arguments are as follows: -\fIpkt\fR points to the start of the packet received; -\fIend\fR points past the end of the packet received; -\fIcur\fR points past the query DN in the query section of the -packet; -\fIqdn\fR points to the original query DN. -The routine should allocate a single buffer to hold the result, -parse the reply filling in the buffer, and return the buffer -using \fIresultp\fR argument. It returns 0 in case of error, -or udns error code (\fBDNS_E_\fIXXX\fR constants) in case of -error. -Note that by the time when the parse routine is called by the -library, packet is already verified to be a reply to the -original query, by matching query DN, query class and query type. - -.PP -Type-specific query inteface supplies necessary parsing routines -automatically. - -.PP -In case of error, query completion status as returned by -\fBdns_status\fR(\fIctx\fR), will contain one of the following values: -.IP "positive value" -length of raw DNS packet if parsing is not requested. -.IP 0 -the query was successeful and the \fIreply\fR points to type-specific -data structure. -.IP \fBDNS_E_TEMPFAIL\fR -temporary error, the resolver nameserver was not able to -process our query or timed out. -.IP \fBDNS_E_PROTOCOL\fR -protocol error, a nameserver returned malformed reply. -.IP \fBDNS_E_NXDOMAIN\fR -the domain name does not exist. -.IP \fBDNS_E_NODATA\fR -there is no data of requested type found. -.IP \fBDNS_E_NOMEM\fR -out of memory while processing request. -.IP \fBDNS_E_BADQUERY\fR -some aspect of the query (most common is the domain name in question) -is invalid, and the library can't even start a query. - -.PP -Library provides two series of routines which uses similar interface -- -one for asyncronous queries and another for syncronous queries. There -are two general low-level routines in each series to submit (asyncronous -interface) and resolve (syncronous interface) queries, as well as several -type-specific routines with more easy-to-use interfaces. To submit -an asyncronous query, use one of \fBdns_submit_\fIXXX\fR() routine, each -of which accepts query parameters, pointers to callback routine and to -callback data, and optional current time hint. Note type-specific -\fBdns_submit_\fIXXX\fR() routines expects specific type of the callback -routine as well, which accepts reply as a pointer to corresponding -structure, not a void pointer). Every \fBdns_submit_\fIXXX\fR() routine -return pointer to internal query structure of type struct\ dns_query, -used as an identifier for the given query. - -.PP -To resolve a query syncronously, use one of \fBdns_resolve_\fIXXX\fR() -routines, which accepts the same query parameters (but not the -callback pointers) as corresponding \fBdns_submit_\fIXXX\fR(), and -return the query result, which is the same as passed to the callback -routine in case of asyncronous interface. - -.PP -In either case, the result memory (if the query completed successefully) -is dynamically allocated and should be freed by an application. If -the query failed for any reason, the result will be NULL, and error -status will be available from \fBdns_status\fR(\fIctx\fR) routine -as shown above. - -.PP -.nf -struct dns_query * -\fBdns_submit_dn\fR(\fIctx\fR, - const unsigned char *\fIdn\fR, \fIqcls\fR, \fIqtyp\fR, \fIflags\fR, - \fIparse\fR, \fIcbck\fR, \fIdata\fR) -struct dns_query * -\fBdns_submit_p\fR(\fIctx\fR, - const char *\fIname\fR, \fIqcls\fR, \fIqtyp\fR, \fIflags\fR, - \fIparse\fR, \fIcbck\fR, \fIdata\fR) - enum dns_class \fIqcls\fR; - enum dns_type \fIqtyp\fR; - int \fIflags\fR; - dns_parse_fn *\fIparse\fR; - dns_query_fn *\fIcbck\fR; - void *\fIdata\fR; -.fi -.RS -submit a query for processing for the given resolver context \fIctx\fR. -Two routines differs only in 3rd argument, which is domain name in -DN format (\fIdn\fR) or asciiz string (\fIname\fR). The query will be -performed for the given domain name, with type \fIqtyp\fR in class \fIqcls\fR, -using option bits in \fIflags\fR, using RR parsing routine pointed by -\fIparse\fR if not-NULL, and upon completion, \fIcbck\fR function will -be called with the \fIdata\fR argument. -In case of successeful query submission, -the routine return pointer to internal query structure which may be treated -as an identifier of the query as used by the library, and may be used as an -argument for \fBdns_cancel\fR() routine. In case of error, NULL will be -returned, and context error status (available using \fIdns_status\fR() routine) -will be set to corresponding error code, which in this case may be -DNS_E_BADQUERY if the \fIname\fR of \fIdn\fR is invalid, DNS_E_NOMEM if -there's no memory available to allocate query structure, or DNS_E_TEMPFAIL -if an internal error occured. -.RE - -.PP -.nf -void *\fBdns_resolve_dn\fR(\fIctx\fR, - const unsigned char *\fIdn\fR, \fIqcls\fR, \fIqtyp\fR, \fIflags\fR, \fIparse\fR); -void *\fBdns_resolve_p\fR(\fIctx\fR, - const char *\fIname\fR, \fIqcls\fR, \fIqtyp\fR, \fIflags\fR, \fIparse\fR) - enum dns_class \fIqcls\fR; - enum dns_type \fIqtyp\fR; - int \fIflags\fR; - dns_parse_fn *\fIparse\fR; -.fi -.RS -syncronous interface. The routines perform all the steps necessary to resolve -the given query and return the result. If there's no positive result for any -reason, all the routines return NULL, and set context error status (available -using \fBdns_status\fR() routine) to indicate the error code. If the query -was successeful, context status code will contain either the length of the -raw DNS reply packet if \fIparse\fR argument was NULL (in which case the return -value is pointer to the reply DNS packet), or 0 (in which case the return value -is the result of \fIparse\fR routine). If the query successeful (return value -is not NULL), the memory returned was dynamically allocated by the library -and should be free()d by application after use. -.RE - -.PP -.nf -void *\fBdns_resolve\fR(\fIctx\fR, struct dns_query *\fIq\fR) -.fi -.RS -wait for the given query \fIq\fR, as returned by one of -\fBdns_submit_\fIXXX\fR() routines, for completion, and -return the result. The callback routine will not be called -for this query. After completion, the query identifier \fIq\fR -is not valid. Both \fBdns_resolve_dn\fR() and \fBdns_resolve_p\fR() -are just wrappers around corresponding submit routines and this -\fBdns_resolve\fR() routine. -.RE - -.PP -.nf -void \fBdns_cancel\fR(\fIctx\fR, struct dns_query *\fIq\fR) -.fi -.RS -cancel an active query \fIq\fR, without calling a callback routine. -After completion, the query identifier \fIq\fR is not valid. -.RE - -.SH "TYPE-SPECIFIC QUERIES" - -.PP -In addition to the generic low-level query interface, the library provides -a set of routines to perform specific queries in a type-safe manner, as -well as parsers for several well-known resource record types. The library -implements high-level interface for A, AAAA, PTR, MX and TXT records -and DNSBL and RHSBL functionality. These routines returns specific types -as result of a query, instead of raw DNS packets. The following types -and routines are available. - -.PP -.nf -struct \fBdns_rr_null\fR { - char *\fBdnsn_qname\fR; /* original query name */ - char *\fBdnsn_cname\fR; /* canonical name */ - unsigned \fBdnsn_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsn_nrr\fR; /* number of records in the set */ -}; -.fi -.PP -NULL RR set, used as a base for all other RR type structures. -Every RR structure as used by the library have four standard -fields as in struct\ \fBdns_rr_null\fR. - -.SS "IN A Queries" -.PP -.nf -struct \fBdns_rr_a4\fR { /* IN A RRset */ - char *\fBdnsa4_qname\fR; /* original query name */ - char *\fBdnsa4_cname\fR; /* canonical name */ - unsigned \fBdnsa4_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsa4_nrr\fR; /* number of addresses in the set */ - struct in_addr \fBdnsa4_addr\fR[]; /* array of addresses */ -}; -typedef void - \fBdns_query_a4_fn\fR(\fIctx\fR, struct dns_rr_a4 *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_a4\fB; -struct dns_query * -\fBdns_submit_a4\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR, - dns_query_a4_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_a4 * -\fBdns_resolve_a4\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR); -.fi -.PP -The \fBdns_rr_a4\fR structure holds a result of an \fBIN A\fR query, -which is an array of IPv4 addresses. Callback routine for IN A queries -expected to be of type \fBdns_query_a4_fn\fR, which expects pointer to -\fBdns_rr_a4\fR structure as query result instead of raw DNS packet. -The \fBdns_parse_a4\fR() is used to convert raw DNS reply packet into -\fBdns_rr_a4\fR structure (it is used internally and may be used directly too -with generic query interface). Routines \fBdns_submit_a4\fR() and -\fBdns_resolve_a4\fR() are used to perform A IN queries in a type-safe -manner. The \fIname\fR parameter is the domain name in question, and -\fIflags\fR is query flags bitmask, with one bit, DNS_NOSRCH, of practical -interest (if the \fIname\fR is absolute, that is, it ends up with a dot, -DNS_NOSRCH flag will be set automatically). - -.SS "IN AAAA Queries" -.PP -.nf -struct \fBdns_rr_a6\fR { /* IN AAAA RRset */ - char *\fBdnsa6_qname\fR; /* original query name */ - char *\fBdnsa6_cname\fR; /* canonical name */ - unsigned \fBdnsa6_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsa6_nrr\fR; /* number of addresses in the set */ - struct in6_addr \fBdnsa6_addr\fR[]; /* array of addresses */ -}; -typedef void - \fBdns_query_a6_fn\fR(\fIctx\fR, struct dns_rr_a6 *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_a6\fB; -struct dns_query * -\fBdns_submit_a6\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR, - dns_query_a6_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_a6 * -\fBdns_resolve_a6\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR); -.fi -.PP -The \fBdns_rr_a6\fR structure holds a result of an \fBIN AAAA\fR query, -which is an array of IPv6 addresses. Callback routine for IN AAAA queries -expected to be of type \fBdns_query_a6_fn\fR, which expects pointer to -\fBdns_rr_a6\fR structure as query result instead of raw DNS packet. -The \fBdns_parse_a6\fR() is used to convert raw DNS reply packet into -\fBdns_rr_a6\fR structure (it is used internally and may be used directly too -with generic query interface). Routines \fBdns_submit_a6\fR() and -\fBdns_resolve_a6\fR() are used to perform AAAA IN queries in a type-safe -manner. The \fIname\fR parameter is the domain name in question, and -\fIflags\fR is query flags bitmask, with one bit, DNS_NOSRCH, of practical -interest (if the \fIname\fR is absolute, that is, it ends up with a dot, -DNS_NOSRCH flag will be set automatically). - -.SS "IN PTR Queries" -.PP -.nf -struct \fBdns_rr_ptr\fR { /* IN PTR RRset */ - char *\fBdnsptr_qname\fR; /* original query name */ - char *\fBdnsptr_cname\fR; /* canonical name */ - unsigned \fBdnsptr_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsptr_nrr\fR; /* number of domain name pointers */ - char *\fBdnsptr_ptr\fR[]; /* array of domain name pointers */ -}; -typedef void - \fBdns_query_ptr_fn\fR(\fIctx\fR, struct dns_rr_ptr *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_ptr\fB; -struct dns_query * -\fBdns_submit_a4ptr\fB(\fIctx\fR, const struct in_addr *\fBaddr\fR, - dns_query_ptr_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_ptr * -\fBdns_resolve_a4ptr\fB(\fIctx\fR, const struct in_addr *\fBaddr\fR); -struct dns_query * -\fBdns_submit_a6ptr\fB(\fIctx\fR, const struct in6_addr *\fBaddr\fR, - dns_query_ptr_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_ptr * -\fBdns_resolve_a6ptr\fB(\fIctx\fR, const struct in6_addr *\fBaddr\fR); -.fi -.PP -The \fBdns_rr_ptr\fR structure holds a result of an IN PTR query, which -is an array of domain name pointers for a given IPv4 or IPv6 address. -Callback routine for IN PTR queries expected to be of type -\fBdns_query_ptr_fn\fR, which expects pointer to \fBdns_rr_ptr\fR -structure as query result instead of raw DNS packet. The \fBdns_parse_ptr\fR() -is used to convert raw DNS reply packet into \fBdns_rr_ptr\fR structure -(it is used internally and may be used directly too with generic query -interface). Routines \fBdns_submit_a4ptr\fR() and \fBdns_resolve_a4ptr\fR() -are used to perform IN PTR queries for IPv4 addresses in a type-safe -manner. Routines \fBdns_submit_a6ptr\fR() and \fBdns_resolve_a6ptr\fR() -are used to perform IN PTR queries for IPv6 addresses. - -.SS "IN MX Queries" -.PP -.nf -struct \fBdns_mx\fR { /* single MX record */ - int \fBpriority\fR; /* priority value of this MX */ - char *\fBname\fR; /* domain name of this MX */ -}; -struct \fBdns_rr_mx\fR { /* IN MX RRset */ - char *\fBdnsmx_qname\fR; /* original query name */ - char *\fBdnsmx_cname\fR; /* canonical name */ - unsigned \fBdnsmx_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsmx_nrr\fR; /* number of mail exchangers in the set */ - struct dns_mx \fBdnsmx_mx\fR[]; /* array of mail exchangers */ -}; -typedef void - \fBdns_query_mx_fn\fR(\fIctx\fR, struct dns_rr_mx *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_mx\fB; -struct dns_query * -\fBdns_submit_mx\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR, - dns_query_mx_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_mx * -\fBdns_resolve_mx\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR); -.fi -.PP -The \fBdns_rr_mx\fR structure holds a result of an IN MX query, which -is an array of mail exchangers for a given domain. Callback routine for IN MX -queries expected to be of type \fBdns_query_mx_fn\fR, which expects pointer to -\fBdns_rr_mx\fR structure as query result instead of raw DNS packet. -The \fBdns_parse_mx\fR() is used to convert raw DNS reply packet into -\fBdns_rr_mx\fR structure (it is used internally and may be used directly too -with generic query interface). Routines \fBdns_submit_mx\fR() and -\fBdns_resolve_mx\fR() are used to perform IN MX queries in a type-safe -manner. The \fIname\fR parameter is the domain name in question, and -\fIflags\fR is query flags bitmask, with one bit, DNS_NOSRCH, of practical -interest (if the \fIname\fR is absolute, that is, it ends up with a dot, -DNS_NOSRCH flag will be set automatically). - -.SS "TXT Queries" -.PP -.nf -struct \fBdns_txt\fR { /* single TXT record */ - int \fBlen\fR; /* length of the text */ - unsigned char *\fBtxt\fR; /* pointer to the text */ -}; -struct \fBdns_rr_txt\fR { /* TXT RRset */ - char *\fBdnstxt_qname\fR; /* original query name */ - char *\fBdnstxt_cname\fR; /* canonical name */ - unsigned \fBdnstxt_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnstxt_nrr\fR; /* number of text records in the set */ - struct dns_txt \fBdnstxt_txt\fR[]; /* array of TXT records */ -}; -typedef void - \fBdns_query_txt_fn\fR(\fIctx\fR, struct dns_rr_txt *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_txt\fB; -struct dns_query * -\fBdns_submit_txt\fB(\fIctx\fR, const char *\fIname\fR, enum dns_class \fIqcls\fR, - int \fIflags\fR, dns_query_txt_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_txt * -\fBdns_resolve_txt\fB(\fIctx\fR, const char *\fIname\fR, - enum dns_class \fIqcls\fR, int \fIflags\fR); -.fi -.PP -The \fBdns_rr_txt\fR structure holds a result of a TXT query, which is an -array of text records for a given domain name. Callback routine for TXT -queries expected to be of type \fBdns_query_txt_fn\fR, which expects pointer -to \fBdns_rr_txt\fR structure as query result instead of raw DNS packet. -The \fBdns_parse_txt\fR() is used to convert raw DNS reply packet into -\fBdns_rr_txt\fR structure (it is used internally and may be used directly too -with generic query interface). Routines \fBdns_submit_txt\fR() and -\fBdns_resolve_txt\fR() are used to perform IN MX queries in a type-safe -manner. The \fIname\fR parameter is the domain name in question, and -\fIflags\fR is query flags bitmask, with one bit, DNS_NOSRCH, of practical -interest (if the \fIname\fR is absolute, that is, it ends up with a dot, -DNS_NOSRCH flag will be set automatically). Note that each TXT string -is represented by \fBstruct\ dns_txt\fR, while zero-terminated (and the -len field of the structure does not include the terminator), may contain -embedded null characters -- content of TXT records is not interpreted -by the library in any way. - -.SS "SRV Queries" -.PP -.nf -struct \fBdns_srv\fR { /* single SRV record */ - int \fBpriority\fR; /* priority of the record */ - int \fBweight\fR; /* weight of the record */ - int \fBport\fR; /* the port number to connect to */ - char *\fBname\fR; /* target host name */ -}; -struct \fBdns_rr_srv\fR { /* SRV RRset */ - char *\fBdnssrv_qname\fR; /* original query name */ - char *\fBdnssrv_cname\fR; /* canonical name */ - unsigned \fBdnssrv_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnssrv_nrr\fR; /* number of text records in the set */ - struct dns_srv \fBdnssrv_srv\fR[]; /* array of SRV records */ -}; -typedef void - \fBdns_query_srv_fn\fR(\fIctx\fR, struct dns_rr_srv *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_srv\fB; -struct dns_query * -\fBdns_submit_srv\fB(\fIctx\fR, const char *\fIname\fR, const char *\fIservice\fR, const char *\fIprotocol\fR, - int \fIflags\fR, dns_query_txt_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_srv * -\fBdns_resolve_srv\fB(\fIctx\fR, const char *\fIname\fR, const char *\fIservice\fR, const char *\fIprotocol\fR, - int \fIflags\fR); -.fi -.PP -The \fBdns_rr_srv\fR structure holds a result of an IN SRV (rfc2782) query, -which is an array of servers (together with port numbers) which are performing -operations for a given \fIservice\fR using given \fIprotocol\fR on a target -domain \fIname\fR. Callback routine for IN SRV queries expected to be of type -\fBdns_query_srv_fn\fR, which expects pointer to \fBdns_rr_srv\fR structure as -query result instead of raw DNS packet. The \fBdns_parse_srv\fR() is used to -convert raw DNS reply packet into \fBdns_rr_srv\fR structure (it is used -internally and may be used directly too with generic query interface). -Routines \fBdns_submit_srv\fR() and \fBdns_resolve_srv\fR() are used to -perform IN SRV queries in a type-safe manner. The \fIname\fR parameter -is the domain name in question, \fIservice\fR and \fRprotocl\fR specifies the -service and the protocol in question (the library will construct query DN -according to rfc2782 rules) and may be NULL (in this case the library -assumes \fIname\fR parameter holds the complete SRV query), and -\fIflags\fR is query flags bitmask, with one bit, DNS_NOSRCH, of practical -interest (if the \fIname\fR is absolute, that is, it ends up with a dot, -DNS_NOSRCH flag will be set automatically). - -.SS "NAPTR Queries" -.PP -.nf -struct \fBdns_naptr\fR { /* single NAPTR record */ - int \fBorder\fR; /* record order */ - int \fBpreference\fR; /* preference of this record */ - char *\fBflags\fR; /* application-specific flags */ - char *\fBservices\fR; /* service parameters */ - char *\fBregexp\fR; /* substitutional regular expression */ - char *\fBreplacement\fR; /* replacement string */ -}; -struct \fBdns_rr_naptr\fR { /* NAPTR RRset */ - char *\fBdnsnaptr_qname\fR; /* original query name */ - char *\fBdnsnaptr_cname\fR; /* canonical name */ - unsigned \fBdnsnaptr_ttl\fR; /* Time-To-Live (TTL) value */ - int \fBdnsnaptr_nrr\fR; /* number of text records in the set */ - struct dns_naptr \fBdnsnaptr_naptr\fR[]; /* array of NAPTR records */ -}; -typedef void - \fBdns_query_naptr_fn\fR(\fIctx\fR, struct dns_rr_naptr *\fIresult\fR, \fIdata\fR) -dns_parse_fn \fBdns_parse_naptr\fB; -struct dns_query * -\fBdns_submit_naptr\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR, - dns_query_txt_fn *\fIcbck\fR, \fIdata\fR); -struct dns_rr_naptr * -\fBdns_resolve_naptr\fB(\fIctx\fR, const char *\fIname\fR, int \fIflags\fR); -.fi -.PP -The \fBdns_rr_naptr\fR structure holds a result of an IN NAPTR (rfc3403) query. -Callback routine for IN NAPTR queries expected to be of type -\fBdns_query_naptr_fn\fR, expects pointer to \fBdns_rr_naptr\fR -structure as query result instead of raw DNS packet. -The \fBdns_parse_naptr\fR() is used to convert raw DNS reply packet into -\fBdns_rr_naptr\fR structure (it is used -internally and may be used directly too with generic query interface). -Routines \fBdns_submit_naptr\fR() and \fBdns_resolve_naptr\fR() are used to -perform IN NAPTR queries in a type-safe manner. The \fIname\fR parameter -is the domain name in question, and \fIflags\fR is query flags bitmask, -with one bit, DNS_NOSRCH, of practical interest (if the \fIname\fR is -absolute, that is, it ends up with a dot, DNS_NOSRCH flag will be set -automatically). - -.SS "DNSBL Interface" -.PP -A DNS-based blocklists, or a DNSBLs, are in wide use nowadays, especially -to protect mailservers from spammers. The library provides DNSBL interface, -a set of routines to perform queries against DNSBLs. Routines accepts an -IP address (IPv4 and IPv6 are both supported) and a base DNSBL zone as -query parameters, and returns either \fBdns_rr_a4\fR or \fBdns_rr_txt\fR -structure. Note that IPv6 interface return IPv4 RRset. -.PP -.nf -struct dns_query * -\fBdns_submit_a4dnsbl\fR(\fIctx\fR, - const struct in_addr *\fIaddr\fR, const char *\fIdnsbl\fR, - dns_query_a4_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_query * -\fBdns_submit_a4dnsbl_txt\fR(\fIctx\fR, - const struct in_addr *\fIaddr\fR, const char *\fIdnsbl\fR, - dns_query_txt_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_query * -\fBdns_submit_a6dnsbl\fR(\fIctx\fR, - const struct in6_addr *\fIaddr\fR, const char *\fIdnsbl\fR, - dns_query_a4_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_query * -\fBdns_submit_a6dnsbl_txt\fR(\fIctx\fR, - const struct in6_addr *\fIaddr\fR, const char *\fIdnsbl\fR, - dns_query_txt_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_rr_a4 *\fBdns_resolve_a4dnsbl\fR(\fIctx\fR, - const struct in_addr *\fIaddr\fR, const char *\fIdnsbl\fR) -struct dns_rr_txt *\fBdns_resolve_a4dnsbl_txt\fR(\fIctx\fR, - const struct in_addr *\fIaddr\fR, const char *\fIdnsbl\fR) -struct dns_rr_a4 *\fBdns_resolve_a6dnsbl\fR(\fIctx\fR, - const struct in6_addr *\fIaddr\fR, const char *\fIdnsbl\fR) -struct dns_rr_txt *\fBdns_resolve_a6dnsbl_txt\fR(\fIctx\fR, - const struct in6_addr *\fIaddr\fR, const char *\fIdnsbl\fR) -.fi -Perform (submit or resolve) a DNSBL query for the given \fIdnsbl\fR -domain and an IP \fIaddr\fR in question, requesting either A or TXT -records. - -.SS "RHSBL Interface" -.PP -RHSBL is similar to DNSBL, but instead of an IP address, the -parameter is a domain name. -.PP -.nf -struct dns_query * -\fBdns_submit_rhsbl\fR(\fIctx\fR, const char *\fIname\fR, const char *\fIrhsbl\fR, - dns_query_a4_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_query * -\fBdns_submit_rhsbl_txt\fR(\fIctx\fR, const char *\fIname\fR, const char *\fIrhsbl\fR, - dns_query_txt_fn *\fIcbck\fR, void *\fIdata\fR); -struct dns_rr_a4 * -\fBdns_resolve_rhsbl\fR(\fIctx\fR, const char *\fIname\fR, const char *\fIrhsbl\fR); -struct dns_rr_txt * -\fBdns_resolve_rhsbl_txt\fR(\fIctx\fR, const char *\fIname\fR, const char *\fIrhsbl\fR); -.fi -Perform (submit or resolve) a RHSBL query for the given \fIrhsbl\fR -domain and \fIname\fR in question, requesting either A or TXT records. - - -.SH "LOW-LEVEL INTERFACE" - -.SS "Domain Names (DNs)" - -.PP -A DN is a series of domain name labels each starts with length byte, -followed by empty label (label with zero length). The following -routines to work with DNs are provided. - -.PP -.nf -unsigned \fBdns_dnlen\fR(const unsigned char *\fIdn\fR) -.fi -.RS -return length of the domain name \fIdn\fR, including the terminating label. -.RE - -.PP -.nf -unsigned \fBdns_dnlabels\fR(const unsigned char *\fIdn\fR) -.fi -.RS -return number of non-zero labels in domain name \fIdn\fR. -.RE - -.PP -.nf -unsigned \fBdns_dnequal\fR(\fIdn1\fR, \fIdn2\fR) - const unsigned char *\fIdn1\fR, *\fIdn2\fR; -.fi -.RS -test whenever the two domain names, \fIdn1\fR and \fIdn2\fR, are -equal (case-insensitive). Return domain name length if equal -or 0 if not. -.RE - -.PP -.nf -unsigned \fBdns_dntodn\fR(\fIsdn\fR, \fIddn\fR, \fIdnsiz\fR) - const unsigned char *\fIsdn\fR; - unsigned char *\fIddn\fR; - unsigned \fIdnsiz\fR; -.fi -.RS -copies the source domain name \fIsdn\fR to destination buffer \fIddn\fR -of size \fIdnsiz\fR. Return domain name length or 0 if \fIddn\fR is -too small. -.RE - -.PP -.nf -int \fBdns_ptodn\fR(\fIname\fR, \fInamelen\fR, \fIdn\fR, \fIdnsiz\fR, \fIisabs\fR) -int \fBdns_sptodn\fR(\fIname\fR, \fIdn\fR, \fIdnsiz\fR) - const char *\fIname\fR; unsigned \fInamelen\fR; - unsigned char *\fIdn\fR; unsigned \fIdnsiz\fR; - int *\fIisabs\fR; -.fi -.RS -convert asciiz name \fIname\fR of length \fInamelen\fR to DN format, -placing result into buffer \fIdn\fR of size \fIdnsiz\fR. Return -length of the DN if successeful, 0 if the \fIdn\fR buffer supplied is -too small, or negative value if \fIname\fR is invalid. If \fIisabs\fR -is non-NULL and conversion was successeful, *\fIisabs\fR will be set to -either 1 or 0 depending whenever \fIname\fR was absolute (i.e. ending with -a dot) or not. Name length, \fInamelength\fR, may be zero, in which case -strlen(\fIname\fR) will be used. Second form, \fBdns_sptodn\fR(), is a -simplified form of \fBdns_ptodn\fR(), equivalent to -.br -.nf -\fBdns_ptodn\fR(\fIname\fR, 0, \fIdn\fR, \fIdnlen\fR, 0). -.fi -.RE - -.PP -.nf -extern const unsigned char \fBdns_inaddr_arpa_dn\fR[] -int \fBdns_a4todn\fR(const struct in_addr *\fIaddr\fR, const unsigned char *\fItdn\fR, - unsigned char *\fIdn\fR, unsigned \fIdnsiz\fR) -int \fBdns_a4ptodn\fR(const struct in_addr *\fIaddr\fR, const char *\fItname\fR, - unsigned char *\fIdn\fR, unsigned \fIdnsiz\fR) -extern const unsigned char \fBdns_ip6_arpa_dn\fR[] -int \fBdns_a6todn\fR(const struct in6_addr *\fIaddr\fR, const unsigned char *\fItdn\fR, - unsigned char *\fIdn\fR, unsigned \fIdnsiz\fR) -int \fBdns_a6ptodn\fR(const struct in6_addr *\fIaddr\fR, const char *\fItname\fR, - unsigned char *\fIdn\fR, unsigned \fIdnsiz\fR) -.fi -.RS -several variants of routines to convert IPv4 and IPv6 address \fIaddr\fR -into reverseDNS-like domain name in DN format, storing result in \fIdn\fR -of size \fIdnsiz\fR. \fItdn\fR (or \fItname\fR) is the base zone name, -like in-addr.arpa for IPv4 or in6.arpa for IPv6. If \fItdn\fR (or \fItname\fR) -is NULL, \fBdns_inaddr_arpa_dn\fR (or \fBdns_ip6_arpa_dn\fR) will be used. -The routines may be used to construct a DN for a DNSBL lookup for example. -All routines return length of the resulting DN on success, -1 if resulting -DN is invalid, or 0 if the \fIdn\fR buffer (\fIdnsiz\fR) is too small. -To hold standard rDNS DN, a buffer of size \fBDNS_A4RSIZE\fR (30 bytes) for -IPv4 address, or \fBDNS_A6RSIZE\fR (74 bytes) for IPv6 address, is sufficient. -.RE - -.PP -.nf -int \fBdns_dntop\fR(\fIdn\fR, \fIname\fR, \fInamesiz\fR) - const unsigned char *\fIdn\fR; - const char *\fIname\fR; unsigned \fInamesiz\fR; -.fi -.RS -convert domain name \fIdn\fR in DN format to asciiz string, placing result -into \fIname\fR buffer of size \fInamesiz\fR. Maximum length of asciiz -representation of domain name is \fBDNS_MAXNAME\fR (1024) bytes. Root -domain is represented as empty string. Return length of the resulting name -(including terminating character, i.e. strlen(name)+1) on success, 0 if the -\fIname\fR buffer is too small, or negative value if \fIdn\fR is invalid -(last case should never happen since all routines in this library which -produce domain names ensure the DNs generated are valid). -.RE - -.PP -.nf -const char *\fBdns_dntosp\fR(const unsigned char *\fIdn\fR) -.fi -.RS -convert domain name \fIdn\fR in DN format to asciiz string using static -buffer. Return the resulting asciiz string on success or NULL on failure. -Note since this routine uses static buffer, it is not thread-safe. -.RE - -.PP -.nf -unsigned \fBdns_dntop_size\fR(const unsigned char *\fIdn\fR) -.fi -.RS -return the buffer size needed to convert the \fIdn\fR domain name -in DN format to asciiz string, for \fBdns_dntop\fR(). The routine -return either the size of buffer required, including the trailing -zero byte, or 0 if \fIdn\fR is invalid. -.RE - -.SS "Working with DNS Packets" - -.PP -The following routines are provided to encode and decode DNS on-wire -packets. This is low-level interface. - -.PP -DNS response codes (returned by \fBdns_rcode\fR() routine) are -defined as constants prefixed with \fBDNS_R_\fR. See udns.h -header file for the complete list. In particular, constants -\fBDNS_R_NOERROR\fR (0), \fBDNS_R_SERVFAIL\fR, \fBDNS_R_NXDOMAIN\fR -may be of interest to an application. - -.PP -.nf -unsigned \fBdns_get16\fR(const unsigned char *\fIp\fR) -unsigned \fBdns_get32\fR(const unsigned char *\fIp\fR) -.fi -.RS -helper routines, convert 16-bit or 32-bit integer in on-wire -format pointed to by \fIp\fR to unsigned. -.RE - -.PP -.nf -unsigned char *\fBdns_put16\fR(unsigned char *\fId\fR, unsigned \fIn\fR) -unsigned char *\fBdns_put32\fR(unsigned char *\fId\fR, unsigned \fIn\fR) -.fi -.RS -helper routine, convert unsigned 16-bit or 32-bit integer \fIn\fR to -on-wire format to buffer pointed to by \fId\fR, return \fId\fR+2 or -\fId\fR+4. -.RE - -.PP -.nf -\fBDNS_HSIZE\fR (12) -.fi -.RS -defines size of DNS header. Data section -in the DNS packet immediately follows the header. In the header, -there are query identifier (id), various flags and codes, -and number of resource records in various data sections. -See udns.h header file for complete list of DNS header definitions. -.RE - -.PP -.nf -unsigned \fBdns_qid\fR(const unsigned char *\fIpkt\fR) -int \fBdns_rd\fR(const unsigned char *\fIpkt\fR) -int \fBdns_tc\fR(const unsigned char *\fIpkt\fR) -int \fBdns_aa\fR(const unsigned char *\fIpkt\fR) -int \fBdns_qr\fR(const unsigned char *\fIpkt\fR) -int \fBdns_ra\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_opcode\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_rcode\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_numqd\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_numan\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_numns\fR(const unsigned char *\fIpkt\fR) -unsigned \fBdns_numar\fR(const unsigned char *\fIpkt\fR) -const unsigned char *\fBdns_payload\fR(const unsigned char *\fIpkt\fR) -.fi -.RS -return various parts from the DNS packet header \fIpkt\fR: -query identifier (qid), -recursion desired (rd) flag, -truncation occured (tc) flag, -authoritative answer (aa) flag, -query response (qr) flag, -recursion available (ra) flag, -operation code (opcode), -result code (rcode), -number of entries in question section (numqd), -number of answers (numan), -number of authority records (numns), -number of additional records (numar), -and the pointer to the packet data (payload). -.RE - -.PP -.nf -int \fBdns_getdn\fR(\fIpkt\fR, \fIcurp\fR, \fIpkte\fR, \fIdn\fR, \fIdnsiz\fR) -const unsigned char *\fBdns_skipdn\fR(\fIcur\fR, \fIpkte\fR) - const unsigned char *\fIpkt\fR, *\fIpkte\fR, **\fIcurp\fR, *\fIcur\fR; - unsigned char *\fIdn\fR; unsigned \fIdnsiz\fR; -.fi -.RS -\fBdns_getdn\fR() extract DN from DNS packet \fIpkt\fR which ends before -\fIpkte\fR starting at position *\fIcurp\fR into buffer pointed to by -\fIdn\fR of size \fIdnsiz\fR. Upon successeful completion, *\fIcurp\fR -will point to the next byte in the packet after the extracted domain name. -It return positive number (length of the DN if \fIdn\fR) upon successeful -completion, negative value on error (when the packet contains invalid data), -or zero if the \fIdnsiz\fR is too small (maximum length of a domain name is -\fBDNS_MAXDN\fR). \fBdns_skipdn\fR() return pointer to the next byte in -DNS packet which ends up before \fIpkte\fR after a domain name which starts -at the \fIcur\fP byte, or NULL if the packet is invalid. \fBdns_skipdn\fR() -is more or less equivalent to what \fBdns_getdn\fR() does, except it does not -actually extract the domain name in question, and uses simpler interface. -.RE - -.PP -.nf -struct \fBdns_rr\fR { - unsigned char \fBdnsrr_dn\fR[DNS_MAXDN]; /* the RR DN name */ - enum dns_class \fBdnsrr_cls\fR; /* class of the RR */ - enum dns_type \fBdnsrr_typ\fR; /* type of the RR */ - unsigned \fBdnsrr_ttl\fR; /* TTL value */ - unsigned \fBdnsrr_dsz\fR; /* size of data in bytes */ - const unsigned char *\fBdnsrr_dptr\fR; /* pointer to the first data byte */ - const unsigned char *\fBdnsrr_dend\fR; /* next byte after RR */ -}; -.fi -.RS -The \fBdns_rr\fR structure is used to hold information about -single DNS Resource Record (RR) in an easy to use form. -.RE - -.PP -.nf -struct \fBdns_parse\fR { - const unsigned char *\fBdnsp_pkt\fR; /* pointer to the packet being parsed */ - const unsigned char *\fBdnsp_end\fR; /* end of the packet pointer */ - const unsigned char *\fBdnsp_cur\fR; /* current packet positionn */ - const unsigned char *\fBdnsp_ans\fR; /* pointer to the answer section */ - int \fBdnsp_rrl\fR; /* number of RRs left */ - int \fBdnsp_nrr\fR; /* number of relevant RRs seen so far */ - unsigned \fBdnsp_ttl\fR; /* TTL value so far */ - const unsigned char *\fBdnsp_qdn\fR; /* the domain of interest or NULL */ - enum dns_class \fBdnsp_qcls\fR; /* class of interest or 0 for any */ - enum dns_type \fBdnsp_qtyp\fR; /* type of interest or 0 for any */ - unsigned char \fBdnsp_dnbuf\fR[DNS_MAXDN]; /* domain name buffer */ -}; -.fi -.RS -The \fBdns_parse\fR structure is used to parse DNS reply packet. -It holds information about the packet being parsed (dnsp_pkt, dnsp_end and -dnsp_cur fields), number of RRs in the current section left to do, and -the information about specific RR which we're looking for (dnsp_qdn, -dnsp_qcls and dnsp_qtyp fields). -.RE - -.PP -.nf -int \fBdns_initparse\fR(struct dns_parse *\fIp\fR, - const unsigned char *\fIqdn\fR, - const unsigned char *\fIpkt\fR, - const unsigned char *\fIcur\fR, - const unsigned char *\fIend\fR) -.fi -.RS -initializes the RR parsing structure \fIp\fR. Arguments \fIpkt\fR, \fIcur\fR -and \fIend\fR should describe the received packet: \fIpkt\fR is the start of -the packet, \fIend\fR points to the next byte after the end of the packet, -and \fIcur\fR points past the query DN in query section (to query class+type -information). And \fIqdn\fR points to the query DN. This is the arguments -passed to \fBdns_parse_fn\fR() routine. \fBdns_initparse\fR() initializes -\fBdnsp_pkt\fR, \fBdnsp_end\fR and \fBdnsp_qdn\fR fields to the corresponding -arguments, extracts and initializes \fBdnsp_qcls\fR and \fBdnsp_qtyp\fR -fields to the values found at \fIcur\fR pointer, initializes -\fBdnsp_cur\fR and \fBdnsp_ans\fR fields to be \fIcur\fR+4 (to the start of -answer section), and initializes \fBdnsp_rrl\fR field to be number of entries -in answer section. \fBdnsp_ttl\fR will be set to max TTL value, 0xffffffff, -and \fBdnsp_nrr\fR to 0. -.RE - -.PP -.nf -int \fBdns_nextrr\fR(struct dns_parse *\fIp\fR, struct dns_rr *\fIrr\fR); -.fi -.RS -searches for next RR in the packet based on the criteria provided in -the \fIp\fR structure, filling in the \fIrr\fR structure and -advancing \fIp\fR->\fBdnsp_cur\fR to the next RR in the packet. -RR selection is based on dnsp_qdn, dnsp_qcls and dnsp_qtyp fields in -the dns_parse structure. Any (or all) of the 3 fields may be 0, -which means any actual value from the packet is acceptable. In case -the field isn't 0 (or NULL for dnsp_qdn), only RRs with corresponding -characteristics are acceptable. Additionally, when dnsp_qdn is non-NULL, -\fBdns_nextrr\fR() performs automatic CNAME expansion. -Routine will return positive value on success, 0 in case it reached the end -of current section in the packet (\fIp\fR->\fBdnsp_rrl\fR is zero), or -negative value if next RR can not be decoded (packet format is invalid). -The routine updates \fIp\fR->\fBdnsp_qdn\fR automatically when this -field is non-NULL and it encounters appropriate CNAME RRs (saving CNAME -target in \fIp\fR->\fBdnsp_dnbuf\fR), so after end of the process, -\fIp\fR->\fBdnsp_qdn\fR will point to canonical name of the domain -in question. The routine updates \fIp\fR->\fBdnsp_ttl\fR value to -be the minimum TTL of all RRs found. -.RE - -.PP -.nf -void \fBdns_rewind\fR(struct dns_parse *\fIp\fR, const unsigned char *\fIqdn\fR) -.fi -.RS -this routine "rewinds" the packet parse state structure to be at the -same state as after a call to \fBdns_initparse\fR(), i.e. reposition -the parse structure \fIp\fR to the start of answer section and -initialize \fIp\fR->\fBdnsp_rrl\fR to the number of entries in -answer section. -.RE - -.PP -.nf -int \fBdns_stdrr_size\fR(const struct dns_parse *\fIp\fR); -.fi -.RS -return size to hold standard RRset structure information, as shown -in \fBdns_rr_null\fR structure (for the query and canonical -names). Used to calculate amount of memory to allocate for common -part of type-specific RR structures in parsing routines. -.RE - -.PP -.nf -void *\fBdns_stdrr_finish\fR(struct dns_rr_null *\fIret\fR, char *\fIcp\fR, - const struct dns_parse *\fIp\fR); -.fi -.RS -initializes standard RRset fields in \fIret\fR structure using buffer -pointed to by \fIcp\fR, which should have at least as many bytes -as \fBdns_stdrr_size\fR(\fIp\fR) returned. Used to finalize common -part of type-specific RR structures in parsing routines. -.RE - -.PP -See library source for usage examples of all the above low-level routines, -especially source of the parsing routines. - -.SS "Auxilary Routines" - -.PP -.nf -int \fBdns_pton\fR(int \fIaf\fR, const char *\fIsrc\fR, void *\fIdst\fR); -.fi -.RS -privides functionality similar to standard \fBinet_pton\fR() routine, -to convert printable representation of an IP address of family \fIaf\fR -(either \fBAF_INET\fR or \fBAF_INET6\fR) pointed to by \fIsrc\fR into -binary form suitable for socket addresses and transmission over network, -in buffer pointed to by \fIdst\fR. The destination buffer should be -of size 4 for \fBAF_INET\fR family or 16 for \fBAF_INET6\fR. -The return value is positive on success, 0 if \fIsrc\fR is not a valid text -representation of an address of family \fIaf\fR, or negative if the -given address family is not supported. -.RE - -.PP -.nf -const char *\fBdns_ntop\fR(int \fIaf\fR, const void *\fIsrc\fR, - char *\fIdst\fR, int \fIdstsize\fR) -.fi -.RS -privides functionality similar to standard \fBinet_ntop\fR() routine, -to convert binary representation of an IP address of family \fIaf\fR -(either \fBAF_INET\fR or \fBAF_INET6\fR) pointed to by \fIsrc\fR -(either 4 or 16 bytes) into printable form in buffer in buffer pointed -to by \fIdst\fR of size \fIdstsize\fR. The destination buffer should be -at least of size 16 bytes for \fBAF_INET\fR family or 46 bytes for -\fBAF_INET6\fR. The return value is either \fIdst\fR, or NULL pointer -if \fIdstsize\fR is too small to hold this address or if the given -address family is not supported. -.RE - -.SH AUTHOR -.PP -The \fBudns\fR library has been written by Michael Tokarev, mjt@corpit.ru. - -.SH VERSION -.PP -This manual page corresponds to udns version 0.0.9, released Jan-2007. diff --git a/deps/udns/udns.h b/deps/udns/udns.h deleted file mode 100644 index 1186bb2..0000000 --- a/deps/udns/udns.h +++ /dev/null @@ -1,745 +0,0 @@ -/* $Id: udns.h,v 1.51 2007/01/15 21:19:08 mjt Exp $ - header file for the UDNS library. - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifndef UDNS_VERSION /* include guard */ - -#define UDNS_VERSION "0.0.9" - -#ifdef WINDOWS -# ifdef UDNS_DYNAMIC_LIBRARY -# ifdef DNS_LIBRARY_BUILD -# define UDNS_API __declspec(dllexport) -# define UDNS_DATA_API __declspec(dllexport) -# else -# define UDNS_API __declspec(dllimport) -# define UDNS_DATA_API __declspec(dllimport) -# endif -# endif -#endif - -#ifndef UDNS_API -# define UDNS_API -#endif -#ifndef UDNS_DATA_API -# define UDNS_DATA_API -#endif - -#include /* for time_t */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* forward declarations if sockets stuff isn't #include'd */ -struct in_addr; -struct in6_addr; -struct sockaddr; - -/**************************************************************************/ -/**************** Common definitions **************************************/ - -UDNS_API const char * -dns_version(void); - -struct dns_ctx; -struct dns_query; - -/* shorthand for [const] unsigned char */ -typedef unsigned char dnsc_t; -typedef const unsigned char dnscc_t; - -#define DNS_MAXDN 255 /* max DN length */ -#define DNS_DNPAD 1 /* padding for DN buffers */ -#define DNS_MAXLABEL 63 /* max DN label length */ -#define DNS_MAXNAME 1024 /* max asciiz domain name length */ -#define DNS_HSIZE 12 /* DNS packet header size */ -#define DNS_PORT 53 /* default domain port */ -#define DNS_MAXSERV 6 /* max servers to consult */ -#define DNS_MAXPACKET 512 /* max traditional-DNS UDP packet size */ -#define DNS_EDNS0PACKET 4096 /* EDNS0 packet size to use */ - -enum dns_class { /* DNS RR Classes */ - DNS_C_INVALID = 0, /* invalid class */ - DNS_C_IN = 1, /* Internet */ - DNS_C_CH = 3, /* CHAOS */ - DNS_C_HS = 4, /* HESIOD */ - DNS_C_ANY = 255 /* wildcard */ -}; - -enum dns_type { /* DNS RR Types */ - DNS_T_INVALID = 0, /* Cookie. */ - DNS_T_A = 1, /* Host address. */ - DNS_T_NS = 2, /* Authoritative server. */ - DNS_T_MD = 3, /* Mail destination. */ - DNS_T_MF = 4, /* Mail forwarder. */ - DNS_T_CNAME = 5, /* Canonical name. */ - DNS_T_SOA = 6, /* Start of authority zone. */ - DNS_T_MB = 7, /* Mailbox domain name. */ - DNS_T_MG = 8, /* Mail group member. */ - DNS_T_MR = 9, /* Mail rename name. */ - DNS_T_NULL = 10, /* Null resource record. */ - DNS_T_WKS = 11, /* Well known service. */ - DNS_T_PTR = 12, /* Domain name pointer. */ - DNS_T_HINFO = 13, /* Host information. */ - DNS_T_MINFO = 14, /* Mailbox information. */ - DNS_T_MX = 15, /* Mail routing information. */ - DNS_T_TXT = 16, /* Text strings. */ - DNS_T_RP = 17, /* Responsible person. */ - DNS_T_AFSDB = 18, /* AFS cell database. */ - DNS_T_X25 = 19, /* X_25 calling address. */ - DNS_T_ISDN = 20, /* ISDN calling address. */ - DNS_T_RT = 21, /* Router. */ - DNS_T_NSAP = 22, /* NSAP address. */ - DNS_T_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */ - DNS_T_SIG = 24, /* Security signature. */ - DNS_T_KEY = 25, /* Security key. */ - DNS_T_PX = 26, /* X.400 mail mapping. */ - DNS_T_GPOS = 27, /* Geographical position (withdrawn). */ - DNS_T_AAAA = 28, /* Ip6 Address. */ - DNS_T_LOC = 29, /* Location Information. */ - DNS_T_NXT = 30, /* Next domain (security). */ - DNS_T_EID = 31, /* Endpoint identifier. */ - DNS_T_NIMLOC = 32, /* Nimrod Locator. */ - DNS_T_SRV = 33, /* Server Selection. */ - DNS_T_ATMA = 34, /* ATM Address */ - DNS_T_NAPTR = 35, /* Naming Authority PoinTeR */ - DNS_T_KX = 36, /* Key Exchange */ - DNS_T_CERT = 37, /* Certification record */ - DNS_T_A6 = 38, /* IPv6 address (deprecates AAAA) */ - DNS_T_DNAME = 39, /* Non-terminal DNAME (for IPv6) */ - DNS_T_SINK = 40, /* Kitchen sink (experimentatl) */ - DNS_T_OPT = 41, /* EDNS0 option (meta-RR) */ - DNS_T_DS = 43, /* DNSSEC */ - DNS_T_NSEC = 47, /* DNSSEC */ - DNS_T_TSIG = 250, /* Transaction signature. */ - DNS_T_IXFR = 251, /* Incremental zone transfer. */ - DNS_T_AXFR = 252, /* Transfer zone of authority. */ - DNS_T_MAILB = 253, /* Transfer mailbox records. */ - DNS_T_MAILA = 254, /* Transfer mail agent records. */ - DNS_T_ANY = 255, /* Wildcard match. */ - DNS_T_ZXFR = 256, /* BIND-specific, nonstandard. */ - DNS_T_MAX = 65536 -}; - -/**************************************************************************/ -/**************** Domain Names (DNs) **************************************/ - -/* return length of the DN */ -UDNS_API unsigned -dns_dnlen(dnscc_t *dn); - -/* return #of labels in a DN */ -UDNS_API unsigned -dns_dnlabels(dnscc_t *dn); - -/* lower- and uppercase single DN char */ -#define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c)) -#define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) - -/* compare the DNs, return dnlen of equal or 0 if not */ -UDNS_API unsigned -dns_dnequal(dnscc_t *dn1, dnscc_t *dn2); - -/* copy one DN to another, size checking */ -UDNS_API unsigned -dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz); - -/* convert asciiz string of length namelen (0 to use strlen) to DN */ -UDNS_API int -dns_ptodn(const char *name, unsigned namelen, - dnsc_t *dn, unsigned dnsiz, int *isabs); - -/* simpler form of dns_ptodn() */ -#define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0) - -UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14]; -#define DNS_A4RSIZE 30 -UDNS_API int -dns_a4todn(const struct in_addr *addr, dnscc_t *tdn, - dnsc_t *dn, unsigned dnsiz); -UDNS_API int -dns_a4ptodn(const struct in_addr *addr, const char *tname, - dnsc_t *dn, unsigned dnsiz); -UDNS_API dnsc_t * -dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne); - -UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10]; -#define DNS_A6RSIZE 74 -UDNS_API int -dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn, - dnsc_t *dn, unsigned dnsiz); -UDNS_API int -dns_a6ptodn(const struct in6_addr *addr, const char *tname, - dnsc_t *dn, unsigned dnsiz); -UDNS_API dnsc_t * -dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne); - -/* convert DN into asciiz string */ -UDNS_API int -dns_dntop(dnscc_t *dn, char *name, unsigned namesiz); - -/* convert DN into asciiz string, using static buffer (NOT thread-safe!) */ -UDNS_API const char * -dns_dntosp(dnscc_t *dn); - -/* return buffer size (incl. null byte) required for asciiz form of a DN */ -UDNS_API unsigned -dns_dntop_size(dnscc_t *dn); - -/* either wrappers or reimplementations for inet_ntop() and inet_pton() */ -UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size); -UDNS_API int dns_pton(int af, const char *src, void *dst); - -/**************************************************************************/ -/**************** DNS raw packet layout ***********************************/ - -enum dns_rcode { /* reply codes */ - DNS_R_NOERROR = 0, /* ok, no error */ - DNS_R_FORMERR = 1, /* format error */ - DNS_R_SERVFAIL = 2, /* server failed */ - DNS_R_NXDOMAIN = 3, /* domain does not exists */ - DNS_R_NOTIMPL = 4, /* not implemented */ - DNS_R_REFUSED = 5, /* query refused */ - /* these are for BIND_UPDATE */ - DNS_R_YXDOMAIN = 6, /* Name exists */ - DNS_R_YXRRSET = 7, /* RRset exists */ - DNS_R_NXRRSET = 8, /* RRset does not exist */ - DNS_R_NOTAUTH = 9, /* Not authoritative for zone */ - DNS_R_NOTZONE = 10, /* Zone of record different from zone section */ - /*ns_r_max = 11,*/ - /* The following are TSIG extended errors */ - DNS_R_BADSIG = 16, - DNS_R_BADKEY = 17, - DNS_R_BADTIME = 18 -}; - -static __inline unsigned dns_get16(dnscc_t *s) { - return ((unsigned)s[0]<<8) | s[1]; -} -static __inline unsigned dns_get32(dnscc_t *s) { - return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16) - | ((unsigned)s[2]<<8) | s[3]; -} -static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) { - *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d; -} -static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) { - *d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255); - *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); - return d; -} - -/* return pseudo-random 16bits number */ -UDNS_API unsigned dns_random16(void); - -/* DNS Header layout */ -enum { - /* bytes 0:1 - query ID */ - DNS_H_QID1 = 0, - DNS_H_QID2 = 1, - DNS_H_QID = DNS_H_QID1, -#define dns_qid(pkt) dns_get16((pkt)+DNS_H_QID) - /* byte 2: flags1 */ - DNS_H_F1 = 2, - DNS_HF1_QR = 0x80, /* query response flag */ -#define dns_qr(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_QR) - DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */ -#define dns_opcode(pkt) (((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3) - DNS_HF1_AA = 0x04, /* auth answer */ -#define dns_aa(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_AA) - DNS_HF1_TC = 0x02, /* truncation flag */ -#define dns_tc(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_TC) - DNS_HF1_RD = 0x01, /* recursion desired (may be set in query) */ -#define dns_rd(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_RD) - /* byte 3: flags2 */ - DNS_H_F2 = 3, - DNS_HF2_RA = 0x80, /* recursion available */ -#define dns_ra(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RA) - DNS_HF2_Z = 0x70, /* reserved */ - DNS_HF2_RCODE = 0x0f, /* response code, DNS_R_XXX above */ -#define dns_rcode(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RCODE) - /* bytes 4:5: qdcount, numqueries */ - DNS_H_QDCNT1 = 4, - DNS_H_QDCNT2 = 5, - DNS_H_QDCNT = DNS_H_QDCNT1, -#define dns_numqd(pkt) dns_get16((pkt)+4) - /* bytes 6:7: ancount, numanswers */ - DNS_H_ANCNT1 = 6, - DNS_H_ANCNT2 = 7, - DNS_H_ANCNT = DNS_H_ANCNT1, -#define dns_numan(pkt) dns_get16((pkt)+6) - /* bytes 8:9: nscount, numauthority */ - DNS_H_NSCNT1 = 8, - DNS_H_NSCNT2 = 9, - DNS_H_NSCNT = DNS_H_NSCNT1, -#define dns_numns(pkt) dns_get16((pkt)+8) - /* bytes 10:11: arcount, numadditional */ - DNS_H_ARCNT1 = 10, - DNS_H_ARCNT2 = 11, - DNS_H_ARCNT = DNS_H_ARCNT1, -#define dns_numar(pkt) dns_get16((pkt)+10) -#define dns_payload(pkt) ((pkt)+DNS_HSIZE) -}; - -/* packet buffer: start at pkt, end before pkte, current pos *curp. - * extract a DN and set *curp to the next byte after DN in packet. - * return -1 on error, 0 if dnsiz is too small, or dnlen on ok. - */ -UDNS_API int -dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end, - dnsc_t *dn, unsigned dnsiz); - -/* skip the DN at position cur in packet ending before pkte, - * return pointer to the next byte after the DN or NULL on error */ -UDNS_API dnscc_t * -dns_skipdn(dnscc_t *end, dnscc_t *cur); - -struct dns_rr { /* DNS Resource Record */ - dnsc_t dnsrr_dn[DNS_MAXDN]; /* the DN of the RR */ - enum dns_class dnsrr_cls; /* Class */ - enum dns_type dnsrr_typ; /* Type */ - unsigned dnsrr_ttl; /* Time-To-Live (TTL) */ - unsigned dnsrr_dsz; /* data size */ - dnscc_t *dnsrr_dptr; /* pointer to start of data */ - dnscc_t *dnsrr_dend; /* past end of data */ -}; - -struct dns_parse { /* RR/packet parsing state */ - dnscc_t *dnsp_pkt; /* start of the packet */ - dnscc_t *dnsp_end; /* end of the packet */ - dnscc_t *dnsp_cur; /* current packet position */ - dnscc_t *dnsp_ans; /* start of answer section */ - int dnsp_rrl; /* number of RRs left to go */ - int dnsp_nrr; /* RR count so far */ - unsigned dnsp_ttl; /* TTL value so far */ - dnscc_t *dnsp_qdn; /* the RR DN we're looking for */ - enum dns_class dnsp_qcls; /* RR class we're looking for or 0 */ - enum dns_type dnsp_qtyp; /* RR type we're looking for or 0 */ - dnsc_t dnsp_dnbuf[DNS_MAXDN]; /* domain buffer */ -}; - -/* initialize the parse structure */ -UDNS_API void -dns_initparse(struct dns_parse *p, dnscc_t *qdn, - dnscc_t *pkt, dnscc_t *cur, dnscc_t *end); - -/* search next RR, <0=error, 0=no more RRs, >0 = found. */ -UDNS_API int -dns_nextrr(struct dns_parse *p, struct dns_rr *rr); - -UDNS_API void -dns_rewind(struct dns_parse *p, dnscc_t *qdn); - - -/**************************************************************************/ -/**************** Resolver Context ****************************************/ - -/* default resolver context */ -UDNS_DATA_API extern struct dns_ctx dns_defctx; - -/* reset resolver context to default state, close it if open, drop queries */ -UDNS_API void -dns_reset(struct dns_ctx *ctx); - -/* reset resolver context and read in system configuration */ -UDNS_API int -dns_init(struct dns_ctx *ctx, int do_open); - -/* return new resolver context with the same settings as copy */ -UDNS_API struct dns_ctx * -dns_new(const struct dns_ctx *copy); - -/* free resolver context returned by dns_new(); all queries are dropped */ -UDNS_API void -dns_free(struct dns_ctx *ctx); - -/* add nameserver for a resolver context (or reset nslist if serv==NULL) */ -UDNS_API int -dns_add_serv(struct dns_ctx *ctx, const char *serv); - -/* add nameserver using struct sockaddr structure (with ports) */ -UDNS_API int -dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa); - -/* add search list element for a resolver context (or reset it if srch==NULL) */ -UDNS_API int -dns_add_srch(struct dns_ctx *ctx, const char *srch); - -/* set options for a resolver context */ -UDNS_API int -dns_set_opts(struct dns_ctx *ctx, const char *opts); - -enum dns_opt { /* options */ - DNS_OPT_FLAGS, /* flags, DNS_F_XXX */ - DNS_OPT_TIMEOUT, /* timeout in secounds */ - DNS_OPT_NTRIES, /* number of retries */ - DNS_OPT_NDOTS, /* ndots */ - DNS_OPT_UDPSIZE, /* EDNS0 UDP size */ - DNS_OPT_PORT, /* port to use */ -}; - -/* set or get (if val<0) an option */ -UDNS_API int -dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val); - -enum dns_flags { - DNS_NOSRCH = 0x00010000, /* do not perform search */ - DNS_NORD = 0x00020000, /* request no recursion */ - DNS_AAONLY = 0x00040000, /* set AA flag in queries */ -}; - -/* set the debug function pointer */ -typedef void -(dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen, - dnscc_t *pkt, int plen, - const struct dns_query *q, void *data); -UDNS_API void -dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn); - -/* open and return UDP socket */ -UDNS_API int -dns_open(struct dns_ctx *ctx); - -/* return UDP socket or -1 if not open */ -UDNS_API int -dns_sock(const struct dns_ctx *ctx); - -/* close the UDP socket */ -UDNS_API void -dns_close(struct dns_ctx *ctx); - -/* return number of requests queued */ -UDNS_API int -dns_active(const struct dns_ctx *ctx); - -/* return status of the last operation */ -UDNS_API int -dns_status(const struct dns_ctx *ctx); -UDNS_API void -dns_setstatus(struct dns_ctx *ctx, int status); - -/* handle I/O event on UDP socket */ -UDNS_API void -dns_ioevent(struct dns_ctx *ctx, time_t now); - -/* process any timeouts, return time in secounds to the - * next timeout (or -1 if none) but not greather than maxwait */ -UDNS_API int -dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now); - -/* define timer requesting routine to use */ -typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data); -UDNS_API void -dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data); - -/**************************************************************************/ -/**************** Making Queries ******************************************/ - -/* query callback routine */ -typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data); - -/* query parse routine: raw DNS => application structure */ -typedef int -dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **res); - -enum dns_status { - DNS_E_NOERROR = 0, /* ok, not an error */ - DNS_E_TEMPFAIL = -1, /* timeout, SERVFAIL or similar */ - DNS_E_PROTOCOL = -2, /* got garbled reply */ - DNS_E_NXDOMAIN = -3, /* domain does not exists */ - DNS_E_NODATA = -4, /* domain exists but no data of reqd type */ - DNS_E_NOMEM = -5, /* out of memory while processing */ - DNS_E_BADQUERY = -6 /* the query is malformed */ -}; - -/* submit generic DN query */ -UDNS_API struct dns_query * -dns_submit_dn(struct dns_ctx *ctx, - dnscc_t *dn, int qcls, int qtyp, int flags, - dns_parse_fn *parse, dns_query_fn *cbck, void *data); -/* submit generic name query */ -UDNS_API struct dns_query * -dns_submit_p(struct dns_ctx *ctx, - const char *name, int qcls, int qtyp, int flags, - dns_parse_fn *parse, dns_query_fn *cbck, void *data); - -/* cancel the given async query in progress */ -UDNS_API int -dns_cancel(struct dns_ctx *ctx, struct dns_query *q); - -/* resolve a generic query, return the answer */ -UDNS_API void * -dns_resolve_dn(struct dns_ctx *ctx, - dnscc_t *qdn, int qcls, int qtyp, int flags, - dns_parse_fn *parse); -UDNS_API void * -dns_resolve_p(struct dns_ctx *ctx, - const char *qname, int qcls, int qtyp, int flags, - dns_parse_fn *parse); -UDNS_API void * -dns_resolve(struct dns_ctx *ctx, struct dns_query *q); - - -/* Specific RR handlers */ - -#define dns_rr_common(prefix) \ - char *prefix##_cname; /* canonical name */ \ - char *prefix##_qname; /* original query name */ \ - unsigned prefix##_ttl; /* TTL value */ \ - int prefix##_nrr /* number of records */ - -struct dns_rr_null { /* NULL RRset, aka RRset template */ - dns_rr_common(dnsn); -}; - -UDNS_API int -dns_stdrr_size(const struct dns_parse *p); -UDNS_API void * -dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p); - -struct dns_rr_a4 { /* the A RRset */ - dns_rr_common(dnsa4); - struct in_addr *dnsa4_addr; /* array of addresses, naddr elements */ -}; - -UDNS_API dns_parse_fn dns_parse_a4; /* A RR parsing routine */ -typedef void /* A query callback routine */ -dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data); - -/* submit A IN query */ -UDNS_API struct dns_query * -dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags, - dns_query_a4_fn *cbck, void *data); - -/* resolve A IN query */ -UDNS_API struct dns_rr_a4 * -dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags); - - -struct dns_rr_a6 { /* the AAAA RRset */ - dns_rr_common(dnsa6); - struct in6_addr *dnsa6_addr; /* array of addresses, naddr elements */ -}; - -UDNS_API dns_parse_fn dns_parse_a6; /* A RR parsing routine */ -typedef void /* A query callback routine */ -dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data); - -/* submit AAAA IN query */ -UDNS_API struct dns_query * -dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags, - dns_query_a6_fn *cbck, void *data); - -/* resolve AAAA IN query */ -UDNS_API struct dns_rr_a6 * -dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags); - - -struct dns_rr_ptr { /* the PTR RRset */ - dns_rr_common(dnsptr); - char **dnsptr_ptr; /* array of PTRs */ -}; - -UDNS_API dns_parse_fn dns_parse_ptr; /* PTR RR parsing routine */ -typedef void /* PTR query callback */ -dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data); -/* submit PTR IN in-addr.arpa query */ -UDNS_API struct dns_query * -dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr, - dns_query_ptr_fn *cbck, void *data); -/* resolve PTR IN in-addr.arpa query */ -UDNS_API struct dns_rr_ptr * -dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr); - -/* the same as above, but for ip6.arpa */ -UDNS_API struct dns_query * -dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr, - dns_query_ptr_fn *cbck, void *data); -UDNS_API struct dns_rr_ptr * -dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr); - - -struct dns_mx { /* single MX RR */ - int priority; /* MX priority */ - char *name; /* MX name */ -}; -struct dns_rr_mx { /* the MX RRset */ - dns_rr_common(dnsmx); - struct dns_mx *dnsmx_mx; /* array of MXes */ -}; -UDNS_API dns_parse_fn dns_parse_mx; /* MX RR parsing routine */ -typedef void /* MX RR callback */ -dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data); -/* submit MX IN query */ -UDNS_API struct dns_query * -dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags, - dns_query_mx_fn *cbck, void *data); -/* resolve MX IN query */ -UDNS_API struct dns_rr_mx * -dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags); - - -struct dns_txt { /* single TXT record */ - int len; /* length of the text */ - dnsc_t *txt; /* pointer to text buffer. May contain nulls. */ -}; -struct dns_rr_txt { /* the TXT RRset */ - dns_rr_common(dnstxt); - struct dns_txt *dnstxt_txt; /* array of TXT records */ -}; -UDNS_API dns_parse_fn dns_parse_txt; /* TXT RR parsing routine */ -typedef void /* TXT RR callback */ -dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data); -/* submit TXT query */ -UDNS_API struct dns_query * -dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags, - dns_query_txt_fn *cbck, void *data); -/* resolve TXT query */ -UDNS_API struct dns_rr_txt * -dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags); - - -struct dns_srv { /* single SRV RR */ - int priority; /* SRV priority */ - int weight; /* SRV weight */ - int port; /* SRV port */ - char *name; /* SRV name */ -}; -struct dns_rr_srv { /* the SRV RRset */ - dns_rr_common(dnssrv); - struct dns_srv *dnssrv_srv; /* array of SRVes */ -}; -UDNS_API dns_parse_fn dns_parse_srv; /* SRV RR parsing routine */ -typedef void /* SRV RR callback */ -dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data); -/* submit SRV IN query */ -UDNS_API struct dns_query * -dns_submit_srv(struct dns_ctx *ctx, - const char *name, const char *srv, const char *proto, - int flags, dns_query_srv_fn *cbck, void *data); -/* resolve SRV IN query */ -UDNS_API struct dns_rr_srv * -dns_resolve_srv(struct dns_ctx *ctx, - const char *name, const char *srv, const char *proto, - int flags); - -/* NAPTR (RFC3403) RR type */ -struct dns_naptr { /* single NAPTR RR */ - int order; /* NAPTR order */ - int preference; /* NAPTR preference */ - char *flags; /* NAPTR flags */ - char *service; /* NAPTR service */ - char *regexp; /* NAPTR regexp */ - char *replacement; /* NAPTR replacement */ -}; - -struct dns_rr_naptr { /* the NAPTR RRset */ - dns_rr_common(dnsnaptr); - struct dns_naptr *dnsnaptr_naptr; /* array of NAPTRes */ -}; -UDNS_API dns_parse_fn dns_parse_naptr; /* NAPTR RR parsing routine */ -typedef void /* NAPTR RR callback */ -dns_query_naptr_fn(struct dns_ctx *ctx, - struct dns_rr_naptr *result, void *data); -/* submit NAPTR IN query */ -UDNS_API struct dns_query * -dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags, - dns_query_naptr_fn *cbck, void *data); -/* resolve NAPTR IN query */ -UDNS_API struct dns_rr_naptr * -dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags); - - -UDNS_API struct dns_query * -dns_submit_a4dnsbl(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl, - dns_query_a4_fn *cbck, void *data); -UDNS_API struct dns_query * -dns_submit_a4dnsbl_txt(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl, - dns_query_txt_fn *cbck, void *data); -UDNS_API struct dns_rr_a4 * -dns_resolve_a4dnsbl(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl); -UDNS_API struct dns_rr_txt * -dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl); - -UDNS_API struct dns_query * -dns_submit_a6dnsbl(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl, - dns_query_a4_fn *cbck, void *data); -UDNS_API struct dns_query * -dns_submit_a6dnsbl_txt(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl, - dns_query_txt_fn *cbck, void *data); -UDNS_API struct dns_rr_a4 * -dns_resolve_a6dnsbl(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl); -UDNS_API struct dns_rr_txt * -dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl); - -UDNS_API struct dns_query * -dns_submit_rhsbl(struct dns_ctx *ctx, - const char *name, const char *rhsbl, - dns_query_a4_fn *cbck, void *data); -UDNS_API struct dns_query * -dns_submit_rhsbl_txt(struct dns_ctx *ctx, - const char *name, const char *rhsbl, - dns_query_txt_fn *cbck, void *data); -UDNS_API struct dns_rr_a4 * -dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl); -UDNS_API struct dns_rr_txt * -dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl); - -/**************************************************************************/ -/**************** Names, Names ********************************************/ - -struct dns_nameval { - int val; - const char *name; -}; - -UDNS_DATA_API extern const struct dns_nameval dns_classtab[]; -UDNS_DATA_API extern const struct dns_nameval dns_typetab[]; -UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[]; -UDNS_API int -dns_findname(const struct dns_nameval *nv, const char *name); -#define dns_findclassname(cls) dns_findname(dns_classtab, (cls)) -#define dns_findtypename(type) dns_findname(dns_typetab, (type)) -#define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode)) - -UDNS_API const char *dns_classname(enum dns_class cls); -UDNS_API const char *dns_typename(enum dns_type type); -UDNS_API const char *dns_rcodename(enum dns_rcode rcode); -const char *_dns_format_code(char *buf, const char *prefix, int code); - -UDNS_API const char *dns_strerror(int errnum); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* include guard */ diff --git a/deps/udns/udns_XtoX.c b/deps/udns/udns_XtoX.c deleted file mode 100644 index cfb6af4..0000000 --- a/deps/udns/udns_XtoX.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id: udns_XtoX.c,v 1.1 2007/01/07 22:20:39 mjt Exp $ - udns_ntop() and udns_pton() routines, which are either - - wrappers for inet_ntop() and inet_pton() or - - reimplementations of those routines. - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "udns.h" - -#ifdef HAVE_INET_PTON_NTOP - -#include -#include -#include - -const char *dns_ntop(int af, const void *src, char *dst, int size) { - return inet_ntop(af, src, dst, size); -} - -int dns_pton(int af, const char *src, void *dst) { - return inet_pton(af, src, dst); -} - -#else - -#define inet_XtoX_prefix udns_ -#include "inet_XtoX.c" - -#endif diff --git a/deps/udns/udns_bl.c b/deps/udns/udns_bl.c deleted file mode 100644 index dc6f53b..0000000 --- a/deps/udns/udns_bl.c +++ /dev/null @@ -1,160 +0,0 @@ -/* $Id: udns_bl.c,v 1.10 2005/09/12 10:55:21 mjt Exp $ - DNSBL stuff - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include "udns.h" -#ifndef NULL -# define NULL 0 -#endif - -struct dns_query * -dns_submit_a4dnsbl(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl, - dns_query_a4_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH, - dns_parse_a4, (dns_query_fn*)cbck, data); -} - -struct dns_query * -dns_submit_a4dnsbl_txt(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl, - dns_query_txt_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (dns_a4ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH, - dns_parse_txt, (dns_query_fn*)cbck, data); -} - -struct dns_rr_a4 * -dns_resolve_a4dnsbl(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl) { - return (struct dns_rr_a4 *) - dns_resolve(ctx, dns_submit_a4dnsbl(ctx, addr, dnsbl, 0, 0)); -} - -struct dns_rr_txt * -dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx, - const struct in_addr *addr, const char *dnsbl) { - return (struct dns_rr_txt *) - dns_resolve(ctx, dns_submit_a4dnsbl_txt(ctx, addr, dnsbl, 0, 0)); -} - - -struct dns_query * -dns_submit_a6dnsbl(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl, - dns_query_a4_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH, - dns_parse_a4, (dns_query_fn*)cbck, data); -} - -struct dns_query * -dns_submit_a6dnsbl_txt(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl, - dns_query_txt_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (dns_a6ptodn(addr, dnsbl, dn, sizeof(dn)) <= 0) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH, - dns_parse_txt, (dns_query_fn*)cbck, data); -} - -struct dns_rr_a4 * -dns_resolve_a6dnsbl(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl) { - return (struct dns_rr_a4 *) - dns_resolve(ctx, dns_submit_a6dnsbl(ctx, addr, dnsbl, 0, 0)); -} - -struct dns_rr_txt * -dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx, - const struct in6_addr *addr, const char *dnsbl) { - return (struct dns_rr_txt *) - dns_resolve(ctx, dns_submit_a6dnsbl_txt(ctx, addr, dnsbl, 0, 0)); -} - -static int -dns_rhsbltodn(const char *name, const char *rhsbl, dnsc_t dn[DNS_MAXDN]) -{ - int l = dns_sptodn(name, dn, DNS_MAXDN); - if (l <= 0) return 0; - l = dns_sptodn(rhsbl, dn+l-1, DNS_MAXDN-l+1); - if (l <= 0) return 0; - return 1; -} - -struct dns_query * -dns_submit_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl, - dns_query_a4_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (!dns_rhsbltodn(name, rhsbl, dn)) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_A, DNS_NOSRCH, - dns_parse_a4, (dns_query_fn*)cbck, data); -} -struct dns_query * -dns_submit_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl, - dns_query_txt_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - if (!dns_rhsbltodn(name, rhsbl, dn)) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_TXT, DNS_NOSRCH, - dns_parse_txt, (dns_query_fn*)cbck, data); -} - -struct dns_rr_a4 * -dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl) { - return (struct dns_rr_a4*) - dns_resolve(ctx, dns_submit_rhsbl(ctx, name, rhsbl, 0, 0)); -} - -struct dns_rr_txt * -dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl) -{ - return (struct dns_rr_txt*) - dns_resolve(ctx, dns_submit_rhsbl_txt(ctx, name, rhsbl, 0, 0)); -} diff --git a/deps/udns/udns_dn.c b/deps/udns/udns_dn.c deleted file mode 100644 index 1264a1d..0000000 --- a/deps/udns/udns_dn.c +++ /dev/null @@ -1,382 +0,0 @@ -/* $Id: udns_dn.c,v 1.7 2006/11/28 22:45:20 mjt Exp $ - domain names manipulation routines - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include "udns.h" - -unsigned dns_dnlen(dnscc_t *dn) { - register dnscc_t *d = dn; - while(*d) - d += 1 + *d; - return (unsigned)(d - dn) + 1; -} - -unsigned dns_dnlabels(register dnscc_t *dn) { - register unsigned l = 0; - while(*dn) - ++l, dn += 1 + *dn; - return l; -} - -unsigned dns_dnequal(register dnscc_t *dn1, register dnscc_t *dn2) { - register unsigned c; - dnscc_t *dn = dn1; - for(;;) { - if ((c = *dn1++) != *dn2++) - return 0; - if (!c) - return (unsigned)(dn1 - dn); - while(c--) { - if (DNS_DNLC(*dn1) != DNS_DNLC(*dn2)) - return 0; - ++dn1; ++dn2; - } - } -} - -unsigned -dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz) { - unsigned sdnlen = dns_dnlen(sdn); - if (ddnsiz < sdnlen) - return 0; - memcpy(ddn, sdn, sdnlen); - return sdnlen; -} - -int -dns_ptodn(const char *name, unsigned namelen, - dnsc_t *dn, unsigned dnsiz, int *isabs) -{ - dnsc_t *dp; /* current position in dn (len byte first) */ - dnsc_t *const de /* end of dn: last byte that can be filled up */ - = dn + (dnsiz >= DNS_MAXDN ? DNS_MAXDN : dnsiz) - 1; - dnscc_t *np = (dnscc_t *)name; - dnscc_t *ne = np + (namelen ? namelen : strlen((char*)np)); - dnsc_t *llab; /* start of last label (llab[-1] will be length) */ - unsigned c; /* next input character, or length of last label */ - - if (!dnsiz) - return 0; - dp = llab = dn + 1; - - while(np < ne) { - - if (*np == '.') { /* label delimiter */ - c = dp - llab; /* length of the label */ - if (!c) { /* empty label */ - if (np == (dnscc_t *)name && np + 1 == ne) { - /* special case for root dn, aka `.' */ - ++np; - break; - } - return -1; /* zero label */ - } - if (c > DNS_MAXLABEL) - return -1; /* label too long */ - llab[-1] = (dnsc_t)c; /* update len of last label */ - llab = ++dp; /* start new label, llab[-1] will be len of it */ - ++np; - continue; - } - - /* check whenever we may put out one more byte */ - if (dp >= de) /* too long? */ - return dnsiz >= DNS_MAXDN ? -1 : 0; - if (*np != '\\') { /* non-escape, simple case */ - *dp++ = *np++; - continue; - } - /* handle \-style escape */ - /* note that traditionally, domain names (gethostbyname etc) - * used decimal \dd notation, not octal \ooo (RFC1035), so - * we're following this tradition here. - */ - if (++np == ne) - return -1; /* bad escape */ - else if (*np >= '0' && *np <= '9') { /* decimal number */ - /* we allow not only exactly 3 digits as per RFC1035, - * but also 2 or 1, for better usability. */ - c = *np++ - '0'; - if (np < ne && *np >= '0' && *np <= '9') { /* 2digits */ - c = c * 10 + *np++ - '0'; - if (np < ne && *np >= '0' && *np <= '9') { - c = c * 10 + *np++ - '0'; - if (c > 255) - return -1; /* bad escape */ - } - } - } - else - c = *np++; - *dp++ = (dnsc_t)c; /* place next out byte */ - } - - if ((c = dp - llab) > DNS_MAXLABEL) - return -1; /* label too long */ - if ((llab[-1] = (dnsc_t)c) != 0) { - *dp++ = 0; - if (isabs) - *isabs = 0; - } - else if (isabs) - *isabs = 1; - - return dp - dn; -} - -dnscc_t dns_inaddr_arpa_dn[14] = "\07in-addr\04arpa"; - -dnsc_t * -dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne) { - dnsc_t *p; - unsigned n; - dnscc_t *s = ((dnscc_t *)addr) + 4; - while(--s >= (dnscc_t *)addr) { - n = *s; - p = dn + 1; - if (n > 99) { - if (p + 2 > dne) return 0; - *p++ = n / 100 + '0'; - *p++ = (n % 100 / 10) + '0'; - *p = n % 10 + '0'; - } - else if (n > 9) { - if (p + 1 > dne) return 0; - *p++ = n / 10 + '0'; - *p = n % 10 + '0'; - } - else { - if (p > dne) return 0; - *p = n + '0'; - } - *dn = p - dn; - dn = p + 1; - } - return dn; -} - -int dns_a4todn(const struct in_addr *addr, dnscc_t *tdn, - dnsc_t *dn, unsigned dnsiz) { - dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz); - dnsc_t *p; - unsigned l; - p = dns_a4todn_(addr, dn, dne); - if (!p) return 0; - if (!tdn) - tdn = dns_inaddr_arpa_dn; - l = dns_dnlen(tdn); - if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0; - memcpy(p, tdn, l); - return (p + l) - dn; -} - -int dns_a4ptodn(const struct in_addr *addr, const char *tname, - dnsc_t *dn, unsigned dnsiz) { - dnsc_t *p; - int r; - if (!tname) - return dns_a4todn(addr, NULL, dn, dnsiz); - p = dns_a4todn_(addr, dn, dn + dnsiz); - if (!p) return 0; - r = dns_sptodn(tname, p, dnsiz - (p - dn)); - return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0; -} - -dnscc_t dns_ip6_arpa_dn[10] = "\03ip6\04arpa"; - -dnsc_t * -dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne) { - unsigned n; - dnscc_t *s = ((dnscc_t *)addr) + 16; - if (dn + 64 > dne) return 0; - while(--s >= (dnscc_t *)addr) { - *dn++ = 1; - n = *s & 0x0f; - *dn++ = n > 9 ? n + 'a' - 10 : n + '0'; - *dn++ = 1; - n = *s >> 4; - *dn++ = n > 9 ? n + 'a' - 10 : n + '0'; - } - return dn; -} - -int dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn, - dnsc_t *dn, unsigned dnsiz) { - dnsc_t *dne = dn + (dnsiz > DNS_MAXDN ? DNS_MAXDN : dnsiz); - dnsc_t *p; - unsigned l; - p = dns_a6todn_(addr, dn, dne); - if (!p) return 0; - if (!tdn) - tdn = dns_ip6_arpa_dn; - l = dns_dnlen(tdn); - if (p + l > dne) return dnsiz >= DNS_MAXDN ? -1 : 0; - memcpy(p, tdn, l); - return (p + l) - dn; -} - -int dns_a6ptodn(const struct in6_addr *addr, const char *tname, - dnsc_t *dn, unsigned dnsiz) { - dnsc_t *p; - int r; - if (!tname) - return dns_a6todn(addr, NULL, dn, dnsiz); - p = dns_a6todn_(addr, dn, dn + dnsiz); - if (!p) return 0; - r = dns_sptodn(tname, p, dnsiz - (p - dn)); - return r != 0 ? r : dnsiz >= DNS_MAXDN ? -1 : 0; -} - -/* return size of buffer required to convert the dn into asciiz string. - * Keep in sync with dns_dntop() below. - */ -unsigned dns_dntop_size(dnscc_t *dn) { - unsigned size = 0; /* the size reqd */ - dnscc_t *le; /* label end */ - - while(*dn) { - /* *dn is the length of the next label, non-zero */ - if (size) - ++size; /* for the dot */ - le = dn + *dn + 1; - ++dn; - do { - switch(*dn) { - case '.': - case '\\': - /* Special modifiers in zone files. */ - case '"': - case ';': - case '@': - case '$': - size += 2; - break; - default: - if (*dn <= 0x20 || *dn >= 0x7f) - /* \ddd decimal notation */ - size += 4; - else - size += 1; - } - } while(++dn < le); - } - size += 1; /* zero byte at the end - string terminator */ - return size > DNS_MAXNAME ? 0 : size; -} - -/* Convert the dn into asciiz string. - * Keep in sync with dns_dntop_size() above. - */ -int dns_dntop(dnscc_t *dn, char *name, unsigned namesiz) { - char *np = name; /* current name ptr */ - char *const ne = name + namesiz; /* end of name */ - dnscc_t *le; /* label end */ - - while(*dn) { - /* *dn is the length of the next label, non-zero */ - if (np != name) { - if (np >= ne) goto toolong; - *np++ = '.'; - } - le = dn + *dn + 1; - ++dn; - do { - switch(*dn) { - case '.': - case '\\': - /* Special modifiers in zone files. */ - case '"': - case ';': - case '@': - case '$': - if (np + 2 > ne) goto toolong; - *np++ = '\\'; - *np++ = *dn; - break; - default: - if (*dn <= 0x20 || *dn >= 0x7f) { - /* \ddd decimal notation */ - if (np + 4 >= ne) goto toolong; - *np++ = '\\'; - *np++ = '0' + (*dn / 100); - *np++ = '0' + ((*dn % 100) / 10); - *np++ = '0' + (*dn % 10); - } - else { - if (np >= ne) goto toolong; - *np++ = *dn; - } - } - } while(++dn < le); - } - if (np >= ne) goto toolong; - *np++ = '\0'; - return np - name; -toolong: - return namesiz >= DNS_MAXNAME ? -1 : 0; -} - -#ifdef TEST -#include -#include - -int main(int argc, char **argv) { - int i; - int sz; - dnsc_t dn[DNS_MAXDN+10]; - dnsc_t *dl, *dp; - int isabs; - - sz = (argc > 1) ? atoi(argv[1]) : 0; - - for(i = 2; i < argc; ++i) { - int r = dns_ptodn(argv[i], 0, dn, sz, &isabs); - printf("%s: ", argv[i]); - if (r < 0) printf("error\n"); - else if (!r) printf("buffer too small\n"); - else { - printf("len=%d dnlen=%d size=%d name:", - r, dns_dnlen(dn), dns_dntop_size(dn)); - dl = dn; - while(*dl) { - printf(" %d=", *dl); - dp = dl + 1; - dl = dp + *dl; - while(dp < dl) { - if (*dp <= ' ' || *dp >= 0x7f) - printf("\\%03d", *dp); - else if (*dp == '.' || *dp == '\\') - printf("\\%c", *dp); - else - putchar(*dp); - ++dp; - } - } - if (isabs) putchar('.'); - putchar('\n'); - } - } - return 0; -} - -#endif /* TEST */ diff --git a/deps/udns/udns_dntosp.c b/deps/udns/udns_dntosp.c deleted file mode 100644 index 933463e..0000000 --- a/deps/udns/udns_dntosp.c +++ /dev/null @@ -1,30 +0,0 @@ -/* $Id: udns_dntosp.c,v 1.5 2005/04/19 21:48:09 mjt Exp $ - dns_dntosp() = convert DN to asciiz string using static buffer - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include "udns.h" - -static char name[DNS_MAXNAME]; - -const char *dns_dntosp(dnscc_t *dn) { - return dns_dntop(dn, name, sizeof(name)) > 0 ? name : 0; -} diff --git a/deps/udns/udns_init.c b/deps/udns/udns_init.c deleted file mode 100644 index c005731..0000000 --- a/deps/udns/udns_init.c +++ /dev/null @@ -1,231 +0,0 @@ -/* $Id: udns_init.c,v 1.6 2007/01/08 00:41:38 mjt Exp $ - resolver initialisation stuff - - Copyright (C) 2006 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef WINDOWS -# include /* includes */ -# include /* for dns server addresses etc */ -#else -# include -# include -# include -#endif /* !WINDOWS */ - -#include -#include -#include "udns.h" - -#define ISSPACE(x) (x == ' ' || x == '\t' || x == '\r' || x == '\n') - -static const char space[] = " \t\r\n"; - -static void dns_set_serv_internal(struct dns_ctx *ctx, char *serv) { - dns_add_serv(ctx, NULL); - for(serv = strtok(serv, space); serv; serv = strtok(NULL, space)) - dns_add_serv(ctx, serv); -} - -static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) { - dns_add_srch(ctx, NULL); - for(srch = strtok(srch, space); srch; srch = strtok(NULL, space)) - dns_add_srch(ctx, srch); -} - -#ifdef WINDOWS - -#ifndef NO_IPHLPAPI -/* Apparently, some systems does not have proper headers for IPHLPAIP to work. - * The best is to upgrade headers, but here's another, ugly workaround for - * this: compile with -DNO_IPHLPAPI. - */ - -typedef DWORD (WINAPI *GetAdaptersAddressesFunc)( - ULONG Family, DWORD Flags, PVOID Reserved, - PIP_ADAPTER_ADDRESSES pAdapterAddresses, - PULONG pOutBufLen); - -static int dns_initns_iphlpapi(struct dns_ctx *ctx) { - HANDLE h_iphlpapi; - GetAdaptersAddressesFunc pfnGetAdAddrs; - PIP_ADAPTER_ADDRESSES pAddr, pAddrBuf; - PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr; - ULONG ulOutBufLen; - DWORD dwRetVal; - int ret = -1; - - h_iphlpapi = LoadLibrary("iphlpapi.dll"); - if (!h_iphlpapi) - return -1; - pfnGetAdAddrs = (GetAdaptersAddressesFunc) - GetProcAddress(h_iphlpapi, "GetAdaptersAddresses"); - if (!pfnGetAdAddrs) goto freelib; - ulOutBufLen = 0; - dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, NULL, &ulOutBufLen); - if (dwRetVal != ERROR_BUFFER_OVERFLOW) goto freelib; - pAddrBuf = malloc(ulOutBufLen); - if (!pAddrBuf) goto freelib; - dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, pAddrBuf, &ulOutBufLen); - if (dwRetVal != ERROR_SUCCESS) goto freemem; - for (pAddr = pAddrBuf; pAddr; pAddr = pAddr->Next) - for (pDnsAddr = pAddr->FirstDnsServerAddress; - pDnsAddr; - pDnsAddr = pDnsAddr->Next) - dns_add_serv_s(ctx, pDnsAddr->Address.lpSockaddr); - ret = 0; -freemem: - free(pAddrBuf); -freelib: - FreeLibrary(h_iphlpapi); - return ret; -} - -#else /* NO_IPHLPAPI */ - -#define dns_initns_iphlpapi(ctx) (-1) - -#endif /* NO_IPHLPAPI */ - -static int dns_initns_registry(struct dns_ctx *ctx) { - LONG res; - HKEY hk; - DWORD type = REG_EXPAND_SZ | REG_SZ; - DWORD len; - char valBuf[1024]; - -#define REGKEY_WINNT "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" -#define REGKEY_WIN9x "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP" - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINNT, 0, KEY_QUERY_VALUE, &hk); - if (res != ERROR_SUCCESS) - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WIN9x, - 0, KEY_QUERY_VALUE, &hk); - if (res != ERROR_SUCCESS) - return -1; - len = sizeof(valBuf) - 1; - res = RegQueryValueEx(hk, "NameServer", NULL, &type, (BYTE*)valBuf, &len); - if (res != ERROR_SUCCESS || !len || !valBuf[0]) { - len = sizeof(valBuf) - 1; - res = RegQueryValueEx(hk, "DhcpNameServer", NULL, &type, - (BYTE*)valBuf, &len); - } - RegCloseKey(hk); - if (res != ERROR_SUCCESS || !len || !valBuf[0]) - return -1; - valBuf[len] = '\0'; - /* nameservers are stored as a whitespace-seperate list: - * "192.168.1.1 123.21.32.12" */ - dns_set_serv_internal(ctx, valBuf); - return 0; -} - -#else /* !WINDOWS */ - -static int dns_init_resolvconf(struct dns_ctx *ctx) { - char *v; - char buf[2049]; /* this buffer is used to hold /etc/resolv.conf */ - int has_srch = 0; - - /* read resolv.conf... */ - { int fd = open("/etc/resolv.conf", O_RDONLY); - if (fd >= 0) { - int l = read(fd, buf, sizeof(buf) - 1); - close(fd); - buf[l < 0 ? 0 : l] = '\0'; - } - else - buf[0] = '\0'; - } - if (buf[0]) { /* ...and parse it */ - char *line, *nextline; - line = buf; - do { - nextline = strchr(line, '\n'); - if (nextline) *nextline++ = '\0'; - v = line; - while(*v && !ISSPACE(*v)) ++v; - if (!*v) continue; - *v++ = '\0'; - while(ISSPACE(*v)) ++v; - if (!*v) continue; - if (strcmp(line, "domain") == 0) { - dns_set_srch_internal(ctx, strtok(v, space)); - has_srch = 1; - } - else if (strcmp(line, "search") == 0) { - dns_set_srch_internal(ctx, v); - has_srch = 1; - } - else if (strcmp(line, "nameserver") == 0) - dns_add_serv(ctx, strtok(v, space)); - else if (strcmp(line, "options") == 0) - dns_set_opts(ctx, v); - } while((line = nextline) != NULL); - } - - buf[sizeof(buf)-1] = '\0'; - - /* get list of nameservers from env. vars. */ - if ((v = getenv("NSCACHEIP")) != NULL || - (v = getenv("NAMESERVERS")) != NULL) { - strncpy(buf, v, sizeof(buf) - 1); - dns_set_serv_internal(ctx, buf); - } - /* if $LOCALDOMAIN is set, use it for search list */ - if ((v = getenv("LOCALDOMAIN")) != NULL) { - strncpy(buf, v, sizeof(buf) - 1); - dns_set_srch_internal(ctx, buf); - has_srch = 1; - } - if ((v = getenv("RES_OPTIONS")) != NULL) - dns_set_opts(ctx, v); - - /* if still no search list, use local domain name */ - if (has_srch && - gethostname(buf, sizeof(buf) - 1) == 0 && - (v = strchr(buf, '.')) != NULL && - *++v != '\0') - dns_add_srch(ctx, v); - - return 0; -} - -#endif /* !WINDOWS */ - -int dns_init(struct dns_ctx *ctx, int do_open) { - if (!ctx) - ctx = &dns_defctx; - dns_reset(ctx); - -#ifdef WINDOWS - if (dns_initns_iphlpapi(ctx) != 0) - dns_initns_registry(ctx); - /*XXX WINDOWS: probably good to get default domain and search list too... - * And options. Something is in registry. */ - /*XXX WINDOWS: maybe environment variables are also useful? */ -#else - dns_init_resolvconf(ctx); -#endif - - return do_open ? dns_open(ctx) : 0; -} diff --git a/deps/udns/udns_misc.c b/deps/udns/udns_misc.c deleted file mode 100644 index 0db7ffd..0000000 --- a/deps/udns/udns_misc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* $Id: udns_misc.c,v 1.8 2005/04/05 22:51:32 mjt Exp $ - miscellaneous routines - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include "udns.h" - -int dns_findname(const struct dns_nameval *nv, const char *name) { - register const char *a, *b; - for(; nv->name; ++nv) - for(a = name, b = nv->name; ; ++a, ++b) - if (DNS_DNUC(*a) != *b) break; - else if (!*a) return nv->val; - return -1; -} - -const char *_dns_format_code(char *buf, const char *prefix, int code) { - char *bp = buf; - unsigned c, n; - do *bp++ = DNS_DNUC(*prefix); - while(*++prefix); - *bp++ = '#'; - if (code < 0) code = -code, *bp++ = '-'; - n = 0; c = code; - do ++n; - while((c /= 10)); - c = code; - bp[n--] = '\0'; - do bp[n--] = c % 10 + '0'; - while((c /= 10)); - return buf; -} - -const char *dns_strerror(int err) { - if (err >= 0) return "successeful completion"; - switch(err) { - case DNS_E_TEMPFAIL: return "temporary failure in name resolution"; - case DNS_E_PROTOCOL: return "protocol error"; - case DNS_E_NXDOMAIN: return "domain name does not exist"; - case DNS_E_NODATA: return "valid domain but no data of requested type"; - case DNS_E_NOMEM: return "out of memory"; - case DNS_E_BADQUERY: return "malformed query"; - default: return "unknown error"; - } -} - -const char *dns_version(void) { - return UDNS_VERSION; -} diff --git a/deps/udns/udns_parse.c b/deps/udns/udns_parse.c deleted file mode 100644 index 5440d92..0000000 --- a/deps/udns/udns_parse.c +++ /dev/null @@ -1,169 +0,0 @@ -/* $Id: udns_parse.c,v 1.14 2005/09/12 10:55:21 mjt Exp $ - raw DNS packet parsing routines - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include "udns.h" - -dnscc_t *dns_skipdn(dnscc_t *cur, dnscc_t *end) { - unsigned c; - for(;;) { - if (cur >= end) - return NULL; - c = *cur++; - if (!c) - return cur; - if (c & 192) /* jump */ - return cur + 1 >= end ? NULL : cur + 1; - cur += c; - } -} - -int -dns_getdn(dnscc_t *pkt, dnscc_t **cur, dnscc_t *end, - register dnsc_t *dn, unsigned dnsiz) { - unsigned c; - dnscc_t *pp = *cur; /* current packet pointer */ - dnsc_t *dp = dn; /* current dn pointer */ - dnsc_t *const de /* end of the DN dest */ - = dn + (dnsiz < DNS_MAXDN ? dnsiz : DNS_MAXDN); - dnscc_t *jump = NULL; /* ptr after first jump if any */ - unsigned loop = 100; /* jump loop counter */ - - for(;;) { /* loop by labels */ - if (pp >= end) /* reached end of packet? */ - return -1; - c = *pp++; /* length of the label */ - if (!c) { /* empty label: terminate */ - if (dn >= de) /* can't fit terminator */ - goto noroom; - *dp++ = 0; - /* return next pos: either after the first jump or current */ - *cur = jump ? jump : pp; - return dp - dn; - } - if (c & 192) { /* jump */ - if (pp >= end) /* eop instead of jump pos */ - return -1; - if (!jump) jump = pp + 1; /* remember first jump */ - else if (!--loop) return -1; /* too many jumps */ - c = ((c & ~192) << 8) | *pp; /* new pos */ - if (c < DNS_HSIZE) /* don't allow jump into the header */ - return -1; - pp = pkt + c; - continue; - } - if (c > DNS_MAXLABEL) /* too long label? */ - return -1; - if (pp + c > end) /* label does not fit in packet? */ - return -1; - if (dp + c + 1 > de) /* if enouth room for the label */ - goto noroom; - *dp++ = c; /* label length */ - memcpy(dp, pp, c); /* and the label itself */ - dp += c; - pp += c; /* advance to the next label */ - } -noroom: - return dnsiz < DNS_MAXDN ? 0 : -1; -} - -void dns_rewind(struct dns_parse *p, dnscc_t *qdn) { - p->dnsp_qdn = qdn; - p->dnsp_cur = p->dnsp_ans; - p->dnsp_rrl = dns_numan(p->dnsp_pkt); - p->dnsp_ttl = 0xffffffffu; - p->dnsp_nrr = 0; -} - -void -dns_initparse(struct dns_parse *p, dnscc_t *qdn, - dnscc_t *pkt, dnscc_t *cur, dnscc_t *end) { - p->dnsp_pkt = pkt; - p->dnsp_end = end; - p->dnsp_rrl = dns_numan(pkt); - p->dnsp_qdn = qdn; - assert(cur + 4 <= end); - if ((p->dnsp_qtyp = dns_get16(cur+0)) == DNS_T_ANY) p->dnsp_qtyp = 0; - if ((p->dnsp_qcls = dns_get16(cur+2)) == DNS_C_ANY) p->dnsp_qcls = 0; - p->dnsp_cur = p->dnsp_ans = cur + 4; - p->dnsp_ttl = 0xffffffffu; - p->dnsp_nrr = 0; -} - -int dns_nextrr(struct dns_parse *p, struct dns_rr *rr) { - dnscc_t *cur = p->dnsp_cur; - while(p->dnsp_rrl > 0) { - --p->dnsp_rrl; - if (dns_getdn(p->dnsp_pkt, &cur, p->dnsp_end, - rr->dnsrr_dn, sizeof(rr->dnsrr_dn)) <= 0) - return -1; - if (cur + 10 > p->dnsp_end) - return -1; - rr->dnsrr_typ = dns_get16(cur); - rr->dnsrr_cls = dns_get16(cur+2); - rr->dnsrr_ttl = dns_get32(cur+4); - rr->dnsrr_dsz = dns_get16(cur+8); - rr->dnsrr_dptr = cur = cur + 10; - rr->dnsrr_dend = cur = cur + rr->dnsrr_dsz; - if (cur > p->dnsp_end) - return -1; - if (p->dnsp_qdn && !dns_dnequal(p->dnsp_qdn, rr->dnsrr_dn)) - continue; - if ((!p->dnsp_qcls || p->dnsp_qcls == rr->dnsrr_cls) && - (!p->dnsp_qtyp || p->dnsp_qtyp == rr->dnsrr_typ)) { - p->dnsp_cur = cur; - ++p->dnsp_nrr; - if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl; - return 1; - } - if (p->dnsp_qdn && rr->dnsrr_typ == DNS_T_CNAME && !p->dnsp_nrr) { - if (dns_getdn(p->dnsp_pkt, &rr->dnsrr_dptr, p->dnsp_end, - p->dnsp_dnbuf, sizeof(p->dnsp_dnbuf)) <= 0 || - rr->dnsrr_dptr != rr->dnsrr_dend) - return -1; - p->dnsp_qdn = p->dnsp_dnbuf; - if (p->dnsp_ttl > rr->dnsrr_ttl) p->dnsp_ttl = rr->dnsrr_ttl; - } - } - p->dnsp_cur = cur; - return 0; -} - -int dns_stdrr_size(const struct dns_parse *p) { - return - dns_dntop_size(p->dnsp_qdn) + - (p->dnsp_qdn == dns_payload(p->dnsp_pkt) ? 0 : - dns_dntop_size(dns_payload(p->dnsp_pkt))); -} - -void *dns_stdrr_finish(struct dns_rr_null *ret, char *cp, - const struct dns_parse *p) { - cp += dns_dntop(p->dnsp_qdn, (ret->dnsn_cname = cp), DNS_MAXNAME); - if (p->dnsp_qdn == dns_payload(p->dnsp_pkt)) - ret->dnsn_qname = ret->dnsn_cname; - else - dns_dntop(dns_payload(p->dnsp_pkt), (ret->dnsn_qname = cp), DNS_MAXNAME); - ret->dnsn_ttl = p->dnsp_ttl; - return ret; -} diff --git a/deps/udns/udns_resolver.c b/deps/udns/udns_resolver.c deleted file mode 100644 index d083397..0000000 --- a/deps/udns/udns_resolver.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* $Id: udns_resolver.c,v 1.98 2007/01/10 13:32:33 mjt Exp $ - resolver stuff (main module) - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifdef WINDOWS -# include /* includes */ -# include /* needed for struct in6_addr */ -#else -# include -# include -# include -# include -# include -# include -# ifdef HAVE_POLL -# include -# else -# ifdef HAVE_SYS_SELECT_H -# include -# endif -# endif -# ifdef HAVE_TIMES -# include -# endif -# define closesocket(sock) close(sock) -#endif /* !WINDOWS */ - -#include -#include -#include -#include -#include -#include -#include "udns.h" - -#ifndef EAFNOSUPPORT -# define EAFNOSUPPORT EINVAL -#endif -#ifndef MSG_DONTWAIT -# define MSG_DONTWAIT 0 -#endif - -struct dns_qlink { - struct dns_query *next, *prev; -}; - -struct dns_query { - struct dns_qlink dnsq_link; /* list entry (should be first) */ - unsigned dnsq_origdnl0; /* original query DN len w/o last 0 */ - unsigned dnsq_flags; /* control flags for this query */ - unsigned dnsq_servi; /* index of next server to try */ - unsigned dnsq_servwait; /* bitmask: servers left to wait */ - unsigned dnsq_servskip; /* bitmask: servers to skip */ - unsigned dnsq_servnEDNS0; /* bitmask: servers refusing EDNS0 */ - unsigned dnsq_try; /* number of tries made so far */ - dnscc_t *dnsq_nxtsrch; /* next search pointer @dnsc_srchbuf */ - time_t dnsq_deadline; /* when current try will expire */ - dns_parse_fn *dnsq_parse; /* parse: raw => application */ - dns_query_fn *dnsq_cbck; /* the callback to call when done */ - void *dnsq_cbdata; /* user data for the callback */ -#ifndef NDEBUG - struct dns_ctx *dnsq_ctx; /* the resolver context */ -#endif - /* char fields at the end to avoid padding */ - dnsc_t dnsq_id[2]; /* query ID */ - dnsc_t dnsq_typcls[4]; /* requested RR type+class */ - dnsc_t dnsq_dn[DNS_MAXDN+DNS_DNPAD]; /* the query DN +alignment */ -}; - -/* working with dns_query lists */ - -static __inline void qlist_init(struct dns_qlink *list) { - list->next = list->prev = (struct dns_query *)list; -} - -static __inline int qlist_isempty(const struct dns_qlink *list) { - return list->next == (const struct dns_query *)list ? 1 : 0; -} - -static __inline struct dns_query *qlist_first(struct dns_qlink *list) { - return list->next == (struct dns_query *)list ? 0 : list->next; -} - -static __inline void qlist_remove(struct dns_query *q) { - q->dnsq_link.next->dnsq_link.prev = q->dnsq_link.prev; - q->dnsq_link.prev->dnsq_link.next = q->dnsq_link.next; -} - -/* insert q between prev and next */ -static __inline void -qlist_insert(struct dns_query *q, - struct dns_query *prev, struct dns_query *next) { - q->dnsq_link.next = next; - q->dnsq_link.prev = prev; - prev->dnsq_link.next = next->dnsq_link.prev = q; -} - -static __inline void -qlist_insert_after(struct dns_query *q, struct dns_query *prev) { - qlist_insert(q, prev, prev->dnsq_link.next); -} - -static __inline void -qlist_insert_before(struct dns_query *q, struct dns_query *next) { - qlist_insert(q, next->dnsq_link.prev, next); -} - -static __inline void -qlist_add_tail(struct dns_query *q, struct dns_qlink *top) { - qlist_insert_before(q, (struct dns_query *)top); -} - -static __inline void -qlist_add_head(struct dns_query *q, struct dns_qlink *top) { - qlist_insert_after(q, (struct dns_query *)top); -} - -#define QLIST_FIRST(list, direction) ((list)->direction) -#define QLIST_ISLAST(list, q) ((q) == (struct dns_query*)(list)) -#define QLIST_NEXT(q, direction) ((q)->dnsq_link.direction) - -#define QLIST_FOR_EACH(list, q, direction) \ - for(q = QLIST_FIRST(list, direction); \ - !QLIST_ISLAST(list, q); q = QLIST_NEXT(q, direction)) - -union sockaddr_ns { - struct sockaddr sa; - struct sockaddr_in sin; -#ifdef HAVE_IPv6 - struct sockaddr_in6 sin6; -#endif -}; - -#define sin_eq(a,b) \ - ((a).sin_port == (b).sin_port && \ - (a).sin_addr.s_addr == (b).sin_addr.s_addr) -#define sin6_eq(a,b) \ - ((a).sin6_port == (b).sin6_port && \ - memcmp(&(a).sin6_addr, &(b).sin6_addr, sizeof(struct in6_addr)) == 0) - -struct dns_ctx { /* resolver context */ - /* settings */ - unsigned dnsc_flags; /* various flags */ - unsigned dnsc_timeout; /* timeout (base value) for queries */ - unsigned dnsc_ntries; /* number of retries */ - unsigned dnsc_ndots; /* ndots to assume absolute name */ - unsigned dnsc_port; /* default port (DNS_PORT) */ - unsigned dnsc_udpbuf; /* size of UDP buffer */ - /* array of nameserver addresses */ - union sockaddr_ns dnsc_serv[DNS_MAXSERV]; - unsigned dnsc_nserv; /* number of nameservers */ - unsigned dnsc_salen; /* length of socket addresses */ - dnsc_t dnsc_srchbuf[1024]; /* buffer for searchlist */ - dnsc_t *dnsc_srchend; /* current end of srchbuf */ - - dns_utm_fn *dnsc_utmfn; /* register/cancel timer events */ - void *dnsc_utmctx; /* user timer context for utmfn() */ - time_t dnsc_utmexp; /* when user timer expires */ - - dns_dbgfn *dnsc_udbgfn; /* debugging function */ - - /* dynamic data */ - unsigned dnsc_nextid; /* next queue ID to use */ - int dnsc_udpsock; /* UDP socket */ - struct dns_qlink dnsc_qactive; /* active list sorted by deadline */ - int dnsc_nactive; /* number entries in dnsc_qactive */ - dnsc_t *dnsc_pbuf; /* packet buffer (udpbuf size) */ - int dnsc_qstatus; /* last query status value */ -}; - -static const struct { - const char *name; - enum dns_opt opt; - unsigned offset; - unsigned min, max; -} dns_opts[] = { -#define opt(name,opt,field,min,max) \ - {name,opt,offsetof(struct dns_ctx,field),min,max} - opt("retrans", DNS_OPT_TIMEOUT, dnsc_timeout, 1,300), - opt("timeout", DNS_OPT_TIMEOUT, dnsc_timeout, 1,300), - opt("retry", DNS_OPT_NTRIES, dnsc_ntries, 1,50), - opt("attempts", DNS_OPT_NTRIES, dnsc_ntries, 1,50), - opt("ndots", DNS_OPT_NDOTS, dnsc_ndots, 0,1000), - opt("port", DNS_OPT_PORT, dnsc_port, 1,0xffff), - opt("udpbuf", DNS_OPT_UDPSIZE, dnsc_udpbuf, DNS_MAXPACKET,65536), -#undef opt -}; -#define dns_ctxopt(ctx,idx) (*((unsigned*)(((char*)ctx)+dns_opts[idx].offset))) - -#define ISSPACE(x) (x == ' ' || x == '\t' || x == '\r' || x == '\n') - -struct dns_ctx dns_defctx; - -#define SETCTX(ctx) if (!ctx) ctx = &dns_defctx -#define SETCTXINITED(ctx) SETCTX(ctx); assert(CTXINITED(ctx)) -#define CTXINITED(ctx) (ctx->dnsc_flags & DNS_INITED) -#define SETCTXFRESH(ctx) SETCTXINITED(ctx); assert(!CTXOPEN(ctx)) -#define SETCTXINACTIVE(ctx) \ - SETCTXINITED(ctx); assert(!ctx->dnsc_nactive) -#define SETCTXOPEN(ctx) SETCTXINITED(ctx); assert(CTXOPEN(ctx)) -#define CTXOPEN(ctx) (ctx->dnsc_udpsock >= 0) - -#if defined(NDEBUG) || !defined(DEBUG) -#define dns_assert_ctx(ctx) -#else -static void dns_assert_ctx(const struct dns_ctx *ctx) { - int nactive = 0; - const struct dns_query *q; - QLIST_FOR_EACH(&ctx->dnsc_qactive, q, next) { - assert(q->dnsq_ctx == ctx); - assert(q->dnsq_link.next->dnsq_link.prev == q); - assert(q->dnsq_link.prev->dnsq_link.next == q); - ++nactive; - } - assert(nactive == ctx->dnsc_nactive); -} -#endif - -enum { - DNS_INTERNAL = 0xffff, /* internal flags mask */ - DNS_INITED = 0x0001, /* the context is initialized */ - DNS_ASIS_DONE = 0x0002, /* search: skip the last as-is query */ - DNS_SEEN_NODATA = 0x0004, /* search: NODATA has been received */ -}; - -int dns_add_serv(struct dns_ctx *ctx, const char *serv) { - union sockaddr_ns *sns; - SETCTXFRESH(ctx); - if (!serv) - return (ctx->dnsc_nserv = 0); - if (ctx->dnsc_nserv >= DNS_MAXSERV) - return errno = ENFILE, -1; - sns = &ctx->dnsc_serv[ctx->dnsc_nserv]; - memset(sns, 0, sizeof(*sns)); - if (dns_pton(AF_INET, serv, &sns->sin.sin_addr) > 0) { - sns->sin.sin_family = AF_INET; - return ++ctx->dnsc_nserv; - } -#ifdef HAVE_IPv6 - if (dns_pton(AF_INET6, serv, &sns->sin6.sin6_addr) > 0) { - sns->sin6.sin6_family = AF_INET6; - return ++ctx->dnsc_nserv; - } -#endif - errno = EINVAL; - return -1; -} - -int dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa) { - SETCTXFRESH(ctx); - if (!sa) - return (ctx->dnsc_nserv = 0); - if (ctx->dnsc_nserv >= DNS_MAXSERV) - return errno = ENFILE, -1; -#ifdef HAVE_IPv6 - else if (sa->sa_family == AF_INET6) - ctx->dnsc_serv[ctx->dnsc_nserv].sin6 = *(struct sockaddr_in6*)sa; -#endif - else if (sa->sa_family == AF_INET) - ctx->dnsc_serv[ctx->dnsc_nserv].sin = *(struct sockaddr_in*)sa; - else - return errno = EAFNOSUPPORT, -1; - return ++ctx->dnsc_nserv; -} - -int dns_set_opts(struct dns_ctx *ctx, const char *opts) { - unsigned i, v; - SETCTXINACTIVE(ctx); - for(;;) { - while(ISSPACE(*opts)) ++opts; - if (!*opts) break; - for(i = 0; i < sizeof(dns_opts)/sizeof(dns_opts[0]); ++i) { - v = strlen(dns_opts[i].name); - if (strncmp(dns_opts[i].name, opts, v) != 0 || - (opts[v] != ':' && opts[v] != '=')) - continue; - opts += v + 1; - v = 0; - if (*opts < '0' || *opts > '9') break; - do v = v * 10 + (*opts++ - '0'); - while (*opts >= '0' && *opts <= '9'); - if (v < dns_opts[i].min) v = dns_opts[i].min; - if (v > dns_opts[i].max) v = dns_opts[i].max; - dns_ctxopt(ctx, i) = v; - break; - } - while(*opts && !ISSPACE(*opts)) ++opts; - } - return 0; -} - -int dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val) { - int prev; - unsigned i; - SETCTXINACTIVE(ctx); - for(i = 0; i < sizeof(dns_opts)/sizeof(dns_opts[0]); ++i) { - if (dns_opts[i].opt != opt) continue; - prev = dns_ctxopt(ctx, i); - if (val >= 0) { - unsigned v = val; - if (v < dns_opts[i].min || v > dns_opts[i].max) { - errno = EINVAL; - return -1; - } - dns_ctxopt(ctx, i) = v; - } - return prev; - } - if (opt == DNS_OPT_FLAGS) { - prev = ctx->dnsc_flags & ~DNS_INTERNAL; - if (val >= 0) - ctx->dnsc_flags = - (ctx->dnsc_flags & DNS_INTERNAL) | (val & ~DNS_INTERNAL); - return prev; - } - errno = ENOSYS; - return -1; -} - -int dns_add_srch(struct dns_ctx *ctx, const char *srch) { - int dnl; - SETCTXINACTIVE(ctx); - if (!srch) { - memset(ctx->dnsc_srchbuf, 0, sizeof(ctx->dnsc_srchbuf)); - ctx->dnsc_srchend = ctx->dnsc_srchbuf; - return 0; - } - dnl = - sizeof(ctx->dnsc_srchbuf) - (ctx->dnsc_srchend - ctx->dnsc_srchbuf) - 1; - dnl = dns_sptodn(srch, ctx->dnsc_srchend, dnl); - if (dnl > 0) - ctx->dnsc_srchend += dnl; - ctx->dnsc_srchend[0] = '\0'; /* we ensure the list is always ends at . */ - if (dnl > 0) - return 0; - errno = EINVAL; - return -1; -} - -static void dns_drop_utm(struct dns_ctx *ctx) { - if (ctx->dnsc_utmfn) - ctx->dnsc_utmfn(NULL, -1, ctx->dnsc_utmctx); - ctx->dnsc_utmctx = NULL; - ctx->dnsc_utmexp = -1; -} - -static void -_dns_request_utm(struct dns_ctx *ctx, time_t now) { - struct dns_query *q; - time_t deadline; - int timeout; - q = qlist_first(&ctx->dnsc_qactive); - if (!q) - deadline = -1, timeout = -1; - else if (!now || q->dnsq_deadline <= now) - deadline = 0, timeout = 0; - else - deadline = q->dnsq_deadline, timeout = (int)(deadline - now); - if (ctx->dnsc_utmexp == deadline) - return; - ctx->dnsc_utmfn(ctx, timeout, ctx->dnsc_utmctx); - ctx->dnsc_utmexp = deadline; -} - -static __inline void -dns_request_utm(struct dns_ctx *ctx, time_t now) { - if (ctx->dnsc_utmfn) - _dns_request_utm(ctx, now); -} - -void dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn) { - SETCTXINITED(ctx); - ctx->dnsc_udbgfn = dbgfn; -} - -void -dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data) { - SETCTXINITED(ctx); - dns_drop_utm(ctx); - ctx->dnsc_utmfn = fn; - ctx->dnsc_utmctx = data; - if (CTXOPEN(ctx)) - dns_request_utm(ctx, 0); -} - -unsigned dns_random16(void) { -#ifdef WINDOWS - FILETIME ft; - GetSystemTimeAsFileTime(&ft); -#define x (ft.dwLowDateTime) -#else - struct timeval tv; - gettimeofday(&tv, NULL); -#define x (tv.tv_usec) -#endif - return ((unsigned)x ^ ((unsigned)x >> 16)) & 0xffff; -#undef x -} - -void dns_close(struct dns_ctx *ctx) { - struct dns_query *q; - SETCTX(ctx); - if (CTXINITED(ctx)) { - if (ctx->dnsc_udpsock >= 0) - closesocket(ctx->dnsc_udpsock); - ctx->dnsc_udpsock = -1; - if (ctx->dnsc_pbuf) - free(ctx->dnsc_pbuf); - ctx->dnsc_pbuf = NULL; - while((q = qlist_first(&ctx->dnsc_qactive)) != NULL) { - qlist_remove(q); - free(q); - } - ctx->dnsc_nactive = 0; - dns_drop_utm(ctx); - } -} - -void dns_reset(struct dns_ctx *ctx) { - SETCTX(ctx); - dns_close(ctx); - memset(ctx, 0, sizeof(*ctx)); - ctx->dnsc_timeout = 4; - ctx->dnsc_ntries = 3; - ctx->dnsc_ndots = 1; - ctx->dnsc_udpbuf = DNS_EDNS0PACKET; - ctx->dnsc_port = DNS_PORT; - ctx->dnsc_udpsock = -1; - ctx->dnsc_srchend = ctx->dnsc_srchbuf; - qlist_init(&ctx->dnsc_qactive); - ctx->dnsc_nextid = dns_random16(); - ctx->dnsc_flags = DNS_INITED; -} - -struct dns_ctx *dns_new(const struct dns_ctx *copy) { - struct dns_ctx *ctx; - SETCTXINITED(copy); - dns_assert_ctx(copy); - ctx = malloc(sizeof(*ctx)); - if (!ctx) - return NULL; - *ctx = *copy; - ctx->dnsc_udpsock = -1; - qlist_init(&ctx->dnsc_qactive); - ctx->dnsc_nactive = 0; - ctx->dnsc_pbuf = NULL; - ctx->dnsc_qstatus = 0; - ctx->dnsc_utmfn = NULL; - ctx->dnsc_utmctx = NULL; - ctx->dnsc_nextid = dns_random16(); - return ctx; -} - -void dns_free(struct dns_ctx *ctx) { - assert(ctx != NULL && ctx != &dns_defctx); - dns_reset(ctx); - free(ctx); -} - -int dns_open(struct dns_ctx *ctx) { - int sock; - unsigned i; - int port; - union sockaddr_ns *sns; -#ifdef HAVE_IPv6 - unsigned have_inet6 = 0; -#endif - - SETCTXINITED(ctx); - assert(!CTXOPEN(ctx)); - - port = htons((unsigned short)ctx->dnsc_port); - /* ensure we have at least one server */ - if (!ctx->dnsc_nserv) { - sns = ctx->dnsc_serv; - sns->sin.sin_family = AF_INET; - sns->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - ctx->dnsc_nserv = 1; - } - - for (i = 0; i < ctx->dnsc_nserv; ++i) { - sns = &ctx->dnsc_serv[i]; - /* set port for each sockaddr */ -#ifdef HAVE_IPv6 - if (sns->sa.sa_family == AF_INET6) { - if (!sns->sin6.sin6_port) sns->sin6.sin6_port = (unsigned short)port; - ++have_inet6; - } - else -#endif - { - assert(sns->sa.sa_family == AF_INET); - if (!sns->sin.sin_port) sns->sin.sin_port = (unsigned short)port; - } - } - -#ifdef HAVE_IPv6 - if (have_inet6 && have_inet6 < ctx->dnsc_nserv) { - /* convert all IPv4 addresses to IPv6 V4MAPPED */ - struct sockaddr_in6 sin6; - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - /* V4MAPPED: ::ffff:1.2.3.4 */ - sin6.sin6_addr.s6_addr[10] = 0xff; - sin6.sin6_addr.s6_addr[11] = 0xff; - for(i = 0; i < ctx->dnsc_nserv; ++i) { - sns = &ctx->dnsc_serv[i]; - if (sns->sa.sa_family == AF_INET) { - sin6.sin6_port = sns->sin.sin_port; - ((struct in_addr*)&sin6.sin6_addr)[3] = sns->sin.sin_addr; - sns->sin6 = sin6; - } - } - } - - ctx->dnsc_salen = have_inet6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); - - if (have_inet6) - sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - else - sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); -#else /* !HAVE_IPv6 */ - sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - ctx->dnsc_salen = sizeof(struct sockaddr_in); -#endif /* HAVE_IPv6 */ - - if (sock < 0) { - ctx->dnsc_qstatus = DNS_E_TEMPFAIL; - return -1; - } -#ifdef WINDOWS - { unsigned long on = 1; - if (ioctlsocket(sock, FIONBIO, &on) == SOCKET_ERROR) { - closesocket(sock); - ctx->dnsc_qstatus = DNS_E_TEMPFAIL; - return -1; - } - } -#else /* !WINDOWS */ - if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0 || - fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) { - closesocket(sock); - ctx->dnsc_qstatus = DNS_E_TEMPFAIL; - return -1; - } -#endif /* WINDOWS */ - /* allocate the packet buffer */ - if ((ctx->dnsc_pbuf = malloc(ctx->dnsc_udpbuf)) == NULL) { - closesocket(sock); - ctx->dnsc_qstatus = DNS_E_NOMEM; - errno = ENOMEM; - return -1; - } - - ctx->dnsc_udpsock = sock; - dns_request_utm(ctx, 0); - return sock; -} - -int dns_sock(const struct dns_ctx *ctx) { - SETCTXINITED(ctx); - return ctx->dnsc_udpsock; -} - -int dns_active(const struct dns_ctx *ctx) { - SETCTXINITED(ctx); - dns_assert_ctx(ctx); - return ctx->dnsc_nactive; -} - -int dns_status(const struct dns_ctx *ctx) { - SETCTX(ctx); - return ctx->dnsc_qstatus; -} -void dns_setstatus(struct dns_ctx *ctx, int status) { - SETCTX(ctx); - ctx->dnsc_qstatus = status; -} - -/* End the query: disconnect it from the active list, free it, - * and return the result to the caller. - */ -static void -dns_end_query(struct dns_ctx *ctx, struct dns_query *q, - int status, void *result) { - dns_query_fn *cbck = q->dnsq_cbck; - void *cbdata = q->dnsq_cbdata; - ctx->dnsc_qstatus = status; - assert((status < 0 && result == 0) || (status >= 0 && result != 0)); - assert(cbck != 0); /*XXX callback may be NULL */ - assert(ctx->dnsc_nactive > 0); - --ctx->dnsc_nactive; - qlist_remove(q); - /* force the query to be unconnected */ - /*memset(q, 0, sizeof(*q));*/ -#ifndef NDEBUG - q->dnsq_ctx = NULL; -#endif - free(q); - cbck(ctx, result, cbdata); -} - -#define DNS_DBG(ctx, code, sa, slen, pkt, plen) \ - do { \ - if (ctx->dnsc_udbgfn) \ - ctx->dnsc_udbgfn(code, (sa), slen, pkt, plen, 0, 0); \ - } while(0) -#define DNS_DBGQ(ctx, q, code, sa, slen, pkt, plen) \ - do { \ - if (ctx->dnsc_udbgfn) \ - ctx->dnsc_udbgfn(code, (sa), slen, pkt, plen, q, q->dnsq_cbdata); \ - } while(0) - -static void dns_newid(struct dns_ctx *ctx, struct dns_query *q) { - /* this is how we choose an identifier for a new query (qID). - * For now, it's just sequential number, incremented for every query, and - * thus obviously trivial to guess. - * There are two choices: - * a) use sequential numbers. It is plain insecure. In DNS, there are two - * places where random numbers are (or can) be used to increase security: - * random qID and random source port number. Without this randomness - * (udns uses fixed port for all queries), or when the randomness is weak, - * it's trivial to spoof query replies. With randomness however, it - * becomes a bit more difficult task. Too bad we only have 16 bits for - * our security, as qID is only two bytes. It isn't a security per se, - * to rely on those 16 bits - an attacker can just flood us with fake - * replies with all possible qIDs (only 65536 of them), and in this case, - * even if we'll use true random qIDs, we'll be in trouble (not protected - * against spoofing). Yes, this is only possible on a high-speed network - * (probably on the LAN only, since usually a border router for a LAN - * protects internal machines from packets with spoofed local addresses - * from outside, and usually a nameserver resides on LAN), but it's - * still very well possible to send us fake replies. - * In other words: there's nothing a DNS (stub) resolver can do against - * spoofing attacks, unless DNSSEC is in use, which helps here alot. - * Too bad that DNSSEC isn't widespread, so relying on it isn't an - * option in almost all cases... - * b) use random qID, based on some random-number generation mechanism. - * This way, we increase our protection a bit (see above - it's very weak - * still), but we also increase risk of qID reuse and matching late replies - * that comes to queries we've sent before against new queries. There are - * some more corner cases around that, as well - for example, normally, - * udns tries to find the query for a given reply by qID, *and* by - * verifying that the query DN and other parameters are also the same - * (so if the new query is against another domain name, old reply will - * be ignored automatically). But certain types of replies which we now - * handle - for example, FORMERR reply from servers which refuses to - * process EDNS0-enabled packets - comes without all the query parameters - * but the qID - so we're forced to use qID only when determining which - * query the given reply corresponds to. This makes us even more - * vulnerable to spoofing attacks, because an attacker don't even need to - * know which queries we perform to spoof the replies - he only needs to - * flood us with fake FORMERR "replies". - * - * That all to say: using sequential (or any other trivially guessable) - * numbers for qIDs is insecure, but the whole thing is inherently insecure - * as well, and this "extra weakness" that comes from weak qID choosing - * algorithm adds almost nothing to the underlying problem. - * - * It CAN NOT be made secure. Period. That's it. - * Unless we choose to implement DNSSEC, which is a whole different story. - * Forcing TCP mode makes it better, but who uses TCP for DNS anyway? - * (and it's hardly possible because of huge impact on the recursive - * nameservers). - * - * Note that ALL stub resolvers (again, unless they implement and enforce - * DNSSEC) suffers from this same problem. - * - * So, instead of trying to be more secure (which actually is not - false - * sense of security is - I think - is worse than no security), I'm trying - * to be more robust here (by preventing qID reuse, which helps in normal - * conditions). And use sequential qID generation scheme. - */ - dns_put16(q->dnsq_id, ctx->dnsc_nextid++); - /* reset all parameters relevant for previous query lifetime */ - q->dnsq_try = 0; - q->dnsq_servi = 0; - /*XXX probably should keep dnsq_servnEDNS0 bits? - * See also comments in dns_ioevent() about FORMERR case */ - q->dnsq_servwait = q->dnsq_servskip = q->dnsq_servnEDNS0 = 0; -} - -/* Find next search suffix and fills in q->dnsq_dn. - * Return 0 if no more to try. */ -static int dns_next_srch(struct dns_ctx *ctx, struct dns_query *q) { - unsigned dnl; - - for(;;) { - if (q->dnsq_nxtsrch > ctx->dnsc_srchend) - return 0; - dnl = dns_dnlen(q->dnsq_nxtsrch); - if (dnl + q->dnsq_origdnl0 <= DNS_MAXDN && - (*q->dnsq_nxtsrch || !(q->dnsq_flags & DNS_ASIS_DONE))) - break; - q->dnsq_nxtsrch += dnl; - } - memcpy(q->dnsq_dn + q->dnsq_origdnl0, q->dnsq_nxtsrch, dnl); - if (!*q->dnsq_nxtsrch) - q->dnsq_flags |= DNS_ASIS_DONE; - q->dnsq_nxtsrch += dnl; - dns_newid(ctx, q); /* new ID for new qDN */ - return 1; -} - -/* find the server to try for current iteration. - * Note that current dnsq_servi may point to a server we should skip -- - * in that case advance to the next server. - * Return true if found, false if all tried. - */ -static int dns_find_serv(const struct dns_ctx *ctx, struct dns_query *q) { - while(q->dnsq_servi < ctx->dnsc_nserv) { - if (!(q->dnsq_servskip & (1 << q->dnsq_servi))) - return 1; - ++q->dnsq_servi; - } - return 0; -} - -/* format and send the query to a given server. - * In case of network problem (sendto() fails), return -1, - * else return 0. - */ -static int -dns_send_this(struct dns_ctx *ctx, struct dns_query *q, - unsigned servi, time_t now) { - unsigned qlen; - unsigned tries; - - { /* format the query buffer */ - dnsc_t *p = ctx->dnsc_pbuf; - memset(p, 0, DNS_HSIZE); - if (!(q->dnsq_flags & DNS_NORD)) p[DNS_H_F1] |= DNS_HF1_RD; - if (q->dnsq_flags & DNS_AAONLY) p[DNS_H_F1] |= DNS_HF1_AA; - p[DNS_H_QDCNT2] = 1; - memcpy(p + DNS_H_QID, q->dnsq_id, 2); - p = dns_payload(p); - /* copy query dn */ - p += dns_dntodn(q->dnsq_dn, p, DNS_MAXDN); - /* query type and class */ - memcpy(p, q->dnsq_typcls, 4); p += 4; - /* add EDNS0 size record */ - if (ctx->dnsc_udpbuf > DNS_MAXPACKET && - !(q->dnsq_servnEDNS0 & (1 << servi))) { - *p++ = 0; /* empty (root) DN */ - p = dns_put16(p, DNS_T_OPT); - p = dns_put16(p, ctx->dnsc_udpbuf); - /* EDNS0 RCODE & VERSION; rest of the TTL field; RDLEN */ - memset(p, 0, 2+2+2); p += 2+2+2; - ctx->dnsc_pbuf[DNS_H_ARCNT2] = 1; - } - qlen = p - ctx->dnsc_pbuf; - assert(qlen <= ctx->dnsc_udpbuf); - } - - /* send the query */ - tries = 10; - while (sendto(ctx->dnsc_udpsock, (void*)ctx->dnsc_pbuf, qlen, 0, - &ctx->dnsc_serv[servi].sa, ctx->dnsc_salen) < 0) { - /*XXX just ignore the sendto() error for now and try again. - * In the future, it may be possible to retrieve the error code - * and find which operation/query failed. - *XXX try the next server too? (if ENETUNREACH is returned immediately) - */ - if (--tries) continue; - /* if we can't send the query, fail it. */ - dns_end_query(ctx, q, DNS_E_TEMPFAIL, 0); - return -1; - } - DNS_DBGQ(ctx, q, 1, - &ctx->dnsc_serv[servi].sa, sizeof(union sockaddr_ns), - ctx->dnsc_pbuf, qlen); - q->dnsq_servwait |= 1 << servi; /* expect reply from this ns */ - - q->dnsq_deadline = now + - (dns_find_serv(ctx, q) ? 1 : ctx->dnsc_timeout << q->dnsq_try); - - /* move the query to the proper place, according to the new deadline */ - qlist_remove(q); - { /* insert from the tail */ - struct dns_query *p; - QLIST_FOR_EACH(&ctx->dnsc_qactive, p, prev) - if (p->dnsq_deadline <= q->dnsq_deadline) - break; - qlist_insert_after(q, p); - } - - return 0; -} - -/* send the query out using next available server - * and add it to the active list, or, if no servers available, - * end it. - */ -static void -dns_send(struct dns_ctx *ctx, struct dns_query *q, time_t now) { - - /* if we can't send the query, return TEMPFAIL even when searching: - * we can't be sure whenever the name we tried to search exists or not, - * so don't continue searching, or we may find the wrong name. */ - - if (!dns_find_serv(ctx, q)) { - /* no more servers in this iteration. Try the next cycle */ - q->dnsq_servi = 0; /* reset */ - q->dnsq_try++; /* next try */ - if (q->dnsq_try >= ctx->dnsc_ntries || - !dns_find_serv(ctx, q)) { - /* no more servers and tries, fail the query */ - /* return TEMPFAIL even when searching: no more tries for this - * searchlist, and no single definitive reply (handled in dns_ioevent() - * in NOERROR or NXDOMAIN cases) => all nameservers failed to process - * current search list element, so we don't know whenever the name exists. - */ - dns_end_query(ctx, q, DNS_E_TEMPFAIL, 0); - return; - } - } - - dns_send_this(ctx, q, q->dnsq_servi++, now); -} - -static void dns_dummy_cb(struct dns_ctx *ctx, void *result, void *data) { - if (result) free(result); - data = ctx = 0; /* used */ -} - -/* The (only, main, real) query submission routine. - * Allocate new query structure, initialize it, check validity of - * parameters, and add it to the head of the active list, without - * trying to send it (to be picked up on next event). - * Error return (without calling the callback routine) - - * no memory or wrong parameters. - *XXX The `no memory' case probably should go to the callback anyway... - */ -struct dns_query * -dns_submit_dn(struct dns_ctx *ctx, - dnscc_t *dn, int qcls, int qtyp, int flags, - dns_parse_fn *parse, dns_query_fn *cbck, void *data) { - struct dns_query *q; - SETCTXOPEN(ctx); - dns_assert_ctx(ctx); - - q = calloc(sizeof(*q), 1); - if (!q) { - ctx->dnsc_qstatus = DNS_E_NOMEM; - return NULL; - } - -#ifndef NDEBUG - q->dnsq_ctx = ctx; -#endif - q->dnsq_parse = parse; - q->dnsq_cbck = cbck ? cbck : dns_dummy_cb; - q->dnsq_cbdata = data; - - q->dnsq_origdnl0 = dns_dntodn(dn, q->dnsq_dn, sizeof(q->dnsq_dn)); - assert(q->dnsq_origdnl0 > 0); - --q->dnsq_origdnl0; /* w/o the trailing 0 */ - dns_put16(q->dnsq_typcls+0, qtyp); - dns_put16(q->dnsq_typcls+2, qcls); - q->dnsq_flags = (flags | ctx->dnsc_flags) & ~DNS_INTERNAL; - - if (flags & DNS_NOSRCH || - dns_dnlabels(q->dnsq_dn) > ctx->dnsc_ndots) { - q->dnsq_nxtsrch = flags & DNS_NOSRCH ? - ctx->dnsc_srchend /* end of the search list if no search requested */ : - ctx->dnsc_srchbuf /* beginning of the list, but try as-is first */; - q->dnsq_flags |= DNS_ASIS_DONE; - dns_newid(ctx, q); - } - else { - q->dnsq_nxtsrch = ctx->dnsc_srchbuf; - dns_next_srch(ctx, q); - } - - qlist_add_head(q, &ctx->dnsc_qactive); - ++ctx->dnsc_nactive; - dns_request_utm(ctx, 0); - - return q; -} - -struct dns_query * -dns_submit_p(struct dns_ctx *ctx, - const char *name, int qcls, int qtyp, int flags, - dns_parse_fn *parse, dns_query_fn *cbck, void *data) { - int isabs; - SETCTXOPEN(ctx); - if (dns_ptodn(name, 0, ctx->dnsc_pbuf, DNS_MAXDN, &isabs) <= 0) { - ctx->dnsc_qstatus = DNS_E_BADQUERY; - return NULL; - } - if (isabs) - flags |= DNS_NOSRCH; - return - dns_submit_dn(ctx, ctx->dnsc_pbuf, qcls, qtyp, flags, parse, cbck, data); -} - -/* process readable fd condition. - * To be usable in edge-triggered environment, the routine - * should consume all input so it should loop over. - * Note it isn't really necessary to loop here, because - * an application may perform the loop just fine by it's own, - * but in this case we should return some sensitive result, - * to indicate when to stop calling and error conditions. - * Note also we may encounter all sorts of recvfrom() - * errors which aren't fatal, and at the same time we may - * loop forever if an error IS fatal. - */ -void dns_ioevent(struct dns_ctx *ctx, time_t now) { - int r; - unsigned servi; - struct dns_query *q; - dnsc_t *pbuf; - dnscc_t *pend, *pcur; - void *result; - union sockaddr_ns sns; - socklen_t slen; - - SETCTX(ctx); - if (!CTXOPEN(ctx)) - return; - dns_assert_ctx(ctx); - pbuf = ctx->dnsc_pbuf; - - if (!now) now = time(NULL); - -again: /* receive the reply */ - - slen = sizeof(sns); - r = recvfrom(ctx->dnsc_udpsock, (void*)pbuf, ctx->dnsc_udpbuf, - MSG_DONTWAIT, &sns.sa, &slen); - if (r < 0) { - /*XXX just ignore recvfrom() errors for now. - * in the future it may be possible to determine which - * query failed and requeue it. - * Note there may be various error conditions, triggered - * by both local problems and remote problems. It isn't - * quite trivial to determine whenever an error is local - * or remote. On local errors, we should stop, while - * remote errors should be ignored (for now anyway). - */ -#ifdef WINDOWS - if (WSAGetLastError() == WSAEWOULDBLOCK) -#else - if (errno == EAGAIN) -#endif - { - dns_request_utm(ctx, now); - return; - } - goto again; - } - - pend = pbuf + r; - pcur = dns_payload(pbuf); - - /* check reply header */ - if (pcur > pend || dns_numqd(pbuf) > 1 || dns_opcode(pbuf) != 0) { - DNS_DBG(ctx, -1/*bad reply*/, &sns.sa, slen, pbuf, r); - goto again; - } - - /* find the matching query, by qID */ - for (q = QLIST_FIRST(&ctx->dnsc_qactive, next);; q = QLIST_NEXT(q, next)) { - if (QLIST_ISLAST(&ctx->dnsc_qactive, q)) { - /* no more requests: old reply? */ - DNS_DBG(ctx, -5/*no matching query*/, &sns.sa, slen, pbuf, r); - goto again; - } - if (pbuf[DNS_H_QID1] == q->dnsq_id[0] && - pbuf[DNS_H_QID2] == q->dnsq_id[1]) - break; - } - - /* if we have numqd, compare with our query qDN */ - if (dns_numqd(pbuf)) { - /* decode the qDN */ - dnsc_t dn[DNS_MAXDN]; - if (dns_getdn(pbuf, &pcur, pend, dn, sizeof(dn)) < 0 || - pcur + 4 > pend) { - DNS_DBG(ctx, -1/*bad reply*/, &sns.sa, slen, pbuf, r); - goto again; - } - if (!dns_dnequal(dn, q->dnsq_dn) || - memcmp(pcur, q->dnsq_typcls, 4) != 0) { - /* not this query */ - DNS_DBG(ctx, -5/*no matching query*/, &sns.sa, slen, pbuf, r); - goto again; - } - /* here, query match, and pcur points past qDN in query section in pbuf */ - } - /* if no numqd, we only allow FORMERR rcode */ - else if (dns_rcode(pbuf) != DNS_R_FORMERR) { - /* treat it as bad reply if !FORMERR */ - DNS_DBG(ctx, -1/*bad reply*/, &sns.sa, slen, pbuf, r); - goto again; - } - else { - /* else it's FORMERR, handled below */ - } - - /* find server */ -#ifdef HAVE_IPv6 - if (sns.sa.sa_family == AF_INET6 && slen >= sizeof(sns.sin6)) { - for(servi = 0; servi < ctx->dnsc_nserv; ++servi) - if (sin6_eq(ctx->dnsc_serv[servi].sin6, sns.sin6)) - break; - } - else -#endif - if (sns.sa.sa_family == AF_INET && slen >= sizeof(sns.sin)) { - for(servi = 0; servi < ctx->dnsc_nserv; ++servi) - if (sin_eq(ctx->dnsc_serv[servi].sin, sns.sin)) - break; - } - else - servi = ctx->dnsc_nserv; - - /* check if we expect reply from this server. - * Note we can receive reply from first try if we're already at next */ - if (!(q->dnsq_servwait & (1 << servi))) { /* if ever asked this NS */ - DNS_DBG(ctx, -2/*wrong server*/, &sns.sa, slen, pbuf, r); - goto again; - } - - /* we got (some) reply for our query */ - - DNS_DBGQ(ctx, q, 0, &sns.sa, slen, pbuf, r); - q->dnsq_servwait &= ~(1 << servi); /* don't expect reply from this serv */ - - /* process the RCODE */ - switch(dns_rcode(pbuf)) { - - case DNS_R_NOERROR: - if (dns_tc(pbuf)) { - /* possible truncation. We can't deal with it. */ - /*XXX for now, treat TC bit the same as SERVFAIL. - * It is possible to: - * a) try to decode the reply - may be ANSWER section is ok; - * b) check if server understands EDNS0, and if it is, and - * answer still don't fit, end query. - */ - break; - } - if (!dns_numan(pbuf)) { /* no data of requested type */ - if (dns_next_srch(ctx, q)) { - /* if we're searching, try next searchlist element, - * but remember NODATA reply. */ - q->dnsq_flags |= DNS_SEEN_NODATA; - dns_send(ctx, q, now); - } - else - /* else - nothing to search any more - finish the query. - * It will be NODATA since we've seen a NODATA reply. */ - dns_end_query(ctx, q, DNS_E_NODATA, 0); - } - /* we've got a positive reply here */ - else if (q->dnsq_parse) { - /* if we have parsing routine, call it and return whatever it returned */ - /* don't try to re-search if NODATA here. For example, - * if we asked for A but only received CNAME. Unless we'll - * someday do recursive queries. And that's problematic too, since - * we may be dealing with specific AA-only nameservers for a given - * domain, but CNAME points elsewhere... - */ - r = q->dnsq_parse(q->dnsq_dn, pbuf, pcur, pend, &result); - dns_end_query(ctx, q, r, r < 0 ? NULL : result); - } - /* else just malloc+copy the raw DNS reply */ - else if ((result = malloc(r)) == NULL) - dns_end_query(ctx, q, DNS_E_NOMEM, NULL); - else { - memcpy(result, pbuf, r); - dns_end_query(ctx, q, r, result); - } - goto again; - - case DNS_R_NXDOMAIN: /* Non-existing domain. */ - if (dns_next_srch(ctx, q)) - /* more search entries exists, try them. */ - dns_send(ctx, q, now); - else - /* nothing to search anymore. End the query, returning either NODATA - * if we've seen it before, or NXDOMAIN if not. */ - dns_end_query(ctx, q, - q->dnsq_flags & DNS_SEEN_NODATA ? DNS_E_NODATA : DNS_E_NXDOMAIN, 0); - goto again; - - case DNS_R_FORMERR: - case DNS_R_NOTIMPL: - /* for FORMERR and NOTIMPL rcodes, if we tried EDNS0-enabled query, - * try w/o EDNS0. */ - if (ctx->dnsc_udpbuf > DNS_MAXPACKET && - !(q->dnsq_servnEDNS0 & (1 << servi))) { - /* we always trying EDNS0 first if enabled, and retry a given query - * if not available. Maybe it's better to remember inavailability of - * EDNS0 in ctx as a per-NS flag, and never try again for this NS. - * For long-running applications.. maybe they will change the nameserver - * while we're running? :) Also, since FORMERR is the only rcode we - * allow to be header-only, and in this case the only check we do to - * find a query it belongs to is qID (not qDN+qCLS+qTYP), it's much - * easier to spoof and to force us to perform non-EDNS0 queries only... - */ - q->dnsq_servnEDNS0 |= 1 << servi; - dns_send_this(ctx, q, servi, now); - goto again; - } - /* else we handle it the same as SERVFAIL etc */ - - case DNS_R_SERVFAIL: - case DNS_R_REFUSED: - /* for these rcodes, advance this request - * to the next server and reschedule */ - default: /* unknown rcode? hmmm... */ - break; - } - - /* here, we received unexpected reply */ - q->dnsq_servskip |= (1 << servi); /* don't retry this server */ - - /* we don't expect replies from this server anymore. - * But there may be other servers. Some may be still processing our - * query, and some may be left to try. - * We just ignore this reply and wait a bit more if some NSes haven't - * replied yet (dnsq_servwait != 0), and let the situation to be handled - * on next event processing. Timeout for this query is set correctly, - * if not taking into account the one-second difference - we can try - * next server in the same iteration sooner. - */ - - /* try next server */ - if (!q->dnsq_servwait) { - /* next retry: maybe some other servers will reply next time. - * dns_send() will end the query for us if no more servers to try. - * Note we can't continue with the next searchlist element here: - * we don't know if the current qdn exists or not, there's no definitive - * answer yet (which is seen in cases above). - *XXX standard resolver also tries as-is query in case all nameservers - * failed to process our query and if not tried before. We don't do it. - */ - dns_send(ctx, q, now); - } - else { - /* else don't do anything - not all servers replied yet */ - } - goto again; - -} - -/* handle all timeouts */ -int dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now) { - /* this is a hot routine */ - struct dns_query *q; - - SETCTX(ctx); - dns_assert_ctx(ctx); - - /* Pick up first entry from query list. - * If its deadline has passed, (re)send it - * (dns_send() will move it next in the list). - * If not, this is the query which determines the closest deadline. - */ - - q = qlist_first(&ctx->dnsc_qactive); - if (!q) - return maxwait; - if (!now) - now = time(NULL); - do { - if (q->dnsq_deadline > now) { /* first non-expired query */ - int w = (int)(q->dnsq_deadline - now); - if (maxwait < 0 || maxwait > w) - maxwait = w; - break; - } - else { - /* process expired deadline */ - dns_send(ctx, q, now); - } - } while((q = qlist_first(&ctx->dnsc_qactive)) != NULL); - - dns_request_utm(ctx, now); /* update timer with new deadline */ - return maxwait; -} - -struct dns_resolve_data { - int dnsrd_done; - void *dnsrd_result; -}; - -static void dns_resolve_cb(struct dns_ctx *ctx, void *result, void *data) { - struct dns_resolve_data *d = data; - d->dnsrd_result = result; - d->dnsrd_done = 1; - ctx = ctx; -} - -void *dns_resolve(struct dns_ctx *ctx, struct dns_query *q) { - time_t now; - struct dns_resolve_data d; - int n; - SETCTXOPEN(ctx); - - if (!q) - return NULL; - - assert(ctx == q->dnsq_ctx); - dns_assert_ctx(ctx); - /* do not allow re-resolving syncronous queries */ - assert(q->dnsq_cbck != dns_resolve_cb && "can't resolve syncronous query"); - if (q->dnsq_cbck == dns_resolve_cb) { - ctx->dnsc_qstatus = DNS_E_BADQUERY; - return NULL; - } - q->dnsq_cbck = dns_resolve_cb; - q->dnsq_cbdata = &d; - d.dnsrd_done = 0; - - now = time(NULL); - while(!d.dnsrd_done && (n = dns_timeouts(ctx, -1, now)) >= 0) { -#ifdef HAVE_POLL - struct pollfd pfd; - pfd.fd = ctx->dnsc_udpsock; - pfd.events = POLLIN; - n = poll(&pfd, 1, n * 1000); -#else - fd_set rfd; - struct timeval tv; - FD_ZERO(&rfd); - FD_SET(ctx->dnsc_udpsock, &rfd); - tv.tv_sec = n; tv.tv_usec = 0; - n = select(ctx->dnsc_udpsock + 1, &rfd, NULL, NULL, &tv); -#endif - now = time(NULL); - if (n > 0) - dns_ioevent(ctx, now); - } - - return d.dnsrd_result; -} - -void *dns_resolve_dn(struct dns_ctx *ctx, - dnscc_t *dn, int qcls, int qtyp, int flags, - dns_parse_fn *parse) { - return - dns_resolve(ctx, - dns_submit_dn(ctx, dn, qcls, qtyp, flags, parse, NULL, NULL)); -} - -void *dns_resolve_p(struct dns_ctx *ctx, - const char *name, int qcls, int qtyp, int flags, - dns_parse_fn *parse) { - return - dns_resolve(ctx, - dns_submit_p(ctx, name, qcls, qtyp, flags, parse, NULL, NULL)); -} - -int dns_cancel(struct dns_ctx *ctx, struct dns_query *q) { - SETCTX(ctx); - dns_assert_ctx(ctx); - assert(q->dnsq_ctx == ctx); - /* do not allow cancelling syncronous queries */ - assert(q->dnsq_cbck != dns_resolve_cb && "can't cancel syncronous query"); - if (q->dnsq_cbck == dns_resolve_cb) - return (ctx->dnsc_qstatus = DNS_E_BADQUERY); - qlist_remove(q); - --ctx->dnsc_nactive; - dns_request_utm(ctx, 0); - return 0; -} - diff --git a/deps/udns/udns_rr_a.c b/deps/udns/udns_rr_a.c deleted file mode 100644 index ca99dfe..0000000 --- a/deps/udns/udns_rr_a.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $Id: udns_rr_a.c,v 1.16 2007/01/09 04:44:51 mjt Exp $ - parse/query A/AAAA IN records - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include -#ifndef WINDOWS -# include -# include -#endif -#include "udns.h" - -/* here, we use common routine to parse both IPv4 and IPv6 addresses. - */ - -/* this structure should match dns_rr_a[46] */ -struct dns_rr_a { - dns_rr_common(dnsa); - unsigned char *dnsa_addr; -}; - -static int -dns_parse_a(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result, unsigned dsize) { - struct dns_rr_a *ret; - struct dns_parse p; - struct dns_rr rr; - int r; - - /* first, validate and count number of addresses */ - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) - if (rr.dnsrr_dsz != dsize) - return DNS_E_PROTOCOL; - if (r < 0) - return DNS_E_PROTOCOL; - else if (!p.dnsp_nrr) - return DNS_E_NODATA; - - ret = malloc(sizeof(*ret) + dsize * p.dnsp_nrr + dns_stdrr_size(&p)); - if (!ret) - return DNS_E_NOMEM; - - ret->dnsa_nrr = p.dnsp_nrr; - ret->dnsa_addr = (unsigned char*)(ret+1); - - /* copy the RRs */ - for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) - memcpy(ret->dnsa_addr + dsize * r, rr.dnsrr_dptr, dsize); - - dns_stdrr_finish((struct dns_rr_null *)ret, - (char *)(ret->dnsa_addr + dsize * p.dnsp_nrr), &p); - *result = ret; - return 0; -} - -int -dns_parse_a4(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { -#ifdef AF_INET - assert(sizeof(struct in_addr) == 4); -#endif - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_A); - return dns_parse_a(qdn, pkt, cur, end, result, 4); -} - -struct dns_query * -dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags, - dns_query_a4_fn *cbck, void *data) { - return - dns_submit_p(ctx, name, DNS_C_IN, DNS_T_A, flags, - dns_parse_a4, (dns_query_fn*)cbck, data); -} - -struct dns_rr_a4 * -dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags) { - return (struct dns_rr_a4 *) - dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_A, flags, dns_parse_a4); -} - -int -dns_parse_a6(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { -#ifdef AF_INET6 - assert(sizeof(struct in6_addr) == 16); -#endif - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_AAAA); - return dns_parse_a(qdn, pkt, cur, end, result, 16); -} - -struct dns_query * -dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags, - dns_query_a6_fn *cbck, void *data) { - return - dns_submit_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags, - dns_parse_a6, (dns_query_fn*)cbck, data); -} - -struct dns_rr_a6 * -dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags) { - return (struct dns_rr_a6 *) - dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_AAAA, flags, dns_parse_a6); -} diff --git a/deps/udns/udns_rr_mx.c b/deps/udns/udns_rr_mx.c deleted file mode 100644 index cf83483..0000000 --- a/deps/udns/udns_rr_mx.c +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id: udns_rr_mx.c,v 1.13 2005/04/20 06:44:34 mjt Exp $ - parse/query MX IN records - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include -#include "udns.h" - -int -dns_parse_mx(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { - struct dns_rr_mx *ret; - struct dns_parse p; - struct dns_rr rr; - int r, l; - char *sp; - dnsc_t mx[DNS_MAXDN]; - - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_MX); - - /* first, validate the answer and count size of the result */ - l = 0; - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) { - cur = rr.dnsrr_dptr + 2; - r = dns_getdn(pkt, &cur, end, mx, sizeof(mx)); - if (r <= 0 || cur != rr.dnsrr_dend) - return DNS_E_PROTOCOL; - l += dns_dntop_size(mx); - } - if (r < 0) - return DNS_E_PROTOCOL; - if (!p.dnsp_nrr) - return DNS_E_NODATA; - - /* next, allocate and set up result */ - l += dns_stdrr_size(&p); - ret = malloc(sizeof(*ret) + sizeof(struct dns_mx) * p.dnsp_nrr + l); - if (!ret) - return DNS_E_NOMEM; - ret->dnsmx_nrr = p.dnsp_nrr; - ret->dnsmx_mx = (struct dns_mx *)(ret+1); - - /* and 3rd, fill in result, finally */ - sp = (char*)(ret->dnsmx_mx + p.dnsp_nrr); - for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) { - ret->dnsmx_mx[r].name = sp; - cur = rr.dnsrr_dptr; - ret->dnsmx_mx[r].priority = dns_get16(cur); - cur += 2; - dns_getdn(pkt, &cur, end, mx, sizeof(mx)); - sp += dns_dntop(mx, sp, DNS_MAXNAME); - } - dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p); - *result = ret; - return 0; -} - -struct dns_query * -dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags, - dns_query_mx_fn *cbck, void *data) { - return - dns_submit_p(ctx, name, DNS_C_IN, DNS_T_MX, flags, - dns_parse_mx, (dns_query_fn *)cbck, data); -} - -struct dns_rr_mx * -dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags) { - return (struct dns_rr_mx *) - dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_MX, flags, dns_parse_mx); -} diff --git a/deps/udns/udns_rr_naptr.c b/deps/udns/udns_rr_naptr.c deleted file mode 100644 index ec4f514..0000000 --- a/deps/udns/udns_rr_naptr.c +++ /dev/null @@ -1,128 +0,0 @@ -/* $Id: udns_rr_naptr.c,v 1.1 2006/11/28 22:58:04 mjt Exp $ - parse/query NAPTR IN records - - Copyright (C) 2005 Michael Tokarev - Copyright (C) 2006 Mikael Magnusson - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include -#include "udns.h" - -/* Get a single string for NAPTR record, pretty much like a DN label. - * String length is in first byte in *cur, so it can't be >255. - */ -static int dns_getstr(dnscc_t **cur, dnscc_t *ep, char *buf) -{ - unsigned l; - dnscc_t *cp = *cur; - - l = *cp++; - if (cp + l > ep) - return DNS_E_PROTOCOL; - if (buf) { - memcpy(buf, cp, l); - buf[l] = '\0'; - } - cp += l; - - *cur = cp; - return l + 1; -} - -int -dns_parse_naptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { - struct dns_rr_naptr *ret; - struct dns_parse p; - struct dns_rr rr; - int r, l; - char *sp; - dnsc_t dn[DNS_MAXDN]; - - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_NAPTR); - - /* first, validate the answer and count size of the result */ - l = 0; - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) { - int i; - dnscc_t *ep = rr.dnsrr_dend; - - /* first 4 bytes: order & preference */ - cur = rr.dnsrr_dptr + 4; - - /* flags, services and regexp */ - for (i = 0; i < 3; i++) { - r = dns_getstr(&cur, ep, NULL); - if (r < 0) - return r; - l += r; - } - /* replacement */ - r = dns_getdn(pkt, &cur, end, dn, sizeof(dn)); - if (r <= 0 || cur != rr.dnsrr_dend) - return DNS_E_PROTOCOL; - l += dns_dntop_size(dn); - } - if (r < 0) - return DNS_E_PROTOCOL; - if (!p.dnsp_nrr) - return DNS_E_NODATA; - - /* next, allocate and set up result */ - l += dns_stdrr_size(&p); - ret = malloc(sizeof(*ret) + sizeof(struct dns_naptr) * p.dnsp_nrr + l); - if (!ret) - return DNS_E_NOMEM; - ret->dnsnaptr_nrr = p.dnsp_nrr; - ret->dnsnaptr_naptr = (struct dns_naptr *)(ret+1); - - /* and 3rd, fill in result, finally */ - sp = (char*)(&ret->dnsnaptr_naptr[p.dnsp_nrr]); - for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) { - cur = rr.dnsrr_dptr; - ret->dnsnaptr_naptr[r].order = dns_get16(cur); cur += 2; - ret->dnsnaptr_naptr[r].preference = dns_get16(cur); cur += 2; - sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].flags = sp)); - sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].service = sp)); - sp += dns_getstr(&cur, end, (ret->dnsnaptr_naptr[r].regexp = sp)); - dns_getdn(pkt, &cur, end, dn, sizeof(dn)); - sp += dns_dntop(dn, (ret->dnsnaptr_naptr[r].replacement = sp), DNS_MAXNAME); - } - dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p); - *result = ret; - return 0; -} - -struct dns_query * -dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags, - dns_query_naptr_fn *cbck, void *data) { - return - dns_submit_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags, - dns_parse_naptr, (dns_query_fn *)cbck, data); -} - -struct dns_rr_naptr * -dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags) { - return (struct dns_rr_naptr *) - dns_resolve_p(ctx, name, DNS_C_IN, DNS_T_NAPTR, flags, dns_parse_naptr); -} diff --git a/deps/udns/udns_rr_ptr.c b/deps/udns/udns_rr_ptr.c deleted file mode 100644 index 410af65..0000000 --- a/deps/udns/udns_rr_ptr.c +++ /dev/null @@ -1,109 +0,0 @@ -/* $Id: udns_rr_ptr.c,v 1.15 2005/09/12 11:21:06 mjt Exp $ - parse/query PTR records - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include "udns.h" - -int -dns_parse_ptr(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { - struct dns_rr_ptr *ret; - struct dns_parse p; - struct dns_rr rr; - int r, l, c; - char *sp; - dnsc_t ptr[DNS_MAXDN]; - - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_PTR); - - /* first, validate the answer and count size of the result */ - l = c = 0; - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) { - cur = rr.dnsrr_dptr; - r = dns_getdn(pkt, &cur, end, ptr, sizeof(ptr)); - if (r <= 0 || cur != rr.dnsrr_dend) - return DNS_E_PROTOCOL; - l += dns_dntop_size(ptr); - ++c; - } - if (r < 0) - return DNS_E_PROTOCOL; - if (!c) - return DNS_E_NODATA; - - /* next, allocate and set up result */ - ret = malloc(sizeof(*ret) + sizeof(char **) * c + l + dns_stdrr_size(&p)); - if (!ret) - return DNS_E_NOMEM; - ret->dnsptr_nrr = c; - ret->dnsptr_ptr = (char **)(ret+1); - - /* and 3rd, fill in result, finally */ - sp = (char*)(ret->dnsptr_ptr + c); - c = 0; - dns_rewind(&p, qdn); - while((r = dns_nextrr(&p, &rr)) > 0) { - ret->dnsptr_ptr[c] = sp; - cur = rr.dnsrr_dptr; - dns_getdn(pkt, &cur, end, ptr, sizeof(ptr)); - sp += dns_dntop(ptr, sp, DNS_MAXNAME); - ++c; - } - dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p); - *result = ret; - return 0; -} - -struct dns_query * -dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr, - dns_query_ptr_fn *cbck, void *data) { - dnsc_t dn[DNS_A4RSIZE]; - dns_a4todn(addr, 0, dn, sizeof(dn)); - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH, - dns_parse_ptr, (dns_query_fn *)cbck, data); -} - -struct dns_rr_ptr * -dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr) { - return (struct dns_rr_ptr *) - dns_resolve(ctx, dns_submit_a4ptr(ctx, addr, NULL, NULL)); -} - -struct dns_query * -dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr, - dns_query_ptr_fn *cbck, void *data) { - dnsc_t dn[DNS_A6RSIZE]; - dns_a6todn(addr, 0, dn, sizeof(dn)); - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_PTR, DNS_NOSRCH, - dns_parse_ptr, (dns_query_fn *)cbck, data); -} - -struct dns_rr_ptr * -dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr) { - return (struct dns_rr_ptr *) - dns_resolve(ctx, dns_submit_a6ptr(ctx, addr, NULL, NULL)); -} diff --git a/deps/udns/udns_rr_srv.c b/deps/udns/udns_rr_srv.c deleted file mode 100644 index 56bbbf7..0000000 --- a/deps/udns/udns_rr_srv.c +++ /dev/null @@ -1,154 +0,0 @@ -/* $Id: udns_rr_srv.c,v 1.2 2005/09/12 12:26:22 mjt Exp $ - parse/query SRV IN (rfc2782) records - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - Copyright 2005 Thadeu Lima de Souza Cascardo - - 2005-09-11: - Changed MX parser file into a SRV parser file - - */ - -#include -#include -#include -#include "udns.h" - -int -dns_parse_srv(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { - struct dns_rr_srv *ret; - struct dns_parse p; - struct dns_rr rr; - int r, l; - char *sp; - dnsc_t srv[DNS_MAXDN]; - - assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_SRV); - - /* first, validate the answer and count size of the result */ - l = 0; - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) { - cur = rr.dnsrr_dptr + 6; - r = dns_getdn(pkt, &cur, end, srv, sizeof(srv)); - if (r <= 0 || cur != rr.dnsrr_dend) - return DNS_E_PROTOCOL; - l += dns_dntop_size(srv); - } - if (r < 0) - return DNS_E_PROTOCOL; - if (!p.dnsp_nrr) - return DNS_E_NODATA; - - /* next, allocate and set up result */ - l += dns_stdrr_size(&p); - ret = malloc(sizeof(*ret) + sizeof(struct dns_srv) * p.dnsp_nrr + l); - if (!ret) - return DNS_E_NOMEM; - ret->dnssrv_nrr = p.dnsp_nrr; - ret->dnssrv_srv = (struct dns_srv *)(ret+1); - - /* and 3rd, fill in result, finally */ - sp = (char*)(ret->dnssrv_srv + p.dnsp_nrr); - for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) { - ret->dnssrv_srv[r].name = sp; - cur = rr.dnsrr_dptr; - ret->dnssrv_srv[r].priority = dns_get16(cur); - ret->dnssrv_srv[r].weight = dns_get16(cur+2); - ret->dnssrv_srv[r].port = dns_get16(cur+4); - cur += 6; - dns_getdn(pkt, &cur, end, srv, sizeof(srv)); - sp += dns_dntop(srv, sp, DNS_MAXNAME); - } - dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p); - *result = ret; - return 0; -} - -/* Add a single service or proto name prepending an undescore (_), - * according to rfc2782 rules. - * Return 0 or the label length. - * Routing assumes dn holds enouth space for a single DN label. */ -static unsigned add_sname(dnsc_t *dn, const char *sn) { - unsigned l; - l = dns_ptodn(sn, 0, dn + 1, DNS_MAXLABEL-1, NULL); - if (l <= 1 || l - 2 != dn[1]) - /* Should we really check if sn is exactly one label? Do we care? */ - return 0; - dn[0] = l - 1; - dn[1] = '_'; - return l; -} - -/* Construct a domain name for SRV query from the given name, service and - * protocol (service may be NULL in which case protocol isn't used). - * Return negative value on error (malformed query), - * or addition query flag(s) to use. - */ -static int -build_srv_dn(dnsc_t *dn, const char *name, const char *srv, const char *proto) -{ - unsigned p = 0, l; - int isabs; - if (srv) { - l = add_sname(dn + p, srv); - if (!l) - return -1; - p += l; - l = add_sname(dn + p, proto); - if (!l) - return -1; - p += l; - } - l = dns_ptodn(name, 0, dn + p, DNS_MAXDN - p, &isabs); - if (!l) - return -1; - return isabs ? DNS_NOSRCH : 0; -} - -struct dns_query * -dns_submit_srv(struct dns_ctx *ctx, - const char *name, const char *srv, const char *proto, - int flags, dns_query_srv_fn *cbck, void *data) { - dnsc_t dn[DNS_MAXDN]; - int r = build_srv_dn(dn, name, srv, proto); - if (r < 0) { - dns_setstatus (ctx, DNS_E_BADQUERY); - return NULL; - } - return - dns_submit_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r, - dns_parse_srv, (dns_query_fn *)cbck, data); -} - -struct dns_rr_srv * -dns_resolve_srv(struct dns_ctx *ctx, - const char *name, const char *srv, const char *proto, int flags) -{ - dnsc_t dn[DNS_MAXDN]; - int r = build_srv_dn(dn, name, srv, proto); - if (r < 0) { - dns_setstatus(ctx, DNS_E_BADQUERY); - return NULL; - } - return (struct dns_rr_srv *) - dns_resolve_dn(ctx, dn, DNS_C_IN, DNS_T_SRV, flags | r, dns_parse_srv); -} diff --git a/deps/udns/udns_rr_txt.c b/deps/udns/udns_rr_txt.c deleted file mode 100644 index ecc71f0..0000000 --- a/deps/udns/udns_rr_txt.c +++ /dev/null @@ -1,98 +0,0 @@ -/* $Id: udns_rr_txt.c,v 1.15 2006/11/28 22:45:20 mjt Exp $ - parse/query TXT records - - Copyright (C) 2005 Michael Tokarev - This file is part of UDNS library, an async DNS stub resolver. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library, in file named COPYING.LGPL; if not, - write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA - - */ - -#include -#include -#include -#include "udns.h" - -int -dns_parse_txt(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end, - void **result) { - struct dns_rr_txt *ret; - struct dns_parse p; - struct dns_rr rr; - int r, l; - dnsc_t *sp; - dnscc_t *cp, *ep; - - assert(dns_get16(cur+0) == DNS_T_TXT); - - /* first, validate the answer and count size of the result */ - l = 0; - dns_initparse(&p, qdn, pkt, cur, end); - while((r = dns_nextrr(&p, &rr)) > 0) { - cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend; - while(cp < ep) { - r = *cp++; - if (cp + r > ep) - return DNS_E_PROTOCOL; - l += r; - cp += r; - } - } - if (r < 0) - return DNS_E_PROTOCOL; - if (!p.dnsp_nrr) - return DNS_E_NODATA; - - /* next, allocate and set up result */ - l += (sizeof(struct dns_txt) + 1) * p.dnsp_nrr + dns_stdrr_size(&p); - ret = malloc(sizeof(*ret) + l); - if (!ret) - return DNS_E_NOMEM; - ret->dnstxt_nrr = p.dnsp_nrr; - ret->dnstxt_txt = (struct dns_txt *)(ret+1); - - /* and 3rd, fill in result, finally */ - sp = (dnsc_t*)(ret->dnstxt_txt + p.dnsp_nrr); - for(dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr) > 0; ++r) { - ret->dnstxt_txt[r].txt = sp; - cp = rr.dnsrr_dptr; ep = rr.dnsrr_dend; - while(cp < ep) { - l = *cp++; - memcpy(sp, cp, l); - sp += l; - cp += l; - } - ret->dnstxt_txt[r].len = sp - ret->dnstxt_txt[r].txt; - *sp++ = '\0'; - } - dns_stdrr_finish((struct dns_rr_null *)ret, (char*)sp, &p); - *result = ret; - return 0; -} - -struct dns_query * -dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags, - dns_query_txt_fn *cbck, void *data) { - return - dns_submit_p(ctx, name, qcls, DNS_T_TXT, flags, - dns_parse_txt, (dns_query_fn *)cbck, data); -} - -struct dns_rr_txt * -dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags) { - return (struct dns_rr_txt *) - dns_resolve_p(ctx, name, qcls, DNS_T_TXT, flags, dns_parse_txt); -} diff --git a/lib/dns.js b/lib/dns.js index cd7bc81..6794ef4 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -1,4 +1,72 @@ -var dns = process.binding('dns'); +var dns = process.binding('cares'); + + +var watchers = {}; +var activeWatchers = {}; + + +var timer = new process.Timer(); + +timer.callback = function () { + for (var socket in activeWatchers) { + var s = parseInt(socket); + channel.processFD( watchers[socket].read ? s : dns.SOCKET_BAD + , watchers[socket].write ? s : dns.SOCKET_BAD + ); + } + updateTimer(); +} + + +function updateTimer() { + timer.stop(); + + for (var socket in activeWatchers) { // if !empty(activeWatchers) + var max = 20000; + var timeout = channel.timeout(max); + + timer.start(timeout, 0); + + return; + } +} + + +var channel = new dns.Channel({SOCK_STATE_CB: function (socket, read, write) { + var watcher; + + if (socket in watchers) { + watcher = watchers[socket].watcher; + } else { + watcher = new process.IOWatcher(); + watchers[socket] = { read: read + , write: write + , watcher: watcher + }; + + watcher.callback = function(read, write) { + channel.processFD( read ? socket : dns.SOCKET_BAD + , write ? socket : dns.SOCKET_BAD + ); + updateTimer(); + } + } + + watcher.set(socket, read == 1, write == 1); + + if (!(read || write)) { + watcher.stop(); + delete activeWatchers[socket]; + return; + } else { + watcher.start(); + activeWatchers[socket] = watcher; + } + + updateTimer(); +}}); + + exports.resolve = function (domain, type_, callback_) { var type, callback; @@ -19,38 +87,64 @@ exports.resolve = function (domain, type_, callback_) { } } -exports.resolve4 = dns.resolve4; -exports.resolve6 = dns.resolve6; -exports.resolveMx = dns.resolveMx; -exports.resolveTxt = dns.resolveTxt; -exports.resolveSrv = dns.resolveSrv; -exports.reverse = dns.reverse; - -// ERROR CODES - -// timeout, SERVFAIL or similar. -exports.TEMPFAIL = dns.TEMPFAIL; -// got garbled reply. -exports.PROTOCOL = dns.PROTOCOL; +exports.getHostByName = function (domain, callback) { + channel.getHostByName(domain, dns.AF_INET, callback); +}; -// domain does not exists. -exports.NXDOMAIN = dns.NXDOMAIN; +// Easy DNS A/AAAA look up +exports.lookup = function (domain, callback) { + var addressType = dns.isIP(domain); + if (addressType) { + process.nextTick(function () { + callback(null, domain, addressType); + }); + } else { + channel.getHostByName(domain, dns.AF_INET, function (err, domains4) { + if (domains4 && domains4.length) { + callback(null, domains4[0], 4); + } else { + channel.getHostByName(domain, dns.AF_INET6, function (err, domains6) { + if (domains6 && domains6.length) { + callback(null, domains6[0], 6); + } else { + callback(err, []); + } + }); + } + }); + } +}; -// domain exists but no data of reqd type. -exports.NODATA = dns.NODATA; -// out of memory while processing. -exports.NOMEM = dns.NOMEM; +exports.resolve4 = function(domain, callback) { channel.query(domain, dns.A, callback) }; +exports.resolve6 = function(domain, callback) { channel.query(domain, dns.AAAA, callback) }; +exports.resolveTxt = function(domain, callback) { channel.query(domain, dns.TXT, callback) }; +exports.resolveSrv = function(domain, callback) { channel.query(domain, dns.SRV, callback) }; +exports.reverse = function(domain, callback) { channel.query(domain, dns.PTR, callback) }; +exports.resolveNs = function(domain, callback) { channel.query(domain, dns.NS, callback) }; -// the query is malformed. -exports.BADQUERY = dns.BADQUERY; var resolveMap = { - 'A': exports.resolve4, + 'A' : exports.resolve4, 'AAAA': exports.resolve6, - 'MX': exports.resolveMx, - 'TXT': exports.resolveTxt, - 'SRV': exports.resolveSrv, - 'PTR': exports.reverse, + 'TXT' : exports.resolveTxt, + 'SRV' : exports.resolveSrv, + 'PTR' : exports.resolvePtr, + 'NS' : exports.resolveNs, }; + +// ERROR CODES +exports.NODATA = dns.NODATA; +exports.FORMERR = dns.FORMERR; +exports.BADRESP = dns.BADRESP; +exports.NOTFOUND = dns.NOTFOUND; +exports.BADNAME = dns.BADNAME; +exports.TIMEOUT = dns.TIMEOUT; +exports.CONNREFUSED = dns.CONNREFUSED; +exports.NOMEM = dns.NOMEM; +exports.DESTRUCTION = dns.DESTRUCTION; + +exports.NOTIMP = dns.NOTIMP; +exports.EREFUSED = dns.EREFUSED; +exports.SERVFAIL = dns.SERVFAIL; diff --git a/lib/dns_cares.js b/lib/dns_cares.js deleted file mode 100644 index 6794ef4..0000000 --- a/lib/dns_cares.js +++ /dev/null @@ -1,150 +0,0 @@ -var dns = process.binding('cares'); - - -var watchers = {}; -var activeWatchers = {}; - - -var timer = new process.Timer(); - -timer.callback = function () { - for (var socket in activeWatchers) { - var s = parseInt(socket); - channel.processFD( watchers[socket].read ? s : dns.SOCKET_BAD - , watchers[socket].write ? s : dns.SOCKET_BAD - ); - } - updateTimer(); -} - - -function updateTimer() { - timer.stop(); - - for (var socket in activeWatchers) { // if !empty(activeWatchers) - var max = 20000; - var timeout = channel.timeout(max); - - timer.start(timeout, 0); - - return; - } -} - - -var channel = new dns.Channel({SOCK_STATE_CB: function (socket, read, write) { - var watcher; - - if (socket in watchers) { - watcher = watchers[socket].watcher; - } else { - watcher = new process.IOWatcher(); - watchers[socket] = { read: read - , write: write - , watcher: watcher - }; - - watcher.callback = function(read, write) { - channel.processFD( read ? socket : dns.SOCKET_BAD - , write ? socket : dns.SOCKET_BAD - ); - updateTimer(); - } - } - - watcher.set(socket, read == 1, write == 1); - - if (!(read || write)) { - watcher.stop(); - delete activeWatchers[socket]; - return; - } else { - watcher.start(); - activeWatchers[socket] = watcher; - } - - updateTimer(); -}}); - - - -exports.resolve = function (domain, type_, callback_) { - var type, callback; - if (typeof(type_) == 'string') { - type = type_; - callback = callback_; - } else { - type = 'A'; - callback = arguments[1]; - } - - var resolveFunc = resolveMap[type]; - - if (typeof(resolveFunc) == 'function') { - resolveFunc(domain, callback); - } else { - throw new Error('Unknown type "' + type + '"'); - } -} - - -exports.getHostByName = function (domain, callback) { - channel.getHostByName(domain, dns.AF_INET, callback); -}; - -// Easy DNS A/AAAA look up -exports.lookup = function (domain, callback) { - var addressType = dns.isIP(domain); - if (addressType) { - process.nextTick(function () { - callback(null, domain, addressType); - }); - } else { - channel.getHostByName(domain, dns.AF_INET, function (err, domains4) { - if (domains4 && domains4.length) { - callback(null, domains4[0], 4); - } else { - channel.getHostByName(domain, dns.AF_INET6, function (err, domains6) { - if (domains6 && domains6.length) { - callback(null, domains6[0], 6); - } else { - callback(err, []); - } - }); - } - }); - } -}; - - -exports.resolve4 = function(domain, callback) { channel.query(domain, dns.A, callback) }; -exports.resolve6 = function(domain, callback) { channel.query(domain, dns.AAAA, callback) }; -exports.resolveTxt = function(domain, callback) { channel.query(domain, dns.TXT, callback) }; -exports.resolveSrv = function(domain, callback) { channel.query(domain, dns.SRV, callback) }; -exports.reverse = function(domain, callback) { channel.query(domain, dns.PTR, callback) }; -exports.resolveNs = function(domain, callback) { channel.query(domain, dns.NS, callback) }; - - -var resolveMap = { - 'A' : exports.resolve4, - 'AAAA': exports.resolve6, - 'TXT' : exports.resolveTxt, - 'SRV' : exports.resolveSrv, - 'PTR' : exports.resolvePtr, - 'NS' : exports.resolveNs, -}; - -// ERROR CODES -exports.NODATA = dns.NODATA; -exports.FORMERR = dns.FORMERR; -exports.BADRESP = dns.BADRESP; -exports.NOTFOUND = dns.NOTFOUND; -exports.BADNAME = dns.BADNAME; -exports.TIMEOUT = dns.TIMEOUT; -exports.CONNREFUSED = dns.CONNREFUSED; -exports.NOMEM = dns.NOMEM; -exports.DESTRUCTION = dns.DESTRUCTION; - -exports.NOTIMP = dns.NOTIMP; -exports.EREFUSED = dns.EREFUSED; -exports.SERVFAIL = dns.SERVFAIL; diff --git a/lib/net.js b/lib/net.js index 7d769e9..9968b66 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1,7 +1,7 @@ var sys = require("sys"); var fs = require("fs"); var events = require("events"); -var dns = require('dns_cares'); +var dns = require('dns'); var kMinPoolSpace = 128; var kPoolSize = 40*1024; diff --git a/src/node.cc b/src/node.cc index 412a666..131b8ca 100644 --- a/src/node.cc +++ b/src/node.cc @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -1186,15 +1185,6 @@ static Handle Binding(const Arguments& args) { binding_cache->Set(module, exports); } - } else if (!strcmp(*module_v, "dns")) { - if (binding_cache->Has(module)) { - exports = binding_cache->Get(module)->ToObject(); - } else { - exports = Object::New(); - DNS::Initialize(exports); - binding_cache->Set(module, exports); - } - } else if (!strcmp(*module_v, "cares")) { if (binding_cache->Has(module)) { exports = binding_cache->Get(module)->ToObject(); @@ -1276,7 +1266,6 @@ static Handle Binding(const Arguments& args) { exports->Set(String::New("buffer"), String::New(native_buffer)); exports->Set(String::New("child_process"),String::New(native_child_process)); exports->Set(String::New("dns"), String::New(native_dns)); - exports->Set(String::New("dns_cares"), String::New(native_dns_cares)); exports->Set(String::New("events"), String::New(native_events)); exports->Set(String::New("file"), String::New(native_file)); exports->Set(String::New("fs"), String::New(native_fs)); diff --git a/src/node_dns.cc b/src/node_dns.cc deleted file mode 100644 index e41c2e3..0000000 --- a/src/node_dns.cc +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright 2009 Ryan Dahl -#include -#include - -#include /* exit() */ -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace node { - -using namespace v8; - -static ev_io io_watcher; -static ev_timer timer_watcher; - -static Persistent errno_symbol; -static Persistent exchange_symbol; -static Persistent priority_symbol; -static Persistent weight_symbol; -static Persistent port_symbol; -static Persistent name_symbol; - -static inline void set_timeout() { - int maxwait = 20; - int wait = dns_timeouts(NULL, maxwait, ev_now(EV_DEFAULT_UC)); - - ev_timer_stop(EV_DEFAULT_UC_ &timer_watcher); - - if (!dns_active(NULL)) return; - - if (wait >= 0) { - ev_timer_set(&timer_watcher, static_cast(wait), 0.0); - ev_timer_start(EV_DEFAULT_UC_ &timer_watcher); - } -} - -static inline void maybe_start() { - ev_io_start(EV_DEFAULT_UC_ &io_watcher); - set_timeout(); -} - -static void ioevent(EV_P_ ev_io *_watcher, int revents) { - assert(revents == EV_READ); - assert(_watcher == &io_watcher); - dns_ioevent(NULL, ev_now(EV_DEFAULT_UC)); - if (!dns_active(NULL)) ev_io_stop(EV_DEFAULT_UC_ &io_watcher); - set_timeout(); -} - -static void timeout(EV_P_ ev_timer *_watcher, int revents) { - assert(revents == EV_TIMEOUT); - assert(_watcher == &timer_watcher); - set_timeout(); -} - -static void ResolveError(Handle *cb) { - HandleScope scope; - int status = dns_status(NULL); - assert(status < 0); - - Local e = Exception::Error(String::NewSymbol(dns_strerror(status))); - Local obj = e->ToObject(); - obj->Set(errno_symbol, Integer::New(status)); - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 1, &e); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } -} - -static void AfterResolveA4(struct dns_ctx *ctx, - struct dns_rr_a4 *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnsa4_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnsa4_ttl); - - Local addresses = Array::New(result->dnsa4_nrr); - for (int i = 0; i < result->dnsa4_nrr; i++) { - HandleScope loop_scope; - - char ip[INET_ADDRSTRLEN]; - dns_ntop(AF_INET, &(result->dnsa4_addr[i]), ip, INET_ADDRSTRLEN); - Local address = String::New(ip); - - addresses->Set(Integer::New(i), address); - } - - Local argv[4] = { Local::New(Null()), addresses, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static void AfterResolveA6(struct dns_ctx *ctx, - struct dns_rr_a6 *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnsa6_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnsa6_ttl); - - Local addresses = Array::New(result->dnsa6_nrr); - for (int i = 0; i < result->dnsa6_nrr; i++) { - HandleScope loop_scope; - - char ip[INET6_ADDRSTRLEN]; - dns_ntop(AF_INET6, &(result->dnsa6_addr[i]), ip, INET6_ADDRSTRLEN); - Local address = String::New(ip); - - addresses->Set(Integer::New(i), address); - } - - Local argv[4] = { Local::New(Null()), addresses, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static void AfterResolveMX(struct dns_ctx *ctx, - struct dns_rr_mx *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnsmx_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnsmx_ttl); - - Local exchanges = Array::New(result->dnsmx_nrr); - for (int i = 0; i < result->dnsmx_nrr; i++) { - HandleScope loop_scope; - - Local exchange = Object::New(); - - struct dns_mx *mx = &(result->dnsmx_mx[i]); - exchange->Set(exchange_symbol, String::New(mx->name)); - exchange->Set(priority_symbol, Integer::New(mx->priority)); - - exchanges->Set(Integer::New(i), exchange); - } - - Local argv[4] = { Local::New(Null()), exchanges, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static void AfterResolveTXT(struct dns_ctx *ctx, - struct dns_rr_txt *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnstxt_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnstxt_ttl); - - Local records = Array::New(result->dnstxt_nrr); - for (int i = 0; i < result->dnstxt_nrr; i++) { - HandleScope loop_scope; - - struct dns_txt *record = &(result->dnstxt_txt[i]); - const char *txt = (const char *)record->txt; - records->Set(Integer::New(i), String::New(txt)); - } - - Local argv[4] = { Local::New(Null()), records, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static void AfterResolveSRV(struct dns_ctx *ctx, - struct dns_rr_srv *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnssrv_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnssrv_ttl); - - Local records = Array::New(result->dnssrv_nrr); - for (int i = 0; i < result->dnssrv_nrr; i++) { - HandleScope loop_scope; - - Local record = Object::New(); - - struct dns_srv *srv = &(result->dnssrv_srv[i]); - record->Set(priority_symbol, Integer::New(srv->priority)); - record->Set(weight_symbol, Integer::New(srv->weight)); - record->Set(port_symbol, Integer::New(srv->port)); - record->Set(name_symbol, String::New(srv->name)); - - records->Set(Integer::New(i), record); - } - - Local argv[4] = { Local::New(Null()), records, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static Handle ResolveA(int type, const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsString()) { - return ThrowException(Exception::Error( - String::New("Argument must be a string."))); - } - - if (!args[1]->IsFunction()) { - return ThrowException(Exception::Error( - String::New("Missing callback argument"))); - } - - String::Utf8Value name(args[0]->ToString()); - - struct dns_query *query; - switch (type) { - case DNS_T_A: - query = dns_submit_a4(NULL, *name, 0, AfterResolveA4, cb_persist(args[1])); - break; - - case DNS_T_AAAA: - query = dns_submit_a6(NULL, *name, 0, AfterResolveA6, cb_persist(args[1])); - break; - - case DNS_T_MX: - query = dns_submit_mx(NULL, *name, 0, AfterResolveMX, cb_persist(args[1])); - break; - - case DNS_T_TXT: - query = dns_submit_txt(NULL, *name, DNS_C_IN, 0, AfterResolveTXT, cb_persist(args[1])); - break; - - case DNS_T_SRV: - query = dns_submit_srv(NULL, *name, NULL, NULL, 0, AfterResolveSRV, cb_persist(args[1])); - break; - - default: - return ThrowException(Exception::Error(String::New("Unsupported type"))); - } - - assert(query); // TODO(ry) better error handling. - - maybe_start(); - - return Undefined(); -} - -static Handle ResolveA4(const Arguments& args) { - return ResolveA(DNS_T_A, args); -} - -static Handle ResolveA6(const Arguments& args) { - return ResolveA(DNS_T_AAAA, args); -} - -static Handle ResolveMX(const Arguments& args) { - return ResolveA(DNS_T_MX, args); -} - -static Handle ResolveTXT(const Arguments& args) { - return ResolveA(DNS_T_TXT, args); -} - -static Handle ResolveSRV(const Arguments& args) { - return ResolveA(DNS_T_SRV, args); -} - -static void AfterReverse(struct dns_ctx *ctx, - struct dns_rr_ptr *result, - void *data) { - assert(ctx == &dns_defctx); - - HandleScope scope; - - Persistent *cb = cb_unwrap(data); - - if (result == NULL) { - ResolveError(cb); - cb_destroy(cb); - return; - } - - /* canonical name */ - Local cname = String::New(result->dnsptr_cname); - - /* Time-To-Live (TTL) value */ - Local ttl = Integer::New(result->dnsptr_ttl); - - Local domains = Array::New(); - - for (int i = 0; i < result->dnsptr_nrr; i++) { - HandleScope loop_scope; - - Local domain = String::New(result->dnsptr_ptr[i]); - domains->Set(Integer::New(i), domain); - } - - Local argv[4] = { Local::New(Null()), domains, ttl, cname }; - - TryCatch try_catch; - - (*cb)->Call(Context::GetCurrent()->Global(), 4, argv); - - if (try_catch.HasCaught()) { - FatalException(try_catch); - } - - cb_destroy(cb); -} - -static Handle Reverse(const Arguments& args) { - HandleScope scope; - - if (args.Length() == 0 || !args[0]->IsString()) { - return ThrowException(Exception::Error( - String::New("Argument must be a string."))); - } - - if (!args[1]->IsFunction()) { - return ThrowException(Exception::Error( - String::New("Missing callback argument"))); - } - - String::Utf8Value ip_address(args[0]->ToString()); - - union { - struct in_addr addr; - struct in6_addr addr6; - } a; - - bool v4; - - if (dns_pton(AF_INET, *ip_address, &a.addr) > 0) { - v4 = true; - } else if (dns_pton(AF_INET6, *ip_address, &a.addr6) > 0) { - v4 = false; - } else { - return ThrowException(Exception::Error(String::New("Invalid IP address"))); - } - - - struct dns_query *query; - - if (v4) { - query = dns_submit_a4ptr(NULL, &a.addr, AfterReverse, cb_persist(args[1])); - } else { - query = dns_submit_a6ptr(NULL, &a.addr6, AfterReverse, cb_persist(args[1])); - } - - assert(query); // TODO(ry) better error handling. - - maybe_start(); - - return Undefined(); -} - -void DNS::Initialize(Handle target) { - if (dns_init(NULL, 0) < 0) { - fprintf(stderr, "Error initializing UDNS context\n"); - exit(-2); - } - - int fd = dns_open(NULL); - - ev_io_init(&io_watcher, ioevent, fd, EV_READ); - ev_init(&timer_watcher, timeout); - - HandleScope scope; - - errno_symbol = NODE_PSYMBOL("errno"); - - exchange_symbol = NODE_PSYMBOL("exchange"); - priority_symbol = NODE_PSYMBOL("priority"); - weight_symbol = NODE_PSYMBOL("weight"); - port_symbol = NODE_PSYMBOL("port"); - name_symbol = NODE_PSYMBOL("name"); - - target->Set(String::NewSymbol("TEMPFAIL"), Integer::New(DNS_E_TEMPFAIL)); - target->Set(String::NewSymbol("PROTOCOL"), Integer::New(DNS_E_PROTOCOL)); - target->Set(String::NewSymbol("NXDOMAIN"), Integer::New(DNS_E_NXDOMAIN)); - target->Set(String::NewSymbol("NODATA"), Integer::New(DNS_E_NODATA)); - target->Set(String::NewSymbol("NOMEM"), Integer::New(DNS_E_NOMEM)); - target->Set(String::NewSymbol("BADQUERY"), Integer::New(DNS_E_BADQUERY)); - - Local resolve4 = FunctionTemplate::New(ResolveA4); - target->Set(String::NewSymbol("resolve4"), resolve4->GetFunction()); - - Local resolve6 = FunctionTemplate::New(ResolveA6); - target->Set(String::NewSymbol("resolve6"), resolve6->GetFunction()); - - Local resolveMx = FunctionTemplate::New(ResolveMX); - target->Set(String::NewSymbol("resolveMx"), resolveMx->GetFunction()); - - Local resolveTxt = FunctionTemplate::New(ResolveTXT); - target->Set(String::NewSymbol("resolveTxt"), resolveTxt->GetFunction()); - - Local resolveSrv = FunctionTemplate::New(ResolveSRV); - target->Set(String::NewSymbol("resolveSrv"), resolveSrv->GetFunction()); - - Local reverse = FunctionTemplate::New(Reverse); - target->Set(String::NewSymbol("reverse"), reverse->GetFunction()); -} - -} // namespace node diff --git a/src/node_dns.h b/src/node_dns.h deleted file mode 100644 index d0da0c9..0000000 --- a/src/node_dns.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2009 Ryan Dahl -#ifndef SRC_DNS_H_ -#define SRC_DNS_H_ - -#include -#include - -namespace node { - -class DNS { - public: - static void Initialize(v8::Handle target); -}; - -} // namespace node -#endif // SRC_DNS_H_ diff --git a/test/disabled/test-dns.js b/test/disabled/test-dns.js index 7121fff..e2a0ac2 100644 --- a/test/disabled/test-dns.js +++ b/test/disabled/test-dns.js @@ -1,6 +1,6 @@ require("../common"); -var dns = require("dns_cares"), +var dns = require("dns"), child_process = require("child_process"), sys = require("sys"); diff --git a/test/simple/test-c-ares.js b/test/simple/test-c-ares.js index e24225e..e84c240 100644 --- a/test/simple/test-c-ares.js +++ b/test/simple/test-c-ares.js @@ -1,6 +1,6 @@ require('../common'); -var dns = require("dns_cares"); +var dns = require("dns"); // Try resolution without callback diff --git a/wscript b/wscript index 1b5f107..fb8f779 100644 --- a/wscript +++ b/wscript @@ -157,10 +157,6 @@ def configure(conf): if not Options.options.system: conf.sub_config('deps/libev') conf.sub_config('deps/c-ares') - if sys.platform.startswith("sunos"): - conf_subproject(conf, 'deps/udns', 'LIBS="-lsocket -lnsl" ./configure') - else: - conf_subproject(conf, 'deps/udns', './configure') else: if not conf.check(lib='v8', uselib_store='V8'): conf.fatal("Cannot find V8") @@ -168,8 +164,6 @@ def configure(conf): conf.fatal("Cannot find libev") if not conf.check(lib='cares', uselib_store='CARES'): conf.fatal("Cannot find c-ares") - if not conf.check(lib='udns', uselib_store='UDNS'): - conf.fatal("Cannot find udns") conf.define("HAVE_CONFIG_H", 1) @@ -213,36 +207,6 @@ def configure(conf): conf.env.append_value('CXXFLAGS', ['-DNDEBUG', '-O3']) conf.write_config_header("config.h") -def build_udns(bld): - default_build_dir = bld.srcnode.abspath(bld.env_of_name("default")) - - default_dir = join(default_build_dir, "deps/udns") - - static_lib = bld.env["staticlib_PATTERN"] % "udns" - - rule = 'cd "%s" && make' - - default = bld.new_task_gen( - target= join("deps/udns", static_lib), - rule= rule % default_dir, - before= "cxx", - install_path= None - ) - - bld.env["CPPPATH_UDNS"] = "deps/udns" - t = join(bld.srcnode.abspath(bld.env_of_name("default")), default.target) - bld.env_of_name('default')["LINKFLAGS_UDNS"] = [t] - - if bld.env["USE_DEBUG"]: - debug_build_dir = bld.srcnode.abspath(bld.env_of_name("debug")) - debug_dir = join(debug_build_dir, "deps/udns") - debug = default.clone("debug") - debug.rule = rule % debug_dir - t = join(bld.srcnode.abspath(bld.env_of_name("debug")), debug.target) - bld.env_of_name('debug')["LINKFLAGS_UDNS"] = [t] - - bld.install_files('${PREFIX}/include/node/', 'deps/udns/udns.h') - def v8_cmd(bld, variant): scons = join(cwd, 'tools/scons/scons.py') @@ -308,7 +272,6 @@ def build(bld): if not bld.env["USE_SYSTEM"]: bld.add_subdirs('deps/libeio deps/libev deps/c-ares') - build_udns(bld) build_v8(bld) else: bld.add_subdirs('deps/libeio') @@ -413,7 +376,6 @@ def build(bld): src/node_io_watcher.cc src/node_child_process.cc src/node_constants.cc - src/node_dns.cc src/node_cares.cc src/node_events.cc src/node_file.cc @@ -431,7 +393,6 @@ def build(bld): deps/v8/include deps/libev deps/c-ares - deps/udns deps/libeio deps/evcom deps/http_parser @@ -443,7 +404,7 @@ def build(bld): node.add_objects = 'cares ev eio evcom http_parser coupling' node.uselib_local = '' - node.uselib = 'RT GNUTLS GPGERROR UDNS CARES V8 EXECINFO DL KVM SOCKET NSL' + node.uselib = 'RT GNUTLS GPGERROR CARES V8 EXECINFO DL KVM SOCKET NSL' else: node.includes = """ src/ @@ -454,7 +415,7 @@ def build(bld): """ node.add_objects = 'eio evcom http_parser coupling' node.uselib_local = 'eio' - node.uselib = 'RT EV GNUTLS GPGERROR UDNS CARES V8 EXECINFO DL KVM SOCKET NSL' + node.uselib = 'RT EV GNUTLS GPGERROR CARES V8 EXECINFO DL KVM SOCKET NSL' node.install_path = '${PREFIX}/lib' node.install_path = '${PREFIX}/bin'