diff --git a/external/Makefile b/external/Makefile index eba90639..1a148694 100644 --- a/external/Makefile +++ b/external/Makefile @@ -329,6 +329,9 @@ assets: tor polipo jtorctl iptables pluto -zip ../assets/$(APP_ABI)/meek-client.mp3 bin/meek-client -$(STRIP) bin/obfs4proxy -zip ../assets/$(APP_ABI)/obfs4proxy.mp3 bin/obfs4proxy + -$(STRIP) ../libs/$(APP_ABI)/pdnsd + -zip ../assets/$(APP_ABI)/pdnsd.mp3 ../libs/$(APP_ABI)/pdnsd + -rm ../libs/$(APP_ABI)/pdnsd assets-clean: -rm ../assets/$(APP_ABI)/polipo.mp3 @@ -336,6 +339,7 @@ assets-clean: -rm ../assets/$(APP_ABI)/xtables.mp3 -rm ../assets/$(APP_ABI)/meek-client.mp3 -rm ../assets/$(APP_ABI)/obfs4proxy.mp3 + -rm ../assets/$(APP_ABI)/pdnsd.mp3 -rm ../libs/jtorctl.jar #------------------------------------------------------------------------------# diff --git a/jni/Android.mk b/jni/Android.mk index 2dd3ef90..f4af1d97 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -17,6 +17,20 @@ LOCAL_PATH := $(call my-dir) ROOT_PATH := $(LOCAL_PATH) EXTERN_PATH := $(LOCAL_PATH)/../external +######################################################## +## pdnsd library +######################################################## + +include $(CLEAR_VARS) + +PDNSD_SOURCES := $(wildcard $(LOCAL_PATH)/pdnsd/src/*.c) + +LOCAL_MODULE := pdnsd +LOCAL_SRC_FILES := $(PDNSD_SOURCES:$(LOCAL_PATH)/%=%) +LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd -DHAVE_STPCPY + +include $(BUILD_EXECUTABLE) + ######################################################## ## libancillary ######################################################## diff --git a/jni/Application.mk b/jni/Application.mk index 3ac89c03..3e5c8225 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -1,4 +1,4 @@ -APP_ABI := armeabi-v7a arm64-v8a mips x86 +APP_ABI := armeabi armeabi-v7a arm64-v8a mips x86 APP_PLATFORM := android-21 APP_STL := stlport_static NDK_TOOLCHAIN_VERSION := 4.9 diff --git a/jni/pdnsd/AUTHORS b/jni/pdnsd/AUTHORS new file mode 100644 index 00000000..fa0454e4 --- /dev/null +++ b/jni/pdnsd/AUTHORS @@ -0,0 +1,58 @@ +Most of pdnsd was written by Thomas Moestl (tmoestl@gmx.net). +In the "par" versions large parts of the code have been revised +and several features have been added by Paul Rombouts. + +Small parts of this program are based on code that was taken from nmap (IP +checksumming), the isdn4k-utils (ippp interface uptest), glibc 2.1.2 (some +definitions for kernel 2.2.x missing in 2.0 glibcs) and FreeBSD +(SIZEOF_ADDR_IFREQ in netdev.c). +nmap was written by Fyodor. The insd4k-utils were written by Fritz Elfert and +others. The GNU C library (glibc) is copyright by the Free Software +Foundation. + +The following people have contributed code: +Andrew M. Bishop contributed support for server labels +Carsten Block contributed 'configure'-able rc scripts +Stephan Boettcher contributed the SCHEME= option. +P.J. Bostley contributed patches to get pdnsd working on + alpha +Frank Elsner contributed rc script fixes +Christian Engstler contributed patches for SuSE compatability +Bjoern Fischer contributed code to make pdnsd leave the case of names + in the cache unchanged +Torben Janssen contributed RedHat rc scripts +Olaf Kirch contributed a security fix for the run_as() + function +Bernd Leibing contributed fixes to the spec file. +Sourav K. Mandal contributed the autoconf/automake code, gdbm + caching facility and many suggestions +Markus Mohr contributed Debian rc scripts +Alexandre Nunes contributed autoconf fixes +Wolfgang Ocker contributed the server_ip option +Soenke J. Peters contributed patches and suggestions for RedHat + compatability +Roman Shterenzon contributed many helpful hints and patches for + FreeBSD compatability. +Andreas Steinmetz contributed the code for the query_port_start and + query_port_end options (which I changed slightly, + so blame any breakage on me ;) +Marko Stolle contributed the contrib/pdnsd_update.pl script that + makes pdnsd usable in a DHCP setup. +Lyonel Vincent extended the serve_aliases option to support an + arbitrary number of aliases +Paul Wagland contributed a patches for bind9-compatability + and for some memory leaks on error paths. +Sverker Wiberg contributed IPv6 build fixes +Michael Wiedmann contributed the pdnsd-ctl.8 man page. +Ron Yorston contributed the dev-uptest for Linux ppp dial- + on-demand devices +Nikita V. Youshchenko contributed extensions to the "if" uptest +Mahesh T. Pai contributed the pdnsd.8 man page. +Nikola Kotur contributed the Slackware start-up script. +Kiyo Kelvin Lee contributed a patch for Cygwin support. +Rodney Brown contributed a patch for Darwin (Apple Mac OS X) support. +Jan-Marek Glogowski contributed a patch implementing the "use_nss" option. + +Please look into the THANKS file for people who helped me in various ways on +this project. +If this list is incomplete, pease drop me a mail! diff --git a/jni/pdnsd/COPYING b/jni/pdnsd/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/jni/pdnsd/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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 program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/jni/pdnsd/COPYING.BSD b/jni/pdnsd/COPYING.BSD new file mode 100644 index 00000000..99fe14ae --- /dev/null +++ b/jni/pdnsd/COPYING.BSD @@ -0,0 +1,26 @@ +A small part of the pdnsd source is licensed under the following BSD-style +license: + +Copyright (C) 2001 Thomas Moestl + +This file is part of the pdnsd package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/jni/pdnsd/ChangeLog b/jni/pdnsd/ChangeLog new file mode 100644 index 00000000..fe774653 --- /dev/null +++ b/jni/pdnsd/ChangeLog @@ -0,0 +1,3304 @@ +2012-04-23 Paul A. Rombouts + + * src/dns_query.c + Refine the return values of p_dns_cached_resolve(), p_dns_resolve() and + p_recursive_query() so that they distinguish between answers found in + the cache and replies obtained by querying other servers. + This, among other things, can be used to prevent data that was recently + obtained from the cache needlessly being added back to the cache. + +2012-04-22 Paul A. Rombouts + + * configure.in + On the Linux platform, check if we can compile and link with the + -pthread flag instead of linking with -lpthread. + +2012-04-21 Paul A. Rombouts + + * src/dns_query.c + When following the delegation chain trying to get an authoritative + answer, pdnsd would answer with SERVFAIL if it failed to get a reply + from the last server in the chain. Instead pdnsd will now use the last + reply in the chain with RCode=0 that raised the AA or RA flag, if there + is one. + +2012-04-19 Paul A. Rombouts + + * src/cache.c + In report_cache_stat(), make copies of volatile data to get a + consistent data set before making calculations with cache size and + entry numbers. + +2012-04-16 Paul A. Rombouts + + * src/netdev.c + If we can't open /proc/net/if_inet6 in is_local_addr() log a warning + message. + +2012-04-15 Paul A. Rombouts + + * src/dns_query.c + The code checking for duplicate IP addresses obtained from NS records + in auth_ok() has been slightly optimized. + +2012-04-12 Paul A. Rombouts + + * src/dns_query.c + When resolving nameservers obtained from NS records, allow pdnsd to use + more than one IP address per nameserver. + In rare cases, using just one IP address for each nameserver will cause + unnecessary resolve failures if the address chosen for each nameserver + happens to be unreachable while the other addresses would lead to + successful resolution, as demonstrated by Yuri Vorobyev. + +2012-03-16 Paul A. Rombouts + + * src/cache.c + When adding RR records one by one to a cache entry using add_cent_rr(), + use the smallest ttl value in case of conflicting ttls. + Code for local/nonlocal conflict resolution has been taken out of + add_cent_rr_int() and put into add_cent_rr() and cr_check_add() + which should be slightly more efficient. + +2012-03-15 Paul A. Rombouts + + * src/dns_query.c + Enforcing strict RFC 2181 compliance by rejecting all the answers + with inconsistent ttl timestamps can cause undesirable resolve failures. + I have tried to implement a more compromising solution, whereby + inconsistent answers that should be normally rejected are still never + cached, but are nevertheless used as intermediary or temporary results + if all else fails. + +2012-03-13 Paul A. Rombouts + + * src/dns_query.c + Fixed a typo in rr_to_cache() that caused pdnsd to fail to compile when + configured with the --enable-strict-rfc2181 option. + Thanks to Gonzalo L. R. for reporting this problem. + Also changed the return value of rr_to_cache() from a simple boolean to + an RC code in order to properly distinguish between memory allocation + errors and time-stamp inconsistencies. + +2012-02-21 Paul A. Rombouts + + * src/dns_query.c + If we have used EDNS in a query and the remote server answered + with rcode "format error", try again with the OPT pseudo-record + removed from the additional section of the query. + + Also fixed a bug in p_exec_query() that caused pdnsd to behave + as if every reply with a non-empty additional section contained + an OPT record. + +2012-02-15 Paul A. Rombouts + + * src/dns_answer.c,src/helpers.c,src/helpers.h,src/icmp.c, + src/ipvers.h,src/main.c,src/netdev.c + Introduced a new macro SEL_IPVER() to reduce some of the clutter in the + code caused by having to support both IPv4 and IPv6. + +2012-01-31 Paul A. Rombouts + + * configure.in + Add AM_PROG_CC_C_O line to configure.in to prevent automake warning. + +2012-01-29 Paul A. Rombouts + + * src/cache.c + In report_cache_stat(), add the average number of bytes used per cache + entry when reporting the cache status, as suggested by M. Galabant. + +2012-01-28 Paul A. Rombouts + + * src/dns_answer.c,src/dns_query.c + Cleaned up the code a bit to avoid warning messages when + compiling with '-Wall -Winline' flags. + +2012-01-18 Paul A. Rombouts + + * src/conff.c + Set the default of the edns_query option to false. + +2011-07-31 Paul Rombouts + + * src/cache.c + Use a slightly more sophisticated merge-sort algorithm in sort_rrl(). + +2011-05-09 Paul Rombouts + + * src/dns_answer.c + In compose_answer(), also add an OPT pseudo-RR to the additional section + of a NXDOMAIN reply when appropriate. + +2011-05-08 Paul Rombouts + + * src/cache.c,src/cache.h,src/dns_query.c,src/status.c + Make the dns_cent_t struct more compact by putting the fields that are + only used for either non-existent or existent domains, but not both, + into a union so that these fields can share memory. + When saving the cache to file, only write the TTL and time-stamp for + a whole domain when it is negatively cached. + +2011-05-06 Paul Rombouts + + * src/cache.c,src/cache.h,src/dns_query.c + At the request of Andrei Caraman, the TTL of a negatively cached domain + is now adjusted in accordance with the min_ttl and max_ttl options, just + as it is done for (negatively) cached records. + Additional change to the TTL policy is that for negative records (and + negative domains) the neg_ttl setting overrides min_ttl if + neg_ttl < min_ttl. + +2011-04-26 Paul Rombouts + + * src/conf-parser.c + Fixed memory leak that can occur when the configuration file is reloaded + and an error is encountered while parsing the definition of a TXT + record. + +2011-03-21 Paul Rombouts + + * src/make_rr_types_h.pl,src/cache.h,src/cache.c,src/dns_answer.c + Introduced arrays rrmuiterlist and rrcachiterlist to make iterating + over all possible RR types in a cache entry in strict ascending order + a little more efficient. + +2011-03-09 Paul Rombouts + + * src/dns_query.c,src/conf-parser.c,src/conf-keywords.h + Implemented a new config option "outgoing_ip", which + makes it possible to bind outgoing connections to + a specific interface. + +2011-02-21 Paul Rombouts + + * src/netdev.c + Fixed UDP socket descriptors leak in the implementation of + is_local_addr() for the FreeBSD platform. Thanks to Ashish Shukla for + reporting this bug. + +2011-02-14 Paul Rombouts + + * src/cache.c + In purge_all_rrsets(), also free the rrext array if it has become empty after + purging all the RR sets. + +2011-02-04 Paul Rombouts + + * src/conff.c,src/conff.h,src/conf-parser.c,src/conf-keywords.h, + src/dns_query.c,src/dns_query.h,src/servers.c + Changed "edns_query" from a "global" option to a "server" + configuration option. + +2011-02-04 Paul Rombouts + + * src/conff.c,src/conff.h,src/dns_query.c,src/dns_query.h,src/servers.c, + src/conf-parser.c + The query uptest sometimes fails because some DNS servers are configured + to ignore empty queries. The new config option "query_test_name" makes + it possible to query for a specific name instead. + +2011-02-01 Paul Rombouts + + * src/dns_query.c + When processing a reply from a remote name server which seems to delegate + to other name servers, check if the names for which NS records have + been supplied have locally defined NS records. If so, the local + records will now override those supplied by the remote server. + +2011-01-31 Paul Rombouts + + * src/conf-parser.c + Added support for defining TXT records in the configuration file. + +2011-01-30 Paul Rombouts + + * src/dns_query.c + Do not cache additional records from a response that is rejected because + it contains IP addresses in the reject list, even when the reply + is processed as a NXDOMAIN reply. + +2011-01-25 Paul Rombouts + + * src/conf-parser.c + Modified the function scan_string() to allow back-slashed escape + sequences in strings. + +2011-01-21 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c,src/conff.h,src/conff.c, + src/conf-parser.c + Added support for EDNS (Extension mechanisms for DNS). + Currently this is only useful for allowing UDP message sizes + to be larger than 512 bytes. + +2011-01-20 Paul Rombouts + + * src/dns_answer.c + To avoid frequent reallocs when composing a DNS reply message, + grow the message buffer in multiples of a certain minimum chunk size. + +2011-01-19 Paul Rombouts + + * src/dns.c,src/dns.h,src/dns_answer.c + Extended debugging info with DNS-message lengths and flags of incoming + messages. + +2011-01-17 Paul Rombouts + + * src/conff.c,src/conff.h,src/conf-parser.c,src/dns_answer.c + Made "ignore_cd" option obsolete. It is now effectively always on. + +2010-12-27 Paul Rombouts + + * src/cache.c,src/cache.h,src/dns_answer.c,src/dns_query.c, + src/make_rr_types.pl,src/rr_types.in,src/rr_types.c + The array of pointers to rr_set_t structs in the dns_cent_t struct + contains mostly null pointers in practice, so is somewhat + inefficient in storage usage. This problem is exacerbated if we add + support for caching more RR-types. To ameliorate to the problem + I have decided to split the array in two, with one part fixed in the + dns_cent_t struct as before, and an extension part that will be + separately allocated, if necessary. If the extension part is used only + for very rarely cached types, in most cases the extension array will not + need to be allocated thus hopefully saving memory overall. + The lookup tables which are necessary to support the new cache entry + structure are cumbersome to write by hand, so I have written a perl + script to do this automatically. As an additional benefit, which RR + types are cache-able is now configurable for each type separately via + rr_types.in. + +2010-03-14 Paul Rombouts + + * src/dns_query.c + Using randomized source ports for outgoing queries in IPv6 mode failed + with the warning "Out of ports in the range 1024-65535, dropping query!", + because the pdnsd tried to bind to the fixed port for incoming queries, + instead of the dynamically chosen port. This is a very old bug, but it + has only become apparent since source port randomization has become the + default. + Thanks to Philip-André Fillion, Phil Sutter, Radoslaw Szkodzinski and + others for reporting this bug and sending patches. + +2009-12-25 Paul Rombouts + + * src/status.c,src/status.h,src/pdnsd-ctl/pdnsd-ctl.c + Add a magic number to pdnsd-ctl command codes to guard against + possible incompatibility between the pdnsd-ctl utility and the + pdnsd server. + +2009-10-18 Paul Rombouts + + * src/dns_query.c + Make root-server discovery a little more fault tolerant, i.e. if some + of the root-server names don't resolve don't necessarily reject the + whole result. + +2009-10-17 Paul Rombouts + + * src/servers.c,src/dns_query.c,src/dns_query.h + Implemented automatic root-server discovery, which can now be configured + by setting "root_server=discover". + +2009-06-14 Paul Rombouts + + * src/dns_query.c,src/consts.c,src/consts.h,src/conf-parser.c + Changed the default behaviour of the "neg_rrs_pol" option. The default + used to be to only cache records negatively in case the AA (authoritive + answer) bit in the reply was set. The new default is to also allow + negative caching in case the reply has the RA (recursion available) bit + set and the query had the RD (recursion desired) bit set. + This gives the behaviour that is usually wanted in case "proxy_only=on" + is set without having to set "neg_rrs_pol=on", which can be more + problematic. The new default can be explicitly set using + "neg_rrs_pol=default". The values "on","off" and "auth" are also + still available. + +2009-06-13 Paul Rombouts + + * src/conff.c,src/conff.h,src/dns_answer.c,src/conf-parser.c,src/conf-keywords.h + Included a patch contributed by Andreas Steinmetz that implements a new + global configuration option "ignore_cd". pdnsd used to check that the CD + bit in the DNS header of queries is zero and return the error code + "format error" if it is not. However, considering the meaning of this + bit today it appears to be harmless to ignore it, so the new "ignore_cd" + is on by default. Setting "ignore_cd=off" gives the earlier strict + behavior. + Also renamed the the Z1, AU, Z2 bits to correspond with their modern names + CD, AD, Z. + +2008-12-19 Paul Rombouts + + * pdnsd-1.2.7/src/dns_query.c + If pdnsd receives a SERVFAIL response with a non-empty answer section, + use the information tentatively if no better response is available. + The previous behaviour was to discard the reply completely, which could + cause failure to resolve some names. + Thanks to Rafal Wijata for providing an example involving PowerDNS servers + replying with CNAME records. + +2008-09-01 Paul Rombouts + + * src/dns_query.c + In p_dns_resolve(), try to reduce the burden on root servers further for + names ending in "arpa". + +2008-08-31 Paul Rombouts + + * src/dns_query.c + In p_exec_query(), if the reply from a remote name server is negative + (either because the rcode is NXDOMAIN or because the answer section + contains no records for the queried name), ignore the remaining records + in the answer section (in particular do not add them to the cache). + +2008-07-29 Paul Rombouts + + * src/conff.c,src/dns_query.c + Made the default of the configuration option query_port_start equal to + 1024. Also improved the algorithm used by pdnsd to select random source + ports to ensure that each (free) port gets an equal chance of being + selected. This should guarantee random source ports in the range + 1024-65535, making pdnsd less vulnerable to some of the issues described + in CERT VU#800113. + The old situation, where pdnsd lets the kernel select the source ports, + is still available by specifying query_port_start=none. + +2008-07-25 Paul Rombouts + + * src/dns_query.c + Fixed a dangling pointer bug in p_exec_query(), which could cause pdnsd + to crash when processing a long reply with many entries in the answer + section. + +2008-05-12 Paul Rombouts + + * src/conf-parser.c,src/conff.c + Added a recursive-depth counter to the read_config_file() and + confparse() functions to prevent the possibility of infinite + recursion when processing include files. + In confparse(), warn when in a server section the root_server option is + set in combination with policy=simple_only or policy=fqdn_only. + +2008-05-10 Paul Rombouts + + * src/ipvers.h + Included a patch contributed by Georg Schwarz which selectively undoes + a Debian patch contributed by Juliusz Chroboczek on platforms for which + the IPV6_RECVPKTINFO macro is not defined (e.g. MacOS X). + +2008-05-08 Paul Rombouts + + * src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + The pdnsd-ctl add command can now also be used to define NS records. + A wildcard record defined with this command now behaves the same way as + one defined in the config file. + +2008-05-07 Paul Rombouts + + * src/conf-parser.c,src/conf-keywords.h,src/conff.c + Added the ability to process "include" sections in the configuration + file. This makes it possible to place local definitions in separate + files and include them from the main configuration file. + +2008-05-05 Paul Rombouts + + * src/conff.c,src/conf-parser.c,src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + Implemented two new pdnsd-ctl commands, which make it easier to add + definitions to the pdnsd cache at run time. "pdnsd-ctl include" is + similar to "pdnsd-ctl config" but only processes configuration sections + that effect the cache and disallows global and server sections. + "pdnsd-ctl eval" directly parses its string arguments as if they were + part of a configuration (include) file. + +2007-09-15 Paul Rombouts + + * src/dns.h,src/dns_answer.c,src/dns_query.c + Changed the declarations of various packed structs, by moving the + __attribute__((packed)) specifiers from the field level to the struct level. + This was necessary to get the correct value for sizeof(rr_hdr_t) when + compiling with gcc for the ARM architecture. + Thanks to Dirk Armbrust for reporting the problem and supplying the solution. + +2007-08-10 Paul Rombouts + + * src/dns_answer.c + Applied a Debian patch contributed by Juliusz Chroboczek which + reportedly fixes a problem with pdnsd running in IPv6 mode + (IPV6_RECVPKTINFO instead of IPV6_PKTINFO). + +2007-08-04 Paul Rombouts + + * src/dns_query.c + When resolving a name recursively, pdnsd would stop querying further + name servers as soon as it received a reply with the authority (aa) flag + set. Unfortunately, it appears this flag is sometimes raised erroneously + in replies. I have implemented a work-around that ignores the aa flag + when there appears to be a clear delegation to a sub-domain. + Thanks to Nico Erfurth for reporting this problem. + + It appears that pdnsd would also fail to consult servers in the authority + section when configured with neg_rrs_pol=on. This has been fixed. + +2007-08-01 Paul Rombouts + + * src/pdnsd-ctl/pdnsd-ctl.c + Made the matching of pdnsd-ctl command names and most of the arguments + case-insensitive. + +2007-07-22 Paul Rombouts + + * src/dns_answer.c + Instead of sharing the responsibility for freeing the answer buffer in + case of an error amongst different functions, only free it in + compose_answer(). + + * configure.in, src/Makefile.am, src/test/Makefile.am + Merged patch contributed by Pierre Habouzit to deal with CFLAGS the + automake way (allowing packagers to override CFLAGS properly). + +2007-07-21 Paul Rombouts + + * src/dns_answer.c + For each target name in a SRV record in the answer section, add + addresses to the additional section of the response, as is recommended + by the RFCs. + +2007-07-14 Paul Rombouts + + * src/list.c,src/list.h + Made modifications to the implementation of dynamic arrays, which + should ensure proper alignment on all supported architectures. + +2007-07-10 Paul Rombouts + + * Upgraded pdnsd's license to GPL version 3. + +2007-07-08 Paul Rombouts + + * src/cache.h,src/dns_query.c + The data field of the rr_bucket_t struct is now aligned such that + it possible to use straightforward assignment to copy IP addresses, + making memcpy unnecessary for this purpose. + +2007-07-07 Paul Rombouts + + * src/dns_query.c + If pdnsd fails to connect to a name server using a IPv6 address, it will + now retry the connection using a IPv4 address, if available. This allows + pdnsd to recover from situations where IPv6 connectivity is temporarily + unavailable, but IPv4 connectivity still functions. + Thanks to Andreas Ferber for reporting this problem. + +2007-07-04 Paul Rombouts + + * src/dns_answer.c + I have reordered the arguments of the add_rr() and related + functions to make them more consistent with each other. + +2007-07-03 Paul Rombouts + + * src/cache.c,src/hash.c + pdnsd will no longer immediately abort in add_dns_hash() if it fails + to allocate memory for a new hash entry. + +2007-07-01 Paul Rombouts + + * src/conff.c,src/conff.h,src/consts.c,src/consts.h, + src/conf-parser.c,src/conf-keywords.h,src/dns_query.c + Implemented the new "reject", "reject_policy" and "reject_recursively" + options for the server section of the configuration file. + + * src/ipvers.h,src/conf-parser.c,src/dns.c,src/status.c, + src/pdnsd-ctl/pdnsd-ctl.c + Allow local AAAA records to be defined even if pdnsd is compiled + without --enable-ipv6, provided there is sufficient support in the + C libraries and --disable-new-rrs was not used. + +2007-06-30 Paul Rombouts + + * src/dns_answer.c + Previously, when the answer buffer was realloced in add_rr(), an + extra 2 bytes used to be reserved, which are unnecessary, as far + as I can tell. I have decided to do without these extra 2 bytes, + which originate from Thomas Moestl's code. As compensation, I have + added extra PDNSD_ASSERT() statements to check that the answer + buffer does not overflow. + +2007-06-27 Paul Rombouts + + * src/status.c, src/pdnsd-ctl/pdnsd-ctl.c + Extended the pdnsd-ctl 'add a' and 'add aaaa' commands to allow + multiple IP addresses to be specified. + +2007-06-25 Paul Rombouts + + * src/conff.c,src/conff.h,src/conf-parser.c,src/conf-keywords.h, + src/dns_query.c + Implemented a new option for the server section of the configuration + file: randomize_servers. + + * src/servers.c + Improved the debug messages in uptest(). + +2007-01-30 Paul Rombouts + + * src/icmp.c + Fixed up the code implementing the ping test in icmp.c, + which was broken for 64-bit systems. + Thanks to Michael Uleysky for reporting this bug. + +2007-01-09 Paul Rombouts + + * src/dns_query.c + auth_ok() now returns 1 if the cache entry has the DF_NEGATIVE flag set, + without providing a list of authoritative servers to continue querying. + Otherwise if we receive a non-authoritative NXDOMAIN reply and pdnsd + is configured with neg_domain_pol=on, pdnsd will continue to try to + get an authoritative answer. The intention is that pdnsd + stops querying as soon as it gets an "unknown domain" answer. + +2006-04-29 Paul Rombouts + + * src/main.c + pdnsd would segfault if it tried to call log_message() (via the + log_warn() and log_error() macros) before the FILE pointer to the debug + output stream was properly initialized. + Thanks to Thomas Cort for discovering this problem and suggesting a fix. + +2006-04-09 Paul Rombouts + + * src/conf-parser.c,src/helpers.c,src/conff.h,src/conff.c + I have included a patch contributed by Jan-Marek Glogowski, that + implements the configuration option "use_nss". With use_nss=off pdnsd + will avoid system functions that may use NSS (i.e. initgroups()), which + may need DNS for LDAP lookups, which can lead to long timeouts and + stalls if pdnsd itself is used for the DNS lookup. + +2006-03-26 Paul Rombouts + + * src/dns_query.c + Negative caching of RR sets is now also supported with lean_query=off. + +2006-03-25 Paul Rombouts + + * src/dns_query.c,src/conf-parser.c,src/main.c + I have implemented a new query method: udp_tcp. With this method a UDP + query is tried first and, if the UDP answer is truncated, the query is + repeated using TCP. This is the behaviour that seems to be recommended + by the DNS standards. However, pdnsd wil not discard the truncated + answer if the TCP requery fails. + +2006-03-24 Paul Rombouts + + * src/dns_answer.c + Previously, pdnsd would add at most one additional A (and AAA) record + for each record in the answer and authority sections. At the request of + Angel Marin, pdnsd will now add all A and AAA records it can find in the + cache for each name that produces additional records. + +2006-01-02 Paul Rombouts + + * src/dns_answer.c + compose_answer() would leak memory if the query contained + an unsupported QTYPE or QCLASS. This has now been fixed. + +2005-12-27 Paul Rombouts + + * configure.in + TCP-query support is now compiled in by default. + It can still be disabled using the configure option + --disable-tcp-queries. + +2005-12-23 Paul Rombouts + + * src/dns_answer.c + Queries received from clients with non-empty answer, authority or + additional sections are now treated as malformed and rejected with + rcode 1 (format error). + +2005-11-06 Paul Rombouts + + * src/conf-parser.c + Time intervals in the configuration files can now be expressed in + seconds, minutes, hours, days and weeks, using the suffixes + s,m,h,d,and w. + +2005-10-14 Paul Rombouts + + * src/consts.c + In the pdnsd configuration file, true/false and yes/no are now accepted + as synonyms for the constants on/off. + +2005-08-24 Paul Rombouts + + * src/helpers.c + I have fixed a potential buffer overflow problem that could occur with + the 'pdnsd-ctl dump' command. + In case of the root domain, the function rhn2str() would write 2 bytes + to the output buffer even if size==1. Theoretically (under pathological + circumstances) this could have allowed the dbuf buffer in the function + dump_cent() to overflow by one byte. + +2005-08-21 Paul Rombouts + + * acconfig.h,src/cache.c,src/conff.c,src/conf-parser.c,src/dns.c, + src/dns_answer.c,src/dns_query.c,src/error.h,src/helpers.c,src/main.c, + status.c + + It appears the newer versions of gcc won't convert a pointer to char + into a pointer to unsigned char and vice versa without complaining. + The changes I have made should get rid of these distracting warning + messages. Unfortunately I had to introduce casts in some cases, + which reduces type safety :-(. + +2005-08-16 Paul Rombouts + + * src/dns.h + Some changes were made to the endianess detection code to + address problems on Mac OS X v10.4 Tiger. + +2005-08-15 Paul Rombouts + + * configure.in + Some changes where made to address the reported problems with the + configure script on Mac OS X v10.4 Tiger. + +2005-08-05 Paul Rombouts + + * src/status.c,src/dns_answer.c + The output of the 'pdnsd-ctl status' command now includes some + statistics on the number of query threads. + +2005-07-29 Paul Rombouts + + * src/main.c + It appears that sigwait() can return EINTR under certain conditions. + This explains the problems reported by Sanjoy Mahajan with strace + and ACPI S3 sleep, which both caused pdnsd to exit prematurely. + The return value of sigwait() is now checked and sigwait() is retried + if the return value is EINTR. + +2005-07-04 Paul Rombouts + + * src/dns_query.c + It appears that some servers that do not support recursive queries + answer with "query refused" instead of "not supported". The + p_exec_query() function now takes that possibility into account. + +2005-07-01 Paul Rombouts + + * src/dns_query.c + In the processing of queries, I will make a distinction between + recoverable errors and non-recoverable ones (typically caused by out of + memory conditions). In the case of non-recoverable errors, no attempt to + query alternative name servers is made. + +2005-06-26 Paul Rombouts + + * src/dns_query.c + In p_recursive_query(), as soon as one of the servers in the q list + replied "no error" or "name error", only this reply was examined and + the other servers in the q list were ignored. Joshua Coombs has brought + to my attention that this strategy sometimes fails when this reply is not + authoritative and doesn't contain any usable references to name servers + in the authority section. + I have modified p_recursive_query() to allow pdnsd to continue querying + the remaining servers in the q list as long as we haven't received an + authoritative answer or usable authority information. This will allow + pdnsd to arrive at the correct answer in some cases where it would + formerly fail. + +2005-06-25 Paul Rombouts + + * src/status.c + The "pdnsd dump" command may now also be given an argument + consisting of a name beginning with a dot. This will dump information + about all names in the cache ending in the given name. An argument + consisting of a name without a leading dot will only give information + about the exact name, as it did before. + +2005-06-24 Paul Rombouts + + * src/servers.c,src/status.c + All uptests are now conducted by the server status thread. If a retest + is requested via a "pdnsd-ctl server", an existing server status thread + is signaled or a new server status thread is spawned if the old one has + exited. This has the effect that a "pdnsd-ctl server label retest" + command will now return immediately without waiting for the tests to + finish. + +2005-06-20 Paul Rombouts + + * src/conf-parser.c,src/servers.c,src/servers.h + At the request of Al-Junaid Walker I have added a new configuration + option for the uptest interval. With "interval=ontimeout" the server is + not tested at startup/reconfig, or at regular intervals, but only after + a DNS query to a server times out. However, once a server is declared + dead it is never considered again unless it is revived using a + "pdnsd-ctl config" or "pdnsd-ctl server" command. + +2005-06-19 Paul Rombouts + + * src/servers.c,src/dns_query.c,src/icmp.c + During an uptest the server configuration data is locked. Especially + with ping or query uptests of unresponsive servers this means that the + execution of "pdnsd-ctl config" or "pdnsd-ctl server" commands can be + delayed for a long time (or even time out). I have made modifications + that allow a "pdnsd-ctl config" or "pdnsd-ctl server" commands to + interrupt pending uptests to allow these commands to proceed without + delay in most cases. + + * src/thread.h + Use the POSIX sigaction() instead of signal() to install signal handlers. + +2005-06-08 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c + I have defined a struct dns_msg_t that includes a message length field. + In the case of sending a DNS message over TCP, we no longer need a + separate write() call to send the message length. This prevents possible + packet fragmentation. + +2005-06-07 Paul Rombouts + + * src/dns_query.c + The query_method=tcp_udp option only used to work with cooperative name + servers, i.e. servers that either send back a TCP reply or explicitly + refuse the TCP connection request. This wasn't sufficiently satisfactory + in practice, because some name servers are completely unresponsive to TCP + connection requests. I have made modifications to allow pdnsd to try UDP + queries in case TCP connections time out. When a short server timeout is + combined with a global timeout that is at least twice as long, this may + allow a query to a name server that only responds to UDP queries to + succeed with query_method=tcp_udp. + +2005-04-20 Paul Rombouts + + * src/cache.c,src/hash.c,src/conff.c,src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + The "pdnsd-ctl empty-cache" command now accepts additional arguments; + these are interpreted as include/exclude names. During execution of the + command the name of each cache entry is matched against the names in the + include/exclude list. If the name ends in a name to be included, the + cache entry is deleted, otherwise not. + This feature was added at the request of Joshua Coombs. + +2005-04-19 Paul Rombouts + + * src/cache.c, src/hash.c + pdnsd will now (temporarily) unlock the cache between emptying hash + buckets, this should allow pdnsd to remain responsive while executing + the "pdnsd-ctl empty-cache" command. However, this only applies to DNS + queries; pdnsd will not accept any new pdnsd-ctl commands while a + pdnsd-ctl command is still running. + +2005-03-29 Paul Rombouts + + * configure.in, src/hash.h + I have added a new configure option --with-hash-buckets=... + This makes it possible to specify a different number of + hash buckets without editing the source files. + +2005-03-17 Paul Rombouts + + * src/error.c + When running in both daemon and debug mode, print warning and + error messages to debug file as well as the syslog. + +2005-03-15 Paul Rombouts + + * src/dns_answer.c + Only call pthread_setspecific() in debug mode, because + pthread_getspecific() is also only used in debug mode. + If pthread_setspecific() fails, treat this as a non-fatal error. + +2005-03-10 Paul Rombouts + + * configure.in + On Linux systems the configure script will now try to detect automatically + whether the system implements the Native POSIX Thread Library, but + the method is not necessarily foolproof. + + * src/dns.c + Local PTR records generated for resolving numeric IPv6 addresses back into + names, are now based on ip6.arpa instead of ip6.int, because the latter domain + will be phased out eventually. + +2005-03-06 Paul Rombouts + + * Makefile.am,src/cache.c + Create an empty cache-file at install time and don't complain about empty + cache files at start up. + +2005-02-20 Paul Rombouts + + * acconfig.h,configure.in,src/conf-parser.c,src/conff.h,src/dns.h, + src/dns_answer.c,src/dns_query.c,src/error.h,src/helpers.h,src/icmp.c, + src/ipvers.h + + I have applied some changes to the code proposed by Rodney Brown to improve + portability. In particular, pdnsd should now compile on the Darwin platform + (Apple Mac OS X). + To support some of these changes, the source package is now built with a + slightly more modern version of autoconf (2.57) and automake (1.6.3). + +2005-01-29 Paul Rombouts + + * src/dns.c,src/dns_answer.c,src/dns_query.c + + I have added some extra debug code to make it easier to discover the + reason that pdnsd considers a query or reply malformed (format error). + +2005-01-12 Paul Rombouts + + * src/dns.c,src/dns_answer.c,src/dns_query.c + + I have extended some debug code contributed by Kiyo Kelvin Lee to dump + the data received by pdnsd in debug mode (queries from clients, replies + from name servers). Because this will give very verbose debug output, + I've arranged it so that this data dump only occurs if pdnsd has been + configured and compiled with --with-debug=9 and pdnsd has been called + with -v9. + + Additionally, in the case that pdnsd rejects a reply from a name server + because it is not well formed, I have refined the debug messages to + distinguish between format errors due to unexpected truncation and + others kinds of format errors. + +2004-10-30 Paul Rombouts + + * src/rr_types.c + I have included some changes proposed by Joseph Pecquet to address + the compilation problems reported by FreeBSD users. + +2004-10-18 Paul Rombouts + + * acconfig.h,configure.in,src/helpers.c,src/helpers.h,src/dns.h + I have merged a patch for CYGWIN support by Kiyo Kelvin Lee into + my version of the code. + +2004-10-15 Paul Rombouts + + * src/cache.c + Invalidating local records with the pdnsd-ctl did not work the way the + documentation described. An invalidated local record would be always be + purged at the next lookup, thus invalidation would practically have the + same effect as deletion. An invalidated local record is of no use at all and + would occupy space until it is purged during a lookup (but not by purge_cache). + The function invalidate_record() now behaves as the documentation describes, i.e. + invalidation of local records has no effect. + +2004-09-27 Paul Rombouts + + * doc/pdnsd.conf.5.in + A new man page describing the format of the pdnsd config file has been + added to the pdnsd package. I've used a customized Perl script to generate + one automatically from the html documentation. + +2004-09-14 Paul Rombouts + + * src/hash.c + The cache entries in a hash chain are now stored in order of increasing long hash + value. The advantage is that if an name is looked up that is not present in the + cache, this can be done by comparing with only half (on average) of the number + of entries in the hash chain. Not a huge speed up, but still worth while, I think. + Additionally, the number of hash computations for each add_cache() call has + been halved. + +2004-09-11 Paul Rombouts + + * src/cache.c + insert_rrl() will no longer add local records to the rr_l list, because + purge_cache() ignores them anyway. + +2004-09-08 Paul Rombouts + + * src/dns.h,src/cache.c,src/dns_query.c,src/dns_answer.c,src/conf-parser.c + I've started using GETINT16,GETINT32,PUTINT16,PUTINT32 macros, which are based + on the NS_GET/NS_PUT macros that can be found in the BIND source, instead of memcpy + for fetching and storing non-aligned integer data. + +2004-09-08 Paul Rombouts + + * src/cache.c,src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + New pdnsd-ctl command: "pdnsd-ctl dump" will print information about all the + entries contained in the cache. + "pdnsd-ctl dump " will only print entries belonging to . + The data fields of the more common rr-types will be printed in human readable + form, the remaining ones in a hexadecimal representation. + With thanks to Dan Jacobson for suggesting this feature. + +2004-08-31 Paul Rombouts + + * src/conf-parser.c + At the suggestion of Dan Tihelka, I have expanded to the server_ip= option + to allow the name of an interface to be specified instead of an IP address. + pdnsd will not bind to the interface name, but will lookup the address the + interface has at start up, and listen on that address. If the address + of the interface changes while pdnsd is running, pdnsd will not notice that. + +2004-08-30 Paul Rombouts + + * src/cache.h,src/cache.c + I've reversed the meaning of the CF_NOAUTH and renamed it CF_AUTH. + I've also added a domain level flag DF_AUTH, which is used to + mark cache entries obtained from authoritave replies in response to + a query of type * (all).. + +2004-08-30 Paul Rombouts + + * src/cache.c + I've changed the format of the cache file. A typical cache entry has empty + sets for most RR types (even more if DNS_NEW_RRS is defined). In the old + format, each empty RR set was represented by a zero byte. + In the new format only non-empty sets are respresented, leading + to a (modest) reduction is size. + +2004-08-28 Paul Rombouts + + * src/conf-parser.c + New option for "rr" sections in the config file: reverse=on/off. + If you want a locally defined name to resolve to a numeric address and vice + versa, you can now achieve this by setting reverse=on before defining the + A record, making it unnecessary to define a seperate PTR record for the reverse + resolving. + +2004-08-20 Paul Rombouts + + * src/cache.h,src/cache.c,src/conf-parser.c,src/dns_query.c + At the request of Daniel Black, I have added support for defining local wildcard records + in pdnsd. The only type supported presently is records beginning with '*.'. + +2004-08-10 Paul Rombouts + + * src/hash.c,src/cache.c,src/dns_query.c,src/dns_answer.c + Sampo Lehtinen has remarked that pdnsd sometimes failed to resolve classless + reversed-delegated IP addresses, and that this has something to do with the fact + that pdnsd did not accept '/' characters in domain names. After reading Sampo's + and Thomas' remarks, and also rfc2317 and some of the rfc's referenced in rfc2317, + I decided pdnsd should place no restrictions at all on the types of characters it + allows in domain names, only on the lengths of the byte sequences. + This led me to make some quite extensive internal changes to pdnsd. Among other + things domain names are now stored in transport format (sequences of bytes preceded + by length bytes) instead of C strings. This is also more efficient because there + is no need any more to convert from one representation to the other, except when + reading the config file, interacting with pdnsd-ctl or running in debug mode. + Conversion between the two representations isn't always possible, though. + For example, domain names in transport format might contain non-printable characters. + These are now printed as escape sequences (three octal digits preceded by a back slash). + Presently there are still restrictions on the characters in the domain names that can + be defined in local records. I doubt this will ever be considered a problem. + +2004-08-02 Paul Rombouts + + * src/dns_query.c + The code for handling NXT records was flawed. A response from a remote server + containing NXT records (even well-formed ones) could cause pdnsd to crash. + The code for handling NAPTR records contained incorrect PDNSD_ASSERT statements, + which could cause pdnsd to abort unnecessarily. + +2004-07-25 Paul A. Rombouts + + * src/list.h,src/list.c,src/dns.c,src/dns_query,src/dns_answer.c + I've noticed that some of the (dynamic) arrays that pdnsd uses are quite sparse. + Instead of using an array structure with elements that are large enough to contain + the largest possible domain name, I've implemented a "list" data structure that + is more compact. The elements of a list can only be accessed sequentially from + beginning to end, but it allows more efficient memory use in case the names are + significantly shorter that the maximum. + +2004-07-22 Paul Rombouts + + * src/conf-parser.c + I've expanded pdnsd's configuration options by adding support in pdnsd for reading + /etc/resolv.conf style files. Instead of specifying IP addresses in a server section, + the option "file=" can be used. + The IP addresses in the lines beginning with "nameserver" will be added to + the list of address for that section, the remaining lines will be ignored. + To avoid the possibility that pdnsd will query itself, local addresses are skipped + (unless pdnsd is configured to listen on a different port number). + +2004-07-21 Paul Rombouts + + * src/cache.h,src/cache.c,src/dns_query.c,src/conf-parser.c + New option for "server" sections in the config file: root_server=on/off. + In case a server section contains only addresses of root servers, which + usually only give the nameservers of top level domains in their reply, + setting root_server=on will enable certain optimizations. This involves using + cached information to reduce queries to the root servers, thus speeding up + the resolving of new names. This option is also necessary to make the + delegation_only option work in combination with root servers. + +2004-07-16 Paul Rombouts + + * src/cache.c,src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + New pdnsd-ctl command: "pdnsd-ctl empty-cache" will make pdnsd delete its entire + cache, freeing all entries. This is useful for debugging purposes, or in situations + where you suspect that stale cache entries are causing you problems, but you are not + sure which ones. + +2004-07-11 Paul Rombouts + + * src/cache.c,src/dns_query.c + I've removed the use of the function add_cache_rr_add(), which was used to + add additional RR records to the cache one at a time. I've changed the code + in dns_query.c such that additional (or off-topic) records are first collected + in arrays of dns_cent_t structures, and then added to the cache using add_cache(). + With this approach only one function, viz. add_cache(), is used for adding + new entries to the cache, which I believe leads to a cleaner programming + interface. Added benefit is that query serial numbers are no longer + necessary. + +2004-07-10 Paul Rombouts + + * src/cache.h,src/cache.c,src/dns_query.c,src/dns_answer.c + I've added two new field to the dns_cent_t struct, namely c_ns and c_soa. + These will be used to remember references to NS and SOA records in the authority + sections of replies from remote name servers. + This information can be used by pdnsd to fill in the authority section of its + own reply. + +2004-06-25 Paul Rombouts + + * src/dns_query.c,src/servers.c,src/consts.c + I've added an new server availability test which can be selected with "uptest=query". + This can be useful as an alternative to "uptest=ping" in case the remote server does not + respond to ICMP_ECHO requests at all, which unfortunately is quite common these days. + "uptest=query" causes pdnsd to send an empty query to remote nameservers. Any well-formed + response (apart from SERVFAIL) within the timeout period will be interpreted as a sign that the + server is "up". + In a sense this new availability test can actually be considered more reliable than the + other ones that pdnsd supports. + With thanks to Juliusz Chroboczek for suggesting this feature. + +2004-06-24 Paul Rombouts + + * src/helpers.c + Don't use getpwnam() while we are multi-threaded, because it returns a pointer to + a statically allocated structure. I will use getpwnam_r() instead, which is thread + safe. Unfortunately there seem to be some portability problems with getpwnam_r(). + For those platforms that lack getpwnam_r(), I will keep the old code with getpwnam() + as an alternative. + +2004-06-23 Paul Rombouts + + * src/servers.c + Check that the number of IP addresses in a server section is nonzero before + testing servers for availability. Otherwise pdnsd could crash in debug mode. + +2004-06-21 Paul Rombouts + + * src/conff.c,src/conf-parser.c,src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + New pdnsd-ctl command: "pdnsd-ctl config" will make pdnsd re-load its configuration file. + In most cases (but there are still some exceptions) this is preferable + to restarting pdnsd after making changes to the configuration file. + An important advantage is that there should be no perceptible interruption in the dns service + when using the reload command. + An alternative config file can be specified with "pdnsd-ctl config ". + +2004-05-31 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c,src/dns_query.h + I've made an adjustment to p_recursive_query() and related functions, so that + when pdnsd chases name servers in pursuit of authoritative records, it avoids + all the name servers already queried for the same name in the recursive calling + chain, not just the servers most recently used. + Although the hops counter will already break any possible cycles, this will + allow pdnsd to detect pathological cycles earlier and waste less resources. + + * src/cache.c + In add_cache(), don't add empty entries to the cache. Empty cache entries + waste memory and are more persistent than non-empty ones, because purge_cache() + cannot get rid of them. + +2004-05-30 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c,src/icmp.c,src/netdev.c + I've removed the calls to getprotobyname() and used the constants IPPROTO_TCP + and IPPROTO_UDP instead. First of all, it doesn't seem very efficient to call + a function repeatedly to look up the same well-known protocol numbers. + More importantly, getprotobyname() stores its results in a statically-allocated + structure and thus cannot be considered thread safe. (getprotobyname_r() + is thread safe, but is not portable.) + +2004-05-27 Paul Rombouts + + * src/dns_answer.c + I've noticed that when pdnsd is restarted shortly after it has answered a TCP + query, it is often not able to bind to the TCP socket again, resulting in a + disabled TCP server thread. The solution appears to be to set the SO_REUSEADDR + socket option before binding the socket. This allows you to use the same port even + if it is busy (in the TIME_WAIT state). + I found the code for this in a patch file from an old Debian package. + +2004-05-20 Paul Rombouts + + * src/dns_query.c + Joseph Pecquet has reported that version 1.1.11 does not compile under FreeBSD v4.x + because the macro ENONET is undefined. I've bypassed the problem by surrounding + the case line using this value with conditional preprocessor directives. + +2004-05-08 Paul Rombouts + + * src/rc/Slackware/rc.pdnsd + I've included a Slackware start-up script contributed by Nikola Kotur. + +2004-05-05 Paul Rombouts + + * doc/pdnsd.8 + I'm very grateful to Mahesh T. Pai for contributing a pdnsd man page, + which was still missing up till now. + +2004-04-30 Paul Rombouts + + * src/servers.c,src/dns_query.c + After considering some suggestions made by Juliusz Chroboczek I have made the + following changes: + + - After receiving a reply from a remote server mark the server up and update the + timestamp so that pdnsd doesn't bother testing this server for availability for a + while. + - After detecting an error with an send/recv call that indicates a server is + unavailable, mark a server down so that pdnsd doesn't bother testing this server + for a while. + - After server timeouts, uptests are never performed by a query/answer thread, + because this may delay the sending of an answer to the client. Instead the + timestamp of a server that needs to be tested for availability is set to zero and + a condition signal is sent to alert the server status thread, which will carry out + the test. Unresponsive servers with uptest=ping will not be marked down + immediately any more, but only after the ping test has definitely failed. + + * src/error.c,src/error.h + I've moved most of the code previously contained in the DEBUG_MSG macro to a new + function debug_msg(). + The DEBUG_MSG macro now simply expands to "if(debug_p) debug_msg();". + This should make the executable a little smaller, and be just as fast when + debugging is off. The DEBUG_MSG macro still expands to nothing if pdnsd is built + without debugging support. + +2004-04-28 Paul Rombouts + + * src/dns_query.h,src/dns_query.c + I've tried to simplify the finite state machine used for processing parallel + queries, by merging the "state" and "nstate" variables used by p_exec_query() and + p_query_sm() resp. into one "state" variable. + By introducing an extra field "iolen" to keep track of the number of bytes read + from or written to a socket, I could also reduce the number of states for TCP + queries. The new code has the additional advantage that it can handle situations + that require multiple read() calls to receive a response. + +2004-04-14 Paul Rombouts + + * src/dns_query.c + I've added an extra check comparing the number if poll/select events actually + handled to the return value of poll/select. This should reduce the chance that + pdnsd will get caught in a busy spin due to unknown remaining bugs. An error + message is logged and an error code is returned when this comparison fails. + +2004-04-13 Paul Rombouts + + * src/dns_query.h,src/dns_query.c + I got rid of the event field in the query_stat_t struct. + I think it is redundant, because its value can be quite simply derived from + the nstate field. + +2004-04-12 Paul Rombouts + + * src/dns_query.c + I appears there was flaw in the code for handling a "Not Implemented" response + from a remote server with the RA (recursion available) bit equal to zero. This + could cause pdnsd to get into a busy spin. I traced the flaw back to Thomas + Moestl's code, so it must be in all the versions of pdnsd I know of. In previous + versions of pdnsd the busy spin would eventually time out. Due to some recent + changes the loop would no longer time out, making the bug more noticeable. + With thanks to Nicolas George for reporting the bug. + + I also discovered a closely related flaw that would cause pdnsd to poll() closed + file descriptors. It usually works out OK in practice, but it is definitively not + the correct way to do it. + + Additionally, I discovered some opportunities to save memory, e.g. by replacing + the nsname buffer in the query_stat_t struct by a pointer to an already existing + copy of a name. + +2004-04-10 Paul Rombouts + + * src/cache.c + Nicolas George remarked that he thought it was strange that subdomains of domains + negated with "neg" sections in the config file were not also negated. I thought that + he had a point, and I've implemented a change so that negating example.com will + now also negate www.example.com, xxx.adserver.example.com, etc. + +2004-04-09 Paul Rombouts + + * src/error.c,src/error.h + I noticed that the code for the log_warn() and log_error() functions was almost + identical, even to the point that log_warn() called syslog() with LOG_ERR + priority. I've merged these two functions into one log_message() function. + +2004-04-08 Paul Rombouts + + * src/main.c,src/conf-parser.c + The -4 and -6 command-line options should now work as advertised. + This wasn't entirely trivial. The rule is that options on the command line + override those in the configuration file. The easiest way to implement this is to + process the command-line options after reading the configuration file. But this + doesn't work for the -4 and -6 options, because the run_ipv4 flag determines how + IP addresses in the config file are parsed. I've inserted some extra tests and + warning messages that will hopefully make this setting nearly foolproof. + + I've added two new command-line options, "-a" and "-i ". + With the -a flag pdnsd will try to detect automatically if IPv6 support is + available on a system, and fall back to IPv4 if not. The -a flag can be used + instead of -4 or -6. + + In IPv6 mode, pdnsd will now automatically convert IPv4 addresses to IPv6-mapped + addresses. The -i option can be used to specify a prefix for this mapping. The + default is ::ffff.0.0.0.0 + There is also a corresponding ipv4_6_prefix= option for the config file. + + In IPv4 mode, if IPv6 support is compiled in, pdnsd will now skip IPv6 addresses + in the config file (except for the server_ip and ping_ip options) with a warning + message. This allows you to have mixed sets of IPv4 and IPv6 address in the same + config file, although in IPv4 mode some server sections may become inactive. + + With thanks to Juliusz Chroboczek for suggesting these changes. + +2004-04-07 Paul Rombouts + + * src/cache.c + I've changed some of the cache-flag definitions to make debugging a little simpler. + Unfortunately, this makes the cache files of previous pdnsd versions incompatible + with the new one. I've introduced a cache version identifier to be added at the + beginning of each cache file. This enables pdnsd to recognize and discard + incompatible cache files. + +2004-04-05 Paul Rombouts + + * src/cache.h,src/cache.c + I've changed the way CACHE_LAT (cache latency, normally 120 secs) is used to + determine whether a cache entry has timed out. Instead of simply adding it to the + ttl (time to live), I use CACHE_LAT if the ttl is less then CACHE_LAT, else the + ttl itself, making CACHE_LAT the minimum ammount of time a cache entry stays in + the cache. + +2004-04-02 Paul Rombouts + + * src/dns_query.c + I've introduced a global timeout parameter. This is the minimum period of time + pdnsd will wait after sending the first query to a remote server before giving + up without having received a reply. + The timeout options in the configuration file are now only minimum timeout intervals. + Setting the global timeout option makes it possible to specify quite short timeout + intervals in the server sections. This will have the effect that pdnsd will start + querying additional servers fairly quickly if the first servers are slow to respond + (but will still continue to listen for responses from the first ones). + This may allow pdnsd to get an answer more quickly in certain situations. + + * src/dns_query.c + When receiving a NXDOMAIN (unknown domain) response from a remote name server, + I think it is still useful to process the authority and additional sections, + so that pdnsd can possibly add a SOA record to its own response. + +2004-04-01 Paul Rombouts + + * src/dns_query.c + In p_recursive_query(), I've slightly changed the way pdnsd does parallel + queries. Active queries or not canceled until we have received a useful response + from a remote name server, or all the queries have failed or timed out. + Thus the par_queries parameter is no longer the maximum number of parallel + queries, but rather the increment with which the number of parallel queries is + increased when the previous set has timed out. + In the worst case all the servers in the list of available servers will be queried + simultaneously. We may be wasting more system resources this way, but the advantage + is that we have a greater chance of catching a reply. + After all, if we wait longer anyway, why not for more servers. + +2004-03-31 Paul Rombouts + + * src/dns_answer.c + I've noticed that in compose_answer() that while adding the name in the query + section it was not passed through compress_name(). While it is true that the + first name occurrence cannot be compressed, it is still sensible to process the + query name with compress_name() so that the offset can be stored and provide + additional opportunities for future compressions. + I've tested this with dig and the responses of pdnsd are now usually a little + smaller in size or can hold more information within the 512 byte limit. + +2004-03-30 Paul Rombouts + + * src/cache.c + I've noticed that pdnsd stored rr records (of the same type) in reverse order + in the cache. + Although I don't see anything inherently wrong with that, I think it's neater to + store them in the order they are processed. + +2004-03-29 Paul Rombouts + + * src/cache.c + I've rearranged the order of the arguments of some of the functions in cache.c + to obtain a more consistent calling interface. + + * src/dns_answer.c + I've noticed that pdnsd would only add NS records to an authority section if it could + find such records matching the queried name (or the last CNAME in the answer) exactly. + However, I understand that a server should try to give NS records as close as possible + to the target name in the naming hierarchy. + I also understand that if a domain name is reported as nonexisting, or no record of + the requested type exists, it is customary to provide a SOA record, searching up the + name hierarchy if necessary. + I've tried to implement this in compose_answer(), although with some limitations. + I only look in the cache, I don't search more then three levels up, and stop before + the top level. + +2004-03-28 Paul Rombouts + + * src/cache.c,src/dns_answer.c + There were some issues with add_cache_rr_add(). + + First of all, the way it was used in rr_to_cache() (or rather not used) meant + that if an "off topic" record was added for a name that lacked an entry in the + cache, the rr set would be created with an incorrect serial number (namely zero). + I've rewritten add_cache_rr_add so that it can create new cache entries if necessary. + This simplifies the code in rr_to_cache() and ensures correct serial numbers. + + Secondly, in add_cache_rr_add() the ttl was compared with that of an existing rrset + without adjusting for the min_ttl and max_ttl options. This could lead to all the + previous records being deleted, retaining only the last one. + +2004-03-27 Paul Rombouts + + * src/dns_answer.c + In compose_answer(), if the rd (recursion desired) bit is set in the query + and the response contains a CNAME record (while a different type of record was + requested), always do a recursive query on the CNAME, even if we have already + added a record of the requested type to the response. + Failing to honor the rd bit will cause some resolver libraries to complain, + even if the answer contains a record of the requested type. + + I've slightly changed the calling interfaces of add_to_response() and add_rrset() + to make them more consistent and efficient. + + In add_rrset() I've fixed a memory leak on one of the error paths. + + In add_additional_rr(), the return value of add_rr() was not checked. + If add_rr() fails, it will free *ans, and functions higher up the calling + chain could be referencing freed memory. + + I've fixed a potential referencing of freed memory or double freeing in add_additional_a(). + If a call of add_additional_rr() fails, it will free *ans. + Previously, add_additional_rr() could be called a second time, in which case + the second call would be referencing freed memory or freeing it a second time.. + +2004-03-23 Paul Rombouts + + * configure.in, src/Makefile.in,src/pdnsd-ctl/Makefile.in,src/test/Makefile.in + Frédéric L. W. Meunier has reported that configure --srcdir option (for building + in directory separate from the source directory) was broken. + Should be fixed now. + +2004-03-20 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c,src/helpers.c,src/icmp.c,src/main.c,src/netdev.c,src/ipvers.h,src/test/if_up.c,src/test/is_local_addr.c,src/test/tping.c,src/test/random.c,src/conf-parser.c + I've eliminated the global variable run_ipv6 from the code. + Enabling both the IPv4 and IPv6 protocols at the same time is not supported + in pdnsd, so the value of run_ipv6 (if it is defined) is simply !run_ipv4. + + * src/dns.c,src/test/is_local_addr.c,src/test/tping.c + It appears the option to compile pdnsd without IPv4 support (i.e. only IPv6 + support) was broken. Should be fixed now. + +2004-03-19 Paul Rombouts + + * src/cache.c + I've discovered an incorrect use of cache locks in lookup_cache(). + We only read locks in place, it is possible for purge_cent() to delete a cache + entry while another thread is trying to read it at the same time, which could + lead to trouble. I've rewritten purge_cent() so that it can be used to test + whether something needs to be purged without actually deleting anything. + If something needs to be deleted, purge_cent() will be called again with + the proper read/write locks in place, excluding access to the cache for all + other threads. + +2004-03-18 Paul Rombouts + + * src/cache.c + I've added a new function sort_rrl() for sorting the rr_l list using a merge-sort + algorithm. Usually the insertion sort used by insert_rrl() is good enough, because + new entries belong near the end most of the time. Reading entries from disk forms + an exception, though, because the rrsets in the file are completely out of order + w.r.t. timestamps, leading to quadratic time complexity of the insertion sort method. + In that case it should be faster to simply append items at the end of the rr_l list + and sort using a more efficient algorithm afterwords. + pdnsd now seems to start up noticeably faster when reading large cache files. + I've also considered using a more sophisticated data structure than a doubly linked + list, but this will add considerable complexity to the code and use more memory. + +2004-03-13 Paul Rombouts + + * src/dns_answer.c + Changed a declaration in udp_answer_thread() so that the buffer used for passing + control messages on to sendmsg() is exactly the right size, instead of an arbitrary + 512 bytes. + Also initialized the msg_flags of the struct msghdr passed on to sendmsg() to zero, + to keep Valgrind from complaining about uninitialized bytes. + +2004-03-12 Paul Rombouts + + * src/icmp.c + Fixed an incorrect call to select() in ping4(). A file descriptor set for detecting + exceptions was initialized but not passed on to select(). This would lead subsequent + code always to behave as if an IO exception had occurred. + Valgrind seems to indicate that when a poll() call times out and returns 0, + the revents field of the struct pollfd is not necessarily set. + I've changed the code to check that the return value is > 0 before examining the + revents field. + +2004-02-06 Paul Rombouts + + * src/conf-parser.c,src/conf-parser.h,src/conf-keywords.h + I've rewritten the parser for the configuration file in C from scratch. + (f)lex and yacc/bison are no longer needed to build pdnsd. + +2004-01-16 Paul Rombouts + + * src/main.c + Load the cache from disk without locking cache access because pdnsd + is still single-threaded at that point. + +2004-01-15 Paul Rombouts + + * src/cache.c,src/hash.c + Moved the responsibility for freeing the cache entries referred by + the hash buckets from destroy_cache() to free_dns_hash() (which is called + by destroy_cache()). Previously, the cache and hash tables were already + completely destroyed by the time free_dns_hash() was called, and there was + nothing left for free_dns_hash() to free. + +2004-01-14 Paul Rombouts + + * src/hash.c,src/make_hashconvtable.c + The hash conversion table is now generated at build time instead + of at run time when pdnsd is started up. + +2004-01-13 Paul Rombouts + + * src/dns.c + In add_host() fixed incorrect generation of IPV6 type of name for PTR record + due to use of && instead of & as masking operator. + +2004-01-13 Paul Rombouts + + * src/icmp.c, src/dns_answer.c + Use unsigned long instead of int error counters to reduce the danger + of wraparound. + +2004-01-06 Paul Rombouts + + * src/main.c,src/thread.c,src/thread.h,src/server.c,src/status.c,src/dns_answer.c + Initialize a global thread attribute object in main.c and use it to create all the detached + threads, instead of initializing a separate attribute object for each new thread. + +2004-01-06 Paul Rombouts + + * src/dns_answer.c + Check the return value of pthread_create() in udp_server_thread() + and tcp_server_thread() to ensure that a new answer thread has actually + been created and free resources if not. + +2004-01-04 Paul Rombouts + + * src/helpers.c,src/cache.c,src/conff.c,src/status.c + Stop writing to control socket after an error has been detected. + +2004-01-03 Paul Rombouts + + * src/pdnsd-ctl/pdnsd-ctl.c + Tried to make the error messages of pdnsd-ctl more helpful. + The complete usage description is now only printed if the 'help' command + is used. For problems with other commands a much shorter message is generated + specific for that command. + +2004-01-02 Paul Rombouts + + * src/helpers.h + Changed the definition of rhnlen(). For valid data this will make no difference, + but it may change the behaviour of pdnsd in certain error situations. + +2004-01-02 Paul Rombouts + + * src/dns.c + Optimized compress_name() some more. + +2004-01-02 Paul Rombouts + + * src/dns_answer.c + Additional code cleanup in compose_answer(). + +2004-01-01 Paul Rombouts + + * doc/pdnsd-ctl.8 + Updated the pdnsd-ctl man page. + +2003-12-31 Paul Rombouts + + * src/pdnsd-ctl/pdnsd-ctl.c + Cleaned up some code. + +2003-12-31 Paul Rombouts + + * src/status.c,src/conff.h,src/conff.c + Some further code cleanup in status.c. + Labels for server sections are no longer limited to 32 chars, + but can have arbitrary length. The string that is used to specify + new DNS-addresses with the "pdnsd-ctl server" command can now also + have arbitrary length. + +2003-12-30 Paul Rombouts + + * doc/html/doc.html + Added information about CNAME and MX resource records, that were + previously undocumented. + +2003-12-26 Paul Rombouts + + * src/dns_query.c + Removed the function p_dns_resolve_from(). This function was essentially + a call to p_recursive_query() with a dummy nocache argument. + p_recursive_query() can now be called with nocache=NULL instead. + +2003-12-26 Paul Rombouts + + * src/dns_query.c + Using a variable length array instead of an malloced buffer to hold the struct pollfd array + in p_recursive_query(). This has the potential for causing portability problems, but I + think that's unlikely because almost all the major C compilers I work with support variable + length arrays nowadays. + +2003-10-18 Paul Rombouts + + * src/helpers.h,src/helpers.c + Fixed a mistake that caused a compile error when using the --with-random-device + configuration option. + Thanks to Daniel Black for reporting this bug. + +2003-10-02 Paul Rombouts + + * conf-lex.l.in,src/conf-parse.y,src/conff.h,src/conff.c,src/dns_query.c + Made the "delegation_only" feature configurable. + +2003-09-25 Paul Rombouts + + * src/helpers.c,src/helpers.h + Added alternative implementations of strdup, strndup, stpcpy, getline and asprintf + in an effort to make the code more portable. + +2003-09-22 Paul Rombouts + + * src/helpers.c,src/conf-parse.y + Made some changes to the parser of the configuration file so that domain names + missing a dot at the end will be tolerated. + +2003-09-21 Paul Rombouts + + * src/dns_query.c + Implemented a first version of the "delegation-only" feature. + It has been "hard-coded" to work for "com" and "net" zones, + and is not yet configurable. + +2003-09-21 Paul Rombouts + + * src/dns.c + Rewrote domain_match(). Also changed the way it is used. + I believe it has a cleaner semantics now. + +2003-09-21 Paul Rombouts + + * src/dns_query.c + Changed the order of the arguments of p_exec_query() and p_recursive_query() + to make it more consistent with the other functions. + +2003-09-18 Paul Rombouts + + * src/dns_answer.c + Reordered the code in process_query() so that a buffer for an error response is + allocated only when it is actually needed. + +2003-09-17 Paul Rombouts + + * src/cache.c + Added parentheses to correct mistaken operator precedence assumption in cache.c. + !cent->flags&DF_NEGATIVE is parsed as (!(cent->flags))&DF_NEGATIVE but I think + what Thomas Moestl must have intended was !((cent->flags)&DF_NEGATIVE). + +2003-09-12 Paul Rombouts + + * src/dns_query.c + Fixed a mistake which caused the effect of the proxy_only option to be reversed. + Thanks to Andrew M. Bishop for reporting this bug. + +2003-09-11 Paul Rombouts + + * src/helpers.c + Rewrote str2rhn() and rhn2str(). + +2003-09-10 Paul Rombouts + + * src/dns.c + Rewrote read_hosts(), the function that reads /etc/hosts-style input. + I believe the parsing algorithm is more robust now. + +2003-09-09 Paul Rombouts + + * src/status.c,src/pdnsd-ctl/pdnsd-ctl.c + Fixed a bug (my fault) that caused improper passing on of flags for the + pdnsd-ctl source command. + Also reordered some of the code, so that data is validated after all of it + has been read from the control socket. This should prevent a "broken pipe" + error message if data validation fails. + Also fixed the reporting of success or failure of the pdnsd-ctl "neg" command. + +2003-09-08 Paul Rombouts + + * src/list.c + Rewrote da_grow1() and da_resize() so that they automatically allocate an array + if given a NULL argument. This makes the use of da_create() redundant in most cases. + +2003-09-08 Paul Rombouts + + * src/conf-parse.y,src/servers.c + At the suggestion of Greg Norris, I changed the code to allow server sections in the + configuration file that don't specify any IP addresses. Such a section will remain + inactive until one or more IP addresses are assigned with the control utility pdnsd-ctl. + +2003-09-04 Paul Rombouts + + * src/dns_answer.c,src/dns_query.c + Oops: in my zeal to declare variables in the smallest possible scope, I ended up + using a pointer to a struct that was out of scope. My understanding of compilers tells me + it should work out OK in practice, but it is definitely a no-no. + Used a union declared in a larger scope instead (which is ugly in another way, + but equally efficient). + Also removed a section of redundant code in udp_server_thread(). + +2003-09-01 Paul Rombouts + + * src/dns_query.c + Corrected the iteration range of a for loop in p_dns_cached_resolve(), which would + otherwise cause an array to be indexed out of bounds in the function set_flags_ttl(). + +2003-08-31 Paul Rombouts + + * src/dns_answer.c + Added cleanup handlers for freeing the resources passed on to udp_answer_thread() and + tcp_answer_thread(). This should ensure the resources are freed even if the threads get + canceled. + +2003-08-30 Paul Rombouts + + * src/cache.c + Revised large portions of code in src/cache.c, used for adding and deleting entries in + the cache. In particular, I rewrote purge_cache(), which I believe was incorrect. + I wouldn't be surprised if this was the cause of the crashed (defunct) threads that some + people were reporting. + Also fixed some memory leaks. + +2003-08-28 Paul Rombouts + + * src/cache.c + Eliminated the overhead of allocation debugging in the case that ALLOC_DEBUG is not defined. + +2003-08-24 Paul Rombouts + + * src/conf-parse.y + No longer allow certain settings of the query_method option in the configuration file + if pdnsd is not compiled with the necessary support. + Thanks to Nikolaus Rath for reporting the bug. + +2003-08-23 Paul Rombouts + + * src/netdev.c + Fixed a bug in is_local_addr() where the result of fgetc(f) is restricted to type char + before being compared to EOF, which can result in the comparison always being false. + Thanks to Gerhard Tonn for reporting the bug. + +2003-07-28 Paul Rombouts + + * doc/html/index.html,doc/html/doc.html,doc/html/dl.html,doc/pdnsd-ctl.8,contrib/README + Revised the documentation. + +2003-07-21 Paul Rombouts + + * src/main.c,src/status.c,src/icmp.c + Setting stat_pipe=0 after opening or binding the control socket fails. + This should prevent further use of the control socket if a problem with + it has been detected previously. + Also properly initialized the global variable int ping_isocket in src/icmp.c + +2003-07-13 Paul Rombouts + + * src/main.c + Polished the code in main(). + +2003-07-04 Paul Rombouts + + * src/helpers.c,src/dns_answer.c,src/dns_query.c + Eliminated the use of inet_ntoa() in favor of the more modern inet_ntop(). + inet_ntop() makes more sense in threaded code and is also recommended in + the glibc info pages. + +2003-07-03 Paul Rombouts + + * src/dns_query.c + Fixed an allocation size error (not mine) in p_exec_query(). + The erroneous size is almost always larger than necessary, so in practice this bug + just wastes memory. But there is also a possibility that the allocated buffer is too + small, which would mean trouble. + Also fixed two memory leaks on some of the error paths in p_exec_query(). + +2003-06-28 Paul Rombouts + + * acconfig.h,configure.in,src/thread.h + Extended the configuration option --with-thread-lib. + Configuring with --with-thread-lib=linuxthreads2 will cause the alternative + definition of THREAD_SIGINIT suggested by Thomas Moestl to be used. + +2003-06-27 Paul Rombouts + + * src/consts.h,src/consts.c,src/conff.c,src/conf-parse.y,src/dns_answer.c + Added two new configuration options for policies of inclusion/exclusion lists. + The new policies options are "simple_only" and "fqdn_only". + This allows me to control to which name servers pdnsd will direct queries for + simple host names. + I also polished the code a bit in report_conf_stat(), used for reporting the current configuration. + +2003-06-20 Paul Rombouts + + * acconfig.h,configure.in,src/thread.h,src/thread.c + Added a configuration option --with-thread-lib=nptl. + This causes the macro THREAD_SIGINIT to be defined as empty in src/thread.h, + and thread_sig() in src/thread.c is never used. + +2003-06-11 Paul Rombouts + + * src/thread.h + Undid the change to the definition of THREAD_SIGINIT suggested to me by + Thomas Moestl, after receiving a report of a problem with this change + from someone running SuSE 7.0. + +2003-06-06 Paul Rombouts + + * src/dns_query.c: + Discovered that I failed to preserve the semantics of Thomas Moestl's code + when I rewrote a section of code in use_server(). Fixed. + +2003-05-19 Paul Rombouts + + * src/cache.c,src/conf-lex.l.in,src/conf-parse.y,src/conff.h,src/dns_answer.c,src/dns_query.c,src/servers.c: + Merged fixes contained in patch file sent to me by Thomas Moestl with my own version. + Changing the version to 1.1.8b1 as suggested by the patch file. + +2003-02-26 Paul Rombouts + + * pdnsd-1.1.7a-par.diff: + Made one big patch file from all the changes I made up till now. + Wrote a description of the changes in a file README.par + Posted patch file on the web so others can use it. + +2003-02-24 Paul Rombouts + + * src/cache.c + Changed the code that writes the cache to disk. + Data is now written strictly sequentially, eliminating the need for fseek(). + This seems to have successfully solved the problem I had with corrupt cache files. + +2002-05-27 Paul Rombouts + + * ChangeLog: + Started experimenting with the source code. + Made many changes between 2002-05-27 and 2002-07-13. + Too lazy to maintain the ChangeLog. + +2002-01-06 Thomas Moestl + + * version: Call it 1.1.7. + +2002-01-04 Thomas Moestl + + * src/dns_answer.c, src/dns_query.c: + Comment and debug message fixes, more assertions. + +2002-01-03 Thomas Moestl + + * src/dns.c, src/dns_answer.c, src/dns_query.c: + More harmless fixes, correct some comments and debug messages, add more + assertions. + + * NEWS, version: 1.1.7p2, correct NEWS entry. + + * src/helpers.c: + Make sure the calling thread of pdnsd_exit() terminates immediately. + +2002-01-02 Thomas Moestl + + * src/dns_answer.c, src/helpers.c, src/icmp.c: + Fix a few more harmless bugs, more paranoia. + + * src/status.c: Fix yet more, probably harmless, problems. + +2002-01-01 Thomas Moestl + + * src/dns.h, src/dns_answer.c, src/dns_query.c: + Fix a few more possible buffer size problems, and add a bunch of + assertions as last lines of defence. + +2001-12-30 Thomas Moestl + + * src/dns.c: Build fix (include error.h). + + * NEWS, version: Call it 1.1.7p1, and add a NEWS entry. + + * TODO: Reduce TODO to what actually is still needed. + + * src/dns.c, src/error.h, src/helpers.c: + Add a bunch of robustness PDNSD_ASSERT()'s. + + * src/dns_query.c: + Fix a bug which may possibly be remotely exploitable to gain access as + the user pdnsd runs as. + This was caused by a dumb single-character mistake :( + + * doc/Makefile.am, configure.in: + Avoid confusing automake 1.5 by not putting a comment into a make rule. + Fix CONFDIR passing. + + Submitted by: GoTaR + + * src/pdnsd-ctl/pdnsd-ctl.c: + Avoid crashing when the buffer contents received using the status command + are not terminated. + +2001-10-14 Thomas Moestl + + * src/rc/SuSE/pdnsd.in, THANKS: + Fix the stop case for the SuSE rc script: killproc requires the full + path of the binary as argument (reported by Bernhard Pelz). + +2001-09-23 Thomas Moestl + + * configure.in: + Revamp the OS autodetect test. OpenBSD and (hopefully) NetBSD are no longer + unsupported. + + * src/helpers.c, THANKS: + Do not try to use arc4random when compiling for NetBSD (submitted by + Thomas Stromberg). + +2001-09-10 Thomas Moestl + + * COPYING.BSD: s/REGENTS/AUTHOR/ in one place. + + * src/cache.c: + It is possible no record of the requested type is present after calling + cr_add_cent_rr_int() (when the record was marked as being local), so + check before dereferencing the pointer to the respective rrset. + Leave the record unmodified when cr_check_add() returns 0.x + +2001-07-26 Thomas Moestl + + * src/rc/RedHat/pdnsd.in: + Add a workaround for @sysconfdir@ substitutions containing ${prefix}. + Spotted by Robert Linden. + +2001-07-04 Thomas Moestl + + * src/rc/RedHat/pdnsd.in: + Add a condrestart handler to the Red Hat rc script, and do some general + cleanup. Contributed by Christian Engstler. + +2001-07-02 Thomas Moestl + + * src/error.h: + Attempt to detect a gcc that cannot yet handle ANSI variadic macros, + and work around this by using the old GCC-style variant. + + * src/conff.c: + Remove a + at the start of a line that got in when merging a diff by + hand. + + * src/servers.c: waitpid() returns a pid_t. + + * src/dns.c: + It's sizeof, not sizof. This should unbreak the IPv6 build. Also silence + some warnings with appropriate casts. + + * NEWS, version: Call it 1.1.6, and add a NEWS entry. + +2001-07-01 Thomas Moestl + + * src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns_query.c, THANKS, version, AUTHORS: + Added a modified version of Andreas Steinmetz's code for + query_port_start and query_port_range, and added him to AUTHORS and + THANKS. + +2001-06-23 Thomas Moestl + + * src/cache.c: + Fix a bogon: deleted would not be reset correctly in the first + purge_cache loop, which could cause pdnsd to loop forever when a + negative record was after a deleted rr. + +2001-06-21 Thomas Moestl + + * src/list.h: + Add (currently unused) list macros that are going to be used in future + code. + + * src/cache.c: + Fix a bogon in the rw lock code: we need to wake up a writer if there + are no readers. The old code was a leftover from a time when + SUSP_THRESH was just r_pend * x. + Fix a typo. + +2001-06-13 Thomas Moestl + + * AUTHORS: Add mention of FreeBSD code to AUTHORS. + + * src/netdev.c: + Add SIZEOF_ADDR_IFREQ (taken from FreeBSD: _SIZEOF_ADDR_IFREQ, net/if.h + rev. 1.58.2.1) and add an appropriate copyright notice. + The reason for this is that other BSDs don't have it, and we are not + supposed to use underscored macros in portable software. + +2001-06-12 Thomas Moestl + + * src/icmp.c: Fix double #inclusion of . + Noticed by Sebastian Stark. + +2001-06-08 Thomas Moestl + + * src/dns_query.c, THANKS: + Allow underscores in the query names reported back, as the comment next + to the decompress_name call already indicated (but the call gave NULL + as the uscore parameter, which disables underscores normally). + Add Michael Ströder, who spotted this, to THANKS. + +2001-06-06 Thomas Moestl + + * src/servers.c, THANKS: + Fix a bug discovered by Stefan Erhardt (and add him to THANKS): the + return value of waitpid was misinterpreted. + +2001-06-04 Thomas Moestl + + * Makefile.am, file-list.base.in, version: + Bump version to 1.1.6p1; wire up COPYING.BSD so that it gets included + in RPM's and tarballs. + + * COPYING.BSD: + Add the BSD-Style copyright notice so that it can be included in binary + distributions. + +2001-06-03 Thomas Moestl + + * src/dns.c, src/dns_answer.c, src/dns_query.c, src/helpers.c, src/status.c, NEWS, version: + Bump version to 1.1.5, and add a NEWS entry for this release. + + Miscellaneous cleanups, mainly in the status.c code; fix a bug that + could cause heap corruption (rhncpy always clobbered the whole buffer, + but only the needed space was reserved in add_rr). This should solve + the crashes some people were seeing (this bug is not an exploitable + security hole as far as I know; the respective buffer is on the heap, + as mentioned). + + * src/error.c: + Paranoia: do not use the argument to crash_msg as a format string + (crash_msg is only used with constant strings, though). + +2001-06-02 Thomas Moestl + + * src/dns.c, src/dns.h, src/dns_answer.c, src/dns_query.c, src/error.h, src/hash.c, src/helpers.c: + Correct underscore handling for SRV records, and a few comment fixes. + + * src/cache.c, src/conff.c, src/dns_query.c, src/error.h, src/helpers.h, src/status.c: + Numerous non-critical argument fixes for printf-like functions. + + * src/dns.c: Remove superfluous \n's. + + * src/conf-parse.y, src/dns_answer.c, src/status.c: + Correct some DEBUG_MSG nits, and fix two format string bugs. One of + them could allow users that are allowed to use pdnsd-ctl with the + server (when the status socket is enabled) to gain the privileges of + the user that runs (the run_as user or the user that started pdnsd on + Linux when strict_setuid is set to off) pdnsd. The status socket is + disabled by default, and if it is enabled, it's default permissions + are quite restrictive, so this isn't a problem for most. + +2001-05-30 Thomas Moestl + + * src/status.c: + Make the status permissions actually work (missed last time). + + * src/dns_answer.c, src/main.c, src/status.c, src/status.h: + Move the status socket initialization to a place where it gets executed + before any threads are started; this way, we can use umask to set the + permissions, and avoid a (in this case harmless, but anyway) race + condition. + While being there, remove obsoleted comments and places referring to + the now-socket as fifo. + +2001-05-29 Thomas Moestl + + * src/cache.c: + Replace a misuse of CF_LOCAL with DF_LOCAL. This had no effect, because + the values are the same. + +2001-05-22 Thomas Moestl + + * src/hash.c, src/helpers.c, THANKS, acconfig.h, configure.in: + Add an option for allowing underscores (_) in domain names. This + violates the RFC's if enabled (which it isn't by default). + Thanks to Eelco Vriezekolk for an initial patch. + + While being there, clean up configure.in and acconfig.c a bit. + + * src/helpers.c, src/status.c: + Add a few comments about security implications. + + * src/cache.c, src/dns_answer.c, src/dns_query.c, src/helpers.c: + Change some occurences of strcpy to strncpy. Again, no risk here, the + buffer lentgh was carefully chosen, and while the data was partially of + remote origin, it was carefully validated before entering the cache (and + thus having a chance of being used by us). + 3 occurences remain: 2 in cache.c, where we allocate a sufficient amount + of memory before (mimicking the non-portable strdup) and one where + we copy a constant and which is obviously correct. + + * src/dns.c: + Change two occurences of strcat to strncat. Again, no risk here, the + buffer lentgh was carefully chosen, the data was validated and supplied + by the starting user. + + * src/dns.c: + Change a sprintf to a snprintf and enlarge a buffer a bit. This is pure + paranoia (alrhough makes code review easier for others), because a.) the + lengths were carefully chosen so that no overrun could occur and + b.) this was locally supplied data. + +2001-05-21 Thomas Moestl + + * src/rc/RedHat/Makefile.am: + Add a missing semicolon in the RedHat rc Makefile.am (discovered by + Christian Engstler). + +2001-05-19 Thomas Moestl + + * HACKING: Remove the mostly outdated HACKING file. + + * src/debug.c: + Catch a corner case in the allocation debug helpers: realloc() with a + size of 0 is effectively a free operation. To my knowledge, this is + not done in the pdnsd sources, however. + + * src/test/test.sh: + Use the correct error function, forgotten in last commit. + + * src/test/clnt-test.sh, src/test/srv-test.sh, src/test/test.sh: + Misc small improvements in the regression test scripts, mostly + adding configuration variables and common error handlers. + Comment a little on the tests that are done in clnt-test.sh + + * src/rr_types.c: Fix a typo in a comment. + + * src/cache.c, src/debug.c, src/dns_answer.c, src/dns_query.c, src/error.h, src/hash.c, src/list.c, src/main.c, src/status.c, src/thread.c, src/thread.h: + New ANSI variadic debug macros (finally), which print a timestamp and + a thread ID now for easier debugging with many parallel queries. + It should be considered to make those inline functions instead. However, + we have the advantage that we use printf in place here and benefit + from parameter checking without specifying obscure function attributes. + + * src/rc/SuSE/.cvsignore, src/test/.cvsignore, src/rc/.cvsignore, src/rc/Debian/.cvsignore, src/rc/RedHat/.cvsignore, contrib/.cvsignore, doc/.cvsignore, src/.cvsignore, src/pdnsd-ctl/.cvsignore, .cvsignore: + Brush up the rotten (pre-autoconf!) .cvsignore files and add some where + necessary. + +2001-05-17 Thomas Moestl + + * src/rc/RedHat/Makefile.am, src/rc/RedHat/pdnsd.in, configure.in, pdnsd.spec.in: + Red Hat rc script and RPM improvements by Christian Engstler. + +2001-05-12 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c: + Fix a place missed when converting rr_info. + + * version: It's 1.1.4, finally. + + * src/rr_types.c, version: + Change some class values in the rr type structure to better values. + Bump beta version. + +2001-05-10 Thomas Moestl + + * src/cache.c, src/dns_answer.c, src/dns_query.c: + Fix a signedness bug that could cause erraneous 0 ttls to be returned. + Add some debug messages, and do some minor fixups. + +2001-05-09 Thomas Moestl + + * src/cache.c, src/rr_types.c: + Fix some bugs in the new conflict resolution code and make it more + complete. + + * src/cache.c, version: + Add conflict resolution code. This needs a bit more checking, and + the tables might still need to be tweaked. + Bump version. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/Makefile.am, src/cache.c, src/cache.h, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/consts.c, src/consts.h, src/debug.c, src/dns.c, src/dns_answer.c, src/dns_answer.h, src/dns_query.c, src/dns_query.h, src/error.c, src/error.h, src/hash.c, src/hash.h, src/helpers.c, src/helpers.h, src/icmp.c, src/icmp.h, src/list.c, src/main.c, src/netdev.c, src/netdev.h, src/rr_types.c, src/rr_types.h, src/servers.c, src/servers.h, src/status.c, src/status.h, src/thread.c, src/thread.h, configure.in, version: + Remove the old infrastructure that theoretically could have allowed for + multiple cache subsystems. This ability was never used, and if it should, + the caching should probably be split into two layers, a higher level + common one and the actual caching backends. + src/cacheing/cache.c and src/cacheing/native/*.[ch] were repo-copied to + src/. + Substitute "conf.h" with for includes. + Purge records a little more often (when adding records, and when + retrieving from the cache). Handle cache_size properly when using + purge_cent. + Introduce some infrastructure in rr_types.[ch] for a record conflict + checker which is to be introduced shortly to enforce cache consistency + even in the purge_cache=off case. + +2001-05-04 Thomas Moestl + + * src/rc/RedHat/pdnsd.in, src/rc/SuSE/pdnsd.in, src/rc/Debian/pdnsd.in: + Revert the last commit. It breaks the rc scripts by spamming them with + make style variable expansions. + + * src/rc/SuSE/pdnsd.in, src/rc/RedHat/pdnsd.in, src/rc/Debian/pdnsd.in, AUTHORS, THANKS: + Fix a rc script bug spotted by Frank Elsner, and add him to AUTHORS and + THANKS. + +2001-05-01 Thomas Moestl + + * version: Bump version to 1.1.4p2. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/status.c: + Fix some bogons and remove some unneeded code in the pdnsd-ctl + interface. + Fix spelling and line length bugs. + +2001-04-30 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c, src/conf-parse.y, src/status.c: + Some corrections for the authrec config file and the pdnsd-ctl noauth + support. + + * src/pdnsd-ctl/pdnsd-ctl.c: + Fix wrong argv index (using getopt changed the indices). + + * src/pdnsd-ctl/pdnsd-ctl.c, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns.c, src/dns.h, src/dns_query.c, src/status.c, THANKS, version, AUTHORS: + Accumulated changes that should go in before 1.1.4: + - merge Andrew M. Bishop's patch that adds a server label option + - make local records authoritative for the domain by default, and add + the authrec option to change this + - add the auth keyword to the pdnsd-ctl source option to support that + - fix a bug in the conf-parse.y grammar causing a shift/reduce conflict + - sync up AUTHORS and THANKS: add Andrew M. Bishop, Kevin A. Burton and + Michael Steinl + - bump version to 1.1.4p1 + + * src/conff.c, src/main.c: + Fix two small bugs: the wrong element of argv was used for the pidfile + option, which could cause pdnsd to segfault, and C_INCLUDED was always + used in slist_add, regardless of the tp parameter. + + * src/helpers.c: + Fix a bogon discovered by Michael Steiner: the fread() return value + was tested against bytes, not the number of items. + + * src/hash.c, src/hash.h, src/cache.c: + purge_cache used to walk over the cache quite inefficiently when it was + called from add_cache. Add a lazy mode for purge_cache which uses the + rrset_l to be efficient in this special case. + Add some #ifdef'ed-out-by-default code to debug the hash function. + +2001-04-12 Thomas Moestl + + * NEWS: Add NEWS entry for 1.1.3. + + * src/dns.c, src/helpers.c, src/icmp.c, contrib/Makefile.am, contrib/README, version: + IPv6, ICMP and build fixes. It's 1.1.3 now! + + * src/debug.c, src/debug.h: Add the new debug support files. + + * src/test/clnt-test.sh, src/cache.c, src/cache.h, src/error.h, src/list.c, src/list.h, src/main.c, src/status.c, src/status.h, src/Makefile.am, src/conf-parse.y, src/conff.h, src/dns.c, src/dns_answer.c, src/dns_query.c: + Add allocation debug support. Some small cleanups before the upcoming + 1.1.3 release. + + * src/dns_query.h, src/helpers.c, src/list.c, src/conff.c, src/dns.c, src/dns_answer.c, src/dns_query.c: + Lots of small bugfixes, cleanups, style and spelling fixes. + + * src/test/clnt-test.sh: Fix nc arguments. + + * src/test/clnt-test.sh, src/test/srv-test.sh, src/test/test.sh: + Add regression test scripts. + +2001-04-11 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c, src/cache.c, src/servers.c, src/dns_answer.c, src/helpers.c, src/helpers.h, src/icmp.c, src/main.c: + Further cleanups and bug, style and spelling fixes. + + * configure.in: Use -g again in the CFLAGS for a while. + + * version: Beta version bump. + + * src/rc/SuSE/pdnsd.in: + killproc does not seem to take the full path, but only the process name + (which is what one would expect). + + * src/hash.c, src/netdev.c, src/rr_types.c, src/status.c, src/conf-parse.y, src/conff.c, src/helpers.c: + Misc. smaller fixes, and fixes on the new features. Also clean up style + and spelling in some places. + + * src/dns_answer.c: + Bring the glibc pthread_cleanup_push/pthread_cleanup_pop return bug + workaround into the main tree. + Without this, a return between those two macros would cause pdnsd + to crash on system using a glibc between 2.1.2 and 2.2.2 (and possibly + others). This could e.g. be cause by a TCP connect() port scan. + +2001-04-10 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c: + Minor fixes, direct error messages to stderr. + + * src/list.c, src/list.h: Add the new list implementations. + + * src/cache.c, src/cache.h, src/conf-parse.y, src/dns.c, src/dns_answer.c, src/dns_query.c, src/helpers.c, src/helpers.h, src/conf-lex.l.in: + Introduce rhnlen and rhncpy and make use of it instead of kluged-up + strcpy/strlen in the appropriate places. + Check that incoming names contain only legal characters in + decompress_name, return RC_FORMAT otherwise (this would result in + wrong handling only, but not in a security hole). + Reorganzie compose_answer and make it more correct for multiple + questions. Get rid of the algorithm that tries to add a higher + level name server; this might be readded in another place somewhen. + Use some more da_* instead of hand-built lists. + Some style cleanups. + + * src/rc/RedHat/Makefile.am: + Add K45pdnsd links for rc6.d (reboot) and rc0.d (halt) following a + suggestion by Stas Sergeev. + +2001-04-06 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c, src/cache.h, src/error.h, src/helpers.c, src/helpers.h, src/main.c, src/servers.c, src/status.c, src/conf-parse.y, src/conff.c, src/conff.h, src/dns.c, src/dns.h, src/dns_answer.c, src/dns_query.c, src/Makefile.am, version: + Bump alpha version; introduce a generic dynamic array type and make use + of it to ged rid of some ugly casts and redundant code. + Minor fixes. + + * src/icmp.h, src/ipvers.h, src/conff.h, src/consts.h, src/dns.h, src/dns_answer.h, src/dns_query.h, src/helpers.h: + Use macros without an underscore as first character to protect the + headers. Underscores are reserved and should not be used in the + application name space. + + * src/error.h: Add PDNSD_ASSERT, change style a little. + +2001-04-03 Thomas Moestl + + * src/hash.c, src/netdev.c, src/servers.c, src/helpers.c, src/icmp.c, src/main.c: + Another slew of small bugfixes, minor updates and small fixes. + + * src/rr_types.c, src/consts.c: + Update rr_types.c copyright date, consts.c should have a rcsid string. + + * src/rr_types.c: cvs add rr_types.c. + + * src/dns.h, src/helpers.h, src/ipvers.h, src/rr_types.h, src/status.h, src/conf-parse.y, src/conff.h: + cvs add rr_types.h that got missed before, update copyright dates, + remove some old config cruft, some minor fixups. + + * src/conff.c, src/consts.c, src/dns_answer.c, src/error.c, src/conf-lex.l.in, src/conf-parse.y: + Update copyright dates, fix some minor bugs. Update copyright dates. + cvs add missed consts.c. + +2001-03-28 Thomas Moestl + + * src/cache.c, src/hash.c, src/error.c, src/servers.c, src/dns_answer.c, version: + Bump version to 1.1.3p4 + Fix some non-critical locking issues (none of them could be fatal). + Adjust copyright dates. + + * src/hash.c: Make the hash compare case insensitive. + +2001-03-25 Thomas Moestl + + * contrib/Makefile.am: Add Id tag to Makefile.am + + * src/cache.c, src/dns_answer.c, src/icmp.c: + Some more type fixes overlooked in last commit. + + * src/conf-parse.y, src/conff.h, src/dns.h, src/dns_answer.c, src/dns_query.c, src/icmp.c: + More type cleanups. Use time_t for time specifications throughout, and + make lengths singed longs. Cast cleanup in icmp.c to fix alpha + unalinged access faults. + + * contrib/dhcp2pdnsd, contrib/pdnsd_dhcp.pl, contrib/save_ram.pl, contrib/Makefile.am, contrib/README, configure.in, version, Makefile.am: + It's 1.1.3p3 now. + Change the contrib infrastructure: there is a Makfile.am in contrib/ + now. Rename Marko Stolle's pdnsd_update.pl to pdnsd_dhcp.pl and bring + it up to date (adding the rc script and save_ram.pl). + + * src/helpers.c, src/dns.c, src/dns_query.c, AUTHORS, THANKS: + Bring in Bjoern Fischer's changes to make pdnsd conserve the case of + cached names, and add him to AUTHORS and THANKS. + + * configure.in: The gdbm backend is discontinued. + + * src/cache.c, src/hash.c: + Cleanup and small bugfixes of the cache code (esp. locking). + + * AUTHORS, THANKS, file-list.base.in, pdnsd.spec.in: + SuSE fixes by Christian Engstler. + Add him to AUTHORS, THANKS. + +2001-03-14 Thomas Moestl + + * src/dns_query.c: + Fix a bug that could cause servers that were not used in the first + parallel query not to be used at all (failure would be returned + instead). + +2001-03-13 Thomas Moestl + + * src/icmp.c: Add define for ip_p equivalent on Linux. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/cache.c, src/dns_query.c, src/icmp.c, src/status.c, src/conf-parse.y, src/dns_answer.c, version: + Bump alpha version, more alignment fixes. All casts should be correct + now. + +2001-03-12 Thomas Moestl + + * src/dns_answer.c, src/dns_query.c, AUTHORS, THANKS: + Add the alpha fixes by P.J. Bostley, and add him to THANKS and AUTHORS. + +2001-03-10 Thomas Moestl + + * src/dns.h, src/helpers.h: + Remove prototype for removed function strtolower. + Use unit16_t and uint32_t instead of unsinged short/long for dns + protocol structures. + +2001-02-25 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c, src/status.c, src/conf-lex.l.in, src/conf-parse.y, AUTHORS, Makefile.am, version: + Add MX and CNAME for rr sections in the config file and MX setting + for pdnsd-ctl. + Typo fixes. + + * src/netdev.c: Two more fixes. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/cache.c, src/dns.c, src/main.c: + More small robustness fixes. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/netdev.c, src/status.c, src/status.h, src/conf-parse.y, src/helpers.c, src/main.c, configure.in, version, Makefile.am, NEWS: + A batch of robustness fixes. Move the status socket to the cache + directory. Various cleanups. + It's 1.3 now (hopefully to be released soon). + +2001-02-21 Thomas Moestl + + * src/main.c, src/conf-lex.l.in: + Fix breakage of the -mtu option and the query_method option (the parser + would not recognize constants that contained underscores). + +2001-02-20 Thomas Moestl + + * contrib/README, contrib/pdnsd_dhcp.pl, AUTHORS, Makefile.am, THANKS, file-list.base.in: + Add Marko Stolle's pdnsd_update.pl DHCP update script, add him to THANKS, + and bring a contrib/ directory in place. + +2001-02-15 Thomas Moestl + + * src/dns_answer.c, configure.in, version: + Some minor build & misc fixes. Bump version to 1.1.2a and release a + version with the spec file fixes to get proper Red Hat RPM's. + +2001-02-09 Thomas Moestl + + * NEWS: Bring NEWS up to date. + + * src/icmp.c: Do not close the socket on error. + + * pdnsd.spec.in: Add spec file fixes for man pages by Sourav K. Mandal + +2001-02-07 Thomas Moestl + + * version: It is now 1.1.2. + + * src/dns_query.c, src/main.c, Makefile.am, THANKS: + Fix a too strict length checking that could cause SERVFAIL to be returned + when the server returned NXDOMAIN. Add Markus Storm to THANKS (he has + reported this bug and supplied helpful information). + Minor tweaking in main.c. + Remove emptying of GZIP_ENV in Makefile.am (this normally contains --best). + +2001-01-27 Thomas Moestl + + * AUTHORS, THANKS: + Add Michael Wiedmann to AUTHORS and THANKS for his pdnsd-ctl.8 man page. + + * doc/Makefile.am, doc/pdnsd-ctl.8, configure.in, Makefile.am: + Add the pdnsd-ctl man page contributed by Michael Wiedmann. For this to + build in a correct way, add doc/Makefile.am and move all doc and + pdnsd.conf.sample related stuff in there. + +2001-01-25 Thomas Moestl + + * src/main.c: Removed unneeded for the non-O_NOFOLLOW case. + +2001-01-24 Thomas Moestl + + * src/main.c: + Add a fchown and a fchmod to the new non-O_NOFOLLOW case (not yet used). + + * src/conf-parse.y, src/main.c, src/status.c: Misc small fixups. + + * version: It's called 1.1.1 now. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/status.c, src/main.c: + Fix command line parsing. Add code to securely create pid files under + OSs that do not support the O_NOFOLLOW flag (those OSs are not supported + yet, though). + Fix a possible race condition in socket creation/chmod. We now create + a directory in /tmp (or whatever TEMPDIR was set) to hold the socket. + + * src/dns.c, src/dns_answer.c, src/icmp.c, src/main.c, src/status.c: + Another slew of copyright notice upgrades. + + * version, configure.in: + Bump beta revision, fix typo (missing $) in configure.in + + * src/dns.c, src/dns_answer.c, src/status.c: + Silence BSD compile time warnings. + + * configure.in: + Cleanup, add autoconf code for building pdnsd on FreeBSD-CURRENT with the + new additionally-linked libc_r. + +2001-01-16 Thomas Moestl + + * src/dns_answer.c, src/icmp.c, version: + Bump beta revision, fix a comment. Also, generate ping id's using pdnsd's + random wrappers instead of using rand() for paranoia. + +2001-01-15 Thomas Moestl + + * src/helpers.c, configure.in: Improve wording. + + * src/helpers.c: Update copyright year (forgotten in last commit). + + * src/dns_answer.c, src/helpers.c, src/main.c, acconfig.h, configure.in, version: + Bump versions. Small fixes (move socket intitializations from + udp_server_thread to init_udp_sockets to prevent warning when startup + takes long. + Make arc4random an option for a query id RNG and make it the default + on FreeBSD. + +2000-12-07 Thomas Moestl + + * src/conf-parse.y, src/main.c, version: + We are at 1.1.1p1. Removed the exec-uptest security warning printef if no + explicit user is given in the strict_setuid case (it is not needed there, + and confuses users). + +2000-11-28 Thomas Moestl + + * src/cache.c, src/helpers.c: + Converted cache locks to use condition vars and have lock contention + prevention. Added comments where not converted. + +2000-11-25 Thomas Moestl + + * AUTHORS, THANKS, pdnsd.spec.in: + Added spec file patches by Bernd Leibing and added him to AUTHORS and + THANKS. + +2000-11-21 Thomas Moestl + + * src/rc/SuSE/Makefile.am: Fixed a hopefully last SuSE rpm build bug. + + * src/rc/SuSE/Makefile.am: + Another one: allow rc.conf manipulation to fail for a clean + rpm build (SuSE only). + + * file-list.base.in: + Last-minute fix: correct filelist for rpm build to reflect the new name + for the sample configuration. + + * version: It's 1.1.0 now. + +2000-11-18 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl.c, src/cache.c, src/dns_query.c, version: + Fixed a condition where the cache code did not give up a lock. + Made the udp code use connect(). + Some small changes. + +2000-11-16 Thomas Moestl + + * version: Calling it 1.1.0b3. + +2000-11-15 Thomas Moestl + + * src/test/Makefile.am, src/pdnsd-ctl/Makefile.am, src/cache.c, src/Makefile.am, src/dns_answer.c, src/error.h, src/icmp.c, src/icmp.h, src/main.c, src/netdev.c, src/servers.c, src/thread.c, Makefile.am, configure.in, version: + Enabled new rr support by default (some resolvers don't seem to like not + supported answers - not our bug, but well). + Made some globals volatile to avoid being bitten by optimisations. + +2000-11-12 Thomas Moestl + + * TODO, version: Called it the first beta. + +2000-11-11 Thomas Moestl + + * src/cache.c, src/conf-lex.l.in, src/conf-parse.y, doc/pdnsd.conf.in: + renanmed rrneg to neg in the config file. + Misc small fixes. + pdnsd-ctl record xxx inval will now also invalidate local records. + + * src/conf-lex.l.in, src/conf-parse.y, src/dns_answer.c, src/status.c, pdnsd.spec.in: + Added --sysconfdir=/etc as argument to configure in the spec file. + Implemented the new rrneg config file section. + + * src/test/Makefile.am, src/pdnsd-ctl/Makefile.am, src/pdnsd-ctl/pdnsd-ctl.c, src/cache.c, src/cache.h, src/status.c, src/status.h, TODO: + Added the neg option to pdnsd-ctl. + + * src/cache.c, src/Makefile.am, src/conf-lex.l.in, src/consts.h, src/dns.c, src/dns.h, src/dns_answer.c, src/dns_query.c, src/helpers.c, src/main.c, configure.in: + Assorted fixes. The new features should be stabilized by now, will + integrate the missing few features now. + Also actived the tcp server by default. + +2000-11-07 Thomas Moestl + + * src/dns_answer.c, src/dns_query.c, src/icmp.c, src/ipvers.h, THANKS, TODO: + Fixed a possible memory and socket leak reported by Erich Reitz. + Implemented udp source address discovery for FreeBSD. + + * src/dns_query.c: Part 2 of yesterdays fix. + +2000-11-06 Thomas Moestl + + * src/dns_query.c, version: + Fixed a bug reported by Erich Reitz: pdnsd could leak fd's and memory if + queries timed out. + + * src/cache.c, src/cache.h, src/Makefile.am, src/dns_answer.c, src/dns_query.c, TODO, configure.in: + Sorted out some bugs for the new neg cacheing. + +2000-11-05 Thomas Moestl + + * src/cache.c, src/dns_query.c, TODO: + Negative cacheing support is now present, but largely untested. + + * src/conff.c, TODO: + The output of pdnsd-ctl status is now complete with all currently + supported options. + + * src/conf-parse.y, src/conff.c, src/conff.h, src/consts.h, src/conf-lex.l.in: + Added the config file options for the nefative cacheing support. + +2000-11-04 Thomas Moestl + + * src/cache.c, src/cache.h, src/conf-parse.y, src/dns.c, src/dns_query.c, src/status.c, version: + The new cache infrastructure for negative cacheing is in place. + Using and testing it remains. + + * src/cache.c, src/cache.h: + First changes to support negative cacheing. This should not break + anything, but the cache file format will be incompatible. + + * src/main.c, src/dns_answer.c: + init_udp_socket() and init_tcp_socket() are now called after + daemonizing on FreeBSD, as bind wants to lock the fd which + can cause later calls to fail after an exit. + +2000-11-03 Thomas Moestl + + * src/dns_query.c, src/icmp.c, src/servers.c: + Minor bugfixes and repository cleanup. + +2000-11-02 Thomas Moestl + + * src/icmp.c, TODO, version: + Called it 1.0.16p4. Fixed some compatability problems with the new code; + the ipv4 implementation seems to be fairly stable, the ipv6 one needs + some testing with dest unreach messages. + + * src/icmp.c, src/main.c: + Rewrote large parts of the ping implementation to be more portable. + +2000-11-01 Thomas Moestl + + * acconfig.h, configure.in, version: + Some config fixes, version to 1.0.16p3. SOCKET_LOCKING should be + off by default, as sendmsg can block. + + * src/pdnsd-ctl/pdnsd-ctl.c, src/error.h, configure.in: + Removed -W* arguments from CFLAGS that were implied by -Wall. + + * src/thread.c, configure.in: + Added some more safety tests to configure.in, and made it give + an error on some conditions. Also made configure do poll and usleep + detectione. + + * src/cache.h, src/test/Makefile.am, src/dns_answer.c, src/error.c, src/error.h, src/helpers.c, src/main.c, src/servers.c, src/status.c, src/thread.c, src/thread.h, src/Makefile.am: + Code cleanup. Beautified some macros, and moved the thread + specific things from error.[ch] over to the new thread.[ch]. + Also introduced usleep_r which tries to be thread safe for + different Unices. + +2000-10-31 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl, src/pdnsd-ctl/pdnsd-ctl.c: + The pdnsd-ctl binary got into cvs. Fixed that. + + * src/pdnsd-ctl/pdnsd-ctl, src/cache.c, src/cache.h, src/error.c, src/helpers.c, src/main.c, version: + Another set of FreeBSD compatability patches. This seems to catch + most of the problems, and pdnsd should be useable with libc_r now. + +2000-10-30 Thomas Moestl + + * src/pdnsd-ctl/pdnsd-ctl, src/conff.c, src/dns_answer.c, src/dns_query.c, src/helpers.c, src/icmp.c, src/main.c, AUTHORS, Makefile.am, THANKS, configure.in, version: + FreeBSD fixes, mostly contributed by Roman Shterenzon. + +2000-10-25 Thomas Moestl + + * src/pdnsd-ctl/Makefile.am, src/pdnsd-ctl/pdnsd-ctl: + pdnsd-ctl was not in cvs. + + * src/dns_query.c, src/error.h, configure.in: Some fixups for 1.0.15. + +2000-10-23 Thomas Moestl + + * src/dns_answer.c, src/dns_query.c, configure.in: + Several fixes for pdnsd to work better when it receives error replys. + + * src/dns.c, src/dns_answer.c: + Fixed another memory leak on an error path in dns_answer.c and did + a pointer signedness fixup in dns.c + +2000-10-21 Thomas Moestl + + * src/dns_answer.c, AUTHORS: + Applied a patch by Paul Wagland that fixes some spelling mistakes + and some memory leaks on error paths. + + * src/dns_query.c, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns_answer.c, NEWS, version: + Bug fixes. Added the randomize_recs option and turned it on + by default. + +2000-10-20 Thomas Moestl + + * src/helpers.c, src/dns.c, src/dns_query.c: + Fixes for the paranoid option to work with root servers + properly. + + * src/dns_query.c, src/dns.h, src/dns_answer.c, AUTHORS, THANKS: + Applied a patch by Paul Wagland for bind9-compatability and added + him to AUTHORS and THANKS. + +2000-10-19 Thomas Moestl + + * src/dns_answer.c, NEWS, version: + Another POLL_* fix. It is now called 1.0.14. + + * src/dns_answer.c, src/dns_query.c, src/icmp.c: BSD build fixes. + + * src/dns_query.c: + Made p_recurdive_query return immediately if a query returns + NXDOMAIN. + + * src/dns_query.c, Makefile.am: + Some bugifixes. It is now called 1.0.13. Releasing. + + * src/cache.c, src/dns_query.c, AUTHORS, NEWS: + Updated AUTHORS and NEWS. Made destroy_cache() lock the cache so + that no thread can access the cache afterwards (could lead to + crashes). + + * src/helpers.c, NEWS, THANKS: + Integrated a security fix contributed by Olaf Kirch: when + changing user IDs, pdnsd did not reinitialize the supplementary + group list, meaning that the process still had the privileges + of the supplementary groups the original user was member of. + + * src/conf-lex.l.in, src/conf-parse.y, Makefile.am, TODO, version: + Introduced the par_queries option. + + * src/dns_answer.c, src/dns_query.c, TODO: + Updated TODO, did some fixups for string handling. + + * HACKING: Added HACKING with some comments about coding style. + +2000-10-18 Thomas Moestl + + * src/dns_answer.c, src/dns_query.c, src/error.h, src/main.c, TODO: + Revieved and fixed the new dns_query.c-poll/select loops. + + * src/test/tping.c, src/dns_query.c, src/icmp.c: + Fixed the new poll/select ping support. + +2000-10-17 Thomas Moestl + + * src/dns_query.c, src/icmp.c, TODO: + Got rid of the O_NONBLOCK loop in the icmp.c ping implementation. + Beta tesing pending. + + * src/rc/Debian/Makefile.am, src/conff.c, src/conff.h, src/dns_query.c, src/dns_query.h, THANKS, TODO, acconfig.h, configure.in: + Corrected the Debian rc script (bug reported by Michael Müller). + Got rid of the nonblocking socket things in dns_query.c, and + using poll/select now. + Testing (esp. --no-poll) remains. + + * src/dns_answer.c: + Got rid of O_NONBLOCK read loops in dns_answer.c, using poll/select + now instead (after one issue about boundaries was cleared up). + +2000-10-16 Thomas Moestl + + * src/rc/SuSE/Makefile.am, src/rc/RedHat/Makefile.am, src/rc/Debian/Makefile.am: + The generated rc scripts do not need to be in the distribution. + + * src/conff.c, src/main.c: + Fixed a server structure members in conff.c. Only delete the socket + if we are in status pipe mode now. + + * src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns_answer.c, src/dns_query.c, acconfig.h, configure.in: + Added the --enable-tcp-subseq and --with-tcp-qtimeout configure + options, added the tcp_qtimeout conf file option, tested things. + 1.0.12 is ready for release. + +2000-10-15 Thomas Moestl + + * src/dns_answer.c, TODO, acconfig.h: + Added TCP timeouts to the answer code. Still need an option in the + conf file and documentation for that (besides beta testing). + + * src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/consts.h, src/dns_query.c, src/helpers.c, src/helpers.h, NEWS, TODO: + Introduced domain inclusion/exclusion lists in the server section + (new options include=, exclude=, policy=). + +2000-10-14 Thomas Moestl + + * src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns_answer.c, src/main.c, NEWS, TODO, version: + Upped version, updated NEWS and TODO and implemented a process + count limit. + +2000-10-13 Thomas Moestl + + * src/rc/Debian/pdnsd.in, src/main.c: + Added the --pdnsd-user option, and made the Debian rc script + use it rather than trying to parse the config file itself. + +2000-10-11 Thomas Moestl + + * src/rc/SuSE/pdnsd, src/rc/SuSE/pdnsd.in, src/rc/RedHat/pdnsd, src/rc/RedHat/pdnsd.in, src/rc/Debian/pdnsd, src/rc/Debian/pdnsd.in, AUTHORS, THANKS, configure.in: + Added the 'configure'-able rc scripts contributed by Carsten Block + and added him to THANKS and AUTHORS. + + * src/main.c: + Added O_NOFOLLOW to the pidfile open() call (if it is defined) + to prevent users creating files as the pdnsd user (using links) + if the admin put the pidfile in a world-writeable directory + against all good advice. + This is not a bug fix! Admins were not, and are still not supposed + to put the pidfile in a directory that is writeable for untrusted + users! + +2000-10-10 Thomas Moestl + + * THANKS: Added Milan P. Stanic to THANKS. + + * src/main.c: + Fixed a missing O_WRONLY in the open() call for pidfile operation. + +2000-10-08 Thomas Moestl + + * src/Makefile.am, src/dns.c, src/dns_answer.c, configure.in, version, acconfig.h: + Released 1.0.11. + Two security fixes in dns.c and dns_answer.c, and misc. smaller issues. + + * src/Makefile.am, src/conf-parse.y, src/dns_answer.c, src/dns_query.c, src/icmp.c, src/servers.c, AUTHORS, THANKS, TODO, acconfig.h, configure.in, version: + 1.0.10 was released some time ago ;-) + This had some IPv6 fixes. + Also fixed minor bug when using SOCKET_LOCKING. + +2000-08-28 Thomas Moestl + + * src/dns_answer.c: Fixed a parameter mismatch in getsockopt() + + * Makefile.am: + Applied Sourav K. Mandal's rpm build patch to the toplevel + Makefile.am + +2000-08-27 Thomas Moestl + + * src/conf-lex.l.in, src/conf-parse.y, src/consts.h, src/servers.c, version: + Added diald support. It's now called 1.0.9. + + * src/conf-parse.y, src/conff.c, src/netdev.c, pdnsd.spec.in: + Fixed some ugly typos in conf-parse.y and netdev.c. + Since I have no further bug reports and these bugs make some + things inconvenient, I will release 1.0.9 immediately. + +2000-08-26 Thomas Moestl + + * pdnsd.spec.in: small spec fix. + + * NEWS, configure.in: Last fixups for 1.0.8. Released it. + + * Makefile.am: Set mode and owner for cache file. + + * src/conf-parse.y, src/dns_answer.c, src/netdev.c, acconfig.h, configure.in, version: + Misc fixes. Hopefully fixed the UDP socket problems under Linux SMP. + +2000-08-20 Thomas Moestl + + * src/cache.c, src/dns_answer.c, AUTHORS, THANKS, configure.in, pdnsd.spec.in, version: + Build fixes by Alexandre Nunes, spec fixes (does now set distro for + configure), first attempt at an "error in udp send"-fix, and fix + for a problem with having records for the root domain in the disk + cache file. + +2000-08-13 Thomas Moestl + + * src/netdev.h, src/servers.c, src/status.c, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/consts.h, src/dns.c, src/dns.h, src/main.c, src/netdev.c, AUTHORS, THANKS: + Some minor fixes. Integrated the ppp device patch by Ron Yorston. + +2000-08-12 Thomas Moestl + + * configure.in: + configure.in was missing in repository. Also removed debugging + flag for build. + + * src/main.c: Made the pid file handling safe for directories. + + * src/dns.c: Part II of the last fix. + + * src/dns.c: + Fixed a nasty bug in decompress_name which would produce errors very + rarely. That was a off-by-one bug, but on the safe side (no overflow, + stopping one by too early). + + * src/main.c: + Fixed several possible problems with strncat(). None of these was + critical or involved remote data. + +2000-08-08 Thomas Moestl + + * src/main.c: Changed FreeBSD signal latency to 250 ms. + + * src/main.c, acconfig.h: + A set of last-minute FreeBSD fixes. pdnsd does now NEED linuxthreads on + BSD. + +2000-08-07 Thomas Moestl + + * version: It's now called 1.0.7. + + * src/main.c, doc/pdnsd.conf.in, Makefile.am: Misc build&BSD fixes. + + * src/conff.c, src/conf-parse.y, version: + Version set to the hopefully last beta. Fixed the proxy_only option. + +2000-08-05 Thomas Moestl + + * src/rc/SuSE/Makefile.am, src/rc/RedHat/Makefile.am, src/rc/Debian/Makefile.am, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns_query.c, src/status.c, doc/pdnsd.conf.in, Makefile.am, TODO: + Added the proxy_only options. Some build fixups. + +2000-07-30 Thomas Moestl + + * src/rc/SuSE/Makefile.am, src/rc/RedHat/Makefile.am, src/rc/Debian/Makefile.am, src/rc/Makefile.am, src/main.c, src/status.h, AUTHORS, INSTALL, Makefile.am, TODO, version: + Many small fixups for 1.0.7. + +2000-07-29 Thomas Moestl + + * src/rc/SuSE/Makefile.am, src/rc/RedHat/Makefile.am, src/rc/Debian/Makefile.am, src/rc/README, src/status.c, src/servers.c, Makefile.am, TODO, acconfig.h: + Assorted fixes. + + * src/cache.c, src/hash.c, src/dns.h, src/dns_answer.c, src/dns_query.c, src/icmp.c, src/ipvers.h, src/servers.c, src/servers.h, src/status.c, src/status.h, src/Makefile.am, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns.c, AUTHORS, Makefile.am, THANKS: + Big heap of updates and fixes. Incorporated build changes from Sourav + K. Mandal and pcmcia SCHEME support by Stephan Boettcher. + +2000-07-22 Thomas Moestl + + * src/rc/Debian/pdnsd: + Applied a patch by Markus Mohr to his debian rc script, which I had + broken in some way. + +2000-07-21 Thomas Moestl + + * src/cache.c, src/main.c, src/status.c, src/status.h: + Worked on the new status socket (pdnsd-ctl) option. + + * src/Makefile.am, version: Upped version, fixed Makefile.am + + * src/cache.c, src/hash.c, src/hash.h, src/cache.h, src/Makefile.am, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/dns.c, src/dns.h, src/dns_answer.c, src/dns_query.c, src/dns_query.h, src/helpers.c, src/helpers.h, src/ipvers.h, src/main.c, src/status.c, src/status.h, AUTHORS, Makefile.am, THANKS, acconfig.h: + Updated AUTHORS and THANKS. Merged in patches by Sourav K. Mandal + and Lyonel Vincent. + +2000-07-20 Thomas Moestl + + * doc/pdnsd.conf: Added pdnsd.conf. Well... + + * src/dns_query.c, src/dns_query.h, doc/pdnsd.conf: + Added some ommited files. + + * src/test/Makefile.am, src/test/if_up.c, src/test/is_local_addr.c, src/test/random.c, src/test/tping.c, src/rc/SuSE/Makefile.am, src/rc/SuSE/pdnsd, src/rc/RedHat/Makefile.am, src/rc/RedHat/pdnsd, src/rc/Debian/pdnsd, src/rc/Makefile.am, src/rc/README, src/Makefile.am, src/conf-lex.l.in, src/conf-parse.y, src/conff.c, src/conff.h, src/consts.h, src/dns.c, src/dns.h, src/dns_answer.c, src/dns_answer.h, src/error.c, src/error.h, src/helpers.c, src/helpers.h, src/icmp.c, src/icmp.h, src/ipvers.h, src/main.c, src/netdev.c, src/netdev.h, src/servers.c, src/servers.h, src/status.c, src/status.h, doc/pdnsd.conf.in, Makefile.am, acconfig.h, file-list.base.in, pdnsd.spec.in: + Checked in the pdnsd files at their new locations. + + * doc/pdnsd.conf, Makefile, a-conf.sh, cache.c, cache.h, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, consts.h, dns.c, dns.h, dns_answer.c, dns_answer.h, dns_query.c, dns_query.h, error.c, error.h, exec-flex.sh, hash.c, hash.h, helpers.c, helpers.h, icmp.c, icmp.h, ipvers.h, main.c, netdev.c, netdev.h, pdnsd-redhat.spec.templ, pdnsd-suse.spec.templ, servers.c, servers.h, status.c, status.h, version: + Removed the moved files. Will add the new ones soon. + +2000-07-16 Thomas Moestl + + * TODO: New tasks in TODO. + +2000-07-15 Thomas Moestl + + * TODO: + Updated TODO: Autoconf support was contributed by Sourav K. Mandal + + * conff.h, dns_query.c, ipvers.h, cache.c: + Fixed some minor bugs and a showstopper in cache.c that caused + crashes in some situations. + +2000-07-12 Thomas Moestl + + * dns_query.c, error.c, error.h, main.c: + Made pdnsd ignore SIGPIPE, which seemed to be responsible for some + crashes. + Accept (grudgingly) SOA rr's where NS ones would be The Right Thing. + +2000-07-10 Thomas Moestl + + * AUTHORS, THANKS, conff.c: + Updated AUTHORS, THANKS, and the fprintfs for the status pipe in + conff.c + + * TODO, config.h.templ, dns.h, dns_answer.c, dns_query.c, dns_query.h, main.c, version: + Added UDP queries and gave the user the choice between TCP and UDP + queries (UDP is the default now). Made the TCP server optional. + Fixed a authoritative record handling bug. Added pidfile support. + +2000-07-07 Thomas Moestl + + * doc/pdnsd.conf: + Inserted run_as="nobody"; again, it is The Right Thing and people + should use it. + + * Makefile: + The pdnsd cache directory is now created as nobody, since the + default run_as in the example pdnsd.conf is also nobody. + + * doc/pdnsd.conf: + Commented the run_as option out (people may run into permission + problems). + + * version: Upped version to 1.0.5 + + * AUTHORS, THANKS, conf.l.templ, conf.y, conff.c, conff.h, dns_answer.c, icmp.c, icmp.h, main.c, version: + Folded in the server_ip option code as contributed by Wolfgang Ocker + and extended it to IPv6. Fixed a bug in IPv4 ping in IPv6 mode. + +2000-07-06 Thomas Moestl + + * cache.c, dns_query.c: + Killed a bug which could cause crashes with more than 2 servers. + + * cache.c: Fixed a bug reported by Bert Frederiks that would break the + serve_aliases option when only one character was between official + name and alias in the /etc/hosts-style file. + +2000-07-04 Thomas Moestl + + * pdnsd-suse.spec.templ: The SuSE spec now uses the new makefile rule. + + * Makefile, THANKS, dns_query.c, helpers.c, version: + Added people to THANKS, fixed a bug that caused uppercase hosts/ + rr-section entries to be ignored in the cache, fixed the SuSE + makefile for pdnsd to run_as nobody, and other small fixups. + +2000-07-03 Thomas Moestl + + * dns_answer.c: + First change after release of 1.0.4: The questions received + are now properly written into the debug file when starting + with -g -d. + + * config.h.templ, dns_query.c: + Fixed a possible way to get around paranoid restrictions. + + * version: Set version to 1.0.4 + + * doc/pdnsd.conf: Added an entry for the paranoid option. + + * cache.c, config.h.templ, dns_answer.c, dns_query.c, ipvers.h: + Revisions and fixups. The complete code revision is now complete. + +2000-06-29 Thomas Moestl + + * dns_query.c: Overhaul. + + * dns_answer.c, dns_query.c, config.h.templ: + Code overhault continued. dns_answer.c is finished. + +2000-06-27 Thomas Moestl + + * conff.c, dns_answer.c, icmp.c, netdev.c, servers.c, status.c: + Continued code overhaul. Fixed several bugs, and simplified some + code. + + * conf.l.templ, conf.y, conff.c, ipvers.h, version: Fixups. + +2000-06-26 Thomas Moestl + + * hash.c: Revised; fixed a minor bug. + + * cache.c: Overhauled. + + * dns_query.c, error.c, helpers.c, helpers.h, ipvers.h, main.c, version, dns.c: + Manual code overhaul. Numerous small patches, greatly simplified + decompress_name(). + +2000-06-25 Thomas Moestl + + * config.h.templ: + Made the C random() RNG the default (using /dev/urandom, we suck up + too much randomness on high load). + + * error.c, error.h, icmp.c, icmp.h, main.c: + Small cleanups. Makes the testsuite compilation easier. + + * Makefile, config.h.templ: Preparing for release of 1.0.4. + +2000-06-24 Thomas Moestl + + * Makefile, THANKS, a-conf.sh, dns_answer.c, dns_query.c, error.c, version: + Fixed bugs with the paranoid option, connect() timeout handling, and + a incompatability in response handling that caused the glibc + resolver to misunderstand error messages pdnsd generated on unknown + query types. This bug, that was reported by James MacLean, could + for example cause ssh to hang some time. + + * Makefile, NEWS, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, dns.c, dns_query.c, dns_query.h, helpers.c, helpers.h, icmp.c, icmp.h, main.c: + Added the paranoid option, and modified the ping uptest so that it + works with strict_setuid. Also made strict_setuid=on the default. + 1.0.4 should be out soon. + +2000-06-23 Thomas Moestl + + * doc/pdnsd.conf: Added a run_as= line, which is sensible normally. + + * Makefile, conf.l.templ, conf.y, conff.c, conff.h, dns_answer.c, dns_answer.h, helpers.c, helpers.h, main.c, servers.c, status.c, version: + Some fixups, added the run_as and strict_setuid security options. + + * THANKS: Updated. + + * AUTHORS, ipvers.h, main.c, netdev.c, version: + Fixed some definitions for glibc2.0-users. Repaced the return at the + end of main() with _exit(). Should not build and run OK on glibc 2.0 + boxen. + Fixed a typo in netdev.c + + * ipvers.h: + Fixed a typo in ipvers.h to fix compile problems on systems without + an IPv6-supporting C library, and possible IPv6 problems using the + status pipe. + + * error.c, version: + Fixed a bug that could cause signals to be delivered to the wrong + process. + +2000-06-22 Thomas Moestl + + * version: Set version to 1.0.1. + + * cache.c, dns_answer.c, error.c, error.h, main.c, pdnsd-suse.spec.templ: + Fixed misc issues reported by Jonathan Hudson and Joachim Dorner, one + of them a real showstopper in cache.c. + + * Makefile, NEWS, README, cache.h, config.h.templ, version: + Updated things for 1.0.0 and released it finally. + + * AUTHORS, THANKS: Updated THANKS and AUTHORS + + * NEWS, a-conf.sh, cache.c, conf.l.templ, conf.y, conff.c, conff.h, dns_answer.c, dns_query.c, error.c, error.h, main.c, servers.c, status.c: + Fixed a-conf.sh and cleaned up signal handling as far as it can be + done ;-). Added the max_ttl option. + +2000-06-21 Thomas Moestl + + * dns_answer.c, error.c, error.h, main.c, servers.c, status.c: + More signal fixes. This is a real pain with LinuxThreads. + + * NEWS, cache.c, dns_answer.c, error.c, error.h, helpers.c, helpers.h, main.c, servers.c, status.c, version: + Fixups for signal handling. This is more than only a little tricky + using the linuxthreads library. This hopefully fixes the deadlocks + we had on signals. + +2000-06-13 Thomas Moestl + + * AUTHORS, THANKS: Updated credits. + + * a-conf.sh: + A primitive configure-like script intended as drop-in replacement + until autoconf support finally comes. + + * .cvsignore, Makefile, cache.c, dns_query.c, ipvers.h, servers.c, version: + Added a primitive configuration script as drop-in. Killed some bugs + and changed the recently added linkdown_kluge option following + suggestions from Daniel Smolik. + +2000-06-12 Thomas Moestl + + * dns_query.h, exec-flex.sh, Makefile, cache.c, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, dns_query.c: + Numerous cleanups and fixes. Implemented the linkdown_kluge option + as proposed by Daniel Smolik. Hope to get ready for 1.0.0 know. + +2000-06-10 Thomas Moestl + + * Makefile, NEWS, TODO, dns_answer.c: + Modified some stuff in dns_answer.c (if no nameserver for a knot in + the dns namespace is found now, its predecessors are tried now in + order to return accurate authority results). This will be paid with a + little more beta time, so the Makefile has developer switches again. + Corrected NEWS and TODO. + + * Makefile, config.h.templ, dns_answer.c, dns_query.c, dns_query.h, hash.h, helpers.c, version: + Removed some dead code, fixed some really minor bugs. Version is up + to 1.0.0p7, which is hopefully the last beta. + + * Makefile, config.h.templ: + Fixed things up for the 1.0.0 distribution version + +2000-06-06 Thomas Moestl + + * Makefile, config.h.templ, icmp.c, netdev.c: + Some minor comment fixes. + + * Makefile, TODO, main.c, version: + BSD fix in Makefile and help update. It is now called 1.0.0p6. TODO + was updated to reflect the project status. + + * dns_answer.c: + BSD & misc fixes. pdnsd runs now nicely on my FreeBSD 4.0 box. + + * dns_answer.c, ipvers.h: + Fixed IPv6 UDP dest address recovery. Also fixed a real stupid bug in + ipvers.h. + + * cache.h, dns_query.c, error.h: + Added DEBUG_MSG6 macros. Cleaned up requery handling. + + * dns.c, dns_answer.c, dns_query.c, dns_query.h: + Fixed another heap of bugs, introduced some sanity checks, no requery + on answers that have ra not set now. + +2000-06-05 Thomas Moestl + + * cache.c: + Fixed write_disk_cache. + + * cache.c, cache.h: + Fixes for rr handling. + +2000-06-04 Thomas Moestl + + * cache.c, dns_answer.c, dns_query.c: + Fixes again: some missing checks for rrset existence added. + + * cache.c, dns_answer.c, helpers.c, icmp.c: + Fixes for the new/modified code and its side effects on old code ;-) + + * ChangeLog.old, NEWS, cache.c, conf.l.templ, conf.y, conff.c, config.h.templ, dns.c, dns_answer.c, dns_query.c, error.c, hash.c, helpers.c, icmp.c, main.c, netdev.c, servers.c, status.c: + Folded the ChangeLog and NEWS of the 0.9.x tree back in and added NEWS for the + upcoming 1.0.0 release. Some compile fixes. Reorganized config.h.templ. Made + the inclusion of the rcsid strings into the executable optional. + + * cache.c, dns_answer.c: + Pile of fixes on recently added/modified code. + +2000-06-03 Thomas Moestl + + * .cvsignore, Makefile, lex.inc.h: + lex.inc.h should not be in CVS (it is automatically generated by + exec-flex.sh). It should also be deleted by 'make mclean'. + + * TODO, cache.c, dns_answer.c, dns_query.c, lex.inc.h: + rfc2181 conformance should be reached by now. Updated TODO. Bugfixing + remains. + + * doc/html/.cvsignore, doc/html/dl.html, doc/html/doc.html, doc/html/faq.html, doc/html/index.html: + Removed the html documentation from CVS. It is maintained separately. + + * doc/pdnsd.conf: + Added CVS/RCS $Id$ tag. + + * cache.h, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, consts.h, dns.c, dns.h, dns_answer.c, dns_answer.h, dns_query.c, dns_query.h, error.c, error.h, exec-flex.sh, hash.c, hash.h, helpers.c, helpers.h, icmp.c, icmp.h, ipvers.h, main.c, netdev.c, netdev.h, pdnsd-redhat.spec.templ, pdnsd-suse.spec.templ, servers.c, servers.h, status.c, status.h, version, AUTHORS, INSTALL, Makefile, NEWS, README, THANKS, TODO, cache.c: + Added CVS/RCS $Id$ tags to most files, did some cleanups, introduced + the new rrset granularity caching. The new code is still much of beta, + use with care. + +2000-06-01 Thomas Moestl + + * Makefile, cache.c, hash.c, helpers.c, icmp.c, netdev.c: + Yet another set of BSD fixes (test programs do now work for me + under FreeBSD). Some other minor fixes. + + * Makefile, error.c, error.h, helpers.c, helpers.h: + Transplanted kill_pdnsd from error.c to helpers.c in order to get the + tests compiled without the thread library. + +2000-05-31 Thomas Moestl + + * pdnsd: + Ooops, executable got in. + + * Makefile, pdnsd: + Added test suite programs. + + * icmp.c, netdev.c: + All basic BSD patches have been folded in. pdnsd will now compile on + FreeBSD with (hopefully) all features. + + * dns_answer.c, Makefile: + Disabled udp targed address discovery for BSD builds (this sadly ist + OS specific at least for IPv4. Must be rewritten under BSD as it is + an RFC compatability issue under some circumstances) + + * cache.c, cache.h, conf.y, conff.c, conff.h, config.h.templ, dns_answer.c, helpers.c, icmp.c, ipvers.h, netdev.c, Makefile: + BSD include & misc build fixes. More to follow... + + * Makefile, cache.h: + BSD Fixes: Makefile should work with BSD make, sed command line, + sorted out naming clash in cache.h + + * .cvsignore: + Added ChangeLog to .cvsignore + + * THANKS, conff.c: + Fixed a bug reported by Jonathan Hudson and added him to THANKS + + * ChangeLog.old: + Added the pre-CVS ChangeLog. + + * .cvsignore, AUTHORS, COPYING, INSTALL, Makefile, NEWS, README, THANKS, TODO, cache.c, cache.h, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, consts.h, dns.c, dns.h, dns_answer.c, dns_answer.h, dns_query.c, dns_query.h, doc/.cvsignore, doc/html/dl.html, doc/html/doc.html, doc/html/faq.html, doc/html/index.html, doc/pdnsd.conf, doc/txt/.cvsignore, error.c, error.h, exec-flex.sh, hash.c, hash.h, helpers.c, helpers.h, icmp.c, icmp.h, ipvers.h, lex.inc.h, main.c, netdev.c, netdev.h, pdnsd-redhat.spec.templ, pdnsd-suse.spec.templ, servers.c, servers.h, status.c, status.h, version: + Initial import of pdnsd-1.0.0p3 source tree into CVS. + + + * .cvsignore, AUTHORS, COPYING, INSTALL, Makefile, NEWS, README, THANKS, TODO, cache.c, cache.h, conf.l.templ, conf.y, conff.c, conff.h, config.h.templ, consts.h, dns.c, dns.h, dns_answer.c, dns_answer.h, dns_query.c, dns_query.h, doc/.cvsignore, doc/html/dl.html, doc/html/doc.html, doc/html/faq.html, doc/html/index.html, doc/pdnsd.conf, doc/txt/.cvsignore, error.c, error.h, exec-flex.sh, hash.c, hash.h, helpers.c, helpers.h, icmp.c, icmp.h, ipvers.h, lex.inc.h, main.c, netdev.c, netdev.h, pdnsd-redhat.spec.templ, pdnsd-suse.spec.templ, servers.c, servers.h, status.c, status.h, version: + New file. + diff --git a/jni/pdnsd/ChangeLog.old b/jni/pdnsd/ChangeLog.old new file mode 100644 index 00000000..0b3553e2 --- /dev/null +++ b/jni/pdnsd/ChangeLog.old @@ -0,0 +1,161 @@ +2000-02-15 + Version 0.2. First working alpha with the extended feature set. + +2000-02-16 + Version 0.3 with many bugfixes, better standard conformity and + some new features. + +2000-02-17 + Did a lint on the code, implemented soft timeouts, again bugfixes, + drastically reduced cache memory requirements, implemented local + records. + Version 0.4 released. + +2000-02-19 + Recursive query finally implemented. Version 0.5 out. + +2000-02-20 + Various bugfixes. The server now always tries to get an AA answer + if possible; this implies recursion. This is to deal better with + caching servers that may return incomplete results on * queries. + This may be a little sub-optimal since it may not take the full + effect of caching, but it is the only real possibility of getting + complete records. + Redid the deps in the makefile for now. + Version is now 0.6. + +2000-02-21 + Another set of bugfixes. Version is 0.6.1. + +2000-02-22 + Another set of bugfixes. It should stabilize by now. Answer compression + is there finally. Version is therefore up again, 0.7 by now. + +2000-02-23 + Minor bugfixes, isdn interface uptest added. The new record types as of + rfc1700 are implemented, but as a compile-time option, since normally + there is no need to waste space for them. + Version is 0.7.1. + +2000-02-24 + Version 0.7.2 with all rrs up to KX (36). #define DNS_NEW_RRS in + config.h and (re)compile if you want to use them. Delete the cache + file before using a version with this option changed! + NSAP-PTR does NOT WORK (any incoming answer containing it may cause + a format error) because it is ill-designed (see TODO). Never mind, it + is officially deprecated anyway. + The secure DNS extension record types defined in RFC 2065 (KEY, SIG, + NXT) are cached only and therefore useless. + +2000-02-26 + Version 0.8 with parallel query (and probably new bugs) introduced. + +2000-02-27 + Version 0.8.1 with minor bugfixes on the new features. + +2000-02-27 + Version 0.8.5 with authority support and the usual bugifxes. Some issues + with standard conformity were also fixed (wow, two versions a day). + +2000-02-28 + Implemented caching of non-authoritative records. This allows better + usage of other caching name servers. This may return non-authoritative + records to any non-wildcard query. If a wildcard query arrives, we + always look for authoritative records, so we do if the non-authoritative + answer does not contain at least one answering record to the query. + This fixes the sub-optimal behaviour since 0.6. + Version is therefore up to 0.8.7 (0.8.6 was also released today + containing bugfixes) + +2000-02-29 + Better thread support, avoiding deadlocks in signal handling. The cost + is unfortunately one more thread. + New option server_port in config file. + Version is 0.8.8. + +2000-03-01 + Nailed a renitent memory leak bug to the wall (shame, what a trivial + mistake). Also improved handling of error conditions slightly. + Version is 0.8.9. + +2000-03-01 + Cache code cleanup. The development of the non-parallel query code + is discontinued, although it still works. If you want serial query, + just set PAR_QUERIES to 1. + Additional information finally implemented. + We are up to 0.9. + +2000-03-02 + Fixed a DoS possibility. + More rfc compatability fixups and a smarter resolver logic. + Version 0.9.1 + +2000-03-02 + Added the source section to the config file handling. This allows to + source your /etc/hosts file. Version 0.9.2. + +2000-03-02 + Avoiding double additional records now. Version 0.9.3. + +2000-03-09 + Fixed some REALLY STUPID bugs. Uuummph, thought it was finished. + However, the number of bugs remaining is always n+1... + Anyway, we are up to 0.9.4. Hope that there are no mean bugs left. + +2000-03-14 + Added another uptest, exec. See README for details. Also grained the + cache size finer (it's now specified in kB). Version 0.9.5 + +2000-04-07 + Fixed some really stupid bugs, what else? Version is 0.9.6 + To be more exact: fixed misc bugs, cleaned up hash.c and cache.c + +2000-04-20 + Again fixed some bugs, version is now 0.9.7. + +2000-04-29 + Fixed a build problem caused by some missing #defines in glibc2.0 and a + minor bug. + Version is up to 0.9.8 + +2000-04-30 + Fixed some unclean C code and did a general C lint. Thanks to Byrial + Jensen for pointing out some issues. Now using stricter compiler flags. + Also replaced the daemon() call in main.c for improved portability. + Pre-Released 0.9.9p1 + +2000-05-03 + Released 0.9.9p2 with the changes of 0.9.9p1, Documentation updates, + bugfixes, and the Red Hat rc scripts contributed by Torben Janssen. + Also, the meaning of the command line option -v has changed. + There is a new config file option "lean_query" that is on by + default. It is an optimization, so please look in the docs when + updating whether you want it switched on or not. + Removed the long-dead serial query code from the distribution tree. + Some resolvers seem to be broken somehow in a respect that it cares + about order in which the records appear. In particular, it wants + cname to appear before other records. Ok, so it be... + + +2000-05-04 + Save all names in lower case in the rrs. + Tidying up the source tree. + The long-awaited cache structure changes have been started. Please + delete you cache files before using this new release. + +2000-05-05 + Fixed several bugs in the old and in the new source tree. + Use time_t instead of long for internal time storage for compatibility. + + +2000-05-06 + Version 0.9.10. + This fixes a bug in uptest=if. Red Hat and configuration fixes + suggested by Soeren J. Peters were included. + +2000-05-08 + Version 0.9.11 + This fixes a locally exploitable security problem (pdnsd.cache was + world-writeable). This is actually a one-line fix; for a description of + possible dangers, please refer to the html documentation. + Thanks to Alan Swanson for reporting. diff --git a/jni/pdnsd/INSTALL b/jni/pdnsd/INSTALL new file mode 100644 index 00000000..03991892 --- /dev/null +++ b/jni/pdnsd/INSTALL @@ -0,0 +1,190 @@ +The installation instructions are in doc/html/doc.html and doc/txt/manual.txt. +The system requirements are listed in doc/html/index.html and doc/txt/intro.txt. +I recommend using the html version. +Following are generic installation instructions for autoconf programs. +I strongly recommend to read the Installation section in the docs! + + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/jni/pdnsd/Makefile.am b/jni/pdnsd/Makefile.am new file mode 100644 index 00000000..146c32a5 --- /dev/null +++ b/jni/pdnsd/Makefile.am @@ -0,0 +1,40 @@ + +SUBDIRS = src doc contrib + +EXTRA_DIST = version ChangeLog.old COPYING.BSD README.par README.par.old PKGBUILD + +# The sample configuration is handled in doc/Makefile.am +install-data-hook: + $(mkinstalldirs) "$(DESTDIR)$(cachedir)" + test -f "$(DESTDIR)$(cachedir)/pdnsd.cache" || \ + touch "$(DESTDIR)$(cachedir)/pdnsd.cache" + if test `whoami` = "root"; then \ + chown $(def_id) "$(DESTDIR)$(cachedir)/pdnsd.cache"; \ + chown $(def_id) "$(DESTDIR)$(cachedir)"; \ + fi + chmod 0640 "$(DESTDIR)$(cachedir)/pdnsd.cache" + chmod 0750 "$(DESTDIR)$(cachedir)" + +dist-hook: $(PACKAGE).spec.in + sed -e '/^%{!?distro: %define distro /c\ + %if 0%{!?distro:1}\ + %if "%{_vendor}" == "redhat"\ + %define distro RedHat\ + %else\ + %if "%{_vendor}" == "suse"\ + %define distro SuSE\ + %else\ + %if "%{_vendor}" == "SuSE"\ + %define distro SuSE\ + %endif\ + %endif\ + %endif\ + %endif' \ + -e 's:[@]PACKAGE[@]:$(PACKAGE):g' \ + -e 's:[@]VERSION[@]:$(VERSION):g' \ + -e 's:[@]fullversion[@]:$(fullversion):g' \ + -e 's:[@]packagerelease[@]:$(packagerelease):g' \ + -e 's:[@]cachedir[@]:/var/cache/$(PACKAGE):g' \ + -e 's:[@]def_id[@]:$(PACKAGE):g' \ + $(PACKAGE).spec.in > $(distdir)/$(PACKAGE).spec + diff --git a/jni/pdnsd/Makefile.in b/jni/pdnsd/Makefile.in new file mode 100644 index 00000000..a865d546 --- /dev/null +++ b/jni/pdnsd/Makefile.in @@ -0,0 +1,734 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/PKGBUILD.in \ + $(srcdir)/config.h.in $(srcdir)/file-list.base.in \ + $(srcdir)/pdnsd.spec.in $(top_srcdir)/configure AUTHORS \ + COPYING ChangeLog INSTALL NEWS THANKS TODO acconfig.h compile \ + depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = pdnsd.spec file-list.base PKGBUILD +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src doc contrib +EXTRA_DIST = version ChangeLog.old COPYING.BSD README.par README.par.old PKGBUILD +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) $(top_srcdir)/acconfig.h + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +pdnsd.spec: $(top_builddir)/config.status $(srcdir)/pdnsd.spec.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +file-list.base: $(top_builddir)/config.status $(srcdir)/file-list.base.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +PKGBUILD: $(top_builddir)/config.status $(srcdir)/PKGBUILD.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-data-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-hook dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-hook install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-recursive uninstall uninstall-am + + +# The sample configuration is handled in doc/Makefile.am +install-data-hook: + $(mkinstalldirs) "$(DESTDIR)$(cachedir)" + test -f "$(DESTDIR)$(cachedir)/pdnsd.cache" || \ + touch "$(DESTDIR)$(cachedir)/pdnsd.cache" + if test `whoami` = "root"; then \ + chown $(def_id) "$(DESTDIR)$(cachedir)/pdnsd.cache"; \ + chown $(def_id) "$(DESTDIR)$(cachedir)"; \ + fi + chmod 0640 "$(DESTDIR)$(cachedir)/pdnsd.cache" + chmod 0750 "$(DESTDIR)$(cachedir)" + +dist-hook: $(PACKAGE).spec.in + sed -e '/^%{!?distro: %define distro /c\ + %if 0%{!?distro:1}\ + %if "%{_vendor}" == "redhat"\ + %define distro RedHat\ + %else\ + %if "%{_vendor}" == "suse"\ + %define distro SuSE\ + %else\ + %if "%{_vendor}" == "SuSE"\ + %define distro SuSE\ + %endif\ + %endif\ + %endif\ + %endif' \ + -e 's:[@]PACKAGE[@]:$(PACKAGE):g' \ + -e 's:[@]VERSION[@]:$(VERSION):g' \ + -e 's:[@]fullversion[@]:$(fullversion):g' \ + -e 's:[@]packagerelease[@]:$(packagerelease):g' \ + -e 's:[@]cachedir[@]:/var/cache/$(PACKAGE):g' \ + -e 's:[@]def_id[@]:$(PACKAGE):g' \ + $(PACKAGE).spec.in > $(distdir)/$(PACKAGE).spec + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/NEWS b/jni/pdnsd/NEWS new file mode 100644 index 00000000..9a83bba1 --- /dev/null +++ b/jni/pdnsd/NEWS @@ -0,0 +1,324 @@ +Version 1.2.9a fixes a bug in the 1.2.9 release that causes a build failure when +pdnsd is configured with --enable-strict-rfc2181. Unless you use this option to +compile pdnsd, there is no need to upgrade from 1.2.9 to 1.2.9a. + +Version 1.2.9 has support for many additional RR types, in particular those +needed for DNSSEC (though no support for the DNSSEC protocol itself yet in +pdnsd). Caching data structures are now more efficient when they only store the +most commonly used RR types. Fine-grained configurability over which RR-types +are cache-able. Pdnsd now has support for EDNS (Extension mechanisms for DNS), +although its usefulness is currently limited to enabling UDP messages larger +than 512 bytes. Defining local TXT records in the configuration file is now +supported. A new configuration option provides a fix in case the query uptest +fails due to remote servers ignoring empty queries. Several bugs have been fixed +including a UDP socket descriptor leak that affected the FreeBSD platform, and +an IPv6 port binding bug. + +Version 1.2.8 implements support for automatic discovery of root servers. +There are also some improvements in the resolver and a new default setting for +the neg_rrs_pol configuration option. + +Version 1.2.7-par fixes some security problems. It contains a fix for a +"dangling pointer" bug that could cause pdnsd to crash when it received a long +reply. It also addresses some of the issues raised in the CERT vulnerability +note VU#800113 by making the default of query_port_start equal to 1024, thereby +ensuring that source ports are randomly selected by the pdnsd resolver in the +range 1024-65535. This release also fixes problems with compiling pdnsd for the +ARM architecture and for the Darwin platform (Max OS X). There are a number of +(minor) new features. pdnsd now supports "include" files, essentially +configuration files that only contain definitions for local records. It is now +possible to define interactively, using pdnsd-ctl, any local record that can be +defined in a configuration file. + +Version 1.2.6-par has an upgraded license: GPL version 3. +A bug has been fixed which which caused pdnsd to handle NXDOMAIN replies +inefficiently when configured with neg_domain_pol=on. Also the code for the +ping test has been fixed, which was broken for 64-bit systems. A new option +randomize_servers can be used to give each server in a section of the +configuration file an equal chance of being queried. The new options reject, +reject_policy and reject_recursively make it possible to check for the presence +of certain IP addresses in the replies of name servers and to correct some types +of unwanted replies or to censor these IP addresses. +The pdnsd-ctl 'add a' and 'add aaaa' commands now allow multiple IP addresses to +be specified for the same name. There are some further improvements to pdnsd's +recursive resolver. + +Version 1.2.5-par introduces a new query method: udp_tcp. With this method a UDP +query is tried first and, if the UDP answer is truncated, the query is repeated +using TCP, which is the behaviour that seems to be recommended by the DNS +standards. There is a new configuration option use_nss, which can be turned off +to prevent lengthy timeouts and stalls in certain situations. A bug has been +fixed which could cause pdnsd to crash if debug output was generated before the +debug output stream was properly initialized. + +In version 1.2.4-par a memory leak and a minor buffer-overflow problem have been +fixed. There is now a fix for some situations that would previously cause pdnsd +to exit prematurely (such as ACPI S3 sleep or trying to attach strace to pdnsd). +Time intervals specified in the configuration file can now be expressed in +minutes, hours, days and weeks as well as seconds. Support for Apple Mac OS X +v10.4 Tiger has been improved. The "pdnsd-ctl status" command now also provides +some information about the status of the running threads. There are some further +improvements in the debugging information provided by pdnsd. +TCP-query support is now compiled in by default (but can still be disabled using +the configure option --disable-tcp-queries). + +In version 1.2.3-par the "pdnsd-ctl empty-cache" command can be provided with an +include/exclude list, allowing the user to specify a selection of names to be +removed, instead of emptying the cache completely. +Additional improvements: pdnsd should now remain responsive while executing the +"pdnsd-ctl empty-cache" command. With the query_method=tcp_udp option pdnsd will +now also try a UDP query after a TCP connection times out, which should allow +pdnsd to resolve the same names with query_method=tcp_udp as with +query_method=udp_only, although perhaps with an occasional delay. +"pdnsd-ctl config" or "pdnsd-ctl server" commands should now run without delays, +even if pdnsd is performing ping or query uptests at the time. A problem with +resolving certain names using root servers has been fixed. + +Version 1.2.2-par has a number of important portability improvements. A bug has +been fixed that prevented pdnsd from compiling successfully on some 64 bit +architectures. The code for determining endianness (most significant or least +significant byte first) should now be more portable. This release has +(experimental) support for the Darwin (Apple Mac OS X) platform. On Linux +systems, the configure script will now try to detect automatically whether the +system implements the Native POSIX Thread Library, but the method used may not +necessarily be foolproof. In addition, the debug features have been improved and +should make it easier to find out why pdnsd considers some queries or replies +malformed. + +Version 1.2.1-par has improved support for non-Linux platforms. This release has +(experimental) support for the Cygwin platform, and should also fix some +compilation glitches that have been reported by FreeBSD users. + +Version 1.2-par is a new and improved version of pdnsd! Most of the changes +effect the internal workings of pdnsd, but there are also a number of +interesting new features (well, I think they are interesting). Among the bugs +fixed are two rather nasty ones which involve the handling of NXT and NAPTR +records and which can cause pdnsd to crash or abort. The new features include a +new server availability test which can be specified with uptest=query, support +for reading the DNS configuration from resolv.conf files, a new option for +optimizing the use of root servers, a new option that makes defining local +records for reverse resolving easier, support for defining wildcard records, a +new pdnsd-ctl command for reloading the config file without restarting pdnsd, +and a new pdnsd-ctl command for dumping information about the names stored in +the cache. +The documentation has also been updated: there is now a pdnsd.conf man page. For +a more complete list of the changes I'll have to refer you to README.par and the +ChangeLog. + +Version 1.1.11a-par contains a fix for FreeBSD users that bypasses a problem +with the macro ENONET, which can cause a compilation failure when it is +undefined. Linux users will notice no difference between 1.1.11a-par and +1.1.11-par. + +Version 1.1.11-par has a rather large number of small changes, which are rather +difficult to summarize. Among the bugs fixed are a race condition in the cache +lookup code, a flaw in the code that caused a busy spin when a remote server +answered with "Not Implemented", and problems with the -4 and -6 command-line +options. Among the improvements are an alternative sorting algorithm which +should allow pdnsd to start up faster when reading a large cache file from disk, +automatic mapping of IPv4 to IPv6 addresses when running in IPv6 mode, somewhat +more efficient memory use, better compression of the replies and changes in the +parallel querying algorithm that should improve the chances of catching a reply +from a remote server. For a more complete list of the changes I'll have to +refer you to README.par and the ChangeLog. + +Version 1.1.10-par has a new parser for configuration files, completely +rewritten from scratch in C. The main advantages are: (f)lex and yacc/bison are +no longer needed to build pdnsd, more informative error messages instead of +merely "parse error", and string literals no longer need to be enclosed in +quotes in most cases. Furthermore, a bug has been fixed that caused incorrect +IPV6-type PTR records to be generated when sourcing /etc/hosts like files. +There have been other small changes, more details can be found in the ChangeLog. + +Version 1.1.9-par adds some missing pieces to the documentation (the pdnsd +manual and the man page for pdnsd-ctl). The changes to the code consist mostly +of optimizations, removal of some size limits due to fixed-size buffers, and +some cleaning up. I've also tried to make the error responses of pdnsd-ctl more +helpful. More details can be found in the ChangeLog. + +Version 1.1.8b1-par8 introduces a "delegation-only" feature that may be useful +for blocking Verisign's Sitefinder. The parser for the configuration file now +tolerates domain names missing a dot at the end. I have provided alternative +implementations for some GNU extensions that I used in an effort to make the +code more portable. In particular, the code should build on FreeBSD again. More +details can be found in the README.par file. + +Version 1.1.8b1-par7 fixing a number of bugs. I have also reworked some of the +code for adding and removing entries in the cache in an effort to improve +efficiency and stability. More details can be found in the ChangeLog. + +Version 1.1.8b1-par6 introduces some further code cleanup. In addition the +documentation has been revised. + +Version 1.1.8b1-par5 fixes a troublesome allocation size error that has been +discovered in Thomas Moestl's code. In practice this bug only wastes memory but +it could also potentially lead to memory corruption. Upgrading is +recommended. More details can be found in the ChangeLog. + +Version 1.1.8b1-par4 has been released. Due to incompatibilities between +various implementations of the pthread library on Linux systems, problems can +occur with signal handling in pdnsd. The usual symptom is failure by pdnsd to +save the cache to disk, and /var/cache/pdnsd/pdnsd.cache remaining empty. If you +experience this kind of trouble, try reconfiguring with different values for the +new --with-thread-lib option. The allowable values are described in the +documentation. + +pdnsd is no longer maintained by Thomas Moestl: I have not had time to maintain +pdnsd for quite a while now, and have been very slow to respond to issues, or +did not respond at all. It is time that I officially announce that pdnsd is no +longer actively maintained; I apologize to all those who reported bugs or asked +questions without receiving any reply. However, Paul A. Rombouts has published a +patch set against the last released version at +http://www.phys.uu.nl/~rombouts/pdnsd.html, which cleans up a lot of code fixes +many bugs. + +Version 1.1.7a fixes a reversed assertion that would cause pdnsd to terminate +if used with the ping uptest. No other changes were made. + +Version 1.1.7 fixes some problems that might be remotely exploitable to +gain access as the user pdnsd runs as (an unprivileged user by default). To do +this, an attacker needs to control a name server that is queried by pdnsd, and +send a malicious reply to such a query. Upgrading is strongly recommended! +There are also minor bug fixes and stability improvements. + +Version 1.1.6 adds the query_port_start and query_port_end options (contributed +by Andreas Steinmetz), that allow confining the ports pdnsd uses for outgoing +queries to a certain range. It also fixes numerous bugs, one of which could +cause pdnsd to hang; update is therefore recommended. + +Version 1.1.5 contains a fix for a security bug that would allow local users +that are allowed to use pdnsd-ctl on a running pdnsd server to execute +arbitrary code as the user that pdnsd runs as (or on Linux, when strict_setuid +is not enabled, as the user that started pdnsd). The danger of this is usually +quite limited; the status socket is not enabled by default, it's default +permissions do only allow the user pdnsd runs as to use the socket, +strict_setuid is enabled by default and pdnsd runs as an unprivileged user. +There is also a new configure option, --enable-underscores, that will make +pdnsd allow underscores in domain names. Furthermore, the SRV record handling +has been fixed to allow underscores in any case (this was not allowed +previously, but is required by the RFC). SOA records are not put in the +answer section any more if no answers are found (this violates the RFC's). +It may be put in the authority section in a later version. +There are also various bugfixes in this release. +Upgrade is recommended. + +Version 1.1.4 fixes various smaller bugs, and should also improve the cache +write performance especially for larger caches. There are also two new +features: servers can now be given a label (using the label server option) +which can be used to identify them for the pdnsd-ctl server command +(contributed by Andrew M. Bishop), and local records can be marked to make +the domain record authoritative in pdnsd's cache (which means that pdnsd will +assume that records that are not present in the cache for that domain are +non-existent); this is on by default now, and can be controlled using the new +authrec server option). + +Version 1.1.3 added contrib/ and had a lot of robustness fixes. +This release addresses a security hole that affects only Linux systems. Due to +a bug in glibc, pdnsd could crash during a port scan. This release contains +a workaround for this, as well as a fix for a deadlock under heavy load +conditions. It also fixes a possible problem that could be triggered by +malicious servers, and contains numerous bug fixes. +A script, contributed by Marko Stolle, makes pdnsd useful in a DHCP setup. +pdnsd also preservers the case of names in the cache, and should work much +better on alpha machines (thanks for the contributions by Bjoern Fischer +and P.J. Bostley that made this possible). New types were dded for rr +sections and pdnsd-ctl. +Upgrade is recommended. + +Version 1.1.2 has a fix for a bug that could cause SERVFAIL to be +returned when NXDOMAIN would be appropriate. The bug surfaced only when +pdnsd queried name servers with a behaviour different from BIND's in the +NXDOMAIN case, e.g. pdnsd querying another pdnsd or e.g. djbdns. + +Version 1.1.1 fixes a possible race condition in status socket creation. +This race might be used by a local attacker to change the access +permissions of a certain file in /tmp. The risk of this is probably +negligible. The default setup uses a non-privileged user, default mode +0600, and the status socket is disabled normally, so this should be +relatively safe. I don't see any possibility to exploit this, it is +more of a paranoia fix. +There are also some other minor fixes and documentation improvements. +Upgrade is recommended. + +Version 1.1.0 introduces negative cacheing, pdnsd-ctl enhancements and +a much improved FreeBSD support. The cache file format has changed from +prior releases. Some configuration defaults have changed, too. + +Version 1.0.15 is mostly a bugfix release. It also has a new option: +randomize_recs in the global section. + +Version 1.0.14 has a fix in icmp.c that will make it build properly +on FreeBSD and older Linux systems. + +Version 1.0.13 has some code cleanup, a fix for the Debian rc install, +and a security fix (contributed by Olaf Kirch): when changing +user and group id, pdnsd did not drop supplementary group IDs that +the original user was member of. + +Version 1.0.12 is a bugfix release and contains some security +enhancements. There are also inclusion/exclusion lists for servers +(new options include=, exclude=, policy= in the server +section). + +Version 1.0.11 fixes two bugs that might be used for denial-of-service +attacks, upgrading is recommended. + +Versions 1.0.9 and 1.0.10 are bugfix releases. + +Version 1.0.8 introduces special linux ppp device support contributed +by Ron Yorston, and has some bugfixes. + +Version 1.0.7 introduces autoconf support, many new config file options and +the new pdnsd-ctl run-time configuration program. + +Version 1.0.6 has another set of bugfixes, in addition to higher compile- +time configurability and UDP query support. It also contains Debian rc +scripts contributed by Markus Mohr. + +Version 1.0.5 has some bugfixes and the new "server_ip" option +contributed by Wolfgang Ocker. + +Version 1.0.4 introduces the new options run_as, strict_setuid and +paranoid. These new options are optional security enhancements. + +Versions 1.0.1, 1.0.2 and 1.0.3 are bugfix releases. + +Version 1.0.0 has a lot of changes compared to the 0.9.x tree, but much of +them "under the hood": +- IPv6 support (experimental; compile- and run-time configurable) +- FreeBSD (and such hopefully *BSD) support +- better rfc2181 compatability +- new options: + - serve_aliases in source section + - linkdown_kluge in global section + - max_ttl in global section +- cache-code reorganization, only one unified hash (of variable depth) +- Optimizations & cleanups +- Automatic deps (only interesting for developers ;-) + +Version 0.9.11 fixes a locally exploitable security hole (the cache file was +world writeable by default). Please see ChangeLog.old for details. + +Version 0.9.10 fixes some bugs and improves build on Red Hat. + +Version 0.9.9 contains the rc scripts for Red Hat Linux contributed by Torben +Janssen, in addition to code cleanups and bugfixes. +The meaning of the option -v has changed in this release. +There is also a new config file option "lean_query" that is on by default. It +is an optimization, so please look in the docs when updating whether you want +it switched on or not. + +When compiling versions after 0.9.8, you will probably get more +compiler warningsthan before. This is because the C compiler settings +have been made stricter. + +Version 0.9.8 fixes a minor bug some build problems with glibc2.0 systems. + +The versions 0.9.6 and 0.9.7 are bugfix releases. + +Version 0.9.5 introduces uptest=exec, and a modified config file syntax (cache +sizes are now specified in kB). + +Version 0.9.4 was the first to be released to the public. For information on +changes, see ChangeLog. + diff --git a/jni/pdnsd/PKGBUILD.in b/jni/pdnsd/PKGBUILD.in new file mode 100644 index 00000000..3d617651 --- /dev/null +++ b/jni/pdnsd/PKGBUILD.in @@ -0,0 +1,24 @@ +# Package build script for Arch Linux, +# contributed by Alexander Drozdov. + +pkgname=@PACKAGE@ +pkgver=@VERSION@ +pkgrel=@packagerelease@ +pkgdesc="pdnsd is a proxy DNS server with permanent caching (the cache contents are written to hard disk on exit) that is designed to cope with unreachable or down DNS servers." +url="http://members.home.nl/p.a.rombouts/pdnsd.html" +license="GPLv3" +depends=() +makedepends=(glibc) +conflicts=() +replaces=() +backup=() +install= +source=(http://members.home.nl/p.a.rombouts/pdnsd/releases/$pkgname-$pkgver-$pkgrel.tar.gz) +md5sums=() + +build() { + cd $startdir/src/$pkgname-$pkgver + ./configure --prefix=/usr --enable-ipv6 --sysconfdir=/etc --with-distribution=ArchLinux + make || return 1 + make DESTDIR=$startdir/pkg install +} diff --git a/jni/pdnsd/README b/jni/pdnsd/README new file mode 100644 index 00000000..7042e934 --- /dev/null +++ b/jni/pdnsd/README @@ -0,0 +1,22 @@ +You can find the documentation for pdnsd in the doc/ directory. The html +documentation (which I recommend) is in the doc/html/ subdirectory. +The pure text documentation (which is generated automatically from the +html documentation) is in doc/txt/. +The following documents are available: + +index.html / intro.txt Overview, system requirements +doc.html / manual.txt Building, installation and usage instructions +faq.html / faq.txt The FAQ + +Share and enjoy! + Thomas + + +For news about recent changes in pdnsd the following files may be of +interest to you: + + README.par + ChangeLog + NEWS + +Last revised: 08 July 2007 by Paul Rombouts diff --git a/jni/pdnsd/README.par b/jni/pdnsd/README.par new file mode 100644 index 00000000..ea181bc6 --- /dev/null +++ b/jni/pdnsd/README.par @@ -0,0 +1,216 @@ + pdnsd version 1.2.9a by Paul Rombouts + ===================================== + +This file describes the version of pdnsd that I maintain personally and am +making available so other people can enjoy the latest features and fixes. Thomas +Moestl no longer maintains pdnsd himself, so I am effectively the new +maintainer. This README describes the new features in version 1.2. This version +has a rather large number of internal changes and also some new features, which +I am rather pleased with, even if I say so myself. I think the changes are +significant enough to warrant increasing the minor version number from 1.1 to +1.2. The differences between my previous "official" release 1.1.11 and Thomas' +last release 1.1.7a are described in my previous README, which I have renamed +REAME.par.old. In this README I restrict myself to describing changes between +1.1.11 and 1.2. +The main difference between versions 1.2 and 1.2.1, aside from some minor +changes, is that 1.2.1 has (experimental) support for the Cygwin platform. +Version 1.2.2 has further improvements in portability and should in +particular now also compile on the Darwin (Apple Mac OS X) platform. +Version 1.2.4 has some important fixes for a memory leak, a minor buffer- +overflow problem and some situations which could cause pdnsd to exit +prematurely. Note that TCP-query support is now compiled in by default, but can +still be disabled using a configure option. +The main new feature of version 1.2.5 is the new query method "udp_tcp". +Version 1.2.6 has an updated license: GPL version 3. The main new feature of +version 1.2.6 is the "reject" option, which makes it possible to censor or +correct for unwanted IP addresses in replies. +Version 1.2.7 contains an important fix for a "dangling pointer" bug and +attempts to make pdnsd less vulnerable to the issues raised in CERT +vulnerability note VU#800113. It also contains some improvements for defining +local records interactively using the pdnsd-ctl utility. +The main new feature of version 1.2.8 is automatic discovery of root servers, +as well as some minor improvements in the resolver. +Version 1.2.9 among other things supports many addtional RR types, uses data +structures that should be more slightly more memory efficient and has support +for EDNS, which allows DNS UDP messages to be larger than 512 bytes. +Version 1.2.9a is a simple bugfix release that fixes a problem with compiling +1.2.9 after configuring with --enable-strict-rfc2181. Unless you use this option +to compile pdnsd, there is no need to upgrade from 1.2.9 to 1.2.9a. + +For instructions how to compile and install pdnsd see doc/html/doc.html or +doc/txt/manual.txt. Note that I am no longer distributing a patch w.r.t. Thomas' +version because the (compressed) patch file is barely smaller than the +(compressed) tar archive. + +Here follows a list of some of changes in version 1.2 from a user's perspective. +For a more technical description of some of the changes in the code see the ChangeLog. +For a short history about recent releases have a look at NEWS or doc/html/index.html. + +- First of all, two potentially rather nasty bugs have been fixed in the code + for the handling of NXT and NAPTR records. A response from a remote server + containing NXT records (even well-formed ones) will very likely cause pdnsd to + crash. The code for handling NAPTR records contained incorrect ASSERT + statements, which could cause pdnsd to abort in a controlled fashion, but + completely unnecessarily. + +- Sampo Lehtinen has remarked that pdnsd sometimes failed to resolve classless + reversed-delegated IP addresses, and that this has something to do with the + fact that pdnsd didn't accept '/' characters in domain names. After reading + some of the relevant RFCs I decided to remove all restrictions on the types + of characters that pdnsd accepts in domain names. Of course for most + applications, there are many characters which don't make sense in domain + names, but I feel that it is the responsibility of the client application to + reject these, not the proxy server. + +- At the suggestion of Dan Tihelka, I have expanded to the server_ip= option to + allow the name of an interface to be specified instead of an IP address. + Presently this has been tested on Linux only. Can someone running pdnsd on + *BSD tell me if the code for getting the address of an interface is different + for Linux and BSD-type systems? + +- At the suggestion of Juliusz Chroboczek I've added an new server availability + test which can be specified with uptest=query. This can be useful as an + alternative to "uptest=ping" in case the remote server does not respond to + ICMP_ECHO requests at all, which unfortunately is quite common these days. + "uptest=query" causes pdnsd to send an empty query to remote name servers. Any + well-formed response (apart from SERVFAIL) within the timeout period will be + interpreted as a sign that the server is "up". + +- Instead of specifying the IP addresses of the name servers that pdnsd should + query in a server section of the config file, you may also specify a + resolv.conf-style file. Preferably this should not be /etc/resolv.conf. If the + contents of the resolv.conf type file changes while pdnsd is running, you can + make pdnsd aware of the changes with the "pdnsd-ctl config" command, see + below. Example: + + server { + label=myisp; + file=/etc/ppp/resolv.conf; + timeout=10; + } + +- There is a new option for "server" sections in the config file: + root_server=on/off. + In case a server section contains only addresses of root servers, which + usually only give the name servers of top level domains in their reply, + setting root_server=on will enable certain optimizations. This involves using + cached information to reduce queries to the root servers, thus speeding up the + resolving of new names. + +- New option for "rr" sections in the config file: reverse=on/off. + If you want a locally defined name to resolve to a numeric address and vice + versa, you can now achieve this by setting reverse=on before defining the A + record, making it unnecessary to define a separate PTR record for the reverse + resolving. + Example: + + rr { + name = localhost; + reverse = on; + a = 127.0.0.1; + } + + has the same effect as: + + rr { + name = localhost; + a = 127.0.0.1; + } + rr { + name = 1.0.0.127.in-addr.arpa; + ptr = localhost; + } + +- In rr sections it is now possible to specify a wildcard name, i.e. a name + starting with the label *. The * in a wildcard can match one or more labels in + a queried name, but only whole labels. For example, *.mydomain will match + a.mydomain or www.a.mydomain, but not mydomain. Before you can specify an rr + section with name=*.mydomain you must define some records for mydomain, + typically NS and/or SOA records. + Example: + + rr { + name = mydomain; + ns = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + rr { + name = *.mydomain; + a = 192.168.1.10; + } + +- There is a slight backwards compatibility problem which involves the name= and + owner= options in rr sections. The new version does not allow you to place + owner= before name=. On the other hand, you may now freely mix the owner + option with the a,ptr,cname,mx and soa options and define as many records of + this type as you like (including zero). + +- pdnsd-ctl has three new commands: + + config: Reloads pdnsd's configuration file. This is more efficient than + restarting pdnsd, and should not cause only noticeable interruption in DNS + service. However, some types of configuration changes cannot be put into + effect this way, and you will be prompted to restart pdnsd instead. + + empty-cache: Empties the cache completely, freeing all existing entries. + In version 1.2.3 you can specify a selection of entries to delete by providing + a list of include/exclude patterns. + + dump: Prints information about all the names stored in the cached. This is + mainly useful for diagnostic purposes. + +- There is now a pdnsd.conf(5) man page, describing pdnsd's configuration file. + The man page has been generated from the html documentation using a customized + Perl script. + +- New in version 1.2.4: Time intervals in the configuration files can now be + expressed in seconds, minutes, hours, days and weeks, using the suffixes + s,m,h,d,and w. + Example: 2h30m is interpreted as 2*60*60 + 30*60 = 9000 seconds. + +- Version 1.2.5 introduces a new configuration option, contributed by Jan-Marek + Glogowski, called "use_nss" which can be turned off to prevent nasty delays in + certain situations. + Besides the query methods "udp_only", "tcp_only" and "tcp_udp" you can now + also specify "udp_tcp", which more closely adheres to the behaviour + recommended by DNS standards. + +- Version 1.2.6 introduces the "randomize_servers" and "reject" options. By + setting "randomize_servers" on you can give each server in a server section an + equal chance of being queried, which is useful when resolving from root + servers, for instance. The "reject" option can be used to censor certain IP + addresses or correct for unwanted replies from servers you don't completely + trust. + +- Version 1.2.7 contains support for "include" files which can be referenced + from configuration files or read interactively using pdnsd-ctl. These files + can be used to add local definitions to the cache without reconfiguring pdnsd. + The new "pdnsd-ctl eval" command can be used to interactively define local + records that could previously only be defined in configuration files but not + with the "pdnsd-ctl add" command. + +- Version 1.2.8 contains support for automatic discovery of root servers. + Instead of supplying a complete list of IP addresses of root servers in a + server section of the configuration file, you need only enter one or two + addresses of name servers which know the names and addresses of the root + servers and set "root_server=discover". + The "neg_rrs_pol" option has a new default setting, which should allow + sensible negative caching of RRs in most situations, even if "proxy_only=on". + +- Version 1.2.9 contains support for EDNS (Extension mechanisms for DNS), which + allows UDP messages to be larger than 512 bytes. Whether pdnsd uses EDNS in + outgoing queries is determined by the configuration option "edns_query". If + pdnsd receives a query using EDNS, it will reply using EDNS regardless of the + configuration settings. + Local TXT records can now be defined in the configuration file. + If the query uptest fails due to remote servers ignoring empty queries, this + can now be remedied using the new "query_test_name" config option. + +The new features are described in greater detail in the manual doc/html/doc.html +or doc/txt/manual.txt. + +Enjoy! + +If you have any questions about my version of pdnsd, you can send these +to . Questions about the original (unmaintained) pdnsd +version should be sent to or . diff --git a/jni/pdnsd/README.par.old b/jni/pdnsd/README.par.old new file mode 100644 index 00000000..4bf0edaf --- /dev/null +++ b/jni/pdnsd/README.par.old @@ -0,0 +1,249 @@ + pdnsd maintenance version 1.1.11-par by Paul Rombouts + ======================================================= + +This file describes the version of pdnsd that I maintain personally and am +making available so other people can enjoy the latest features and fixes. +Thomas Moestl no longer maintains pdnsd himself, so I am effectively the new +maintainer. The current version is 1.1.11-par, which has a rather large number +of small changes. Among the bugs fixed are a race condition in the cache lookup +code, a flaw in the code that caused a busy spin when a remote server answered +with "Not Implemented", and problems with the -4 and -6 command-line options. +Among the improvements are an alternative sorting algorithm which should allow +pdnsd to start up faster when reading a large cache file from disk, automatic +mapping of IPv4 to IPv6 addresses when running in IPv6 mode, somewhat more +efficient memory use, and better compression of the replies. Some of the new +features are described in the second half of this file (look for "new in version +1.1.11"). For the rest of the changes I will have to refer you to the ChangeLog. +For a short history about recent releases have a look at doc/html/index.html. + +Since version 1.1.9 I've added some missing pieces to the documentation (the +manual doc/html/doc.html,doc/txt/manual.txt and the man page doc/pdnsd-ctl.8). +Version 1.1.11 finally has a man page doc/pdnsd.8, thanks to a contribution by +Mahesh T. Pai. + +The first part of this file describes how to patch, compile, install and run +pdnsd. The second part describes some of the changes I've made to Thomas +Moestl's code. + +Unless you're using the pre-patched source archive pdnsd-1.1.11-par.tar.gz you +must first apply my patch file pdnsd-1.1.11-par.diff.gz before compiling and +installing pdnsd according to Thomas Moestl's instructions described in the the +documentation. Use a freshly untarred copy of Thomas Moestl's original version +1.1.7a source, cd into the source directory pdnsd-1.1.7a and apply the command: + +gzip -cd /pdnsd-1.1.11-par.diff.gz | patch -p2 -N -Z + +Note: I have used GNU extensions so there may be some portability issues. I have +supplied alternatives for some of the less portable functions. There should be no +problem with most Linux distributions. + +That's it! You should now be able to compile, install and run pdnsd. See the +documentation in doc/html/doc.html or doc/txt/manual.txt for more detailed +instructions. + +Some people may want change the compiler optimization flag. I use the -O2 flag, +but it might be safer to use a lower level of optimization or no optimization at +all. In that case prefix the configure command with the desired compiler flags +like this (assuming you're using a bash shell): + + CFLAGS="-O1 -g -Wall" ./configure ... + +I have added a new configuration option "--with-thread-lib=", which you +should use if you experience problems with signal handling under Linux. The +usual symptom is failure by pdnsd to save the cache to disk, and +/var/cache/pdnsd/pdnsd.cache remaining empty. If you experience this kind of +trouble, try reconfiguring with different values for the --with-thread-lib +option. The allowable values are "linuxthreads" (the default), "linuxthreads2" +(or "lt2" for short), and "nptl". I recommend that you first configure and +compile without the --with-thread-lib option, then if you experience trouble try +again with --with-thread-lib=lt2 and recompile. +If your Linux system has an implementation of the Native POSIX Thread Library, +which is the case with Red Hat 9 for instance, you should use +--with-thread-lib=nptl . +Ideally, I would like to write a configure script which automatically detects +which kind of thread library is being used on a Linux system, but I don't have a +clue yet how to do this. If you can help me with this please write to me at the +email address listed at the end of this file. + +The rest of this file describes some of the modifications I've made, but you +don't have to read it if you simply want to run pdnsd as you're used to. + + +- The main new feature I've added enables you to change the server addresses + that pdnsd uses at run-time using pdnsd-ctl. I've done this because the ISPs I + use do not specify fixed DNS server addresses, but expect their clients to use + dynamic DNS configuration (DHCP in the case of the cable connection, RFC1877 + in case of isdn). I've extended the options that can be given with the + "server" command to pdnsd-ctl, to allow IP addresses to be specified as an + additional argument after "up|down|retest". This allows me to put something + like this in my ifup-local script: + + pdnsd-ctl server isp-label up "$DNS1 $DNS2" + + For more details how to use pdnsd-ctl read the updated documentation in + the doc/html directory. There is also a manpage for pdnsd-ctl. + This was quite tricky to implement because there might be pending queries + while the addresses are being changed. It certainly was an interesting + exercise in writing multi-threaded code for me. + + +- I've implemented a feature which allowed me to specify multiple IP addresses + per server section in the configuration file. This allowed for a much more + compact configuration file (3 server sections instead of 7 in my case), + because most configuration options are identical for servers belonging to the + same ISP. It also made the output of "pdnsd-ctl status" more compact. And it + was necessary to enable a satisfactory implementation of the previous feature. + Example of the new syntax: + + ip = 123.456.789.001, 123.456.789.002, 123.456.789.003; + + At the suggestion of Greg Norris server sections no longer have to specify IP + addresses. A server section without IP addresses will remain inactive until it + is assigned one more addresses at run-time with pdnsd-ctl. + +- I've changed the implementation of dynamic arrays to make it slightly more + efficient, and improve type safety. I also got rid of several arrays of fixed + size in favor of dynamically allocated arrays. In particular, I got rid of + all occurrences of MAXPATH. I also made several static variables "automatic". + +- The output of the "status" command of pdnsd-ctl now gives more meaningful + constant names "ping|none|if|exec" instead of numbers for the "uptest" option. + I've also added some information that was previously missing. + +- I've fixed I a problem that caused pdnsd to use up a lot of CPU time and slow + down my system considerably when it received a query that took a long time to + resolve. It turned out that pdnsd can get into a "busy spin" when one of the + DNS servers pdnsd is querying refuses the connection. Apart from fixing this + bug, to speed things up additionally, I thought it would be a good idea to + mark a server down (without retesting it) after detecting errno==ECONNREFUSED. + This gives me very satisfactory performance, with the problematic server being + tried only once during every testing interval. + + New in version 1.1.11: An additional busy spin condition, triggered when a + remote server answers with "Not Implemented", has been discovered and fixed. + In case there are remaining bugs in the multiplexing code, I've added a test + that checks if the number of events reported by poll/select matches the number + of events handled by pdnsd. If not, pdnsd will log an error message and give + up. Although the bugs still need to be reported and fixed, at least this + should prevent pdnsd from wasting CPU cycles. + +- Due to a bug in Thomas' code, pdnsd tries, but fails, to remove the control + socket "pdnsd.status" before exiting. This has also been fixed. In version + 1.1.8b1-par6 I have cleaned this up some more so that pdnsd will handle + situations where it can't open or bind the control socket more gracefully. + +- I've rewritten some of the code that saves the contents of the cache to the + file "pdnsd.cache" just before pdnsd exits. This is because I noticed in my + logfiles that pdnsd occasionally had problems reading this file back at + startup. I eliminated the use of fseek() in Thomas' code. I could not find + anything that was demonstrably incorrect about his use of fseek(), but it + seemed better to me to do without it and write the file in a strictly + sequential order. Anyway, it turned out my hunch paid off: no more error + messages about "pdnsd.cache" in my logfile. + + New in version 1.1.11: I've added some new code for sorting the queue used for + purging stale cache entries. This should allow pdnsd to start up faster when + reading large cache files from disk. + +- I've extended the configuration options for policies of inclusion/exclusion + lists in server sections. The new policies options are "simple_only" and + "fqdn_only". Setting policy=simple_only will cause the server to used only for + simple hostnames if no other rule matches. On the other hand, setting + policy=fqdn_only will cause the server to be used only for fully qualified + domain names (i.e. the name has at least one dot in-between). I find these + options useful for controlling which name servers (if any) will be used by + pdnsd for simple host names. + +- I've added a new "delegation_only" option that can be used to undo the + unwanted effects of DNS "wildcards". It works roughly as the feature by the + same name in BIND. It is turned off by default. To block Verisign's + Sitefinder, add the following line to the global section of the configuration + file: + + delegation_only= com, net; + + If you find that this feature blocks some legitimate domain names, you will + probably need to add the address of a nameserver that provides good authority + information. More information can be found at + http://www.phys.uu.nl/~rombouts/pdnsd/delegationonly.html + +- It is no longer mandatory that domain names in the configuration file end in a + dot. + +- The parser for configuration files has been rewritten purely in C, so (f)lex + and yacc/bison are no longer needed to build pdnsd. + It is no longer necessary to place strings between quotes in the configuration + file, unless a string contains a special character such as whitespace, a token + that normally starts a comment, or one of the characters ",;{}". Note that + these special characters are illegal in domain names anyway. + +- New in version 1.1.11: Negating whole domains with a neg section in the + config file will result in all the subdomains being negated as well. + For example, adding the lines + + neg {name=doubleclick.com; types=domain;} + neg {name=doubleclick.net; types=domain;} + + will also negate ad.doubleclick.com, ad.fr.doubleclick.net, etc. + +- New in version 1.1.11: When running in IPv6 mode, pdnsd will now automatically + map any IPv4 addresses it reads in the config file to IPv6 addresses. + When pdnsd has been compiled with IPv6 support and runs in IPv4 mode, it will + skip IPv6 addresses with a warning message. This may result in certain server + sections becoming inactive, though. + + The -4 and -6 options should now work as advertised. + I've added two new command-line options, "-a" and "-i ". + With the -a flag pdnsd will try to detect automatically if IPv6 support is + available on a system, and fall back to IPv4 if not. The -a flag can be used + instead of -4 or -6. + The -i option can be used to specify a prefix for mapping IPv4 to IPv6 + address. The default is ::ffff.0.0.0.0. There is also a corresponding + ipv4_6_prefix= option for the config file. + +- New in version 1.1.11: I've slightly changed the way pdnsd does parallel + queries. Active queries or not canceled until we have received a useful + response from a remote name server, or all the queries have failed or timed + out. Thus the par_queries parameter is no longer the maximum number of + parallel queries, but rather the increment with which the number of parallel + queries is increased when the previous set has timed out. In the worst case + there will be pending queries to all the servers in the list of available + servers simultaneously. We may be wasting more system resources this way, but + the advantage is that we have a greater chance of catching a reply. After all, + if we wait longer anyway, why not for more servers. + I've also introduced a global timeout parameter. This is the minimum period of + time pdnsd will wait after sending the first query to a remote server before + giving up without having received a reply. The timeout options in the + configuration file are now only minimum timeout intervals. Setting the global + timeout option makes it possible to specify quite short timeout intervals in + the server sections. This will have the effect that pdnsd will start querying + additional servers fairly quickly if the first servers are slow to respond + (but will still continue to listen for responses from the first ones). This + may allow pdnsd to get an answer more quickly in certain situations. + + After receiving a reply from a remote server the server is marked up and its + time stamp is updated. This will have the effect that pdnsd doesn't bother + testing this server for availability for a period of time, and thus the + overhead caused by testing is reduced. After server timeouts, uptests are + performed by the separate server status thread, not by threads that have to + answer queries. Unresponsive servers with uptest=ping will not be marked down + immediately any more, but only after the ping test has definitely failed. + +I've also included a number of bug-fixes contained in a patch file supplied to +me by Thomas Moestl. In addition to the things I had already fixed, the +following issues are addressed: some memory leaks, dropping of root privileges +before calling uptest scripts in case pdnsd was started setuid root (which is a +bad idea anyway), passing on open fd's to uptests, integer overruns in the +status reporting code, fixing string passing from the lexer, more consistent +treatment of underscores in domain names. + +In addition to the things I've listed above, I've made various little changes to +fix minor bugs, improve efficiency or elegance, or simply to suit my my own +coding style. These changes are too numerous to list here, but some of them are +listed in the ChangeLog. Of course if you are really interested in the +nitty-gritty you can always compare the source of my version with Thomas' +original code. + +If you have any questions about the modifications I've made, you can send these +to . Questions about the original pdnsd version should +be sent to or . diff --git a/jni/pdnsd/THANKS b/jni/pdnsd/THANKS new file mode 100644 index 00000000..9c7e3bbc --- /dev/null +++ b/jni/pdnsd/THANKS @@ -0,0 +1,66 @@ +This is a (hopefully complete) list of people I have to thank for helping me +develop and improve pdnsd: + +David G. Andersen +Andrew M. Bishop +Daniel Black +Carsten Block +Stephan Boettcher +P.J. Bostley +Rodney Brown +Kevin A. Burton +Juliusz Chroboczek +Joachim Dorner +Frank Elsner +Christian Engstler +Stefan Erhardt +Bjoern Fischer +Stefan Förster +Bert Frederiks +Mike Hammer +Jonathan Hudson +Torben Janssen +Byrial Jensen +Olaf Kirch +Nikola Kotur +Kiyo Kelvin Lee +Bernd Leibing +Patrick Loschmidt +James MacLean +Sourav K. Mandal +Fraser McCrossan +Markus Mohr +Michael Müller +Gustavo Niemeyer +Alexandre Nunes +Wolfgang Ocker +Mahesh T. Pai +Bernhard Pelz +Soenke J. Peters +Erich Reitz +Paul A. Rombouts +Brian Schroeder +Roman Shterenzon +Daniel Smolik +Milan P. Stanic +Michael Steiner +Norbert Steinl +Andreas Steinmetz +Marko Stolle +Markus Storm +Michael Ströder +Thomas Stromberg +Alan Swanson +Lyonel Vincent +Eelco Vriezekolk +Paul Wagland +Sverker Wiberg +Michael Wiedmann +Ron Yorston +Nikita V. Youshchenko +Jan-Marek Glogowski +Thomas Cort +Pierre Habouzit +Dirk Armbrust +Georg Schwarz +Ashish Shukla diff --git a/jni/pdnsd/TODO b/jni/pdnsd/TODO new file mode 100644 index 00000000..f6a1650a --- /dev/null +++ b/jni/pdnsd/TODO @@ -0,0 +1,20 @@ +- Implement a reference counter to ensure that newly entered records are not + purged immediately (really needed?) +- Perhaps do a two-step form of recursive query: first query those servers we + have got cached, then (if unsuccessful) look the others up and query again. + The impact of this optimisation may not be very big, because all sane servers + give A records for NS records if possible. +- Test for compatibility on other Unix-like Systems other than the BSDs and + Linux; rewrite the functions in netdev.c and icmp.c for those OSs if + necessary. Also try to get compatibility for other compilers than gcc. +- Write an install rule for the Slackware start-up script. +- Update the FAQ. +- Implement DNSSEC support. Since version 1.2.9, pdnsd is able to cache the RR + types necessary for DNSSEC, but the resolver is not yet security aware. +- Implement a lookup table (hash table) for queries in progress. This would + enable a thread that is resolving a query that is already being handled by + another thread to wait for that other thread to finish and copy its result + rather than independently query remote servers. It is very common for + resolvers to resend UDP queries if they don't get a reply within a timeout + period and if the answer is not yet cached, this will result in multiple + threads duplicating each others work in the current implementation. diff --git a/jni/pdnsd/acconfig.h b/jni/pdnsd/acconfig.h new file mode 100644 index 00000000..c8640712 --- /dev/null +++ b/jni/pdnsd/acconfig.h @@ -0,0 +1,191 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* ONLY EDIT acconfig.h, NEVER config.h or config.h.in! + * config.h MAY BE OVERWRITTEN BY make, config.h.in by autoheader! */ + +/* Define your Target here. Currently defined are TARGET_LINUX (any + * architecture), TARGET_BSD (experimental; tested on FreeBSD, hopefully + * works for other BSD variants) and TARGET_CYGWIN. */ +#define TARGET TARGET_LINUX + +/* change the #undef to #define if you do not want to compile with special + * ISDN support for Linux. Note that the ISDN support will not compile ok on + * unpatched kernerls earlier than 2.2.12 (if you did apply newer isdn patches, + * it may work fine). This is not on by default because it will cause compile + * problems on some systems */ +#undef ISDN_SUPPORT + +/* The following regulates the IP Protocol support. Supported types are IPv4 + * and IPv6 (aka IPng). You may enable either or both of these protocols. + * Enabling in this context means that support for the respective protocol + * will be in the binary. When running the binary, one of the protocols may + * be activated via command line switches. Note that activating both IPv4 and + * IPv6 is pointless (and will not work because two UDP and two TCP threads + * will be started that concur for ports). Because of that, it is not allowed. + * When pdnsd runs with IPv6 activated it should be able to service queries + * from IPv6 as well as from IPv4 hosts, provided that you host is configured + * properly. + * For each of the protocols there are two options: ENABLE_IPV4 and ENABLE_IPV6 + * control whether support for the respective protocol is available in the + * binary. DEFAULT_IPV4 selects which protocol is enabled on pdnsd + * startup by default. 1 means IPv4, while 0 means IPv6. If support for + * a protocol was included in the executable, you can specify command line + * parameters to activate or deactivate that protocol (the options are -4 and + * -6), but it makes more sense to use the run_ipv4=on/off option in the + * configuration file. + * Make your choice. Note that IPv6 support is experimental in pdnsd. + * In normal operation, you will currently only need IPv4. */ +#undef ENABLE_IPV4 +#define DEFAULT_IPV4 1 +#undef ENABLE_IPV6 + +/* In all pdnsd versions before 1.0.6, DNS queries were always done over + * TCP. Now, you have the choice. You can control that behaviour using + * the -m command line switch, and you can give a preset here. There + * are 3 different modes: + * UDP_ONLY: This is undoubtedly the fastest query method, because + * no TCP negotiation needs to be done. + * TCP_ONLY: This is slower than uo, but generally more secure + * against DNS spoofing. Note that some name servers on the + * internet do not support TCP queries, notably dnscache. + * TCP_UDP: TCP, then UDP. If the TCP query fails with a "connection refused"- + * error or times out, the query is retried using UDP. + * UDP_TCP: UDP, then TCP. If the UDP reply is truncated (i.e. the tc flag is set), + * the query is retried using TCP. */ +#define M_PRESET UDP_ONLY + +/* In addition to choosing the presets, you may also completely disable + * one of the protocols (TCP for preset UDP_ONLY and UDP for preset TCP_ONLY). + * This saves some executable space. */ +#undef NO_UDP_QUERIES +#undef NO_TCP_QUERIES + +/* With the following option, you can disable the TCP server functionality + * of pdnsd. Nearly no program does TCP queries, so you probably can do + * this safely and save some executable space and one thread. + * You also can turn off the TCP server at runtime with the --notcp option. */ +#undef NO_TCP_SERVER + +/* By undefining the following, you can disable the UDP source address + * discovery code. This is not recommended, but you may need it when + * running into compilation problems. */ +#undef SRC_ADDR_DISC + +/* NO_POLL specifies not to use poll(2), but select(2) instead. If you are + * unsure about what this means, just leave this as it is.*/ +#undef NO_POLL + +/* Define this for "hard" RFC 2181 compliance: this RFC states that + * implementations should discard answers whose RR sets have multiple + * different time stamps. While correct answers are generated, incorrect + * ones are normally tolerated and corrected. Full RFC compliance is + * however only achieved by deactivating this behaviour and thus being + * intolerant. */ +#undef RFC2181_ME_HARDER + +/* Define this to the device you want to use for getting random numbers. + * Leave this undefined if you wand to use the standard C library random + * function, which basically should be sufficient. + * Linux and FreeBSD have two random number devices: /dev/random and + * /dev/urandom. /dev/urandom might be less secure in some cases, but + * should still be more than sufficient. The use of /dev/random is + * discouraged, as reading from this device blocks when new random bits + * need to be gathered. */ +#undef RANDOM_DEVICE +#undef R_DEFAULT +#undef R_RANDOM +#undef R_ARC4RANDOM +/*#define RANDOM_DEVICE "/dev/urandom"*/ + +/* Designate which database manager to use for cacheing. + * default: native; others: gdbm */ +#define CACHE_DBM DBM_NATIVE + +#define CACHEDIR "/var/cache/pdnsd" + +#define TEMPDIR "/tmp"; + +/* This is for various debugging facilities that produce debug output and + * double-check some values. You can enable debug messages with the -g option. + * Normally, you can switch this off safely by setting the number after DEBUG + * to 0. This will increase speed (although only marginally), save space + * in the executable (only about 12kB) and some stack space per thread + * (which may be significant if you have many threads running simultaneously). + * However, it may be an aid when debugging config files. + * The only defined debug levels by now are in the range 0 - 9. + * Define this to 9 if you want hex dumps of all the queries and replies pdnsd + * receives (you must also call pdnsd with -v9 to actually see the hex dumps). + * When in doubt, leave it defined to 1. */ +#define DEBUG 1 + +/* This defines the default verbosity of informational messages you will get. + This has nothing to to with the debug option (-g), but may be set with -v + option. 0 is for normal operation, up to 3 for debugging. + Unlike the debug messages, these messages will also be written to the syslog.*/ +#define VERBOSITY 0 + +/* Redefine this if you want another hash size. + * The number of hash buckets is computed as power of two (1< sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/jni/pdnsd/compile b/jni/pdnsd/compile new file mode 100644 index 00000000..1b1d2321 --- /dev/null +++ b/jni/pdnsd/compile @@ -0,0 +1,142 @@ +#! /bin/sh +# Wrapper for compilers which do not understand `-c -o'. + +scriptversion=2005-05-14.22 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand `-c -o'. +Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file `INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; +esac + +ofile= +cfile= +eat= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we strip `-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/jni/pdnsd/config.h b/jni/pdnsd/config.h new file mode 100644 index 00000000..2bfa2686 --- /dev/null +++ b/jni/pdnsd/config.h @@ -0,0 +1,437 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* ONLY EDIT acconfig.h, NEVER config.h or config.h.in! + * config.h MAY BE OVERWRITTEN BY make, config.h.in by autoheader! */ + +/* Define your Target here. Currently defined are TARGET_LINUX (any + * architecture), TARGET_BSD (experimental; tested on FreeBSD, hopefully + * works for other BSD variants) and TARGET_CYGWIN. */ +#define TARGET TARGET_LINUX + +/* change the #undef to #define if you do not want to compile with special + * ISDN support for Linux. Note that the ISDN support will not compile ok on + * unpatched kernerls earlier than 2.2.12 (if you did apply newer isdn patches, + * it may work fine). This is not on by default because it will cause compile + * problems on some systems */ +/* #undef ISDN_SUPPORT */ + +/* The following regulates the IP Protocol support. Supported types are IPv4 + * and IPv6 (aka IPng). You may enable either or both of these protocols. + * Enabling in this context means that support for the respective protocol + * will be in the binary. When running the binary, one of the protocols may + * be activated via command line switches. Note that activating both IPv4 and + * IPv6 is pointless (and will not work because two UDP and two TCP threads + * will be started that concur for ports). Because of that, it is not allowed. + * When pdnsd runs with IPv6 activated it should be able to service queries + * from IPv6 as well as from IPv4 hosts, provided that you host is configured + * properly. + * For each of the protocols there are two options: ENABLE_IPV4 and ENABLE_IPV6 + * control whether support for the respective protocol is available in the + * binary. DEFAULT_IPV4 selects which protocol is enabled on pdnsd + * startup by default. 1 means IPv4, while 0 means IPv6. If support for + * a protocol was included in the executable, you can specify command line + * parameters to activate or deactivate that protocol (the options are -4 and + * -6), but it makes more sense to use the run_ipv4=on/off option in the + * configuration file. + * Make your choice. Note that IPv6 support is experimental in pdnsd. + * In normal operation, you will currently only need IPv4. */ +#define ENABLE_IPV4 1 +#define DEFAULT_IPV4 1 +#undef ENABLE_IPV6 + +/* In all pdnsd versions before 1.0.6, DNS queries were always done over + * TCP. Now, you have the choice. You can control that behaviour using + * the -m command line switch, and you can give a preset here. There + * are 3 different modes: + * UDP_ONLY: This is undoubtedly the fastest query method, because + * no TCP negotiation needs to be done. + * TCP_ONLY: This is slower than uo, but generally more secure + * against DNS spoofing. Note that some name servers on the + * internet do not support TCP queries, notably dnscache. + * TCP_UDP: TCP, then UDP. If the TCP query fails with a "connection refused"- + * error or times out, the query is retried using UDP. + * UDP_TCP: UDP, then TCP. If the UDP reply is truncated (i.e. the tc flag is set), + * the query is retried using TCP. */ +#define M_PRESET TCP_ONLY + +/* In addition to choosing the presets, you may also completely disable + * one of the protocols (TCP for preset UDP_ONLY and UDP for preset TCP_ONLY). + * This saves some executable space. */ +/* #undef NO_UDP_QUERIES */ +/* #undef NO_TCP_QUERIES */ + +/* With the following option, you can disable the TCP server functionality + * of pdnsd. Nearly no program does TCP queries, so you probably can do + * this safely and save some executable space and one thread. + * You also can turn off the TCP server at runtime with the --notcp option. */ +/* #undef NO_TCP_SERVER */ + +/* By undefining the following, you can disable the UDP source address + * discovery code. This is not recommended, but you may need it when + * running into compilation problems. */ +#define SRC_ADDR_DISC 1 + +/* NO_POLL specifies not to use poll(2), but select(2) instead. If you are + * unsure about what this means, just leave this as it is.*/ +/* #undef NO_POLL */ + +/* Define this for "hard" RFC 2181 compliance: this RFC states that + * implementations should discard answers whose RR sets have multiple + * different time stamps. While correct answers are generated, incorrect + * ones are normally tolerated and corrected. Full RFC compliance is + * however only achieved by deactivating this behaviour and thus being + * intolerant. */ +/* #undef RFC2181_ME_HARDER */ + +/* Define this to the device you want to use for getting random numbers. + * Leave this undefined if you wand to use the standard C library random + * function, which basically should be sufficient. + * Linux and FreeBSD have two random number devices: /dev/random and + * /dev/urandom. /dev/urandom might be less secure in some cases, but + * should still be more than sufficient. The use of /dev/random is + * discouraged, as reading from this device blocks when new random bits + * need to be gathered. */ +/* #undef RANDOM_DEVICE */ +#define R_DEFAULT 1 +/* #undef R_RANDOM */ +/* #undef R_ARC4RANDOM */ +/*#define RANDOM_DEVICE "/dev/urandom"*/ + +/* Designate which database manager to use for cacheing. + * default: native; others: gdbm */ +#define CACHE_DBM DBM_NATIVE + +#define CONFDIR "/data/data/net.typeblog.socks" + +#define CACHEDIR "/data/data/net.typeblog.socks" + +#define TEMPDIR "/data/data/net.typeblog.socks/cache"; + +/* This is for various debugging facilities that produce debug output and + * double-check some values. You can enable debug messages with the -g option. + * Normally, you can switch this off safely by setting the number after DEBUG + * to 0. This will increase speed (although only marginally), save space + * in the executable (only about 12kB) and some stack space per thread + * (which may be significant if you have many threads running simultaneously). + * However, it may be an aid when debugging config files. + * The only defined debug levels by now are in the range 0 - 9. + * Define this to 9 if you want hex dumps of all the queries and replies pdnsd + * receives (you must also call pdnsd with -v9 to actually see the hex dumps). + * When in doubt, leave it defined to 1. */ +#define DEBUG 1 + +/* This defines the default verbosity of informational messages you will get. + This has nothing to to with the debug option (-g), but may be set with -v + option. 0 is for normal operation, up to 3 for debugging. + Unlike the debug messages, these messages will also be written to the syslog.*/ +#define VERBOSITY 0 + +/* Redefine this if you want another hash size. + * The number of hash buckets is computed as power of two (1< and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the `asprintf' function. */ +#define HAVE_ASPRINTF 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `getline' function. */ +#if defined(__aarch64__) || defined(__x86_64__) +#define HAVE_GETLINE 1 +#endif + +/* Define to 1 if you have the `getpwnam_r' function. */ +//#define HAVE_GETPWNAM_R 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `inet_ntop' function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mempcpy' function. */ +//#define HAVE_MEMPCPY 1 + +/* Define to 1 if you have the `mkfifo' function. */ +#define HAVE_MKFIFO 1 + +/* Define to 1 if you have the `nanosleep' function. */ +#define HAVE_NANOSLEEP 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if the system has the type `socklen_t'. */ +#define HAVE_SOCKLEN_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `stpcpy' function. */ +#if defined(__aarch64__) || defined(__x86_64__) +#define HAVE_STPCPY 1 +#endif + +/* Define to 1 if you have the `stpncpy' function. */ +//#define HAVE_STPNCPY 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strndup' function. */ +#define HAVE_STRNDUP 1 + +/* Define to 1 if the system has the type `struct ifreq'. */ +#define HAVE_STRUCT_IFREQ 1 + +/* Define to 1 if the system has the type `struct in6_addr'. */ +#define HAVE_STRUCT_IN6_ADDR 1 + +/* Define to 1 if the system has the type `struct in_pktinfo'. */ +#define HAVE_STRUCT_IN_PKTINFO 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the `uname' function. */ +#define HAVE_UNAME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vasprintf' function. */ +#define HAVE_VASPRINTF 1 + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ diff --git a/jni/pdnsd/config.h.in b/jni/pdnsd/config.h.in new file mode 100644 index 00000000..c4ac9948 --- /dev/null +++ b/jni/pdnsd/config.h.in @@ -0,0 +1,430 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* ONLY EDIT acconfig.h, NEVER config.h or config.h.in! + * config.h MAY BE OVERWRITTEN BY make, config.h.in by autoheader! */ + +/* Define your Target here. Currently defined are TARGET_LINUX (any + * architecture), TARGET_BSD (experimental; tested on FreeBSD, hopefully + * works for other BSD variants) and TARGET_CYGWIN. */ +#define TARGET TARGET_LINUX + +/* change the #undef to #define if you do not want to compile with special + * ISDN support for Linux. Note that the ISDN support will not compile ok on + * unpatched kernerls earlier than 2.2.12 (if you did apply newer isdn patches, + * it may work fine). This is not on by default because it will cause compile + * problems on some systems */ +#undef ISDN_SUPPORT + +/* The following regulates the IP Protocol support. Supported types are IPv4 + * and IPv6 (aka IPng). You may enable either or both of these protocols. + * Enabling in this context means that support for the respective protocol + * will be in the binary. When running the binary, one of the protocols may + * be activated via command line switches. Note that activating both IPv4 and + * IPv6 is pointless (and will not work because two UDP and two TCP threads + * will be started that concur for ports). Because of that, it is not allowed. + * When pdnsd runs with IPv6 activated it should be able to service queries + * from IPv6 as well as from IPv4 hosts, provided that you host is configured + * properly. + * For each of the protocols there are two options: ENABLE_IPV4 and ENABLE_IPV6 + * control whether support for the respective protocol is available in the + * binary. DEFAULT_IPV4 selects which protocol is enabled on pdnsd + * startup by default. 1 means IPv4, while 0 means IPv6. If support for + * a protocol was included in the executable, you can specify command line + * parameters to activate or deactivate that protocol (the options are -4 and + * -6), but it makes more sense to use the run_ipv4=on/off option in the + * configuration file. + * Make your choice. Note that IPv6 support is experimental in pdnsd. + * In normal operation, you will currently only need IPv4. */ +#undef ENABLE_IPV4 +#define DEFAULT_IPV4 1 +#undef ENABLE_IPV6 + +/* In all pdnsd versions before 1.0.6, DNS queries were always done over + * TCP. Now, you have the choice. You can control that behaviour using + * the -m command line switch, and you can give a preset here. There + * are 3 different modes: + * UDP_ONLY: This is undoubtedly the fastest query method, because + * no TCP negotiation needs to be done. + * TCP_ONLY: This is slower than uo, but generally more secure + * against DNS spoofing. Note that some name servers on the + * internet do not support TCP queries, notably dnscache. + * TCP_UDP: TCP, then UDP. If the TCP query fails with a "connection refused"- + * error or times out, the query is retried using UDP. + * UDP_TCP: UDP, then TCP. If the UDP reply is truncated (i.e. the tc flag is set), + * the query is retried using TCP. */ +#define M_PRESET UDP_ONLY + +/* In addition to choosing the presets, you may also completely disable + * one of the protocols (TCP for preset UDP_ONLY and UDP for preset TCP_ONLY). + * This saves some executable space. */ +#undef NO_UDP_QUERIES +#undef NO_TCP_QUERIES + +/* With the following option, you can disable the TCP server functionality + * of pdnsd. Nearly no program does TCP queries, so you probably can do + * this safely and save some executable space and one thread. + * You also can turn off the TCP server at runtime with the --notcp option. */ +#undef NO_TCP_SERVER + +/* By undefining the following, you can disable the UDP source address + * discovery code. This is not recommended, but you may need it when + * running into compilation problems. */ +#undef SRC_ADDR_DISC + +/* NO_POLL specifies not to use poll(2), but select(2) instead. If you are + * unsure about what this means, just leave this as it is.*/ +#undef NO_POLL + +/* Define this for "hard" RFC 2181 compliance: this RFC states that + * implementations should discard answers whose RR sets have multiple + * different time stamps. While correct answers are generated, incorrect + * ones are normally tolerated and corrected. Full RFC compliance is + * however only achieved by deactivating this behaviour and thus being + * intolerant. */ +#undef RFC2181_ME_HARDER + +/* Define this to the device you want to use for getting random numbers. + * Leave this undefined if you wand to use the standard C library random + * function, which basically should be sufficient. + * Linux and FreeBSD have two random number devices: /dev/random and + * /dev/urandom. /dev/urandom might be less secure in some cases, but + * should still be more than sufficient. The use of /dev/random is + * discouraged, as reading from this device blocks when new random bits + * need to be gathered. */ +#undef RANDOM_DEVICE +#undef R_DEFAULT +#undef R_RANDOM +#undef R_ARC4RANDOM +/*#define RANDOM_DEVICE "/dev/urandom"*/ + +/* Designate which database manager to use for cacheing. + * default: native; others: gdbm */ +#define CACHE_DBM DBM_NATIVE + +#define CACHEDIR "/var/cache/pdnsd" + +#define TEMPDIR "/tmp"; + +/* This is for various debugging facilities that produce debug output and + * double-check some values. You can enable debug messages with the -g option. + * Normally, you can switch this off safely by setting the number after DEBUG + * to 0. This will increase speed (although only marginally), save space + * in the executable (only about 12kB) and some stack space per thread + * (which may be significant if you have many threads running simultaneously). + * However, it may be an aid when debugging config files. + * The only defined debug levels by now are in the range 0 - 9. + * Define this to 9 if you want hex dumps of all the queries and replies pdnsd + * receives (you must also call pdnsd with -v9 to actually see the hex dumps). + * When in doubt, leave it defined to 1. */ +#define DEBUG 1 + +/* This defines the default verbosity of informational messages you will get. + This has nothing to to with the debug option (-g), but may be set with -v + option. 0 is for normal operation, up to 3 for debugging. + Unlike the debug messages, these messages will also be written to the syslog.*/ +#define VERBOSITY 0 + +/* Redefine this if you want another hash size. + * The number of hash buckets is computed as power of two (1< and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `getline' function. */ +#undef HAVE_GETLINE + +/* Define to 1 if you have the `getpwnam_r' function. */ +#undef HAVE_GETPWNAM_R + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mempcpy' function. */ +#undef HAVE_MEMPCPY + +/* Define to 1 if you have the `mkfifo' function. */ +#undef HAVE_MKFIFO + +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_IF_H + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if the system has the type `socklen_t'. */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `stpcpy' function. */ +#undef HAVE_STPCPY + +/* Define to 1 if you have the `stpncpy' function. */ +#undef HAVE_STPNCPY + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + +/* Define to 1 if the system has the type `struct ifreq'. */ +#undef HAVE_STRUCT_IFREQ + +/* Define to 1 if the system has the type `struct in6_addr'. */ +#undef HAVE_STRUCT_IN6_ADDR + +/* Define to 1 if the system has the type `struct in_pktinfo'. */ +#undef HAVE_STRUCT_IN_PKTINFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the `uname' function. */ +#undef HAVE_UNAME + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/jni/pdnsd/configure b/jni/pdnsd/configure new file mode 100644 index 00000000..a3b78220 --- /dev/null +++ b/jni/pdnsd/configure @@ -0,0 +1,11389 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.63. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="src" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +ALLOCA +thread_CFLAGS +RANLIB +threadlib +specbuild +def_id +cachedir +distribution +packagerelease +fullversion +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +with_distribution +with_target +with_cachedir +enable_isdn +enable_ipv4 +enable_ipv6 +enable_ipv4_startup +enable_ipv6_startup +enable_udp_queries +enable_tcp_queries +with_query_method +enable_tcp_server +enable_src_addr_disc +enable_socket_locking +enable_poll +enable_new_rrs +enable_strict_rfc2181 +with_random_device +enable_underscores +with_default_id +with_debug +with_verbosity +with_hash_buckets +enable_hash_debug +enable_rcsids +with_tcp_qtimeout +enable_tcp_subseq +with_par_queries +with_max_nameserver_ips +enable_specbuild +with_thread_lib +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { $as_echo "$as_me: error: working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-isdn Enable ISDN support (may cause problems on + some systems; only for Linux) + --disable-ipv4 Disable IPv4 networking support + (default=enabled) + --enable-ipv6 Enable IPv6 networking support + --disable-ipv4-startup Disable IPv4 on pdnsd startup by default + (default=enabled) + --enable-ipv6-startup Enable IPV6 on pdnsd startup by default + (default=IPv4) + --disable-udp-queries Disable udp as query method. + --disable-tcp-queries Disable tcp as query method. + --disable-tcp-server Disable the TCP serving ability of pdnsd + --disable-src-addr-disc Disable the UDP source address discovery + --enable-socket-locking Enable the UDP socket locking + --disable-poll Disable poll(2) and use select(2) + (default=enabled) + --disable-new-rrs Disable new DNS RR types (obsolete, currently ignored) + --enable-strict-rfc2181 Enforce strict RFC 2181 compliance + --enable-underscores Allow _ in domain names (obsolete, currently ignored) + --enable-hash-debug Debug hash tables (warning: massive output) + --enable-rcsids Enable RCS IDs in executables (obsolete, currently ignored) + --enable-tcp-subseq Enable multiple dns querys using one + tcp connection + --enable-specbuild Only used when building pdnsd from spec files + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-distribution=distro Specify target distribution (default=Generic; + others: RedHat, SuSE, Debian, ArchLinux) + --with-target=platform Change compilation target platform (default: + autodetect; others: Linux, BSD, Cygwin) + --with-cachedir=dir Default directory for pdnsd cache + (default=/var/cache/pdnsd) + --with-query-method=qm Specify the query method (default=udponly; + others: tcponly, tcpudp, udptcp) + --with-random-device=device Specify random device other than + /dev/random; default: C Library random() PRNG; + special value arc4random for BSD C Library + arc4random function (default on FreeBSD) + --with-default-id=id Specify default uid/gid for pdnsd + (default=nobody) + --with-debug=level Specify debugging level (0 means no debug support) + --with-verbosity=level Specify default message verbosity + --with-hash-buckets=num Number of hash buckets to use (default=1024). + The number actually used is the smallest power of two + greater or equal to the number specified here. + --with-tcp-qtimeout=secs Specify default tcp query timeout (default=30) + --with-par-queries=num Specify default parallel query number (default=2) + --with-max-nameserver-ips=num Specify maximum number of IP addresses used per nameserver obtained from NS records (default=3) + --with-thread-lib=lib Specify thread library, overriding automatic detection (for Linux only). + Possible values: LinuxThreads, + LinuxThreads2 (implements a fix for newer glibcs) + or NPTL (Native POSIX Thread Library) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.63 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +package="pdnsd" +version=`cut -d - -f 1 "$srcdir"/version` +fullversion=`cat "$srcdir"/version` +packagerelease=`cut -d - -f 2- "$srcdir"/version` + +distribution="Generic" +target="autodetect" +cachedir="/var/cache/$package" +ipv4_default=1 +have_ipv4="yes" +#newrrs="yes" +query_m="udponly" +have_tcp_server="yes" +adisc="default" +slock="no"; +def_id="nobody" +#have_rcsids="no" +udp_queries="yes" +tcp_queries="yes" +tempdir="/tmp" +randomdev=default +freebsd_pthread="4" +specbuild=no +threadlib=default + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + +done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + { { $as_echo "$as_me:$LINENO: error: unsafe absolute working directory name" >&5 +$as_echo "$as_me: error: unsafe absolute working directory name" >&2;} + { (exit 1); exit 1; }; };; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + { { $as_echo "$as_me:$LINENO: error: unsafe srcdir value: \`$srcdir'" >&5 +$as_echo "$as_me: error: unsafe srcdir value: \`$srcdir'" >&2;} + { (exit 1); exit 1; }; };; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +$as_echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:$LINENO: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=$package + VERSION=$version + + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +ac_config_headers="$ac_config_headers config.h" + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + fi + fi +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + if test "${ac_cv_header_minix_config_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 +$as_echo_n "checking for minix/config.h... " >&6; } +if test "${ac_cv_header_minix_config_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +$as_echo "$ac_cv_header_minix_config_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking minix/config.h usability" >&5 +$as_echo_n "checking minix/config.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking minix/config.h presence" >&5 +$as_echo_n "checking minix/config.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 +$as_echo_n "checking for minix/config.h... " >&6; } +if test "${ac_cv_header_minix_config_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_minix_config_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +$as_echo "$ac_cv_header_minix_config_h" >&6; } + +fi +if test "x$ac_cv_header_minix_config_h" = x""yes; then + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_SOURCE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_1_SOURCE 2 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _MINIX 1 +_ACEOF + + fi + + + + { $as_echo "$as_me:$LINENO: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_safe_to_define___extensions__=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_safe_to_define___extensions__=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + cat >>confdefs.h <<\_ACEOF +#define __EXTENSIONS__ 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _ALL_SOURCE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _GNU_SOURCE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define _TANDEM_SOURCE 1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$fullversion" +_ACEOF + + + + + +# Check whether --with-distribution was given. +if test "${with_distribution+set}" = set; then + withval=$with_distribution; distribution=$withval +fi + + + + +# Check whether --with-target was given. +if test "${with_target+set}" = set; then + withval=$with_target; target=$withval +fi + +case $target in + Linux|linux) + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_LINUX +_ACEOF + + target="Linux" + ;; + BSD| bsd) + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_BSD +_ACEOF + + target="BSD" + ;; + Cygwin|CYGWIN|cygwin) + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_CYGWIN +_ACEOF + + target="cygwin" + ;; + autodetect) + ;; + *) + { { $as_echo "$as_me:$LINENO: error: --with-target must have Linux, BSD or Cygwin as parameter." >&5 +$as_echo "$as_me: error: --with-target must have Linux, BSD or Cygwin as parameter." >&2;} + { (exit 1); exit 1; }; } + ;; +esac + + +# Check whether --with-cachedir was given. +if test "${with_cachedir+set}" = set; then + withval=$with_cachedir; cachedir=$withval +fi + +cat >>confdefs.h <<_ACEOF +#define CACHEDIR "$cachedir" +_ACEOF + + + +# Check whether --enable-isdn was given. +if test "${enable_isdn+set}" = set; then + enableval=$enable_isdn; test $enableval = "yes" && cat >>confdefs.h <<\_ACEOF +#define ISDN_SUPPORT 1 +_ACEOF + +fi + + +# Check whether --enable-ipv4 was given. +if test "${enable_ipv4+set}" = set; then + enableval=$enable_ipv4; have_ipv4=$enableval +fi + + +test $have_ipv4 = "yes" && cat >>confdefs.h <<\_ACEOF +#define ENABLE_IPV4 1 +_ACEOF + + +# Check whether --enable-ipv6 was given. +if test "${enable_ipv6+set}" = set; then + enableval=$enable_ipv6; if test $enableval = "yes" ; then + cat >>confdefs.h <<\_ACEOF +#define ENABLE_IPV6 1 +_ACEOF + + if test $have_ipv4 != "yes" ; then + ipv4_default=0 + fi + fi +fi + + +# Check whether --enable-ipv4-startup was given. +if test "${enable_ipv4_startup+set}" = set; then + enableval=$enable_ipv4_startup; if test $enableval = "yes" ; then + ipv4_default=1 + else + ipv4_default=0 + fi +fi + + +# Check whether --enable-ipv6-startup was given. +if test "${enable_ipv6_startup+set}" = set; then + enableval=$enable_ipv6_startup; if test $enableval = "yes" ; then + ipv4_default=0 + else + ipv4_default=1 + fi +fi + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_IPV4 $ipv4_default +_ACEOF + + +# Check whether --enable-udp-queries was given. +if test "${enable_udp_queries+set}" = set; then + enableval=$enable_udp_queries; udp_queries=$enableval +fi + + +# Check whether --enable-tcp-queries was given. +if test "${enable_tcp_queries+set}" = set; then + enableval=$enable_tcp_queries; tcp_queries=$enableval +fi + + + +# Check whether --with-query-method was given. +if test "${with_query_method+set}" = set; then + withval=$with_query_method; query_m=$withval +fi + +case $query_m in + udponly|UDPonly) + cat >>confdefs.h <<\_ACEOF +#define M_PRESET UDP_ONLY +_ACEOF + + udp_queries=yes; + ;; + tcponly|TCPonly) + cat >>confdefs.h <<\_ACEOF +#define M_PRESET TCP_ONLY +_ACEOF + + tcp_queries=yes; + ;; + tcpudp|TCPUDP) + cat >>confdefs.h <<\_ACEOF +#define M_PRESET TCP_UDP +_ACEOF + + udp_queries=yes; + tcp_queries=yes; + ;; + udptcp|UDPTCP) + cat >>confdefs.h <<\_ACEOF +#define M_PRESET UDP_TCP +_ACEOF + + udp_queries=yes; + tcp_queries=yes; + ;; + *) + { { $as_echo "$as_me:$LINENO: error: --with-query-method must have udponly, tcponly, tcpudp or udptcp as parameter." >&5 +$as_echo "$as_me: error: --with-query-method must have udponly, tcponly, tcpudp or udptcp as parameter." >&2;} + { (exit 1); exit 1; }; } + ;; +esac + +test $udp_queries != "yes" && cat >>confdefs.h <<\_ACEOF +#define NO_UDP_QUERIES 1 +_ACEOF + +test $tcp_queries != "yes" && cat >>confdefs.h <<\_ACEOF +#define NO_TCP_QUERIES 1 +_ACEOF + + +# Check whether --enable-tcp-server was given. +if test "${enable_tcp_server+set}" = set; then + enableval=$enable_tcp_server; have_tcp_server=$enableval +fi + + +test $have_tcp_server != "yes" && cat >>confdefs.h <<\_ACEOF +#define NO_TCP_SERVER 1 +_ACEOF + + +# Check whether --enable-src-addr-disc was given. +if test "${enable_src_addr_disc+set}" = set; then + enableval=$enable_src_addr_disc; adisc=$enableval +fi + + +# Check whether --enable-socket-locking was given. +if test "${enable_socket_locking+set}" = set; then + enableval=$enable_socket_locking; slock=$enableval +fi + + +test $slock = "yes" && cat >>confdefs.h <<\_ACEOF +#define SOCKET_LOCKING 1 +_ACEOF + + +# Check whether --enable-poll was given. +if test "${enable_poll+set}" = set; then + enableval=$enable_poll; test $enableval != "yes" && cat >>confdefs.h <<\_ACEOF +#define NO_POLL 1 +_ACEOF + +fi + + +# Check whether --enable-new-rrs was given. +if test "${enable_new_rrs+set}" = set; then + enableval=$enable_new_rrs; newrrs=$enableval +fi + + +# Check whether --enable-strict-rfc2181 was given. +if test "${enable_strict_rfc2181+set}" = set; then + enableval=$enable_strict_rfc2181; test $enableval = "yes" && cat >>confdefs.h <<\_ACEOF +#define RFC2181_ME_HARDER 1 +_ACEOF + +fi + + + +# Check whether --with-random-device was given. +if test "${with_random_device+set}" = set; then + withval=$with_random_device; randomdev=$withval +fi + + +if test "$randomdev" = arc4random ; then + cat >>confdefs.h <<\_ACEOF +#define R_ARC4RANDOM 1 +_ACEOF + +elif test "$randomdev" = random ; then + cat >>confdefs.h <<\_ACEOF +#define R_RANDOM 1 +_ACEOF + +elif test "$randomdev" = default ; then + cat >>confdefs.h <<\_ACEOF +#define R_DEFAULT 1 +_ACEOF + +else + cat >>confdefs.h <<_ACEOF +#define RANDOM_DEVICE "$randomdev" +_ACEOF + +fi + +# Check whether --enable-underscores was given. +if test "${enable_underscores+set}" = set; then + enableval=$enable_underscores; underscores=$enableval +fi + + + +# Check whether --with-default-id was given. +if test "${with_default_id+set}" = set; then + withval=$with_default_id; def_id=$withval +fi + + + + +# Check whether --with-debug was given. +if test "${with_debug+set}" = set; then + withval=$with_debug; cat >>confdefs.h <<_ACEOF +#define DEBUG $withval +_ACEOF + +fi + + + +# Check whether --with-verbosity was given. +if test "${with_verbosity+set}" = set; then + withval=$with_verbosity; cat >>confdefs.h <<_ACEOF +#define VERBOSITY $withval +_ACEOF + +fi + + + +# Check whether --with-hash-buckets was given. +if test "${with_hash_buckets+set}" = set; then + withval=$with_hash_buckets; powof2=1 + hashsz=0 + + while test $powof2 -lt "$withval" + do + powof2=`expr 2 '*' $powof2` + hashsz=`expr $hashsz '+' 1` + done + cat >>confdefs.h <<_ACEOF +#define HASH_SZ $hashsz +_ACEOF + + +fi + + +# Check whether --enable-hash-debug was given. +if test "${enable_hash_debug+set}" = set; then + enableval=$enable_hash_debug; test $enableval = "yes" && cat >>confdefs.h <<\_ACEOF +#define DEBUG_HASH 1 +_ACEOF + +fi + + +# Check whether --enable-rcsids was given. +if test "${enable_rcsids+set}" = set; then + enableval=$enable_rcsids; have_rcsids=$enableval +fi + + + +# Check whether --with-tcp-qtimeout was given. +if test "${with_tcp_qtimeout+set}" = set; then + withval=$with_tcp_qtimeout; cat >>confdefs.h <<_ACEOF +#define TCP_TIMEOUT $withval +_ACEOF + +fi + + +# Check whether --enable-tcp-subseq was given. +if test "${enable_tcp_subseq+set}" = set; then + enableval=$enable_tcp_subseq; test $enableval = "yes" && cat >>confdefs.h <<\_ACEOF +#define TCP_SUBSEQ 1 +_ACEOF + +fi + + + +# Check whether --with-par-queries was given. +if test "${with_par_queries+set}" = set; then + withval=$with_par_queries; cat >>confdefs.h <<_ACEOF +#define PAR_QUERIES $withval +_ACEOF + +fi + + + +# Check whether --with-max-nameserver-ips was given. +if test "${with_max_nameserver_ips+set}" = set; then + withval=$with_max_nameserver_ips; cat >>confdefs.h <<_ACEOF +#define MAXNAMESERVIPS $withval +_ACEOF + +fi + + +# Check whether --enable-specbuild was given. +if test "${enable_specbuild+set}" = set; then + enableval=$enable_specbuild; specbuild=$enableval +fi + + + + + +# Check whether --with-thread-lib was given. +if test "${with_thread_lib+set}" = set; then + withval=$with_thread_lib; threadlib=$withval +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc + +if test "x$CC" != xcc; then + { $as_echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest2.$ac_objext && { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest2.$ac_objext && { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define NO_MINUS_C_MINUS_O 1 +_ACEOF + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + +done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +if test "$target" = "autodetect" ; then + { $as_echo "$as_me:$LINENO: checking for autodetect build target" >&5 +$as_echo_n "checking for autodetect build target... " >&6; } + uname_sys=`uname` + if test $? -ne 0 ; then + { $as_echo "$as_me:$LINENO: result: failed" >&5 +$as_echo "failed" >&6; } + { { $as_echo "$as_me:$LINENO: error: uname failed or was not found in path" >&5 +$as_echo "$as_me: error: uname failed or was not found in path" >&2;} + { (exit 1); exit 1; }; } + else + case "${uname_sys}" in + Linux) + { $as_echo "$as_me:$LINENO: result: Linux" >&5 +$as_echo "Linux" >&6; } + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_LINUX +_ACEOF + + target="Linux" + ;; + FreeBSD|NetBSD|OpenBSD|Darwin) + { $as_echo "$as_me:$LINENO: result: \"${uname_sys}\"" >&5 +$as_echo "\"${uname_sys}\"" >&6; } + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_BSD +_ACEOF + + target="BSD" + ;; + CYGWIN*) + { $as_echo "$as_me:$LINENO: result: \"${uname_sys}\"" >&5 +$as_echo "\"${uname_sys}\"" >&6; } + cat >>confdefs.h <<\_ACEOF +#define TARGET TARGET_CYGWIN +_ACEOF + + target="cygwin" + ;; + *) + { $as_echo "$as_me:$LINENO: result: failed" >&5 +$as_echo "failed" >&6; } + { { $as_echo "$as_me:$LINENO: error: Your system type could not be identified. Try setting it manually using +--with-target" >&5 +$as_echo "$as_me: error: Your system type could not be identified. Try setting it manually using +--with-target" >&2;} + { (exit 1); exit 1; }; } + ;; + esac + fi +fi + +#if test "$target" = BSD ; then +# uname_sys=`uname` +# if test "$uname_sys" = FreeBSD ; then +# AC_MSG_CHECKING([for FreeBSD version]) +# osrel=`sysctl -n kern.osreldate` +# if test $osrel -ge 500016 ; then +# AC_MSG_RESULT([5.0 (>= 500016)]) +# freebsd_pthread="5" +# else +# AC_MSG_RESULT([<=5.0 (< 500016)]) +# freebsd_pthread="4" +# fi +# fi +#fi + +if test "$adisc" = "default"; then + if test "$target" = "cygwin" ; then +# Don't do UDP source address discovery on Cygwin platform by default. + adisc="no" + else + adisc="yes" + fi +fi + +test "$adisc" = "yes" && cat >>confdefs.h <<\_ACEOF +#define SRC_ADDR_DISC 1 +_ACEOF + + + +if test "$target" = "Linux"; then +{ $as_echo "$as_me:$LINENO: checking if we can compile and link with -pthread" >&5 +$as_echo_n "checking if we can compile and link with -pthread... " >&6; } +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -pthread" +cat >conftest.$ac_ext <<_ACEOF + +#include + +void *thread_func(void *data) +{ + *((int *)data)=1; + return data; +} + +int main() +{ + pthread_t thread; + void *retval; + int val; + + if(pthread_create(&thread, NULL, thread_func, &val)) + return 1; + + if(pthread_join(thread,&retval)) + return 1; + + return (*((int *)retval)!=1); +} + +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + gcc_pthread_flag="yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + gcc_pthread_flag="no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +{ $as_echo "$as_me:$LINENO: result: $gcc_pthread_flag" >&5 +$as_echo "$gcc_pthread_flag" >&6; } + + if test "$gcc_pthread_flag" = yes ; then + thread_CFLAGS="-pthread" + + else + +{ $as_echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_pthread_pthread_create=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_pthread_pthread_create=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +fi + + fi +fi +if test "$target" = "BSD" -a `uname` != Darwin ; then +# if test $freebsd_pthread = 4 ; then + thread_CFLAGS="-pthread" + +# else +# AC_CHECK_LIB(c_r, pthread_create, , +# AC_MSG_ERROR([You must have libc_r installed to build/run pdnsd!])) +# fi; +fi + +if test "$target" = "Linux" -a "$threadlib" = default; then +{ $as_echo "$as_me:$LINENO: checking if this is an NPTL-based system" >&5 +$as_echo_n "checking if this is an NPTL-based system... " >&6; } +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $thread_CFLAGS" +if test "$cross_compiling" = yes; then + + { $as_echo "$as_me:$LINENO: result: couldn't run test program" >&5 +$as_echo "couldn't run test program" >&6; } + threadlib=linuxthreads + +else + cat >conftest.$ac_ext <<_ACEOF + +#include +#include +#include +#include +#include +#include + +/* All this function does is return its PID (in a roundabout way). */ +void *thread_func(void *data) +{ + *((int *)data)=getpid(); + return data; +} + +int main() +{ + pthread_t thread; + void *retval; + int err,mainpid,thrdpid; + + err=pthread_create(&thread, NULL, thread_func, &thrdpid); + if(err) { + fprintf(stderr,"pthread_create failed: %s\n",strerror(err)); + return 1; + } + err=pthread_join(thread,&retval); + if(err) { + fprintf(stderr,"pthread_join failed: %s\n",strerror(err)); + return 1; + } + mainpid=getpid(); + /* In LinuxThreads implementations, the pids of the threads will usually differ + in a non Posix-compliant way. */ + fprintf(stderr,"main pid=%d, thread pid=%d\n",mainpid,*((int *)retval)); + return (*((int *)retval)!=mainpid); +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + threadlib=nptl + +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + threadlib=linuxthreads + +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +CFLAGS="$old_CFLAGS" +fi + +if test "$threadlib" = nptl -o "$threadlib" = NPTL; then + cat >>confdefs.h <<\_ACEOF +#define THREADLIB_NPTL 1 +_ACEOF + +elif test "$threadlib" = linuxthreads2 -o "$threadlib" = LinuxThreads2 -o "$threadlib" = lt2; then + cat >>confdefs.h <<\_ACEOF +#define THREADLIB_LINUXTHREADS2 1 +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if test "${ac_cv_header_sys_wait_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_sys_wait_h=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_sys_wait_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + + + + + + + +for ac_header in fcntl.h malloc.h sys/ioctl.h sys/time.h syslog.h unistd.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 +$as_echo_n "checking $ac_header usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 +$as_echo_n "checking $ac_header presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + +fi +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + +for ac_header in sys/types.h sys/socket.h net/if.h netinet/in.h sys/poll.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif + + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const /**/ +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for pid_t" >&5 +$as_echo_n "checking for pid_t... " >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_pid_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((pid_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +$as_echo "$ac_cv_type_pid_t" >&6; } +if test "x$ac_cv_type_pid_t" = x""yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for size_t" >&5 +$as_echo_n "checking for size_t... " >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_size_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((size_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +$as_echo "$ac_cv_type_size_t" >&6; } +if test "x$ac_cv_type_size_t" = x""yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if test "${ac_cv_header_time+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_time=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_time=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if test "${ac_cv_struct_tm+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_struct_tm=time.h +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_struct_tm=sys/time.h +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +cat >>confdefs.h <<\_ACEOF +#define TM_IN_SYS_TIME 1 +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for socklen_t" >&5 +$as_echo_n "checking for socklen_t... " >&6; } +if test "${ac_cv_type_socklen_t+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_socklen_t=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof (socklen_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof ((socklen_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_socklen_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 +$as_echo "$ac_cv_type_socklen_t" >&6; } +if test "x$ac_cv_type_socklen_t" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKLEN_T 1 +_ACEOF + + +else + cat >>confdefs.h <<\_ACEOF +#define socklen_t int +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for struct in6_addr" >&5 +$as_echo_n "checking for struct in6_addr... " >&6; } +if test "${ac_cv_type_struct_in6_addr+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_struct_in6_addr=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof (struct in6_addr)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof ((struct in6_addr))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_struct_in6_addr=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_struct_in6_addr" >&5 +$as_echo "$ac_cv_type_struct_in6_addr" >&6; } +if test "x$ac_cv_type_struct_in6_addr" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN6_ADDR 1 +_ACEOF + + +fi +{ $as_echo "$as_me:$LINENO: checking for struct in_pktinfo" >&5 +$as_echo_n "checking for struct in_pktinfo... " >&6; } +if test "${ac_cv_type_struct_in_pktinfo+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_struct_in_pktinfo=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof (struct in_pktinfo)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof ((struct in_pktinfo))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_struct_in_pktinfo=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_struct_in_pktinfo" >&5 +$as_echo "$ac_cv_type_struct_in_pktinfo" >&6; } +if test "x$ac_cv_type_struct_in_pktinfo" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN_PKTINFO 1 +_ACEOF + + +fi +{ $as_echo "$as_me:$LINENO: checking for struct ifreq" >&5 +$as_echo_n "checking for struct ifreq... " >&6; } +if test "${ac_cv_type_struct_ifreq+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type_struct_ifreq=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof (struct ifreq)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ +if (sizeof ((struct ifreq))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_struct_ifreq=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_struct_ifreq" >&5 +$as_echo "$ac_cv_type_struct_ifreq" >&6; } +if test "x$ac_cv_type_struct_ifreq" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IFREQ 1 +_ACEOF + + +fi + + +{ $as_echo "$as_me:$LINENO: checking for CPP C99 Variadic macro support" >&5 +$as_echo_n "checking for CPP C99 Variadic macro support... " >&6; } +cat >conftest.$ac_ext <<_ACEOF + +#define a(...) junk(0,__VA_ARGS__) +extern void junk(int i,...); +int main() +{ + a(0); + a("a"); + a(0, "a", 1); + return 0; +} + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cpp_c99_variadic="yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cpp_c99_variadic="no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $cpp_c99_variadic" >&5 +$as_echo "$cpp_c99_variadic" >&6; } +if test $cpp_c99_variadic = yes; then + cat >>confdefs.h <<\_ACEOF +#define CPP_C99_VARIADIC_MACROS 1 +_ACEOF + +else + if test "$GCC" != yes; then + { { $as_echo "$as_me:$LINENO: error: Compiler must support C99 or gcc variadic macros" >&5 +$as_echo "$as_me: error: Compiler must support C99 or gcc variadic macros" >&2;} + { (exit 1); exit 1; }; } + fi; +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:$LINENO: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_working_alloca_h=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_working_alloca_h=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA_H 1 +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func_alloca_works=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_alloca_works=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA 1 +_ACEOF + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +cat >>confdefs.h <<\_ACEOF +#define C_ALLOCA 1 +_ACEOF + + +{ $as_echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if test "${ac_cv_os_cray+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + return find_stack_direction () < 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } + +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if test "${ac_cv_prog_gcc_traditional+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + +{ $as_echo "$as_me:$LINENO: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if test "${ac_cv_func_memcmp_working+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_working=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_memcmp_working=yes +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_memcmp_working=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ $as_echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if test "${ac_cv_type_signal+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + +for ac_func in vprintf +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ $as_echo "$as_me:$LINENO: checking for _doprnt" >&5 +$as_echo_n "checking for _doprnt... " >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub__doprnt || defined __stub____doprnt +choke me +#endif + +int +main () +{ +return _doprnt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_func__doprnt=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +$as_echo "$ac_cv_func__doprnt" >&6; } +if test "x$ac_cv_func__doprnt" = x""yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + +{ $as_echo "$as_me:$LINENO: checking for library containing nanosleep" >&5 +$as_echo_n "checking for library containing nanosleep... " >&6; } +if test "${ac_cv_search_nanosleep+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char nanosleep (); +int +main () +{ +return nanosleep (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_search_nanosleep=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_nanosleep+set}" = set; then + break +fi +done +if test "${ac_cv_search_nanosleep+set}" = set; then + : +else + ac_cv_search_nanosleep=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_nanosleep" >&5 +$as_echo "$ac_cv_search_nanosleep" >&6; } +ac_res=$ac_cv_search_nanosleep +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:$LINENO: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if test "${ac_cv_search_socket+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib -lnsl $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_search_socket=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_socket+set}" = set; then + break +fi +done +if test "${ac_cv_search_socket+set}" = set; then + : +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:$LINENO: checking for library containing inet_aton" >&5 +$as_echo_n "checking for library containing inet_aton... " >&6; } +if test "${ac_cv_search_inet_aton+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_aton (); +int +main () +{ +return inet_aton (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_search_inet_aton=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_inet_aton+set}" = set; then + break +fi +done +if test "${ac_cv_search_inet_aton+set}" = set; then + : +else + ac_cv_search_inet_aton=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_inet_aton" >&5 +$as_echo "$ac_cv_search_inet_aton" >&6; } +ac_res=$ac_cv_search_inet_aton +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + + + + + + + + + +for ac_func in nanosleep gettimeofday mkfifo select socket strerror uname snprintf vsnprintf +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + true +else + { { $as_echo "$as_me:$LINENO: error: One of the functions required for pdnsd were not found." >&5 +$as_echo "$as_me: error: One of the functions required for pdnsd were not found." >&2;} + { (exit 1); exit 1; }; } +fi +done + + +for ac_func in poll +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + true +else + cat >>confdefs.h <<\_ACEOF +#define NO_POLL 1 +_ACEOF + +fi +done + + + + + + + + + + + + + +for ac_func in strdup strndup stpcpy stpncpy strlcpy mempcpy getline asprintf vasprintf getpwnam_r inet_ntop inet_pton +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_config_files="$ac_config_files pdnsd.spec Makefile file-list.base contrib/Makefile doc/Makefile doc/pdnsd.8 doc/pdnsd.conf.5 doc/pdnsd.conf src/Makefile src/pdnsd-ctl/Makefile src/rc/Makefile src/rc/RedHat/Makefile src/rc/RedHat/pdnsd src/rc/SuSE/Makefile src/rc/SuSE/pdnsd src/rc/Debian/Makefile src/rc/Debian/pdnsd src/rc/Slackware/Makefile src/rc/Slackware/rc.pdnsd src/rc/ArchLinux/Makefile src/rc/ArchLinux/pdnsd src/test/Makefile PKGBUILD" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.63. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTION]... [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.63, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { $as_echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { $as_echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "pdnsd.spec") CONFIG_FILES="$CONFIG_FILES pdnsd.spec" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "file-list.base") CONFIG_FILES="$CONFIG_FILES file-list.base" ;; + "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "doc/pdnsd.8") CONFIG_FILES="$CONFIG_FILES doc/pdnsd.8" ;; + "doc/pdnsd.conf.5") CONFIG_FILES="$CONFIG_FILES doc/pdnsd.conf.5" ;; + "doc/pdnsd.conf") CONFIG_FILES="$CONFIG_FILES doc/pdnsd.conf" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/pdnsd-ctl/Makefile") CONFIG_FILES="$CONFIG_FILES src/pdnsd-ctl/Makefile" ;; + "src/rc/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/Makefile" ;; + "src/rc/RedHat/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/RedHat/Makefile" ;; + "src/rc/RedHat/pdnsd") CONFIG_FILES="$CONFIG_FILES src/rc/RedHat/pdnsd" ;; + "src/rc/SuSE/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/SuSE/Makefile" ;; + "src/rc/SuSE/pdnsd") CONFIG_FILES="$CONFIG_FILES src/rc/SuSE/pdnsd" ;; + "src/rc/Debian/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/Debian/Makefile" ;; + "src/rc/Debian/pdnsd") CONFIG_FILES="$CONFIG_FILES src/rc/Debian/pdnsd" ;; + "src/rc/Slackware/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/Slackware/Makefile" ;; + "src/rc/Slackware/rc.pdnsd") CONFIG_FILES="$CONFIG_FILES src/rc/Slackware/rc.pdnsd" ;; + "src/rc/ArchLinux/Makefile") CONFIG_FILES="$CONFIG_FILES src/rc/ArchLinux/Makefile" ;; + "src/rc/ArchLinux/pdnsd") CONFIG_FILES="$CONFIG_FILES src/rc/ArchLinux/pdnsd" ;; + "src/test/Makefile") CONFIG_FILES="$CONFIG_FILES src/test/Makefile" ;; + "PKGBUILD") CONFIG_FILES="$CONFIG_FILES PKGBUILD" ;; + + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=' ' +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 +$as_echo "$as_me: error: could not setup config headers machinery" >&2;} + { (exit 1); exit 1; }; } +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 +$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + ac_file_inputs="$ac_file_inputs '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 +$as_echo "$as_me: error: could not create -" >&2;} + { (exit 1); exit 1; }; } + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/jni/pdnsd/configure.in b/jni/pdnsd/configure.in new file mode 100644 index 00000000..473abf17 --- /dev/null +++ b/jni/pdnsd/configure.in @@ -0,0 +1,548 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src) + +package="pdnsd" +version=`cut -d - -f 1 "$srcdir"/version` +fullversion=`cat "$srcdir"/version` +packagerelease=`cut -d - -f 2- "$srcdir"/version` + +distribution="Generic" +target="autodetect" +cachedir="/var/cache/$package" +ipv4_default=1 +have_ipv4="yes" +#newrrs="yes" +query_m="udponly" +have_tcp_server="yes" +adisc="default" +slock="no"; +def_id="nobody" +#have_rcsids="no" +udp_queries="yes" +tcp_queries="yes" +tempdir="/tmp" +randomdev=default +freebsd_pthread="4" +specbuild=no +threadlib=default + +AM_INIT_AUTOMAKE($package, $version, [no-define]) +AM_CONFIG_HEADER(config.h) +AC_GNU_SOURCE +AC_DEFINE_UNQUOTED(VERSION,"$fullversion") +AC_SUBST(fullversion) +AC_SUBST(packagerelease) + +AC_ARG_WITH(distribution, +[ --with-distribution=distro Specify target distribution (default=Generic; + others: RedHat, SuSE, Debian, ArchLinux)], + distribution=$withval) +AC_SUBST(distribution) + +AC_ARG_WITH(target, +[ --with-target=platform Change compilation target platform (default: + autodetect; others: Linux, BSD, Cygwin)], + target=$withval) +case $target in + Linux|linux) + AC_DEFINE(TARGET, TARGET_LINUX) + target="Linux" + ;; + BSD| bsd) + AC_DEFINE(TARGET, TARGET_BSD) + target="BSD" + ;; + Cygwin|CYGWIN|cygwin) + AC_DEFINE(TARGET, TARGET_CYGWIN) + target="cygwin" + ;; + autodetect) + ;; + *) + AC_MSG_ERROR([--with-target must have Linux, BSD or Cygwin as parameter.]) + ;; +esac + +AC_ARG_WITH(cachedir, +[ --with-cachedir=dir Default directory for pdnsd cache + (default=/var/cache/pdnsd)], + cachedir=$withval) +AC_DEFINE_UNQUOTED(CACHEDIR, "$cachedir") +AC_SUBST(cachedir) + +AC_ARG_ENABLE(isdn, +[ --enable-isdn Enable ISDN support (may cause problems on + some systems; only for Linux)], + test $enableval = "yes" && AC_DEFINE(ISDN_SUPPORT)) + +AC_ARG_ENABLE(ipv4, +[ --disable-ipv4 Disable IPv4 networking support + (default=enabled)], + have_ipv4=$enableval) + +test $have_ipv4 = "yes" && AC_DEFINE(ENABLE_IPV4) + +AC_ARG_ENABLE(ipv6, +[ --enable-ipv6 Enable IPv6 networking support], +[ if test $enableval = "yes" ; then + AC_DEFINE(ENABLE_IPV6) + if test $have_ipv4 != "yes" ; then + ipv4_default=0 + fi + fi]) + +AC_ARG_ENABLE(ipv4-startup, +[ --disable-ipv4-startup Disable IPv4 on pdnsd startup by default + (default=enabled)], +[ if test $enableval = "yes" ; then + ipv4_default=1 + else + ipv4_default=0 + fi]) + +AC_ARG_ENABLE(ipv6-startup, +[ --enable-ipv6-startup Enable IPV6 on pdnsd startup by default + (default=IPv4)], +[ if test $enableval = "yes" ; then + ipv4_default=0 + else + ipv4_default=1 + fi]) + +AC_DEFINE_UNQUOTED(DEFAULT_IPV4, $ipv4_default) + +AC_ARG_ENABLE(udp-queries, +[ --disable-udp-queries Disable udp as query method.], + udp_queries=$enableval) + +AC_ARG_ENABLE(tcp-queries, +[ --disable-tcp-queries Disable tcp as query method.], + tcp_queries=$enableval) + +AC_ARG_WITH(query-method, +[ --with-query-method=qm Specify the query method (default=udponly; + others: tcponly, tcpudp, udptcp)], + query_m=$withval) +case $query_m in + udponly|UDPonly) + AC_DEFINE(M_PRESET, UDP_ONLY) + udp_queries=yes; + ;; + tcponly|TCPonly) + AC_DEFINE(M_PRESET, TCP_ONLY) + tcp_queries=yes; + ;; + tcpudp|TCPUDP) + AC_DEFINE(M_PRESET, TCP_UDP) + udp_queries=yes; + tcp_queries=yes; + ;; + udptcp|UDPTCP) + AC_DEFINE(M_PRESET, UDP_TCP) + udp_queries=yes; + tcp_queries=yes; + ;; + *) + AC_MSG_ERROR([--with-query-method must have udponly, tcponly, tcpudp or udptcp as parameter.]) + ;; +esac + +test $udp_queries != "yes" && AC_DEFINE(NO_UDP_QUERIES) +test $tcp_queries != "yes" && AC_DEFINE(NO_TCP_QUERIES) + +AC_ARG_ENABLE(tcp-server, +[ --disable-tcp-server Disable the TCP serving ability of pdnsd], + have_tcp_server=$enableval) + +test $have_tcp_server != "yes" && AC_DEFINE(NO_TCP_SERVER) + +AC_ARG_ENABLE(src-addr-disc, +[ --disable-src-addr-disc Disable the UDP source address discovery], + adisc=$enableval) + +AC_ARG_ENABLE(socket-locking, +[ --enable-socket-locking Enable the UDP socket locking], + slock=$enableval) + +test $slock = "yes" && AC_DEFINE(SOCKET_LOCKING) + +AC_ARG_ENABLE(poll, +[ --disable-poll Disable poll(2) and use select(2) + (default=enabled)], + test $enableval != "yes" && AC_DEFINE(NO_POLL)) + +AC_ARG_ENABLE(new-rrs, +[ --disable-new-rrs Disable new DNS RR types (obsolete, currently ignored)], + newrrs=$enableval) + +AC_ARG_ENABLE(strict-rfc2181, +[ --enable-strict-rfc2181 Enforce strict RFC 2181 compliance], + test $enableval = "yes" && AC_DEFINE(RFC2181_ME_HARDER)) + +AC_ARG_WITH(random-device, +[ --with-random-device=device Specify random device other than + /dev/random; default: C Library random() PRNG; + special value arc4random for BSD C Library + arc4random function (default on FreeBSD)], + randomdev=$withval) + +if test "$randomdev" = arc4random ; then + AC_DEFINE(R_ARC4RANDOM) +elif test "$randomdev" = random ; then + AC_DEFINE(R_RANDOM) +elif test "$randomdev" = default ; then + AC_DEFINE(R_DEFAULT) +else + AC_DEFINE_UNQUOTED(RANDOM_DEVICE, "$randomdev") +fi + +AC_ARG_ENABLE(underscores, +[ --enable-underscores Allow _ in domain names (obsolete, currently ignored)], + underscores=$enableval) + +AC_ARG_WITH(default-id, +[ --with-default-id=id Specify default uid/gid for pdnsd + (default=nobody)], + def_id=$withval) +AC_SUBST(def_id) + +AC_ARG_WITH(debug, +[ --with-debug=level Specify debugging level (0 means no debug support)], + AC_DEFINE_UNQUOTED(DEBUG, $withval)) + +AC_ARG_WITH(verbosity, +[ --with-verbosity=level Specify default message verbosity], + AC_DEFINE_UNQUOTED(VERBOSITY, $withval)) + +AC_ARG_WITH(hash-buckets, +[ --with-hash-buckets=num Number of hash buckets to use (default=1024). + The number actually used is the smallest power of two + greater or equal to the number specified here.], + powof2=1 + hashsz=0 + + while test $powof2 -lt "$withval" + do + powof2=`expr 2 '*' $powof2` + hashsz=`expr $hashsz '+' 1` + done + AC_DEFINE_UNQUOTED(HASH_SZ, $hashsz) +) + +AC_ARG_ENABLE(hash-debug, +[ --enable-hash-debug Debug hash tables (warning: massive output)], + test $enableval = "yes" && AC_DEFINE(DEBUG_HASH)) + +AC_ARG_ENABLE(rcsids, +[ --enable-rcsids Enable RCS IDs in executables (obsolete, currently ignored)], + have_rcsids=$enableval) + +AC_ARG_WITH(tcp-qtimeout, +[ --with-tcp-qtimeout=secs Specify default tcp query timeout (default=30)], + AC_DEFINE_UNQUOTED(TCP_TIMEOUT, $withval)) + +AC_ARG_ENABLE(tcp-subseq, +[ --enable-tcp-subseq Enable multiple dns querys using one + tcp connection], + test $enableval = "yes" && AC_DEFINE(TCP_SUBSEQ)) + +AC_ARG_WITH(par-queries, +[ --with-par-queries=num Specify default parallel query number (default=2)], + AC_DEFINE_UNQUOTED(PAR_QUERIES, $withval)) + +AC_ARG_WITH(max-nameserver-ips, +[ --with-max-nameserver-ips=num Specify maximum number of IP addresses used per nameserver obtained from NS records (default=3)], + AC_DEFINE_UNQUOTED(MAXNAMESERVIPS, $withval)) + +AC_ARG_ENABLE(specbuild, +[ --enable-specbuild Only used when building pdnsd from spec files], + specbuild=$enableval) + +AC_SUBST(specbuild) + +AC_ARG_WITH(thread-lib, +[ --with-thread-lib=lib Specify thread library, overriding automatic detection (for Linux only). + Possible values: LinuxThreads, + LinuxThreads2 (implements a fix for newer glibcs) + or NPTL (Native POSIX Thread Library)], + threadlib=$withval) + +AC_SUBST(threadlib) + +dnl Checks for programs. +AC_PROG_CC +AM_PROG_CC_STDC +AM_PROG_CC_C_O +AC_PROG_INSTALL + +dnl For dbm subsystem libraries +AC_PROG_RANLIB + +if test "$target" = "autodetect" ; then + AC_MSG_CHECKING([for autodetect build target]) + uname_sys=`uname` + if test $? -ne 0 ; then + AC_MSG_RESULT([failed]) + AC_MSG_ERROR([uname failed or was not found in path]) + else + case "${uname_sys}" in + Linux) + AC_MSG_RESULT(Linux) + AC_DEFINE(TARGET, TARGET_LINUX) + target="Linux" + ;; + FreeBSD|NetBSD|OpenBSD|Darwin) + AC_MSG_RESULT("${uname_sys}") + AC_DEFINE(TARGET, TARGET_BSD) + target="BSD" + ;; + CYGWIN*) + AC_MSG_RESULT("${uname_sys}") + AC_DEFINE(TARGET, TARGET_CYGWIN) + target="cygwin" + ;; + *) + AC_MSG_RESULT([failed]) + AC_MSG_ERROR( +[Your system type could not be identified. Try setting it manually using +--with-target]) + ;; + esac + fi +fi + +#if test "$target" = BSD ; then +# uname_sys=`uname` +# if test "$uname_sys" = FreeBSD ; then +# AC_MSG_CHECKING([for FreeBSD version]) +# osrel=`sysctl -n kern.osreldate` +# if test $osrel -ge 500016 ; then +# AC_MSG_RESULT([5.0 (>= 500016)]) +# freebsd_pthread="5" +# else +# AC_MSG_RESULT([<=5.0 (< 500016)]) +# freebsd_pthread="4" +# fi +# fi +#fi + +if test "$adisc" = "default"; then + if test "$target" = "cygwin" ; then +# Don't do UDP source address discovery on Cygwin platform by default. + adisc="no" + else + adisc="yes" + fi +fi + +test "$adisc" = "yes" && AC_DEFINE(SRC_ADDR_DISC) + + +dnl Checks for libraries. +if test "$target" = "Linux"; then +AC_MSG_CHECKING([if we can compile and link with -pthread]) +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -pthread" +AC_LINK_IFELSE([ +#include + +void *thread_func(void *data) +{ + *((int *)data)=1; + return data; +} + +int main() +{ + pthread_t thread; + void *retval; + int val; + + if(pthread_create(&thread, NULL, thread_func, &val)) + return 1; + + if(pthread_join(thread,&retval)) + return 1; + + return (*((int *)retval)!=1); +} +], + gcc_pthread_flag="yes", gcc_pthread_flag="no") +CFLAGS="$old_CFLAGS" +AC_MSG_RESULT([$gcc_pthread_flag]) + + if test "$gcc_pthread_flag" = yes ; then + thread_CFLAGS="-pthread" + AC_SUBST(thread_CFLAGS) + else + AC_CHECK_LIB(pthread, pthread_create) + fi +fi +if test "$target" = "BSD" -a `uname` != Darwin ; then +# if test $freebsd_pthread = 4 ; then + thread_CFLAGS="-pthread" + AC_SUBST(thread_CFLAGS) +# else +# AC_CHECK_LIB(c_r, pthread_create, , +# AC_MSG_ERROR([You must have libc_r installed to build/run pdnsd!])) +# fi; +fi + +if test "$target" = "Linux" -a "$threadlib" = default; then +AC_MSG_CHECKING([if this is an NPTL-based system]) +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $thread_CFLAGS" +AC_RUN_IFELSE([ +#include +#include +#include +#include +#include +#include + +/* All this function does is return its PID (in a roundabout way). */ +void *thread_func(void *data) +{ + *((int *)data)=getpid(); + return data; +} + +int main() +{ + pthread_t thread; + void *retval; + int err,mainpid,thrdpid; + + err=pthread_create(&thread, NULL, thread_func, &thrdpid); + if(err) { + fprintf(stderr,"pthread_create failed: %s\n",strerror(err)); + return 1; + } + err=pthread_join(thread,&retval); + if(err) { + fprintf(stderr,"pthread_join failed: %s\n",strerror(err)); + return 1; + } + mainpid=getpid(); + /* In LinuxThreads implementations, the pids of the threads will usually differ + in a non Posix-compliant way. */ + fprintf(stderr,"main pid=%d, thread pid=%d\n",mainpid,*((int *)retval)); + return (*((int *)retval)!=mainpid); +} +], +[ + AC_MSG_RESULT([yes]) + threadlib=nptl +], +[ + AC_MSG_RESULT([no]) + threadlib=linuxthreads +], +[ + AC_MSG_RESULT([couldn't run test program]) + threadlib=linuxthreads +]) +CFLAGS="$old_CFLAGS" +fi + +if test "$threadlib" = nptl -o "$threadlib" = NPTL; then + AC_DEFINE(THREADLIB_NPTL) +elif test "$threadlib" = linuxthreads2 -o "$threadlib" = LinuxThreads2 -o "$threadlib" = lt2; then + AC_DEFINE(THREADLIB_LINUXTHREADS2) +fi + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h malloc.h sys/ioctl.h sys/time.h syslog.h unistd.h) +AC_CHECK_HEADERS(sys/types.h sys/socket.h net/if.h netinet/in.h sys/poll.h,,, +[#include +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif +]) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_HEADER_TIME +AC_STRUCT_TM +AC_CHECK_TYPES(socklen_t,, AC_DEFINE(socklen_t,int),[#include +#include +#include +#include ]) +AC_CHECK_TYPES([struct in6_addr, struct in_pktinfo, struct ifreq],,,[#include +#include +#include +#include ]) + +AC_MSG_CHECKING([for CPP C99 Variadic macro support]) +AC_COMPILE_IFELSE([ +#define a(...) junk(0,__VA_ARGS__) +extern void junk(int i,...); +int main() +{ + a(0); + a("a"); + a(0, "a", 1); + return 0; +} +], + cpp_c99_variadic="yes", cpp_c99_variadic="no") +AC_MSG_RESULT([$cpp_c99_variadic]) +if test $cpp_c99_variadic = yes; then + AC_DEFINE(CPP_C99_VARIADIC_MACROS) +else + if test "$GCC" != yes; then + AC_MSG_ERROR([Compiler must support C99 or gcc variadic macros]) + fi; +fi + +dnl Checks for library functions. +AC_FUNC_ALLOCA +AC_PROG_GCC_TRADITIONAL +AC_FUNC_MEMCMP +AC_TYPE_SIGNAL +AC_FUNC_VPRINTF +AC_SEARCH_LIBS(nanosleep, rt) +AC_SEARCH_LIBS(socket, socket,,,-lnsl) +AC_SEARCH_LIBS(inet_aton, resolv) +AC_CHECK_FUNCS(nanosleep gettimeofday mkfifo select socket strerror uname snprintf vsnprintf, true, + AC_MSG_ERROR([One of the functions required for pdnsd were not found.])) +AC_CHECK_FUNCS(poll, true, AC_DEFINE(NO_POLL)) +AC_CHECK_FUNCS(strdup strndup stpcpy stpncpy strlcpy mempcpy getline asprintf vasprintf getpwnam_r inet_ntop inet_pton) + +AC_OUTPUT([ +pdnsd.spec +Makefile +file-list.base +contrib/Makefile +doc/Makefile +doc/pdnsd.8 +doc/pdnsd.conf.5 +doc/pdnsd.conf +src/Makefile +src/pdnsd-ctl/Makefile +src/rc/Makefile +src/rc/RedHat/Makefile +src/rc/RedHat/pdnsd +src/rc/SuSE/Makefile +src/rc/SuSE/pdnsd +src/rc/Debian/Makefile +src/rc/Debian/pdnsd +src/rc/Slackware/Makefile +src/rc/Slackware/rc.pdnsd +src/rc/ArchLinux/Makefile +src/rc/ArchLinux/pdnsd +src/test/Makefile +PKGBUILD +]) diff --git a/jni/pdnsd/contrib/Makefile.am b/jni/pdnsd/contrib/Makefile.am new file mode 100644 index 00000000..5bdec20a --- /dev/null +++ b/jni/pdnsd/contrib/Makefile.am @@ -0,0 +1,2 @@ + +EXTRA_DIST = pdnsd_dhcp.pl dhcp2pdnsd change_pdnsd_server_ip.pl README diff --git a/jni/pdnsd/contrib/Makefile.in b/jni/pdnsd/contrib/Makefile.in new file mode 100644 index 00000000..a400dfe9 --- /dev/null +++ b/jni/pdnsd/contrib/Makefile.in @@ -0,0 +1,323 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = contrib +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = pdnsd_dhcp.pl dhcp2pdnsd change_pdnsd_server_ip.pl README +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/contrib/README b/jni/pdnsd/contrib/README new file mode 100644 index 00000000..19e4f44d --- /dev/null +++ b/jni/pdnsd/contrib/README @@ -0,0 +1,30 @@ +Last revised: 27 July 2003 by Paul Rombouts + +This directory contains user-contributed scripts for use with pdnsd. +So far there are: + +pdnsd_dhcp.pl, save_ram.pl + A perl script contributed by Marko Stolle (derived from a script by + Mike Stella) to watch a ISC DHCPD leases file and add local records for + the hosts listed there. This makes pdnsd useable in a DHCP setup. + Please look into the script for usage instructions (you will probably + also need to customize some settings there). + For details about save_ram.pl, please look into pdnsd_dhcp.pl + +dhcp2pdnsd + A rc script for pdnsd, also by Marko Stolle. You might need to change + it slightly to make it run with your distro. + +change_pdnsd_server_ip.pl + A perl script contributed by Paul Rombouts for automatically updating + the configuration file if the DNS server configuration has changed. + For instance, you could place the following line in the script + /sbin/ifup-local + + /usr/local/sbin/change_pdnsd_server_ip.pl isplabel "$DNS" /etc/pdnsd.conf + + where $DNS contains the IP addresses (in comma separated format) of the + DNS servers obtained by DHCP negotiation. The perl script only + overwrites /etc/pdnsd.conf if the DNS configuration has actually + changed, in which case the previous configuration file is saved as + /etc/pdnsd.conf.save diff --git a/jni/pdnsd/contrib/change_pdnsd_server_ip.pl b/jni/pdnsd/contrib/change_pdnsd_server_ip.pl new file mode 100644 index 00000000..1eafca0d --- /dev/null +++ b/jni/pdnsd/contrib/change_pdnsd_server_ip.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl -w +# +# A Perl script to change the ip addresses of dns servers +# in the pdnsd configuration file. +# +# Written by Paul A. Rombouts +# +# This file Copyright 2002, 2004 Paul A. Rombouts +# It may be distributed under the GNU Public License, version 2, or +# any higher version. See section COPYING of the GNU Public license +# for conditions under which this file may be redistributed. +# + +use strict; + +unless(@ARGV) {die "Error: no label specified.\n"} +my $label=shift; +unless(@ARGV) {die "Error: no DNS addresses specified.\n"} +my $dns_str=shift; +my $pdnsd_conf='/etc/pdnsd.conf'; +if(@ARGV) { + $pdnsd_conf=shift; + if(@ARGV) {warn "Warning: spurious arguments ignored: @ARGV\n"} +} + +#unless($label =~ /^\".*\"$/) {$label="\"$label\""} +#unless($dns_str =~ /^\".*\"$/) {$dns_str =~ s/^[\s,]*/\"/; $dns_str =~ s/[\s,]*$/\"/} +#unless($dns_str =~ /\"\s*\,\s*\"/) {$dns_str =~ s/[\s,]+/","/g} + +my @lines=(); +my $found_section=0; +my $changed=0; +my $ip_patt = qr/^((?:[^#]*?(?:\{|;))*?)(\s*ip\s*=\s*)("?[\w.:]+"?(?:\s*,\s*"?[\w.:]+"?)*)\s*;/; + +open(CONFFILE,$pdnsd_conf) or die "Can't open $pdnsd_conf: $!\n"; + +while() { + if(/^\s*server\s*\{/) { + my $sect_beg=$#lines+1; + my $sect_end; + my $found_label=0; + LOOP: { + do { + push @lines,$_; + if(/^(?:.*(?:\{|;))?\s*label\s*=\s*"?\Q$label\E"?\s*;/) { + if($found_label++) { + warn "Server section with multiple labels found.\n"; + close(CONFFILE); + exit 2; + } + } + if(/\}\s*$/) { + $sect_end=$#lines; + last LOOP; + } + } while(); + } + unless(defined($sect_end)) { + warn "Server section without proper ending found.\n"; + close(CONFFILE); + exit 2; + } + if(!$found_label) {next} + if(!($found_section++)) { + my $found_ip=0; + for(my $i=$sect_beg; $i<=$sect_end;++$i) { + if($lines[$i] =~ $ip_patt) { + my $matched=''; my $rest; + do { + $rest=$'; + if(!($found_ip++)) { + if($3 eq $dns_str) { + $matched.=$&; + } + else { + $matched.="$1$2$dns_str;"; + $changed=1; + } + } + else { + $matched.=$1; + $changed=1; + } + } while($rest =~ $ip_patt); + $lines[$i] = $matched.$rest; + } + } + if(!$found_ip) { + unless($lines[$sect_end] =~ s/\}\s*$/ ip=$dns_str;\n$&/) { + warn "Can't add ip specification to server section labeled $label.\n"; + close(CONFFILE); + exit 2; + } + $changed=1; + } + } + else { + splice @lines,$sect_beg; + $changed=1; + } + } + else {push @lines,$_} +} + +close(CONFFILE) or die "Can't close $pdnsd_conf: $!\n"; + +if(!$found_section) { + warn "No server sections labeled $label found.\n"; + exit 2; +} +elsif(!$changed) { + exit 0; +} + +rename($pdnsd_conf,"$pdnsd_conf.save") or die "Can't rename $pdnsd_conf: $!\n"; + +unless((open(CONFFILE,">$pdnsd_conf") or (warn("Can't open $pdnsd_conf for writing: $!\n"),0)) and + (print CONFFILE (@lines) or (warn("Can't write to $pdnsd_conf: $!\n"),0)) and + (close(CONFFILE) or (warn("Can't close $pdnsd_conf after writing: $!\n"),0))) { + rename("$pdnsd_conf.save",$pdnsd_conf) or die "Can't rename $pdnsd_conf.save: $!\n"; + exit 3; +} + +exit 1; diff --git a/jni/pdnsd/contrib/dhcp2pdnsd b/jni/pdnsd/contrib/dhcp2pdnsd new file mode 100644 index 00000000..73b631cc --- /dev/null +++ b/jni/pdnsd/contrib/dhcp2pdnsd @@ -0,0 +1,45 @@ +#! /bin/sh +# +# dhcp2pdnsd Start/Stop DHCP to DNS update script +# +# chkconfig: 345 96 99 +# description: DHCP to DNS update script +# processname: dhcp2pdnsd.pl +# +# $Id: dhcp2pdnsd,v 1.1 2001/03/25 20:01:34 tmm Exp $ + +where="/usr/local/bin/" +name="pdnsd_dhcp.pl" + +# Source function library. +. /etc/rc.d/init.d/functions + +# Get config. +. /etc/sysconfig/network + +# See how we were called. +case "$1" in + start) + $where$name > /dev/null 2> /dev/null & + action "Starting DHCP to DNS update script: " /bin/true + ;; + stop) + p=`ps h -C $name | awk '{print $1}'` + [ $p -gt 0 ] 2> /dev/null && kill $p && action "Stopping DHCP to DNS update script: " /bin/true + [ $p -gt 0 ] 2> /dev/null || action "Stopping DHCP to DNS update script: " /bin/false + ;; + status) + p=`ps h -C $name | awk '{print $1}'` + [ $p -gt 0 ] 2> /dev/null && echo 'running as '$p + [ $p -gt 0 ] 2> /dev/null || echo 'not running' + ;; + restart|reload) + $0 stop + $0 start + ;; + *) + echo "Usage: dhcp2pdnsd {start|stop|status|restart|reload}" + exit 1 +esac + +exit 0 diff --git a/jni/pdnsd/contrib/pdnsd_dhcp.pl b/jni/pdnsd/contrib/pdnsd_dhcp.pl new file mode 100644 index 00000000..9cf0c879 --- /dev/null +++ b/jni/pdnsd/contrib/pdnsd_dhcp.pl @@ -0,0 +1,246 @@ +#!/usr/bin/perl +# $Id: pdnsd_dhcp.pl,v 1.2 2001/03/25 20:01:34 tmm Exp $ +########################################################################## +# +# Filename: pdnsd_dhcp.pl +# Description: Dynamic DNS-DHCP update script for pdnsd +# Author: Mike Stella +# Modified by: Marko Stolle +# Created: November 19, 2001 +# Last Updated: February 28, 2001 +# Email: fwd2m@gmx.de +# +########################################################################### +# +# This code is Copyright (c) 1998-2001 by Mike Stella and Marko Stolle +# +# NO WARRANTY is given for this program. If it doesn't +# work on your system, sorry. If it eats your hard drive, +# again, sorry. It works fine on mine. Good luck! +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +########################################################################### +# +# This script reads a dhcpd.leases file and dynamically updates pdnsd with +# hostname and ip information. +# +# It assumes that your DHCP server recieves hostnames from the +# clients, and that your clients offer their hostnames to the server. +# Some versions of Linux DHCP clients don't do that. I use ISC's +# DHCPD, found at http://www.isc.org - though others may work just +# fine. +# +# This version of the script updates the pdnsd database. The status +# control socket of pdnsd has to be enabled (psnsd -d -s). +# +########################################################################### +# +# 02/20/2001 - first working version +# 02/21/2001 - security patches by Thomas Moestl +# 02/22/2001 - re-read dhcpd.leases if ttl has expireds since last update +# 02/24/2001 - try to get domainname if not specified +# 02/28/2001 - randomized temporary filename +# added possibility to save some RAM (read below) +# +########################################################################### + + +# You may save some memory if you use absolute values with sysopen +# in sub update_dns and don't use tmpnam().. +# Just switch the '#' in front of the 'until sysopen' in the sub +# update_dns, check the necessary modes on your system using save_ram.pl +# and add a '#' in front of the following three lines. +# Not using the tmpnam() function may open a security breach on systems +# with not absolute trustworthy local users (Risk: a user may write a +# script which creates files with the same names as this script and block +# it that way. Unlikely because the filenames are now even without tmpnam() +# randomized and an attacker has to create a very large number of files.) + +use Fcntl; +use strict; +use POSIX qw(tmpnam); + +$|=1; + +########################################################################### +### Globals - you can change these as needed + +# Domain name +# if not changed script will try to get it from the system +my $domain_name = "domain"; + +# DHCPD lease file +my $lease_file = "/var/lib/dhcp/dhcpd.leases"; + +# path to pdnsd-ctl +my $pdnsd_ctl = "/usr/local/sbin/pdnsd-ctl"; + +# owning name server for the newly added records +my $nameserver = "localhost."; + +# TTL (Time To Live) for the new records +my $ttl = "86400"; + +# number of seconds to check the lease file for updates +my $update_freq = 30; + +my $debug = 0; + +########################################################################### +### Don't mess with anything below unless you REALLY need to modify the +### code. And if you do, please let me know, I'm always interested in +### in improving this program. + +# Make a pid file +`echo $$ > /var/run/pdnsd_update.pid`; + +my $logstr; +my $modtime = 0; +my $temp_dir = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP}; + +use vars qw (%db); + +my $version = "1.03"; + + +########################################################################### +# Main Loop + + # try to find domainname if necessary + if ($domain_name eq "domain") { + $domain_name = `dnsdomainname`; + } + else { + $domain_name = "$domain_name\n"; + } + +while (1) { + + # check the file's last updated time, if it's been changed, update + # the DNS and save the time. Update DNS even if there a no changes on + # the leases file if ttl since last DNS update has expired. + # This will ALWAYS run once - on startup, since $modtime starts at zero. + + + my @stats = stat ($lease_file); + + + if (($stats[9] > $modtime) or (time >= $modtime+$ttl)){ + + # clear the old hash + undef %db; + + printf STDERR "updating DNS with dhcpd.leases\n"; + $modtime = time; + &read_lease_file; + &update_dns; + } + + # wait till next check time + sleep $update_freq; + +} # end main +########################################################################### + + +### write out the import file +sub update_dns { + my ($ip, $hostname, $fname); + + do { $fname = tmpnam() } + until sysopen(DNSFILE, $fname, O_WRONLY|O_CREAT|O_EXCL, 0600); +# do { $fname = "$temp_dir/d2d".int(rand(time())) } +# until sysopen(DNSFILE, $fname, 1|64|128, 0600); + + while (($hostname,$ip) = each (%db)) { + print DNSFILE "$ip $hostname.$domain_name"; + } + close DNSFILE; + + system ("$pdnsd_ctl source $fname $nameserver $ttl"); + unlink($fname); +} + + +### reads the lease file & makes a hash of what's in there. +sub read_lease_file { + + unless (open(LEASEFILE,$lease_file)) { + #`logger -t dns_update.pl error opening dhcpd lease file`; + print STDERR "Can't open lease file\n"; + return; + } + + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + my $curdate = sprintf "%02d%02d%02d%02d%02d%20d%20d", + ($year+1900),($mon+1),$mday,$hour,$min,$sec; + + ## Loop here, reading from LEASEFILE + while () { + my ($ip, $hostname, $mac, $enddate,$endtime); + + if (/^\s*lease/i) { + + # find ip address + $_ =~ /^\s*lease\s+(\S+)/; + $ip = $1; + + # do the rest of the block - we're interested in hostname, + # mac address, and the lease time + while ($_ !~ /^}/) { + $_ = ; + # find hostname + if ($_ =~ /^\s*client/i) { + #chomp $_; + #chop $_; + $_ =~ /\"(.*)\"/; + $hostname = $1; + + # change spaces to dash, remove dots - microsoft + # really needs to not do this crap + $hostname =~ s/\s+/-/g; + $hostname =~ s/\.//g; + } + # get the lease end date + elsif ($_ =~ /^\s*ends/i) { + $_ =~ m/^\s*ends\s+\d\s+([^;]+);/; + $enddate = $1; + $enddate =~ s|[/: ]||g; + } + } + # lowercase it - stupid dhcp clients + $hostname =~ tr/[A-Z]/[a-z]/; + + ($debug < 1 ) || print STDERR "$hostname $ip $enddate $curdate\n"; + + # Store hostname/ip in hash - this way we can do easy dupe checking + if (($hostname ne "") and ($enddate > $curdate)) { + $db{$hostname} = $ip; + } + } + } + close LEASEFILE; +} + +### left around for testing +sub print_db { + my ($key,$value); + + while (($key,$value) = each (%db)) { + print "$key - $value\n"; + } +} + diff --git a/jni/pdnsd/depcomp b/jni/pdnsd/depcomp new file mode 100644 index 00000000..04701da5 --- /dev/null +++ b/jni/pdnsd/depcomp @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/jni/pdnsd/doc/Makefile.am b/jni/pdnsd/doc/Makefile.am new file mode 100644 index 00000000..b3e21984 --- /dev/null +++ b/jni/pdnsd/doc/Makefile.am @@ -0,0 +1,28 @@ + +man_MANS = pdnsd.8 pdnsd-ctl.8 pdnsd.conf.5 + +# Note: pdnsd-ctl.8, pdnsd.conf.5.in, dl.html and the txt docs are handled by dist-hook rule. +EXTRA_DIST = pdnsd.conf.in pdnsd.8.in \ + html/dl.html.in html/doc.html html/faq.html html/index.html \ + doc_makefile html/doc_makefile txt/doc_makefile \ + html2confman.pl html/htmlsubst.pl + +# XXX: Do not insist to set the config file owner to root to avoid breaking RPM +# builds +install-data-hook: + $(mkinstalldirs) "$(DESTDIR)$(sysconfdir)" + if test `whoami` = "root"; then \ + $(INSTALL) -o 0 -g 0 -m 644 pdnsd.conf "$(DESTDIR)$(sysconfdir)/pdnsd.conf.sample" ; \ + else \ + $(INSTALL) -m 644 pdnsd.conf "$(DESTDIR)$(sysconfdir)/pdnsd.conf.sample" ; \ + fi + +dist-hook: doc_makefile + @$(MAKE) -f doc_makefile doc + cp -p --parents pdnsd-ctl.8 pdnsd.conf.5.in \ + html/dl.html txt/faq.txt txt/intro.txt txt/manual.txt \ + $(distdir) + +distclean-local: doc_makefile + @$(MAKE) -f doc_makefile clean + diff --git a/jni/pdnsd/doc/Makefile.in b/jni/pdnsd/doc/Makefile.in new file mode 100644 index 00000000..7f07fe69 --- /dev/null +++ b/jni/pdnsd/doc/Makefile.in @@ -0,0 +1,483 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = doc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/pdnsd.8.in $(srcdir)/pdnsd.conf.5.in \ + $(srcdir)/pdnsd.conf.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pdnsd.8 pdnsd.conf.5 pdnsd.conf +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +man5dir = $(mandir)/man5 +am__installdirs = "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(man_MANS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +man_MANS = pdnsd.8 pdnsd-ctl.8 pdnsd.conf.5 + +# Note: pdnsd-ctl.8, pdnsd.conf.5.in, dl.html and the txt docs are handled by dist-hook rule. +EXTRA_DIST = pdnsd.conf.in pdnsd.8.in \ + html/dl.html.in html/doc.html html/faq.html html/index.html \ + doc_makefile html/doc_makefile txt/doc_makefile \ + html2confman.pl html/htmlsubst.pl + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pdnsd.8: $(top_builddir)/config.status $(srcdir)/pdnsd.8.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +pdnsd.conf.5: $(top_builddir)/config.status $(srcdir)/pdnsd.conf.5.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +pdnsd.conf: $(top_builddir)/config.status $(srcdir)/pdnsd.conf.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-man5: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" + @list=''; test -n "$(man5dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man5dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man5dir)" && rm -f $$files; } +install-man8: $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man5 install-man8 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man5 uninstall-man8 + +.MAKE: install-am install-data-am install-strip + +.PHONY: all all-am check check-am clean clean-generic dist-hook \ + distclean distclean-generic distclean-local distdir dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-data-hook install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man5 \ + install-man8 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am uninstall-man uninstall-man5 uninstall-man8 + + +# XXX: Do not insist to set the config file owner to root to avoid breaking RPM +# builds +install-data-hook: + $(mkinstalldirs) "$(DESTDIR)$(sysconfdir)" + if test `whoami` = "root"; then \ + $(INSTALL) -o 0 -g 0 -m 644 pdnsd.conf "$(DESTDIR)$(sysconfdir)/pdnsd.conf.sample" ; \ + else \ + $(INSTALL) -m 644 pdnsd.conf "$(DESTDIR)$(sysconfdir)/pdnsd.conf.sample" ; \ + fi + +dist-hook: doc_makefile + @$(MAKE) -f doc_makefile doc + cp -p --parents pdnsd-ctl.8 pdnsd.conf.5.in \ + html/dl.html txt/faq.txt txt/intro.txt txt/manual.txt \ + $(distdir) + +distclean-local: doc_makefile + @$(MAKE) -f doc_makefile clean + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/doc/doc_makefile b/jni/pdnsd/doc/doc_makefile new file mode 100644 index 00000000..f5e8f86d --- /dev/null +++ b/jni/pdnsd/doc/doc_makefile @@ -0,0 +1,38 @@ +# This file was written by Paul Rombouts. +# Because pdnsd currently has a very idiosyncratic method of building documentation +# I prefer to keep the actual build rules outside of the Makefiles an ordinary user +# would use to compile pdnsd and therefore I have put them into separate 'doc_makefile's. +# +# To rebuild pdnsd docs after you have modified something that other files depend on, +# run 'make -f doc_makefile doc' in the doc/ directory. +# This makefile is also invoked when you build a pdnsd distribution tarball +# using 'make dist' in the toplevel pdnsd source directory. +# +# If anyone thinks there is a much more elegant method for building the pdnsd docs +# using a conventional autoconf/automake process, please let me know. + +versionfile = ../version + +doc: pdnsd-ctl.8 pdnsd.conf.5.in html txt +.PHONY: pdnsd-ctl.8 doc html txt clean + +pdnsd-ctl.8: + @pver=`cat $(versionfile)` && \ + mver=`perl -e 'while(<>) {if(/^\s*\.TH(?:\s+(?:"[^"]*"|[^"\s]+)){3}\s+"pdnsd\s+([^"]*)"/) {print "$$1\n";exit 0}} \ + die "Cannot find version in $$ARGV\n"' $@` && { \ + test "$$mver" = "$$pver" || { \ + perl -p -i.makesave -e 's/^(\s*\.TH(?:\s+(?:"[^"]*"|[^"\s]+)){3}\s+"pdnsd\s+)[^"]*(")/$${1}'"$$pver"'$${2}/' $@ && \ + echo "Updated version in $@: $$mver -> $$pver"; \ + }; \ + } + +pdnsd.conf.5.in: html/doc.html html2confman.pl + perl html2confman.pl $< > $@ + +html txt: + @cd $@ && $(MAKE) -f doc_makefile + +clean: + @rm -fv pdnsd.conf.5.in + @cd html && $(MAKE) -f doc_makefile clean + @cd txt && $(MAKE) -f doc_makefile clean diff --git a/jni/pdnsd/doc/html/dl.html b/jni/pdnsd/doc/html/dl.html new file mode 100644 index 00000000..3f9c6140 --- /dev/null +++ b/jni/pdnsd/doc/html/dl.html @@ -0,0 +1,96 @@ + + + + pdnsd Download Page + + + + + + + + + + + + + +
+ pdnsd Homepage + + pdnsd FAQ + + Documentation + + GNU GPL (pdnsd's License) + + Download Section +
+ +

pdnsd Download Page

+ +

The original author of pdnsd is Thomas Moestl, + but since 2003, he no longer maintains pdnsd. + However, Paul A. Rombouts has extensively revised the code and maintains + a version with many fixes and improvements at + http://members.home.nl/p.a.rombouts/pdnsd.html.
+ He has pre-patched tarballs and RPM packages available for download at this site.
+

+

+ If you are interested in the very latest code or if you want to participate in + pdnsd development, checkout the pdnsd git repository + at gitorious.org. +

+ + The most recent tarball is pdnsd-1.2.9b-par.tar.gz + (GPG signature).
+ The most recent RPM packages are: + + + + + + + + + + + + + + + + + + + + + +
Package NameSizeDescription
pdnsd-1.2.9b-par.src.rpm514kBSource RPM (binary packages can also be built directly from the tarball). +
pdnsd-1.2.9b-par_sl6.i686.rpm???i686 binary built on a Scientific Linux 6.2 system. +
pdnsd-1.2.9b-par_sl6.x86_64.rpm282kBx86_64 binary built on a Scientific Linux 6.2 system. +
+ If you want to check the signatures on these packages you will need a copy of my GPG key + which you can get here + or from a public key server. +

+ There are also Debian, + Ubuntu, + Gentoo, + Mandriva + and FreeBSD + packages, but these may not include the latest version.
+ If you are looking for other versions released by Paul Rombouts, visit this + download directory. +

+
+
+

+ Last revised: 24 Apr 2012 by Paul A. Rombouts +

+ + diff --git a/jni/pdnsd/doc/html/dl.html.in b/jni/pdnsd/doc/html/dl.html.in new file mode 100644 index 00000000..dffe2b02 --- /dev/null +++ b/jni/pdnsd/doc/html/dl.html.in @@ -0,0 +1,96 @@ + + + + pdnsd Download Page + + + + + + + + + + + + + +
+ pdnsd Homepage + + pdnsd FAQ + + Documentation + + GNU GPL (pdnsd's License) + + Download Section +
+ +

pdnsd Download Page

+ +

The original author of pdnsd is Thomas Moestl, + but since 2003, he no longer maintains pdnsd. + However, Paul A. Rombouts has extensively revised the code and maintains + a version with many fixes and improvements at + http://members.home.nl/p.a.rombouts/pdnsd.html.
+ He has pre-patched tarballs and RPM packages available for download at this site.
+

+

+ If you are interested in the very latest code or if you want to participate in + pdnsd development, checkout the pdnsd git repository + at gitorious.org. +

+ + The most recent tarball is pdnsd-$version.tar.gz + (GPG signature).
+ The most recent RPM packages are: + + + + + + + + + + + + + + + + + + + + + +
Package NameSizeDescription
pdnsd-$version.src.rpm$sizeof("$HOME/rpmbuild/SRPMS/pdnsd-$version.src.rpm")Source RPM (binary packages can also be built directly from the tarball). +
pdnsd-${version}${extver}.${arch}.rpm$sizeof("$HOME/rpmbuild/RPMS/pdnsd-${version}${extver}.${arch}.rpm")${arch} binary built on a $system. +
pdnsd-${version}${extver}.${arch2}.rpm$sizeof("$HOME/rpmbuild/RPMS/pdnsd-${version}${extver}.${arch2}.rpm")${arch2} binary built on a $system. +
+ If you want to check the signatures on these packages you will need a copy of my GPG key + which you can get here + or from a public key server. +

+ There are also Debian, + Ubuntu, + Gentoo, + Mandriva + and FreeBSD + packages, but these may not include the latest version.
+ If you are looking for other versions released by Paul Rombouts, visit this + download directory. +

+
+
+

+ Last revised: $date by Paul A. Rombouts +

+ + diff --git a/jni/pdnsd/doc/html/doc.html b/jni/pdnsd/doc/html/doc.html new file mode 100644 index 00000000..95828c5c --- /dev/null +++ b/jni/pdnsd/doc/html/doc.html @@ -0,0 +1,2630 @@ + + + + pdnsd Documentation + + + + + + + + + + + + + + +
+ pdnsd Homepage + + pdnsd FAQ + + Documentation + + GNU GPL (pdnsd's License) + + Download Section +
+ +

pdnsd Documentation

+ This is the "official" pdnsd documentation and reference written by + Thomas Moestl with revisions by + Paul A. Rombouts.
+ This manual is a part of the pdnsd package, and may be distributed in + original or modified form under terms of the GNU General Public + License, as published by the Free Software Foundation; either version + 3, or (at your option) any later version.
+ You can find a copy of the GNU GPL in the file COPYING in the source or documentation directory.
+ This manual is up-to-date for version 1.2.9b. For older documentation, please refer to the doc + directory of the respective pdnsd package.
+ If you want a quicker introduction to pdnsd, you can try some of the + HOWTOs available on the web. + For Apple Mac users, Brian Wells has published a good HOWTO at + http://web.mac.com/brianwells/main/pdnsd.html. + + +

0. Installation

+

0.1 Installing binary RPM's

+ To install a binary RPM, just do
+

rpm -i pdnsd-<version>.rpm

+ This should install pretty much everything automatically. The only thing left + for you to do is adapt your configuration file (stored in /etc/pdnsd.conf) + according to your needs (see below). + In the Red Hat and SuSE RPMs, a start script is also installed; read the section + 0.4, Start at Boot Time about that. + +
+

0.2 Building RPM's

+ It is possible to build a binary RPM from a source package using the command
+

rpmbuild --rebuild pdnsd-<version>.src.rpm

+ or alternatively from a tarball using the command
+

rpmbuild -tb pdnsd-<version>.tar.gz

+ You can do this as root, but it is safer to build a binary package first as a normal user, + and then, when all has gone well, install the resulting binary package as root as in the previous section. + How to build an RPM package without being root is described at + + http://www.ibm.com/developerworks/linux/library/l-rpm1/.

+ Several pdnsd-specific options are available when building RPM packages: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ --with isdn + + Has the same effect as --enable-isdn (see below). +
+ --without poll + + Has the same effect as --disable-poll (see below). +
+ --without nptl + + Has the same effect as --with-thread-lib=linuxthreads (see below). +
+ --with ipv6 + + Has the same effect as --enable-ipv6 (see below). +
+ --without tcpqueries + + Has the same effect as --disable-tcp-queries (see below). +
+ --without debug + + Has the same effect as --with-debug=0 (see below). +
+ --define "distro <distro>" + + Has the same effect as --with-distribution=<distro> (see below). +
+ --define "run_as_user <user>" + + Has the same effect as --with-default-id=<user> (see below).
+ For RPMs the default <user> is "pdnsd". +
+ --define "run_as_uid <uid>" + + If the user defined by the previous option does not exist when the RPM is installed, + the pre-install script will try to create a new user with numerical id <uid>. + The default is to let the system choose the numerical id at install time. +
+ --define "cachedir <dir>" + + Has the same effect as --with-cachedir=<dir> (see below). +
+ You can also configure which compiler flags will be used by setting the environment variable + CFLAGS. + Using a bash shell, you can do that on the command line like this: +  CFLAGS="-O1 -Wall" rpmbuild ...
+ This is useful if you prefer a different level of optimization, for instance. + +
+

0.3 Installing from pure sources (tar archives or git repositories)

+

0.3.1 Setting up the source code tree

+ Source code is available in the form of snapshots (tarballs) or a git repository + with the very latest development code and a (nearly) complete history of all the revisions. + Cloning a git repository is useful if you need a recent fix or feature + that is not yet contained in a main release or you want to participate in pdnsd development. + Otherwise you will probably find the tarballs more convenient because they are much more compact. +
0.3.1.1 Unpacking a tar archive
+ The pdsnsd snapshot releases come in the form of a gzip'ed tar archive. + To decompress it (using a modern tar) do
+

tar -xzf pdnsd-<version>.tar.gz

+ If your tar doesn't do this, use:
+

gzip -dc pdnsd-<version>.tar.gz | tar -xf -

+
0.3.1.2 Cloning a git repository
+ To clone a git repository you need to install, if not already installed, + the git version control system, which is available as a package in most modern Linux distributions. + Then run the command:
+

git clone git://gitorious.org/pdnsd/pdnsd.git pdnsd

+ In rare cases, if you are behind some kind of firewall, the special git protocol can't be used + and you will need to fall back to the http protocol. + See the gitorious.org website or git documentation for more information. + +

0.3.2 Configuring the source

+ Change into the pdnsd source directory and run configure. It takes the following command line + options (if you do not specify an option, defaults will be used):
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ --prefix=dir + + Specify the prefix directory. The pdnsd files are installed in subdirectories + of the prefix, the pdnsd and pdnsd-ctl executables are for example installed + in the sbin subdirectory of the prefix. The default for this is /usr/local; + you might want to set this to /usr (using --prefix=/usr). +
+ --sysconfdir=dir + + Specify the config directory. pdnsd expects its pdnsd.conf file to reside + there if the -c option is not given at startup. + The default for this is the etc subdirectory of your prefix, e.g. /usr/local/etc + if you did not specify a prefix. To set this e.g. to /etc, use --sysconfdir=/etc. +
+ --with-distribution=distro + + Specify target distribution (default=Generic; others: RedHat, SuSE, Debian)
+ See below for the effect of these settings. +
+ --with-target=platform + + Change compilation target platform (default: autodetect; others: Linux, BSD, Cygwin).
+ autodetect will attempt to detect whether you are using Linux, *BSD or Cygwin and + should normally be sufficient. If this does not work, try specifying + your system manually (for the Darwin platform (Apple Mac OS X) specify BSD here). +
+ --with-cachedir=dir + + Default directory for pdnsd cache (default=/var/cache/pdnsd)
+ This setting can be changed via config file settings when pdnsd has been built. +
+ --with-hash-buckets=num + + Number of hash buckets to use (default=1024). The default should be + sufficient for most purposes, but if you want to store a large number of names + in the cache, cache lookups may be faster if the number of hash buckets + is comparable to the number of names stored in the cache. + The number actually used is the smallest power of two + greater or equal to the number specified here. +
+ --enable-isdn + + Enable ISDN support
+ This option will work only on Linux and may cause problems with 2.0.x or + old 2.2.x kernels. You will need it for a proper if uptest + under Linux for ISDN ppp devices. +
+ --disable-ipv4 + + Disable IPv4 networking support (default=enabled) +
+ --enable-ipv6 + + Enable IPv6 networking support.
+ If your OS does support IPv6 properly, you should be able to serve also + IPv4 queries using this. Normally, this is disabled and you won't need + it. +
+ --disable-ipv4-startup + + Disable IPv4 on pdnsd startup by default (default=enabled) +
+ --enable-ipv6-startup + + Enable IPV6 on pdnsd startup by default (default=IPv4). + These options are only defaults, you can specify on + the command line or in the config files which IP version + will really be used. + Normally, you won't need to change these. +
+ --disable-udp-queries + + Disable UDP as query method. You shouldn't need to change + this. +
+ --disable-tcp-queries + + Disable TCP as query method. This only effects the querying of + name servers by pdnsd, not the ability of pdnsd to answer + TCP queries from clients. + TCP queries are slower than UDP queries, but can be more secure + against certain types of attacks and are able to handle large answers. + For normal use this can be disabled. + (Note that the default has changed: TCP-query support + is now compiled in by default, but it still depends on the run-time + options whether it is actually used.) +
+ --with-query-method=qm + + Specify the query method (default=udponly, others: tcponly, tcpudp, udptcp). + If you have enabled both UDP and TCP queries, this lets you control + which query method pdnsd will use by default. tcpudp will try TCP + first and fall back to UDP if TCP is not supported by the server; + udptcp will try UDP first and, if the answer was truncated, will repeat + the query using TCP. + udponly and tcponly should be clear. Note that this only effects + the compiled-in default; the query method can still be changed using + command-line options or options in the configuration file. +
+ --disable-tcp-server + + Disable the TCP server. + In this case pdnsd will not be able to respond to TCP queries from clients. + This may cause problems with very large answers. +
+ --disable-src-addr-disc + + Disable the UDP source address discovery.
+ You need this only if you have trouble with messages saying + "could not discover udp source address".
+ For the Cygwin target, this option is disabled by default. +
+ --disable-poll + + Disable poll(2) and use select(2) (default=enabled)
+ You will normally not need this. +
+ --disable-new-rrs + + Since version 1.2.9 this option is obsolete and ignored. + It is now possible to configure for each RR type separately whether it is + cacheable by pdnsd by editing the file src/rr_types.in. + The comments in this file explain how to do this. +
+ --enable-strict-rfc2181 + + Enforce strict RFC 2181 compliance.
+ This will cause pdnsd to reject DNS answers with incorrect + timestamp settings (multiple RRs of the same type and for the same domain with + different TTLs). Normally not needed. +
+ --enable-underscores + + This option is obsolete. Since version 1.2, pdnsd places no restrictions + on the types of characters in domain names (there are still a few restrictions + for locally defined names, though). +
+ --with-random-device=device + + Specify random device; default: C Library random() PRNG
+ pdnsd uses (pseudo-) random numbers as query IDs for security reasons + (this makes forging DNS answers more difficult). This option + controls where pdnsd gets these from. The default is the C library + random() function, which is relatively weak. + You can specify a device like /dev/urandom here if you like; pdnsd will read + random numbers from it 16-bit-wise. /dev/urandom is present under Linux and + most BSD derivates. You should not use /dev/random - it is more secure, but + may block and delay pdnsd's answers for a long time.
+ You can specify arc4random to use the BSD arc4random() + library function (default for FreeBSD target), which is considered safe.
+ You can also specify random as device to use the C Library + random() function (described above). +
+ --with-default-id=user + + Specify default user for pdnsd (default=nobody). + This is the user that will be entered for the run_as + option in the config file (see below) that will be installed during make install. + You can change this any time in your config file. +
+ --with-debug=level + + Specify debugging level. Normally you can safely switch debugging off + by setting the level to 0. This will increase speed (although only + marginally) and save space in the executable (only about 12kB). + However, more significant may be the savings in stack space, especially + if pdnsd is put under heavy load and there are many simultaneous + running threads.
+ Presently the only defined debug levels are in the range 0 - 9. + Setting the level to 9 enables hex dumps of the queries and replies + pdnsd receives and should normally not be needed. Debug output will only + be generated if you turn on special switches; it might be useful for + debugging your config files, so I recommend using the default (1). + However, if you use pdnsd under heavy load, a better strategy may be + to compile one version of pdnsd without debug support (configured with + --with-debug=0) for production use, and one version with + with debug support (e.g. --with-debug=9) + for diagnostic purposes. +
+ --with-verbosity=level + + Specify default message verbosity. The default should be ok. +
+ --enable-rcsids + + Enable RCS IDs in executables (default=disabled).
+ For personal use, there is no need to do this. If you build rpm's, it + might have advantages. +
+ --enable-tcp-subseq + + Enable subsequent tcp queries. The DNS protocol standard + requires that servers must be capable of answering multiple + subsequent queries that are sent over the same tcp connection, and that + the server may only close the connection by himself after a certain + timeout. This feature is rarely used, but may make denial-of-service + attacks easier, as it allows for an attacker to hold a connection open + a long time (although the attacker's IP is most likely revealed then). + For full standard compliance, you should use this option. + If you do not use --enable-tcp-server, is option is not honored. +
+ --with-tcp-qtimeout=secs + + Specify default tcp query timeout after which the connection is closed + if no full query has been received. The default is 30s. + You can also change this option at run time using the tcp_qtimeout + config file option. + If you do not use --enable-tcp-server, is option is not honored. +
+ --with-par-queries=num + + Specify the default number of queries that can be executed in parallel. + You can also change this option at run time using the par_queries + config file option. See the description of that option for an explanation + of what it really does.
+ The default for this option is 2. +
+ --with-max-nameserver-ips=num + + New in version 1.2.9b: + Specify the maximum number of IP addresses that can be used per nameserver obtained + from NS records (when resolving names recursively). + Just one IP address per nameserver is sufficient in the vast majority of cases + (and this was the strategy used by pdnsd in previous versions), + but in rare cases this will cause unnecessary resolve failures if the address chosen + for each nameserver happens to be unreachable while the other addresses would lead to + successful resolution.
+ The default for this option is 3. +
+ --with-thread-lib=lib + + Added by Paul Rombouts: Use this option if you experience problems with + signal handling under Linux. The usual symptom is that pdnsd fails to save + the cache to disk, and /var/cache/pdnsd/pdnsd.cache remains empty. + If you experience this kind of trouble, try reconfiguring with different values + for the --with-thread-lib option. The allowable values are + linuxthreads (or lt for short), linuxthreads2 + (or lt2 for short), and nptl. + By default the configure script tries to detect automatically whether + linuxthreads or nptl is more appropriate for your system, + but the method used is not foolproof. Look for the line: + checking if this is an NPTL-based system...
+ If the automatic test mistakenly indentifies the thread library on your system as + NPTL based, you should reconfigure with --with-thread-lib=lt and recompile. + If the result of the automatic test is "no" or if + --with-thread-lib=lt does not have the desired effect, try again using + --with-thread-lib=lt2 . +
+ Normally, you will need only --prefix, --sysconfdir and + --with-distribution. + If you specify your distribution using --with-distribution, this has the + following effects: +
    +
  • An rc script is copied in the appropriate localtion, which enables pdnsd to start + at machine boot time (see 0.4) +
  • Distribution-specific portions might be included in the generated pdnsd.spec + file (only important if you want to build rpm archives yourself). +
+ If you choose Generic, no rc script is installed, and a generic spec + file is generated.
+ + Further instructions are in the INSTALL document in the pdnsd source directory. + ./configure --help will give you a list of all supported command line + options.

+ Note added by Paul Rombouts: Some people may want change the compiler optimization flag. + I use the -O2 flag, but it might be safer to use a lower level of + optimization or no optimization at all. In that case prefix the + configure command with the desired compiler flags like this + (assuming you're using a bash shell): +

CFLAGS="-O1 -Wall" ./configure ...

+ + +
+

0.3.3 Building & installing

+ Type make in the source directory. Should work by now.
+ To install, type make install or do the installation by hand (see 0.3.4).
+ make install will do the following ($prefix is the prefix directory; see above):
+
    +
  1. copies pdnsd to $(prefix)/sbin/ +
  2. copies pdnsd-ctl to $(prefix)/sbin/ +
  3. copies docs/pdnsd.conf.sample (a sample configuration) to the pdnsd config directory. +
  4. creates your cache directory if it is not there. + After installation, you should check the file permissions and create or edit + /etc/pdnsd.conf to fit your needs (see below). + If you use the run_as option, please make sure that your + cache directory is owned by the user you specified with this option! +
+ You must be root for this installation!
+ Security notes: never make the pdnsd cache directory + writeable for untrusted users, or you will get several security holes: + the users might modify the cache contents, or plant dangerous links.
+ If you use a pidfile, you should be aware that you introduce security + problems if you place the pidfile in a directory in a NFS filesystem that + is writeable for untrusted users. Generally, the pidfile directory + (typically /var/run) should not be writeable for untrusted users. +
+

0.3.4 Manual installation

+ For a manual installation, you need to do the following steps: +
    +
  1. Copy pdnsd and pdnsd-ctl from your build directory to an appropriate location (e.g. /usr/sbin). +
  2. Copy docs/pdnsd.conf into the directory you want it to reside (/etc by default, + and change it according to your needs (see below). +
  3. Create your caching directory; default is /var/cache/pdnsd (you may change this + in your pdnsd.conf); Permissions should be at max rwxr-xr-x (if you want to + protect your cache and status socket, make it rwx------). +
+ Thats it! +
+ +

0.4 Start at boot time

+ In the src/rc folder of the pdnsd distribution are start scripts + for pdnsd designed for different Linux distros. There are scripts + for SuSE, Redhat, Debian, Arch Linux and Slackware now.
+ The start scripts are automatically installed during RPM install, and also during make install + if you specified your distro.
+ For Slackware Linux there is a start-up script contributed by Nikola Kotur, but presently + it must be installed manually. + See src/rc/README and src/rc/Slackware/rc.pdnsd for details. + +

0.4.1 SuSE Linux startup

+ rc/SuSE/pdnsd is a start script for SuSE Linux. It was tested for 6.? but should run on some + versions below. You can do make install as root in the rc/SuSE + directory to install it, or you can install manually:
+ + + + + + + +
+ manual installation +
+ For manual installation, copy rc/SuSE/pdnsd into /sbin/init.d/, go to + /sbin/init.d/rc2.d/ and create there the following two symlinks:
+ S11pdnsd to ../pdnsd (do ln -s ../pdnsd S11pdnsd in that dir)
+ K34pdnsd to ../pdnsd (do ln -s ../pdnsd K34pdnsd in that dir)
+ The numbers dictate the order different services are started and + might need to be modified. Then edit your /etc/rc.config file and + add the line START_PDNSD=yes to start pdnsd at boot time. +
+

+ If you used the make install command, START_PDNSD=yes has been + appended to your /etc/rc.config file, causing pdnsd to be started + at boot time. If you don't want that, change the yes into no. +

+ This start script was created from /sbin/init.d/skeleton by me, so the + most is copyrighted by SuSE. They put it under the GPL, however, so + the license stated in COPYING also applies to this script. + There is NO WARRANTY OF ANY KIND on these scripts. + This is no official SuSE script, and SuSE naturally does NO support + for it. +

0.4.2 Red Hat Linux startup

+ rc/Redhat/pdnsd is a start script for Red Hat Linux. It was contibuted by Torben + Janssen.
+ This was tested for 6.1 but should run on 5.0+. You can do make install as root in the + rc/Redhat directory to install it, or you can install manually:
+ + + + + + + +
+ manual installation +
+ For manual installation, copy rc/Redhat/pdnsd into /etc/rc.d/init.d/
+ Then go to /etc/rc.d/rc3.d and create there the following symlink:
+ S78pdnsd -> ../init.d/pdnsd + (do ln -f -s ../init.d/pdnsd S78pdnsd in that dir)
+ + Then go to /etc/rc.d/rc0.d and create there the following symlink:
+ K78pdnsd -> ../init.d/pdnsd + (do ln -f -s ../init.d/pdnsd K78pdnsd in that dir)
+ + Then go to /etc/rc.d/rc6.d and create there the following symlink:
+ K78pdnsd -> ../init.d/pdnsd + (do ln -f -s ../init.d/pdnsd K78pdnsd in that dir) +
+ This script is also covered by license stated in COPYING. + Again, there is NO WARRANTY OF ANY KIND on these scripts. + This is no offical Redhat script, and Redhat naturally does NO support + for it +
+

0.5 Notes for FreeBSD users

+ The special handling of ISDN ppp devices is only supported on Linux. It is not needed in FreeBSD, the normal + device handling also works fine with isdn4bsd devices.
+ When compiled for FreeBSD, pdnsd as a small RFC compatability issue: RFC2181 demands answers on dns querys + to be sent with the same source address the query packet went to. In seldom cases, this will not be the case, + because the kernel selects the source address depending on the interface that was used for sending the answer.
+ Setting the source address currently does not work for IPv4. I have written a kernel patch that will provide an easy way + to program this. We'll see if or when it gets commited.
+
+
+

1 Invocation

+ When invoking pdnsd, you can specify various options at the command line. Command line options + always override config file options. The various --noX options are present to override + config file options. +

+ pdnsd --help (or -h) gives you an overview of the pdnsd command line options. +

+

+ pdnsd --version (or -V for short) prints licence and version information. +

+

+ To start pdnsd as background daemon, specifiy --daemon (or -d for short) on + the command line. Diagnostic and error messages after the actual daemon start + will be printed to the syslog instead of the console. --nodaemon will disable this. +

+

+ When starting pdnsd as a daemon, the -p option may be helpful: It writes the pid + of the server process to the file of the name given as argument to this option.
+ Example: pdnsd -d -p /var/run/pdnsd.pid +

+

+ If you want to specify a configuration file other than /etc/pdnsd.conf, specify + -c or --config-file on the command line, followed by a filename. +

+

+ If pdnsd was compiled with debugging support, you may specify -g or + --debug on the command line. This will cause extra diagnostic messages to be + printed. When pdnsd runs in daemon mode, the messages will be written to the pdnsd.debug + file in your cache directory. --nodebug disables debugging. +

+

+ pdnsd -vn sets the verbosity level of pdnsd. n is normally a digit from 0 to 3, + where 0 means normal operation, while 3 will most verbose. + Level 9 can be used in combination with the --debug option for very + extensive debug information.
+ Note: The current implementation mostly ignores the verbosity level, + so you may not notice much difference between the various levels. +

+

+ The option -s or --status enables the status control socket. This is a named socket in + the cache directory called pdnsd.status. This socket allows run-time configuration of pdnsd + using the utility pdnsd-ctl. See below for more details about pdnsd-ctl. + --nostatus disables status control. + See also the configuration option status_ctl in the global section. +

+

+ The option --notcp disables the seldom needed TCP server thread, which may + save you some resources. -t or --tcp will enable it. + See also the tcp_server configuration option. +

+

+ Using the -m option, you can select the method pdnsd uses to query other name servers. + Following methods are supported (see also the query_method + configuration option):
+ -muo: pdnsd will use UDP only. This is the fastest method, and should be supported by all name servers + on the Internet.
+ -mto: pdnsd will use TCP only. TCP queries usually take longer time than UDP queries, but are more secure + against certain attacks, where an attacker tries to guess your query id and to send forged answers. TCP queries + are not supported by some name servers.
+ -mtu: pdnsd will try to use TCP, and will fall back to UDP if its connection is refused or times out.
+ -mut: New in version 1.2.5: pdnsd will try to use UDP, and will repeat the query using TCP if the UDP reply was truncated + (i.e. the tc bit is set). This is the behaviour recommended by the DNS standards.
+

+

+ The -4 option switches to IPv4 mode, providing pdnsd was compiled with IPv4 support.
+ The -6 option switches to IPv6 mode, providing pdnsd was compiled with IPv6 support.
+ The -a option is only available when pdnsd was compiled with both IPv4 and IPv6 support. + With this option, pdnsd will try to detect automatically if a system supports IPv6, and fall back to IPv4 otherwise.
+

+

+ With -i prefix or --ipv4_6_prefix=prefix you can set the prefix pdnsd uses (when running in IPv6 + mode) to map IPv4 addresses in the configuration file to IPv6 addresses. + There is also a corresponding option for the config file, see below. + Must be a valid IPv6 address. + The default is ::ffff:0.0.0.0 +

+ +

2 The configuration file

+ This section describes the layout of the configuration file and the available + configuration options. + The default location of the file is /etc/pdnsd.conf. This may be changed + with the -c command line option. + An example pdnsd.conf comes with the pdnsd distribution in the docs directory + and will be installed to /etc/ by make install. + +
+

2.1 Layout

+ The configuration file is divided into sections. Each section is prefixed with + the section name and opening curlies ({) and closed with closing curlies (}). + In each section, configuration options can be given in the form +
+ option_name=option_value; +
+ Option value may be a string literal, a number, a time specification or a constant. + In previous versions of pdnsd strings had to be enclosed + in quotes ("), but since version 1.1.10 this is no longer necessary, unless + a string contains a special character such as whitespace, a token that normally starts + a comment, or one of ",;{}\". + Since version 1.2.9 a backslash (\) inside a string is interpreted as an escape character, + so it is possible to include special characters in strings (both quoted or unquoted) + by preceding them with a backslash. Some escape sequences are in interpreted as in the C + programming language, e.g. \t becomes a tab, + \n becomes a new-line control char.
+ A time specification consists a sequence of digits followed by a one-letter suffix. + The following suffixes are recognized: + s (seconds), m (minutes), h (hours), + d (days) and w (weeks). + If the suffix is missing, seconds are assumed. + If several time specifications are concatenated, their values are added together; + e.g. 2h30m is interpreted as 2*60*60 + 30*60 = 9000 seconds.
+ Some options take more than one value; in this case, the values are separated with commas.
+ If you may supply one of a set of possible values to an option, this is noted + in the documentation as + (option1|option2|option3|...)
+ The constants true|false and yes|no + are accepted as synonyms for the constants on|off.
+ Comments may be enclosed in /* and */, nested comments are possible. If the + # sign or two slashes (//) appear in the configuration file, everything from + these signs to the end of the current line is regarded as a comment and ignored.
+ There are examples for nearly all options in the sample config file. +
+

2.1.1 global Section

+ The global section specifies parameters that affect the overall behaviour of the + server. If you specify multiple global sections, the settings of those later in + the file will overwrite the earlier given values.
+ These are the possible options:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ perm_cache=(number|off);
+ Switch the disk cache off or supply a maximum cache size in kB. If the disk + cache is switched off, 8 bytes will still be written to disk. + The memory cache is always 10kB larger than the file cache. + This value is 2048 (2 MB) by default. +
+ cache_dir=string;
+ Set the directory you want to keep the cache in. + The default is "/var/cache/pdnsd" + (unless pdnsd was compiled with a different default). +
+ server_port=number;
+ Set the server port. This is especially useful when you want to start the + server and are not root. Note that you may also not specify uptest=ping in + the server section as non-root.
+ The default port is 53, the RFC-standard one. Note that you should only use + non-standard ports when you only need clients on your machine to communicate + with the server; others will probably fail if the try to contact the server + on the basis of an NS record, since the A record that supplies the address for + (among others) name servers does not have a port number specification. +
+ server_ip=string;
+ or
+ interface=string;
+ Set the IP address pdnsd listens on for requests. This can be useful + when the host has several interfaces and you want pdnsd not to listen on + all interfaces. For example, it is possible to bind pdnsd to listen on + 127.0.0.2 to allow pdnsd to be a forwarder for BIND. + The default setting for this option is server_ip=any, which means that + pdnsd will listen on all of your local interfaces. + Presently you can only specify one address here; if you want pdnsd to listen on multiple + interfaces but not all you will have to specify server_ip=any + and use firewall rules to restrict access.
+ The IP address used to need quotation marks around it, but since version 1.1.10 + this is no longer necessary.
+ If pdnsd has been compiled with both IPv4 and IPv6 support, and you want to + specify an IPv6 address here, then unless pdnsd was compiled to start up in IPv6 mode + by default, you will need to use the -6 command-line option or + set run_ipv4=off first (see below) in order to ensure that the + IPv6 address is parsed correctly.
+ If pdnsd is running in IPv6 mode and you specify an IPv4 address here, + it will automatically be mapped to an IPv6 address.
+ New in version 1.2: You may also give the name of an interface + such as "lo" or "eth0" here, instead of an IP address + (this has been tested on Linux, and may or may not work on other platforms). + pdnsd will not bind to the interface name, but will look up the address of the + interface at start-up and listen on that address. If the address of the interface + changes while pdnsd is running, pdnsd will not notice that. You will need to + restart pdnsd in that case. +
+ outgoing_ip=string;
+ or
+ outside_interface=string;
+ New in version 1.2.9: + Set the IP address of the interface used by pdnsd for outgoing queries. + This can be useful when the host has several interfaces and you want pdnsd + to send outgoing queries via only one of them. + For example, if pdnsd is running on a host with one interface with IP address + 192.168.1.1 connected to the local network, and another with IP address 123.xxx.yyy.zzz + connected to the internet, you may specify server_ip=192.168.1.1 + and outgoing_ip=123.xxx.yyy.zzz to enforce that pdnsd only responds + to queries received from the local network, and only sends outgoing queries via + the interface connected to the internet.
+ The default setting for this option is any, which means that + the kernel is free to decide which interface to use. + Like with the server_ip option, you may also give the name of an + interface here, instead of an IP address. +
+ linkdown_kluge=(on|off);
+ This option enables a kluge that some people might need: when all servers are + marked down, with this option set the cache is not even used when a query is + received, and a DNS error is returned in any case. The only exception from this + is that local records (as specified in rr and source + sections are still served normally. + In general, you probably want to get cached entries even when the network is down, + so this defaults to off. +
+ max_ttl=timespec;
+ This option sets the maximum time a record is held in cache. All dns + resource records have a time to live field that says for what period of time the + record may be cached before it needs to be requeried. If this is more than the + value given with max_ttl, this time to live value is set to max_ttl. + This is done to prevent records from being cached an inappropriate long period of time, because + that is almost never a good thing to do. Default is 604800s (one week). +
+ min_ttl=timespec;
+ This option sets the minimum time a record is held in cache. All dns + resource records have a time to live field that says for what period of time the + record may be cached before it needs to be requeried. If this is less than the + value given with min_ttl, this time to live value is set to min_ttl. + Default is 120 seconds. +
+ neg_ttl=timespec;
+ This option sets the time that negatively cached records will remain valid in the + cache if no time to live can be determined. This is always the case when whole + domains are being cached negatively, and additionally when record types are cached + negatively for a domain for which no SOA record is known to pdnsd. If a SOA is present, + the ttl of the SOA is taken. +
+ neg_rrs_pol=(on|off|auth|default);
+ This sets the RR set policy for negative caching; this tells pdnsd under which circumstances + it should cache a record type negatively for a certain domain. off will + turn the negative caching of record types off, on will always add a negative + cache entry when a name server did not return a record type we asked it for, and auth + will only add such entries if the answer came from an authoritative name server for that + domain.
+ New in version 1.2.8: The default setting will add a negatively cached record + if either the answer was authoritive or the answer indicated the name server had "recursion available" + while the query explicitly requested such recursion.
+ The preset is "default" (used to be auth). +
+ neg_domain_pol=(on|off|auth);
+ This is analogue to neg_rrs_pol for whole domain negative caching. It should be safe + to set this on, because I have not seen a caching server that will falsely claim that a + domain does not exist.
+ The default is auth. +
+ run_as=string;
+ This option allows you to let pdnsd change its user and group id after operations that needed + privileges have been done. This helps minimize security risks and is therefore recommended. The + supplied string gives a user name whose user id and primary group id are taken.
+ A little more details: after reading the config file, becoming a daemon (if specified) and starting + the server status thread, the main thread changes its gid and uid, as do all newly created threads + thereafter. By taking another uid and gid, those threads run with the privileges of the + specified user. + Under Linux and FreeBSD, the server status thread runs with the original privileges only when the strict_setuid option + is set to off (see below, on by default), because these may be needed + for exec uptests. The manager thread also retains its original privileges in this case. + You should take care that the user you specify has write permissions on your cache file and + status pipe (if you need a status pipe). You should look out for error messages like "permission denied" + and "operation not permitted" to discover permission problems.
+
+ strict_setuid=(on|off);
+ When used together with the run_as option, this option lets you specify that all threads of the + program will run with the privileges of the run_as user. This provides higher security than + the normal run_as + option, but is not always possible. See the run_as option for further discussion.
+ This option is on by default.
+ Note that this option has no effect on Non-Linux systems. +
+ paranoid=(on|off);
+ Normally, pdnsd queries all servers in recursive mode (i.e. instructs servers to query other servers themselves + if possible, + and to give back answers for domains that may not be in its authority), and accepts additional records with information + for servers that are not in the authority of the queried server. This opens the possibility of so-called cache poisoning: + a malicious attacker might set up a dns server that, when queried, returns forged additional records. This way, he might + replace trusted servers with his own ones by making your dns server return bad IP addresses. This option protects + you from cache poisoning by rejecting additional records + that do not describe domains in the queried servers authority space and not doing recursive queries any more. + An exception + to this rule are the servers you specify in your config file, which are trusted.
+ The penalty is a possible performance decrease, in particular, more queries might be necessary for the same + operation.
+ You should also notice that there may be other similar security problems, which are essentially problems of + the DNS, i.e. + any "traditional" server has them (the DNS security extensions solve these problems, but are not widely + supported). + One of this vulnerabilities is that an attacker may bombard you with forged answers in hopes that one may match a + query + you have done. If you have done such a query, one in 65536 forged packets will be succesful (i.e. an average packet + count of 32768 is needed for that attack). pdnsd can use TCP for queries, + which has a slightly higher overhead, but is much less vulnerable to such attacks on sane operating systems. Also, pdnsd + chooses random query ids, so that an attacker cannot take a shortcut. If the attacker is able to listen to your network + traffic, this attack is relatively easy, though.
+ This vulnerability is not pdnsd's fault, and is possible using any conventional + name server (pdnsd is perhaps a little more secured against this type of attacks if you make it use TCP).
+ The paranoid option is off by default.
+
+ ignore_cd=(on|off);
+ New in version 1.2.8: This option lets you specify that the CD bit of a DNS query will be ignored. + Otherwise pdnsd will reply FORMERR to clients that set this bit in a query. + It is safe to enable this option, as the CD bit refers to 'Checking Disabled' + which means that the client will accept non-authenticated data.
+ This option is on by default. Turn it off if you want the old behaviour (before version 1.2.8). +
+ scheme_file=string;
+ In addition to normal uptests, you may specify that some servers shall only be queried when a certain + pcmcia-cs scheme is active (only under linux). For that, pdnsd needs to know where the file resides that + holds the pcmcia scheme information. Normally, this is either /var/lib/pcmcia/scheme or + /var/state/pcmcia/scheme. +
+ status_ctl=(on|off);
+ This has the same effect as the -s command line option: the status control is enabled when + on is specified.
+ Added by Paul Rombouts: Note that pdnsd-ctl allows run-time configuration of pdnsd, + even the IP addesses of the name servers can be changed. If you're not using pdnsd-ctl and + you want maximum security, you should not enable this option. It is disabled by default. +
+ daemon=(on|off);
+ This has the same effect as the -d command line option: the daemon mode is enabled when + on is specified.
+ Default is off. +
+ tcp_server=(on|off);
+ tcp_server=on has the same effect as the -t or --tcp + command-line option: it enables TCP serving. + Similarly, tcp_server=off is like the --notcp command-line option.
+ Default is on. +
+ pid_file=string;
+ This has the same effect as the -p command line option: you can specify a file that pdnsd + will write its pid into when it starts in daemon mode. +
+ verbosity=number;
+ This has the same effect as the -v command line option: you can set the verbosity of pdnsd's + messages with it. The argument is a number between 0 (few messages) to 3 (most messages). +
+ query_method=(tcp_only|udp_only|tcp_udp|udp_tcp);
+ This has the same effect as the -m command line option. + Read the documentation for the command line option on this. + tcp_only corresponds to the to, udp_only to the uo, + tcp_udp to the tu and udp_tcp to the ut + argument of the command line option.
+ If you use query_method=tcp_udp, it is recommended that you also set the global timeout option to at least twice the longest server timeout. +
+ run_ipv4=(on|off);
+ This has the same effect as the -4 or -6 command line option: + if on is specified, IPv4 support is enabled, and IPv6 support is disabled (if available). + If off is specified, IPv4 will be disabled and IPv6 will be enabled. + For this option to be meaningful, pdnsd needs to be compiled with support for the protocol you choose. + If pdnsd was compiled with both IPv4 and IPv6 support, and you want to include IPv6 addresses + in the configuration file, you will probably need to specify run_ipv4=off first to + ensure that the IPv6 addresses are parsed correctly. +
+ debug=(on|off);
+ This has the same effect as the -g command line option: the debugging messages are enabled when + on is specified. +
+ ctl_perms=number;
+ This option allows you to set the file permissions that the pdnsd status control socket will have. These + are the same as file permissions. The owner of the file will be the run_as user, or, if none is specified, + the user who started pdnsd. If you want to specify the permissions in octal (as usual), don't forget + the leading zero (0600 instead of 600!). To use the status control, write access is needed. The default + is 0600 (only the owner may read or write).
+ Please note that the socket is kept in the cache directory, and that the cache directory permissions + might also need to be adjusted. Please ensure that the cache directory is not writeable for untrusted + users. +
+ proc_limit=number;
+ With this option, you can set a limit on the pdnsd threads that will be active simultaneously. If + this number is exceeded, queries are queued and may be delayed some time. + See also the procq_limit option.
+ The default for this option is 40. +
+ procq_limit=number;
+ When the query thread limit proc_limit is exceeded, connection attempts to pdnsd will be queued. + With this option, you can set the maximum queue length. + If this length is also exceeded, the incoming queries will be dropped. + That means that tcp connections will be closed and udp queries will just be dropped, which + will probably cause the querying resolver to wait for an answer until it times out.
+ See also the proc_limit option. A maximum of proc_limit+procq_limit + query threads will exist at any one time (plus 3 to 6 threads that will always + be present depending on your configuration).
+ The default for this option is 60. +
+ tcp_qtimeout=timespec;
+ This option sets a timeout for tcp queries. If no full query has been received on a tcp connection + after that time has passed, the connection will be closed. The default is set using the + --with-tcp-qtimeout option to configure. +
+ par_queries=number;
+ This option used to set the maximum number of remote servers that would be queried simultaneously, + for every query that pdnsd receives.
+ Since version 1.1.11, the meaning of this option has changed slightly. + It is now the increment with which the number of parallel queries is + increased when the previous set of servers has timed out. + For example, if we have a list server1, server2, server3, etc. of available servers + and par_queries=2, then pdnsd will first send queries to server1 and server2, + and listen for responses from these servers.
+ If these servers do not send a reply within their timeout period, pdnsd will send additional + queries to server3 and server4, and listen for responses from + server1, server2, server3 and server4, and so on until a useful reply is + received or the list is exhausted.
+ In the worst case there will be pending queries to all the servers in the list of available servers. + We may be using more system resources this way (but only if the first servers in the list + are slow or unresponsive), but the advantage is that we have a greater chance of catching a reply. + After all, if we wait longer anyway, why not for more servers.
+ See also the explanation of the global timeout option below.
+ 1 or 2 are good values for this option. + The default is set at compile time using the --with-par-queries option to configure. +
+ timeout=timespec;
+ This is the global timeout parameter for dns queries. + This specifies the minimum period of time pdnsd will wait after sending the + first query to a remote server before giving up without having + received a reply. The timeout options in the configuration file are + now only minimum timeout intervals. Setting the global timeout option + makes it possible to specify quite short timeout intervals in the + server sections (see below). This will have the effect that pdnsd will start + querying additional servers fairly quickly if the first servers are + slow to respond (but will still continue to listen for responses from + the first ones). This may allow pdnsd to get an answer more quickly in + certain situations.
+ If you use query_method=tcp_udp it is recommended that + you make the global timeout at least twice as large as the largest + server timeout, otherwise pdnsd may not have time to try a UDP query + if a TCP connection times out.
+ Default value is 0. +
+ randomize_recs=(on|off);
+ If this option is turned on, pdnsd will randomly reorder the cached records of one type + when creating an answer. This supports round-robin DNS schemes and increases fail + safety for hosts with multiple IP addresses, so this is usually a good idea.
+ On by default. +
+ query_port_start=(number|none);
+ If a number is given, this defines the start of the port range used for queries of pdnsd. The + value given must be >= 1024. The purpose of this option is to aid certain firewall + configurations that are based on the source port. Please keep in mind that another application + may bind a port in that range, so a stateful firewall using target port and/or process uid may + be more effective. In case a query start port is given pdnsd uses this port as the first port of a + specified port range (see query_port_end) used for queries. + pdnsd will try to randomly select a free port from this range as local port for the query.
+ To ensure that there are enough ports for pdnsd to use, the range between query_port_start and + query_port_end should be adjusted to at least (par_queries * proc_limit). + A larger range is highly recommended for security reasons, and also because other applications may + allocate ports in that range. If possible, this range should be kept out of the space + that other applications usually use.
+ The default for this option is 1024. Together with the default value of query_port_end, + this makes it the hardest for an attacker to guess the source port used by the pdnsd resolver. + If you specify none here, pdnsd will let the kernel choose the source port, but + this may leave pdnsd more vulnerable to an attack. +
+ query_port_end=number;
+ Used if query_port_start is not none. Defines the last port of the range started by query_port_start + used for querys by pdnsd. The default is 65535, which is also the maximum legal value for this option. + For details see the description of query_port_start. +
+ delegation_only=string;
+ Added by Paul Rombouts: This option specifies a "delegation-only" zone. + This means that if pdnsd receives a query for a name that is in a + subdomain of a "delegation-only" zone but the remote name server + returns an answer with an authority section lacking any NS RRs for + subdomains of that zone, pdnsd will answer NXDOMAIN (unknown domain). + This feature can be used for undoing the undesired effects of DNS + "wildcards". Several "delegation-only" zones may be specified together. + If you specify root servers in a server section it is + important that you set root_server=on in such a section.
+ Example: +

delegation_only="com","net";

+ This feature is off by default. It is recommended that you only use + this feature if you actually need it, because there is a risk that + some legitimate names will be blocked, especially if the remote + name servers queried by pdnsd return answers with empty authority + sections. +
+ ipv4_6_prefix=string;
+ This option has the same effect as the -i command-line option. + When pdnsd runs in IPv6 mode, this option specifies the prefix pdnsd uses to convert IPv4 addresses in + the configuration file (or addresses specified with pdnsd-ctl) + to IPv6-mapped addresses. + The string must be a valid IPv6 address. Only the first 96 bits are used. + Note that this only effects the parsing of IPv4 addresses listed after this option.
+ The default is "::ffff.0.0.0.0". +
+ use_nss=(on|off);
+ If this option is turned on, pdnsd will call initgroups() to set up the group access list, + whenever pdnsd changes its user and group id (see run_as option). + There is a possible snag, though, if initgroups() uses NSS (Name Service Switch) and + NSS in turn uses DNS. In such a case you may experience lengthy timeouts and stalls. + By setting use_nss=off, you can disable the initgroups() call + (only possible in versions 1.2.5 and later).
+ This option was contributed by Jan-Marek Glogowski.
+ On by default. +
+ udpbufsize=number;
+ New in version 1.2.9: + This option sets the upper limit on the size of UDP DNS messages. The default is 1024.
+ See also the edns_query server option below. +
+ +
+

2.1.2 server Section

+ Each server section specifies a set of name servers that pdnsd should try to get + resource records or authoritative name server information from. The servers are + queried in the order of their appearance (or parallel to a limited extend). + If one fails, the next one is taken and so on.
+ You probably want to specify the dns server in your LAN, the caching dns servers + of your internet provider or even a list of root servers in one or more server sections.
+ The supported options in this section are:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ label=string;
+ Specify a label for the server section. This can be used to refer to this section + when using pdnsd-ctl, the pdnsd control utility.
+ You can give several server sections the same label, but if you want to change the addresses + of a server section (see ip option below) during run-time with + "pdnsd-ctl server label up dns1,dns2,...", + the label must be unique. +
+ ip=string;
+ Give the IP (the address, not the host name) of the server.
+ Multiple IP addresses can be given per server section. + This can be done by entering multiple lines of the form ip=string; + or a single line like this: +

ip=string,string,string;

+ IP addresses do not have to be specified in the configuration file. + A server section without IP addresses will remain inactive until it is assigned + one or more addresses with pdnsd-ctl, + the pdnsd control utility.
+ If pdnsd has been compiled with both IPv4 and IPv6 support, any IPv6 addresses you specify + here will be skipped with a warning message, unless pdnsd is running in IPv6 mode. + Thus, unless pdnsd was compiled to startup in IPv6 mode by default, you need to use the + command-line option -6 or set run_ipv4=off + first (see global section) in order to ensure + that IPv6 addresses are parsed correctly.
+ If pdnsd is running in IPv6 mode and you specify an IPv4 address here, + it will automatically be mapped to an IPv6 address. +
+ file=string;
+ New in version 1.2: This option allows you to give the name of a resolv.conf-style file. + Of the lines beginning with the nameserver keyword, the second field will be parsed as an + IP address, as if it were specified with the ip= option. The remaining lines will be ignored. + If the contents of the file changes while pdnsd is running, you can make pdnsd aware of the changes through the + use of pdnsd-ctl, the pdnsd control utility. + This is usually most conveniently done by placing the command "pdnsd-ctl config" in a script + that is automatically run whenever the DNS configuration changes.
+ For example, suppose you have a ppp client that writes the DNS configuration for your ISP to the file + /etc/ppp/resolv.conf and runs the script /etc/ppp/ip-up when a new + connection is established. One way of ensuring that pdnsd is automatically reconfigured is to + add a server section in the config file with file=/etc/ppp/resolv.conf and to + add the command "pdnsd-ctl config" to /etc/ppp/ip-up. +
+ port=number;
+ Give the port the remote name server listens on. Default is 53 (the official + dns port) +
+ uptest=(ping|none|if|dev|diald|exec|query);
+ Determine the method to check whether the server is available. Currently + defined methods are: + +
    +
  • ping: Send an ICMP_ECHO request to the server. If it doesn't respond + within the timeout, it is regarded to be unavailable until the next probe. +
  • none: The availability status is not changed, only the time stamp is updated. +
  • if: Check whether the interface (specified in the interface= option) is + existent, up and running. This currently works for all "ordinary" + network interfaces, interfaces that disappear when down (e.g. ppp?), + and additionally for Linux isdn interfaces (as of kernel 2.2). Note that + you need a /dev/isdninfo device file (major#45, minor#255), or the + isdn uptest will always fail. +
  • dev and diald: Perform an if uptest, and, if that + was succesful, additionally check whether a program is running that + has locked a given (modem-) device. The needed parameters are an interface (specified as for the if + uptest, e.g. "ppp0") and a device relative to /dev (e.g. + "modem" for /dev/modem specified using the device= option. + pdnsd will then look for a pid file for the given interface in /var/lock (e.g. + /var/run/ppp0.pid) and for a lockfile for the given device (e.g. /var/lock/LCK..modem), + and then test whether the locking process is the process that created the pid file and this process is still + alive. If this is the case, the normal if uptest is executed for the given interface.
    + The dev option is for pppd dial-on-demand, diald is the same for diald users. +
  • exec: Executes a given command in the /bin/sh shell + (as /bin/sh -c <command>) + and evaluates the result (the return code of the last command) in the shell's way of handling return codes, + i.e. 0 indicates success, all other indicate failure. The shell's process name will be + uptest_sh. The command is given with the uptest_cmd option (see below). + For secuity issues, also see that entry. +
  • query: New in version 1.2: + This works like the ping test, except it sends an (empty) DNS query to the remote server. + If the server sends a well-formed response back within the timeout period (except SERVFAIL), + it will be regarded as available. + This test is useful if a remote server does not respond to ICMP_ECHO requests at all, + which unfortunately is quite common these days. + It can also happen that a remote server is online but ignores empty DNS queries. + Then you will need the set the query_test_name option (see below). + In many cases this test will be a more reliable indicator of availability + than the ones mentioned before. +
+

+ The default value is none. +

+ NOTE: If you use on-demand dialing, use none, if, + dev, diald or exec, + since ping or query will send packets + in the specified interval and the interface will thus frequently dial! +

+ ping_timeout=number;
+ Sets the timeout for the ping test in tenths of seconds + (this unit is used for legacy reasons; actually the current implementation is + only accurate to a second).
+ The default is 600 (one minute). +
+ ping_ip=string;
+ The IP address for the ping test. The default is the IP of the name server. +
+ query_test_name=string;
+ New in version 1.2.9: + Sets the name to be queried when using uptest=query availability test. + If the string is the unquoted constant none, + an empty query is used (this the default), otherwise a query of type A will be + sent for the domain name specified here. It is not necessary for the domain name + to exist or have a record of type A in order for the uptest to succeed.
+ If the the remote server ignores empty queries, you will probably want to set + query_test_name="." (the root domain). +
+ uptest_cmd=string,string;
+ or
+ uptest_cmd=string;
+ Sets the command for the uptest=exec function to the first string. + If the second string is given, it specifies a user with whose user + id and primary group id the command is executed.
+ This is especially useful if you are executing the server as root, + but do not want the uptest to be performed with root privileges. + In fact, you should never execute the uptest as root if you can help + it.
+ If the server is running setuid or setgid, the privileges thus gained + are attempted to be dropped even before changing identity to the + specified user to prevent setuid/gid security holes (otherwise, any + user might execute commands as root if you setuid the executable).
+ Note that this is not always possible, and that pdnsd should never + be installed as setuid or setgid. + The command is executed using /bin/sh, so you should be able to use + shell builtin commands. +
+ interval=(timespec|onquery|ontimeout);
+ Sets the interval for the server up-test. The default is 900 seconds; + however, a test is forced when a query times out and the timestamp is reset then.
+ If you specify onquery instead of a timeout, the interface will be + tested before every query. This is to prevent automatically dialing + interfaces (diald/pppd or ippp) to dial on dns queries. It is intended to be + used in connection with an interface-testing uptest ;-)
+ Note that using uptest=exec, you might run into performance problems + on slow machines when you use that option. + DON'T use onquery with uptest=ping or + uptest=query, as it may cause delays if the server does not answer + (btw, it doesn't make sense anyway). + Note also that using onquery is no guarantee that the interface + will not be used. When another (reachable) dns server tells pdnsd + to query a third dns server for data, pdnsd will do that and has + no means of checking whether this will dial up the interface or not. + This however should be a rare situation.
+ New in version 1.2.3: + A third possibility is to specify interval=ontimeout. + In this case the server is not tested at startup/reconfiguration, nor at regular intervals, + but only after a DNS query to a server times out. Certain types of network problems + such as a refused connection will also cause the server to be considered unavailable. + However, once a server is declared dead it is never considered again unless it is revived using a + pdnsd-ctl config or server command. + The idea behind this option is to minimize uptests by assuming all + servers are available until there is reason to believe otherwise. +
+ interface=string;
+ The network interface (or network device, e.g. "eth0") for the uptest=if option. + Must be specified if uptest=if is given. +
+ device=string;
+ The (modem-) device that is used for the dev uptest. If you use this for a dial-on-demand + ppp uptest (together with uptest=dev), you need to enter the device you are using for your + pppd here, e.g. modem for /dev/modem.
+ Must be specified if uptest=dev is given. +
+ timeout=timespec;
+ Set the timeout for the dns query. The default is 120 seconds. You probably want to set this lower.
+ Timeouts specified in the configuration file are only treated as the + minimum period of time to wait for a reply. A queries to a remote + server are not canceled until a useful reply has been received, or all + the other queries have timed out or failed.
+ If you have also set the global timeout option, you may consider setting a fairly small value here. + See the explanation of the timeout option in the global + section for what that means. +
+ purge_cache=(on|off);
+ In every fetched dns record, there is a cache timeout given, which + specifies how long the fetched data may be cached until it needs to be + reloaded. If purge_cache is set to off, the stale records are not purged + (unless the cache size would be exceeded, in this case the oldest records are purged). + Instead, they are still served if they cannot succesfully be + updated (e.g. because all servers are down).
+ Default is off. +
+ caching=(on|off);
+ Specifies if caching shall be performed for this server at all. Default is + on. +
+ lean_query=(on|off);
+ Specifies whether to use the "lean" query mode. In this mode, only the + information actually queried from pdnsd is resolved and cached. This has + the advantage that usually less cache space is used and the query is + usually faster. In 90% of the cases, only address (A) records are needed + anyway. If switched off, pdnsd will always cache all data about a host + it can find and will specifically ask for all available records + (well, at least it is a good approximation for what it really does ;-) + This will of course increase the answer packet sizes.
+ Some buggy name servers may not deliver CNAME records when not asked for + all records. I do not know if such servers are around, but if you have + trouble resolving certain host names, try turning this option off.
+ A last note: If you use multiple pdnsd's that access each other, turning + this option on is probably a big win.
+ This on by default. +
+ edns_query=(on|off);
+ New in version 1.2.9: + Specifies whether to use EDNS (Extension mechanisms for DNS) for outgoing queries. + Currently this is only useful for allowing UDP message sizes larger than 512 bytes. + Note that setting this option on can give problems in combination with some legacy + systems or software, including, embarrassingly enough, previous versions of pdnsd.
+ The default is off, but if your network can handle UDP payloads + significantly larger than 512 bytes, the recommended value is on.
+ Note that this option only effects outgoing queries. If pdnsd receives a query using + EDNS, it will reply using EDNS regardless of the value of this option. +
+ See also the udpbufsize option above. +
+ scheme=string;
+ You can specify a pcmcia-cs scheme that is used in addition to the uptests. If you specify + a scheme here, the server this section is for will only be queries if the given scheme + is active. Shell wildcards (* and ?) are allowed in the string under their special + meanings. You need to use the scheme_file option on the global + section to make this option work. +
+ preset=(on|off);
+ This allows you to specify the initial state of a server before any uptest is performed. + on specifies that the server is regarded available. The default is on. + This is especially useful when you set uptest=none; and want to change + the status of a server only via pdnsd-ctl. +
+ proxy_only=(on|off);
+ When this option is set to on, answers given by the servers are always accepted, and no + other servers (as, for example, specified in the NS records of the query domain) are + queried. If you do not turn this option on, pdnsd will do such queries in some cases + (in particular when processing ANY queries).
+ This option is useful when you do not want pdnsd to make connections to outside servers + for some reasons (e.g. when a firewall is blocking such queries).
+ I recommend that you turn on lean_query when using this option.
+ Default is off. +
+ root_server=(on|off|discover);
+ Set this option to on if the servers specified in a section are root servers. + A root server will typically only give the name servers for the top-level domain in its reply. + Setting root_server=on will cause pdnsd to try to use cached information about + top-level domains to reduce to number of queries to root servers, making the resolving of + new names more efficient. + You can get a list of available root servers by running the command + "dig . ns".
+ This option is also necessary if you use the delegation_only option.
+ New in version 1.2.8: This option may also be set to "discover". + This will cause pdnsd to query the servers provided with the ip= option + to obtain the full list of root servers. The root-server addresses will replace the addresses + specified with the ip= option. + This will only be done once on startup, or after a "pdnsd-ctl config" command. + In this case the name servers specified with the ip= option don't have to be + root servers, they just have to know the names and addresses of the root servers. + After root-server discovery pdnsd will behave just as if root_server=on + had been specified.
+ Default is off. +
+ randomize_servers=(on|off);
+ New in version 1.2.6: Set this option to on to give each name server + in this section an equal chance of being queried. If this option is off, the name servers + are always queried starting with the first one specified. Even with this option on, the + query order is not truly random. Only the first server is selected randomly; the following + ones are queried in consecutive order, wrapping around to the beginning of the list when + the end is reached. Note that this option only effects the order within a section. The + servers in the first (active) section are always queried before those in the second one, + etc.
The default is off, but if you are resolving from root servers setting this + option on is highly recommended. If root_server=on this option also effects + the query order of the name servers for the top-level domains. +
+ reject=string;
+ New in version 1.2.6: This option can be used to make pdnsd reject replies that + contain certain IP addresses. You can specify a single IP address, which will be matched + exactly, or a range of addresses using an address/mask pair. + The mask can be specified as a simple integer, indicating the number of initial 1 bits in + the mask, or in the usual IP address notation. IP addresses may be either IPv4 or IPv6 + (provided there is sufficient support in the C libraries and support for AAAA records was + not disabled). + When addresses in the reject list are compared with those in a reply, only the bits + corresponding to those set in the netmask are significant, the rest are ignored.
+ Multiple addresses or address/mask pairs may be specified; this can be done by entering + multiple lines of the form reject=string; + or a single line like this: +

reject=string,string,string;

+ How pdnsd reacts when an address in the reply matches one in the reject list, + depends on the reject_policy option, see below. +
+ reject_policy=(fail|negate);
+ New in version 1.2.6: + This option determines what pdnsd does when an address in the reply from a name server + matches the reject list (see above). If this option is set to + fail, pdnsd will try another server, or, if there no more servers to try, + return the answer SERVFAIL. If this option is set to negate, pdnsd will + immediately return the answer NXDOMAIN (unknown domain) without querying additional + servers. The fail setting is useful if you don't always trust the servers in + this section, but do trust the servers in the following section. The negate + setting can be used to completely censor certain IP addresses. In this case you should put + the same reject list in every server section, and also set the + reject_recursively option (see below) to true.
+ The default is fail. +
+ reject_recursively=(on|off);
+ New in version 1.2.6: Normally pdnsd checks for addresses in the + reject list (see above) only when the reply comes directly from a name server + listed in the configuration file. With this option set to on, pdnsd will + also do this check for name servers that where obtained from NS records in the authority + section of a previous reply (which was incomplete and non-authoritative).
+ Default is off. +
+ policy=(included|excluded|simple_only|fqdn_only);
+ pdnsd supports inclusion/exclusion lists for server sections: with include= + and exclude= (see below) you can specify domain names for which this server + will be used or will not be used. The first match counts (i.e., the first include or + exclude rule in a server section that matches a domain name is applied, and the + search for other rules is terminated). If no rule matched a given domain name, + the policy= option determines whether this server is used for the + lookup for that domain name; when included is given, the server will + be asked, and when excluded is given, it will not. + If simple_only is given the server will be used if the name to lookup + is a simple (single-label) domain name, on the other hand if fqdn_only + is given the server will be used only for names consisting of two or more labels + (i.e. the name has at least one dot in-between).
+ If no server is available for a queried domain, pdnsd will return an error message + to the client that usually will stop the client's attempts to resolve a specific + domain from this server (the libc resolver will e.g. return an error to the application that + tried to resolve the domain if no other servers are available in the resolv.conf). + This may be of use sometimes.
+ Note: the simple_only and fqdn_only constants + were added by Paul Rombouts. + They are useful for controlling which name servers (if any) will be used by + pdnsd for resolving simple (single-label) host names. + fqdn_only used to stand for "fully qualified domain name only", but this is + actually a misnomer. The names in queries received by pdnsd are always considered to be + fully qualified. If you do not exactly understand what the options simple_only and + fqdn_only are good for, you are probably better off not using them.
+ The default for this option is included. +
+ include=string;
+ This option adds an entry to the exclusion/inclusion list. If a domain matches + the name given as string, the server is queried if this was the first matching rule + (see also the entry for policy).
+ If the given name starts with a dot, the whole subdomain + of the given name including the one of that name is matched, e.g. ".foo.bar." + will match the domain names a.foo.bar., a.b.c.foo.bar. and foo.bar.
+ If it does not start in a dot, only exactly the given name (ignoring the case, of course) + will be matched (hint: if you want to include all subdomains, but not the domain of the given + name itself, place an exact-match exclude rule before the include rule, e.g: + exclude="foo.bar."; include=".foo.bar.";
+ Previous versions of pdnsd + required that names given with this and the next option ended in a dot, but since + version 1.1.8b1-par8, pdnsd automatically adds a dot at the end if it + is missing.
+ pdnsd now also accepts a more compact notation for adding several "include" entries in + one line, e.g.: +

include=".foo",".bar",".my.dom";

+
+ exclude=string;
+ This option adds an entry to the exclusion/inclusion list. If a domain matches + the name given as string, the server is not queried if this was the first matching rule + (see also the entry for policy).
+ If the given name starts with a dot, the whole subdomain + of the given name including the one of that name is matched, e.g. ".foo.bar." + will match the domain names a.foo.bar., a.b.c.foo.bar. and foo.bar.
+ If it does not start in a dot, only exactly the given name (ignoring the case, of course) + will be matched (hint: if you want to exclude all subdomains, but not the domain of the given + name itself, place an exact-match include rule before the exclude rule, e.g: + include="foo.bar."; exclude=".foo.bar.";
+ pdnsd now also accepts a more compact notation for adding several "exclude" entries in + one line, e.g.: +

exclude=".foo",".bar",".my.dom";

+
+
+

2.1.3 rr Section

+ Every rr section specifies a dns resource record that is stored locally. It + allows you to specify own dns records that are served by pdnsd in a limited way. + Only A, PTR, CNAME, MX, NS and SOA records are implemented.
+ This option is intended to allow you to define RRs for 1.0.0.127.in-addr.arpa. + and localhost. (and perhaps even one or two hosts) without having to start an + extra named if your cached name servers do not serve those records. + It is NOT intended and not capable to work as a full-featured name server. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ name=string;
+ Specifies the name of the resource records, i.e. the domain name of + the resource the record describes. This option must be specified + before any a, ptr, cname, + mx, ns or soa records. + Names are interpreted as absolute domain names + (i.e. pdnsd assumes they end in the root domain). + For this and all following arguments that take domain names, you need to + specify domain names in dotted notation (example venera.isi.edu.).
+ Previous versions of pdnsd + required that domain names given in the configuration file ended in a + dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a + dot at the end if it is missing.
+ New in version 1.2: It is also possible to specify a name starting + with the label *. Such a name is called a wildcard. The * in a wildcard + can match one or more labels in a queried name, but only whole labels. + Any other * characters in a wildcard, apart from the leading one, + will only match a literal *.
+ For example, *.mydomain will match a.mydomain or www.a.mydomain, but not + mydomain. *.a*.mydomain will match www.a*.mydomain, but not www.ab.mydomain. + *a.mydomain will only match itself.
+ Before you can specify an rr section with name=*.mydomain + you must define some records for mydomain, typically NS and/or SOA records. + Example: +
+    rr {
+	name = mydomain;
+	ns = localhost;
+	soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400;
+    }
+    rr {
+	name = *.mydomain;
+	a = 192.168.1.10;
+    }
+ In this example, www.mydomain and ftp.mydomain will resolve to the numeric + address 192.168.1.10 (unless you add rr sections explicitly + specifying different addresses for www.mydomain or ftp.mydomain). + If you want mydomain also to resolve to a numeric address, + add an A record to the first rr section. +
+ ttl=timespec;
+ Specifies the ttl (time to live) for all resource records in this section after this entry. + This may be redefined. The default is 86400 seconds (=1 day). +
+ authrec=(on|off);
+ If this is turned on, pdnsd will create authoritative local records for this rr section. + This means that pdnsd flags the domain record so that records of this domain that are not + present in the cache are treated as non-existent, i.e. no other servers are queried for + that record type, and an response containing none of those records is returned. This is + most time what people want: if you add an A record for a host, and it has no AAAA record + (thus no IPv6 address), you normally don't want other name servers to be queried for it.
+ This is on by default.
+ Please note that this only has an effect if it precedes the name option! +
+ reverse=(on|off);
+ New in version 1.2: If you want a locally defined name to resolve to a numeric address + and vice versa, you can achieve this by setting reverse=on before defining the A record + (see below). The alternative is to define a separate PTR record, but you will + probably find this option much more convenient.
+ The default is off. +
+ a=string;
+ Defines an A (host address) record. The argument is an IPv4 address in dotted notation. + pdnsd will serve this address for the host name given in the name option.
+ Provided there is sufficient support in the C libraries and support for AAAA records was not + disabled, the argument string may also be an IPv6 address, in which case an AAAA record + will be defined.
+ This option be may used multiple times within an rr section, causing + multiple addresses to be defined for the name. However, if you put the different addresses + in different rr sections for the same name, the definition in the last + rr section will cancel the definitions in the previous ones. +
+ ptr=string;
+ Defines a PTR (domain name pointer) record. The argument is a host name in + dotted notation (see name). The ptr record is for resolving adresses into names. For example, if + you want the adress 127.0.0.1 to resolve into localhost, and localhost into 127.0.0.1, you need something + like the following sections:
+
+    rr {
+	name = localhost;
+	a = 127.0.0.1;
+	owner = localhost;
+	soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400;
+    }
+    rr {
+	name = 1.0.0.127.in-addr.arpa;
+	ptr = localhost;
+	owner = localhost;
+	soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400;
+    }
+ The second section is for reverse resolving and uses the ptr option. + Note that you can get the same effect by specifying only the first rr section + with reverse=on.
+ There is something special about the name in the second section: + when a resolver wants to get a host name from an internet address, + it composes an address that is built of the IP address in reverse byte order + (1.0.0.127 instead of 127.0.0.1) where each byte of the adress written + as number constitutes a sub-domain under the domain in-addr.arpa.
+ So, if you want to compose an adress for reverse resolving, take your ip in dotted notation (e.g. 1.2.3.4), + reverse the byte order (4.3.2.1) and append in-addr.arpa. (4.3.2.1.in-addr.arpa.) + Then, define an rr section giving this address as name and the domain name corresponding to + that ip in the ptr option. +
+ cname=string;
+ Defines a CNAME (canonical name) record. + The argument should be a fully-qualified host name in dotted notation (see name). + A CNAME is the DNS equivalent of an alias or symbolic link.
+ A useful application for CNAMEs is giving short, easy to remember nicknames to hosts with complicated names. + For example, you might want the name "news" to refer to your ISP's news server "nntp2.myisp.com". + Instead of adding an A record for "news" with the same address as "nntp2.myisp.com", you could + put in a CNAME pointing to "nntp2.myisp.com", so that if the IP address of the news server changes, + there is no need to update the record for "news".
+ To implement this with pdnsd, you could add the following section to your configuration file:
+
+    rr {
+	name = news;
+	cname = nntp2.myisp.com;
+	owner = localhost;
+    }
+
+ mx=string,number;
+ Defines an MX (mail exchange) record. The string is the host name of the mail server in dotted notation (see name). + The number specifies the preference level.
+ When you send mail to someone, your mail typically goes from your E-mail client to an SMTP server. + The SMTP server then checks for the MX record of the domain in the E-mail address. + For example, with joe@example.com, it would look for the MX record for example.com and find + that the name of mail server for that domain is, say, mail.example.com. + The SMTP server then gets the A record for mail.example.com, and connects to the mail server.
+ If there are multiple MX records, the SMTP server will pick one based on the preference level + (starting with the lowest preference number, working its way up).
+ Don't define MX records with pdnsd unless you know what you're doing. +
+ owner=string;
+ or
+ ns=string;
+ Defines an NS (name server) record. Specifies the name of the host which should be authoritative for the records + you defined in the rr section. This is typically the host pdnsd runs on.
+ Note: In previous versions of pdnsd this option had to be specified before + any a, ptr, cname, mx or soa entries. + In version 1.2, the restrictions on this option are same as the options just mentioned, + and it must listed after the name= option. + This can be a pain if you want to use an old config file which specifies owner= + before name= (sorry about that). + Apart from greater consistency, the advantage is that you can now specify as many NS records as you like (including zero). +
+ soa=string,string,number,timespec,timespec,timespec,timespec;
+ This defines a soa (start of authority) record. The first string is the + domain name of the server and should be equal to the name you specified as + owner.
+ The second string specifies the email address of the maintainer of the name + server. It is also specified as a domain name, so you will have to replace the + @ sign in the name with a dot (.) to get the name you have to specify here. + The next parameter (the first number) is the serial number of the record. You + should increment this number if you change the record.
+ The 4th parameter is the refresh timeout. It specifies after what amount + of time a caching server should attempt to refresh the cached record.
+ The 5th parameter specifies a time after which a caching server should attempt + to refresh the record after a refresh failure.
+ The 6th parameter defines the timeout after which a cached record expires if it + has not been refreshed.
+ The 7th parameter is the ttl that is specified in every rr and should be the + same as given with the ttl option (if you do not specify a ttl, use the default 86400). +
+ txt=string,...,string;
+ New in version 1.2.9: + Defines an TXT record. You can specify one or more strings here. +
+
+

2.1.4 neg Section

+ Every neg section specifies a dns resource record or a dns domain that should be + cached negatively locally. Queries for negatively cached records are always answered + immediatley with an error or an empty answer without querying other hosts as long + as the record is valid. The records defined with neg sections remain + valid until they are explicitely invalidated or deleted by the user using + pdnsd-ctl.
+ This is useful if a certain application asks periodically for nonexisting hosts or + RR types and you do not want a query to go out every time the cached record has + timed out. Example: Netscape Communicator will ask for the servers news and mail + on startup if unconfigured. If you do not have a dns search list for your network, + you can inhibit outgoing queries for these by specifying
+
+    neg {
+	name = news;
+	types = domain;
+    }
+    neg {
+	name = mail;
+	types = domain;
+    }
+ in your config file. If you have a search list, you have to repeat that for any + entry in your search list in addition to the entries given above!
+ In versions 1.1.11 and later, if you negate whole domains this way, all subdomains + will be negated as well. Thus if you specify
+ neg {name=example.com; types=domain;} in the + config file, this will also negate www.example.com, xxx.adserver.example.com, etc. +

+ + + + + + + + + + +
+ name=string;
+ Specifies the name of the domain for which negative cache entries are created. + This option must be specified before the types option. + Names are interpreted as absolute domain names (i.e. pdnsd + assumes they end in the root domain). + You need to specify domain names in dotted notation (example venera.isi.edu.).
+ Previous versions of pdnsd + required that domain names given in the configuration file ended in a + dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a + dot at the end if it is missing. +
+ ttl=timespec;
+ Specifies the ttl (time to live) for all resource records in this section after this entry. + This may be redefined. The default is 86400 seconds (=1 day). +
+ types=(domain|rr_type[,rr_type[,rr_type[,...]]]);
+ Specifies what is to be cached negatively: domain will cache the whole + domain negatively; alternatively, you can specify a comma-separated list of RR types + which are to be cached negatively. You may specify multiple types options, but + domain and the RR types are mutually exclusive.
+ The RR types are specified using their official names from the RFC's in capitals, + e.g. A, CNAME, NS, PTR, MX, + AAAA, ...
+ The command pdnsd-ctl list-rrtypes will give you a complete list + of those types. pdnsd-ctl is built along with pdnsd + and will be installed in the same directory as the pdnsd binary during make install. +
+
+

2.1.5 source Section

+ Every source section allows you to let pdnsd read the records from a file in an + /etc/hosts-like format. pdnsd will generate records to resolve the entries + address from its host name and vice versa for every entry in the file. This is + normally easier than defining an rr for every of your addresses, since localhost + and your other FQDNs are normally given in /etc/hosts.
+ The accepted format is as follows: The #-sign initiates a comment, the rest of + the line from the first occurence of this character on is ignored. Empty lines + are tolerated.
+ The first entry on a line (predeceded by an arbitrary number of tabs and spaces) + is the IP in dotted notation, the second entry on one line (separated by the + first by an arbitrary number of tabs and spaces) is the FQDN (fully qualified + domain name) for that ip. The rest of the line is ignored by default (in the original + /etc/hosts, it may contain information not needed by pdnsd). +

+ + + + + + + + + + + + + + + + +
+ owner=string;
+ Specifies the name of the host pdnsd runs on and that are specified in dns + answers (specifically, nameserver records). + Must be specified before any file entries.
+ Names are interpreted as absolute domain names (i.e. pdnsd + assumes they end in the root domain). + You need to specify domain names in dotted notation (example venera.isi.edu.).
+ Previous versions of pdnsd + required that domain names given in the configuration file ended in a + dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a + dot at the end if it is missing. +
+ ttl=timespec;
+ Specifies the ttl (time to live) for all resource records in this section after + this entry. This may be redefined. The default is 86400 seconds (=1 day). +
+ file=string;
+ The string specifies a file name. For every file entry in a source section, + pdnsd will try to load the given file as described above. Failure is indicated + only when the file cannot be opened, malformed entries will be ignored. +
+ serve_aliases=(on|off);
+ If this is turned on pdnsd will serve the aliases given in a hosts-style file. + These are the third entry in a line of a hosts-style file, which usually give a "short name" for the host. + This may be used to support broken clients without a proper domain-search option. + If no aliases are given in a line of the file, pdnsd behaves as without this option for this line.
+ This feature was suggested by Bert Frederiks.
+ It is off by default. +
+ authrec=(on|off);
+ If this is turned on, pdnsd will create authoritative local records with the data from the hosts file. + Please see the description of the option of the same name in the rr section for a closer description of + what this means. Please note that this only has an effect for files sourced with file options + subsequent to this option.
+ This is on by default. +
+
+

2.1.6 include Section

+ A configuration file may include other configuration files. + However, only the top-level configuration file may contain global + and server sections, + thus include files are effectively limited to sections that add local definitions to the cache.
+ Include sections currently only have one type of option, which may be given multiple times within a single section. +

+ + + + +
+ file=string;
+ The string specifies a file name. For every file option in an include section, + pdnsd will parse the given file as described above. The file may contain include sections itself, + but as a precaution pdnsd checks that a certain maximum depth is not exceeded to guard against + the possibility of infinite recursion. +
+
+

3 pdnsd-ctl

+

+ pdnsd-ctl allows you to configure pdnsd at run time. To make this work, you have to start pdnsd with the -s + option (or use the status_ctl option in the config file). You also should make sure that you + have appropriate permissions on the control socket (use the ctl_perms option to make this sure) and of your pdnsd + cache directory (pdnsd keeps its socket there). Please make sure the pdnsd cache directory is not writeable for untrusted users!

+

+ pdnsd-ctl accepts two command-line options starting with a dash.
+ -c may be used to specify the cache directory (and takes this as argument). + The default for this setting is the pdnsd default cache directory (specified at compile time). + The cache directory for pdnsd-ctl must be the same pdnsd uses!
+ -q can be used to make the output of pdnsd-ctl less verbose.

+

+ The following table lists the commands that pdnsd-ctl supports. The command must always be + the first command-line option (not starting with a dash), the arguments to the command must follow in the given order.
+ In the following table, keywords are in a normal font, while placeholders are in italics.
+ Alternatives are specified like (alt1|alt2|alt3). + Optional arguments are placed between square brackets [].

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CommandArgumentsDescription
helpPrint a command summary.
versionPrint version and license info.
status + Print a description of pdnsd's cache status, thread status and configuration. + Also shows which remote name servers are assumed to be available. +
server(index|label)  (up|down|retest)  [dns1[,dns2[,...]]] + Set the status of the server with the given index or label (where the given label + matches the one given with the label option in the respective server section in the config file) + to up or down, or force a retest. The index is assigned in the order of definition in + pdnsd.conf starting with 0. Use the status command to view the indices and labels. + You can specify all instead of an index or label to perform the action for all + servers registered with pdnsd. Example:
+ pdnsd-ctl server 0 retest
+ An optional third argument consisting of a list of IP addresses (separated by commas or + white-space characters) can be given. + This list will replace the previous list of addresses of name servers used by pdnsd in the + specified section of the config file. + For example in the /etc/ppp/ip-up script called by pppd you could + place the following line:
+ pdnsd-ctl server isplabel up $DNS1,$DNS2
+ If white space is used to separate addresses the list will have to be quoted. + Spurious commas and white-space characters are ignored. + The last argument may also be an empty string, in which case the existing IP addresses are + removed and the corresponding server section becomes inactive. +
recordname  (delete|invalidate) + Delete or invalidate the records of the given domain name if it is in the + cache. Invalidation means that the records are marked as timed out, and + will be reloaded if possible (if purge_cache is set to on, they will + be deleted in any case).
+ For local records (i.e., records that were given in the config file + using a rr section, records read from a hosts-style file + and records added using pdnsd-ctl), invalidation has no effect. Deletion + will work, though. Example:
+ pdnsd-ctl record localhost. delete +
sourcefn  owner  [ttl]  [(on|off)]  [noauth] + Load a hosts-style file. Works like using the pdnsd + source configuration section. + owner and ttl are used as in the source section. ttl has a default + of 900 (it does not need to be specified). The next to last argument corresponds + to the serve_aliases option, and is off by default (i.e. if it is not specified). + noauth is used to make the domains non-authoritative - please see + the description of the authrec config file options for a description of what + that means. + fn is the filename. The file must be readable by pdnsd! Example:
+ pdnsd-ctl source /etc/hosts localhost. 900 off +
adda  addr  name  [ttl]  [noauth] + Add a record of the given type to the pdnsd cache, replacing existing + records for the same name and type. The 2nd argument corresponds + to the value of the option in the rr section that is named like + the first argument: a is a record for hostname-to-address mapping, + aaaa is the same thing for IPv6 addresses, and ptr is for address-to-hostname + mapping. See the documentation for the rr section for more details. + In case of A and AAAA records, the addr argument may be a list of IP addresses, + separated by commas or white space, causing multiple addresses to be defined + for the same name. + The ttl is optional, the default is 900 seconds. + noauth is used to make the domains non-authoritative - please see + the description of the authrec config file options for a description of what + that means. + If you want no other record than the newly added in the cache, do
+ pdnsd-ctl record name delete + before adding records. This is also better when overwriting local records. Example:
+ pdnsd-ctl add a 127.0.0.1 localhost. 900 +
addaaaa  addr  name  [ttl]  [noauth]
addptr  host  name  [ttl]  [noauth]
addcname  host  name  [ttl]  [noauth]
addmx  host  name  pref  [ttl]  [noauth]
addns  host  name  [ttl]  [noauth]
negname  [type]  [ttl] + Add a negatively cached record to pdnsd's cache, replacing existing + records for the same name and type. If no type is given, the whole + domain is cached negatively. For negatively cached records, errors are + immediately returned on a query, without querying other servers first. + The ttl is optional, the default is 900 seconds.
+ You can get a list of all types you can pass to this command using + pdnsd-ctl list-rrtypes. The type is treated case-sensitive! + Example:
+ pdnsd-ctl neg foo.bar A 900
+ pdnsd-ctl neg foo.baz 900
+
config[filename] + Reload pdnsd's configuration file.
+ The config file must be owned by the uid that pdnsd had when it was + started, and be readable by pdnsd's run_as uid. If no file name is + specified, the config file used at start-up is reloaded.
+ Note that some configuration changes, like the port or IP address pdnsd listens on, + cannot be made this way and you will receive an error message. + In these cases, you will have to restart pdnsd instead. +
includefilename + Parse the given file as an include file, see the documentation on + include sections for a description + what this file may contain.
+ This command is useful for adding definitions to the cache without reconfiguring pdnsd. +
evalstring + Parse the given string as if it were part of pdnsd's configuration file. + The string should hold one or more complete configuration sections. + However, global and + server sections are not allowed, + just as in include files. + If multiple strings are given, they will be joined using newline chars + and parsed together.
+ This command is useful for adding records interactively to the cache + that cannot be defined using the "pdnsd-ctl add" command, + (e.g. soa records). +
empty-cache[[+|-]name ...] + If no arguments are provided, the cache will be completely emptied, + freeing all existing entries. + Note that this also removes local records, as defined by the config file. + To restore local records, run "pdnsd-ctl config" or + "pdnsd-ctl include filename" immediately afterwards.
+ The "pdnsd-ctl empty-cache" command now accepts additional arguments; + these are interpreted as include/exclude names. If an argument starts with a '+' + the name will be included. If an argument starts with a '-' it will be + excluded. If an argument does not begin with '+' or '-', a '+' is + assumed. If the domain name of a cache entry ends in one of the names in + the list, the first match will determine what happens. If the matching + name is to be included, the cache entry is deleted, otherwise not. + If there are no matches, the default action is not to delete. + Note that if you want to delete exactly one name and no others, you should + use "pdnsd-ctl record name delete", + this is also much more efficient.
+ Examples:
+ pdnsd-ctl empty-cache
+ This command will remove all cache entries.
+
+ pdnsd-ctl empty-cache microsoft.com msft.net
+ This will remove all entries ending in microsoft.com or msft.net.
+
+ pdnsd-ctl empty-cache -localdomain -168.192.in-addr.arpa .
+ This will remove all entries except those ending in localdomain or + 168.192.in-addr.arpa. Note that '.' is the root domain which matches any + domain name. +
dump[name] + Print information stored in the cache about name. + If name begins with a dot and is not the root domain, information about + the names in the cache ending in name (including name without + the leading dot) will be printed. + If name is not specified, information about all the names in the cache will + be printed.
+ For each RR record the time and date that this record has been added to the cache + will be printed in the form mm/dd HH:MM:SS (locally defined records are printed without a time stamp). + After that the type of record is printed with the data. For the more common types + of RR records the data will be printed in human readable form, the remaining ones in a + hexadecimal representation.
+ This command is mainly useful for diagnostic purposes.
+ Note that if you pipe the output of this command through an application that + reads only part of the output and then blocks (such as more or less), + pdnsd will not be able to add new entries to the cache until the pipe is closed. + It is preferable to capture the output in a file in such a case. +
list-rrtypes + List available rr types for the neg command. + Note that those are only used for the neg command, not for add! +
+
+
+

4 contrib/

+ The contrib directory in the pdnsd distribution contains useful user-contributed scripts.
+ So far, there are scripts contributed by Marko Stolle and Paul Rombouts that make pdnsd + usable in a DHCP setup. + Please take a look into the README file in the contrib directory for further information. +
+
+

5 Problems...

+ If you have problems with configuring or running pdnsd, be sure to read the FAQ. + If this does not help you, pdnsd crashes or you find bugs, please mail one of the authors.
+ Note added by Paul A. Rombouts: + Thomas Moestl no longer maintains the code. I have revised the code and added new features. + See README.par and the + ChangeLog in the source directory + (or /usr/share/doc/pdnsd-<version> if you have installed a binary package) + for more details. + If you have questions about my modifications, you can find my email address at the end of + README.par. +
+
+

6 Hacking

+ Here comes some information you might find useful for hacking pdnsd. +
+

6.1 Source files

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Makefile.am, configure.in, acconfig.h + autoconf/automake/autoheader scripts. Makefile.am's are in most subdirectories. +
pdnsd.spec.in + A template from which configure generates a spec file for building rpm's for various + distributions. +
version + Contains only the program version string. Needed for several templates. +
src/rc/* + rc (start-up) scripts for various linux distributions. +
src/cache.c + The pdnsd cache subsystem(s) as defined in src/cache.h. + This is the "traditional" pdnsd system which keeps the cache in memory and uses hash tables for accesses. + Sourav K. Mandal is working on a system using gdbm. +
src/pdnsd-ctl/* + Contains the code for pdnsd-ctl, a program that allows you to control pdnsd at run time. +
src/conf-lex.l.in + The lex/flex source file for the config file lexer. This is a template because there might be + inserted "%option yylineno" for proper flex support. + (obsolete, superseded by src/conf-parser.c) +
src/conf-lex.l + This is automatically generated by configure from conf-lex.l.in. It may be overwritten + in any make, so never modify this, but conf-lex.l.in instead! + (obsolete, superseded by src/conf-parser.c) +
src/conf-parse.y + The yacc/bison source of the config file parser. + (obsolete, superseded by src/conf-parser.c) +
src/conf-parser.c, src/conf-parser.h, src/conf-keywords.h + The config file parser written purely in C (versions 1.1.10-par and later). +
src/conff.c, src/conff.h + The configuration handler functions and their prototypes. The parser is called from here. +
src/consts.h + Some constants used by the parser, config file handler functions and in the server status thread, + among others. +
src/dns.c, src/dns.h + Define dns message structures, constants, and some common dns data handlers. dns.h contains gcc-specific + code (in praticular, "__attribute__((packed))"). +
src/dns_answer.c, src/dns_answer.h + Define functions that answer incoming dns queries. +
src/dns_query.c, src/dns_query.h + Define functions to manage outgoing dns queries. +
src/error.c, src/error.h + Functions for error output to stderr or the syslog, and debug output to stderr or pdnsd.debug. +
src/hash.c, src/hash.h + Contains the code for storing and looking up cache entries in the hash table. +
src/helpers.c, src/helpers.h + Define miscellaneous helper functions. +
src/icmp.c, src/icmp.h + Define a function for performing a ping test. This contains OS-specific code. +
src/main.c + Contains main(), which holds the command line parser, performs initialisations and signal handling. +
src/make_hashconvtable.c + Contains the code for the executable make_hashconvtable, which is only run once, during build time, to generate the file hashconvtable.h, used by src/hash.c (versions 1.1.10-par and later). + (obsolete since version 1.2) +
src/make_rr_types_h.pl + A perl script for generating src/rr_types.h, + a C header file containing macro definitions and tables needed for handling the + RR types known to pdnsd, from the text file src/rr_types.in. +
src/rr_types.c, src/rr_types.h, src/rr_types.in + These define tables and macros needed for handling the RR types known to pdnsd. + Since version 1.2.9, rr_types.h is an automatically generated file, + see make_rr_types_h.pl. +
src/netdev.c, src/netdev.h + Define functions for network device handling. OS-specific. +
src/servers.c, src/servers.h + Define functions for the server status thread that performs the periodical uptests. +
src/status.c, src/status.h + Define functions for the status control thread. This is pdnsd's interface to pdnsd-ctl. +
+ +
+
+
+ Copyright (C) 2000, 2001 Thomas Moestl
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2012 Paul A. Rombouts +
+

+ Last revised: 19 April 2012 by Paul A. Rombouts +

+ + diff --git a/jni/pdnsd/doc/html/doc_makefile b/jni/pdnsd/doc/html/doc_makefile new file mode 100644 index 00000000..28fb7d50 --- /dev/null +++ b/jni/pdnsd/doc/html/doc_makefile @@ -0,0 +1,23 @@ + +versionfile = ../../version +arch = i686 +arch2 = x86_64 +extver = _sl6 +system = Scientific Linux 6.2 system + +doc: dl.html +.PHONY: doc clean + +# If the existing dl.html contains '???', then certain packages were missing +# during the previous build and dl.html needs to be built again. +ifneq ($(shell grep -F -l -e '???' dl.html),) +.PHONY: dl.html +endif + +dl.html: %.html: %.html.in htmlsubst.pl $(versionfile) + perl htmlsubst.pl version=`cat $(versionfile)` \ + baseurl='http://members.home.nl/p.a.rombouts/pdnsd/' \ + arch=$(arch) arch2=$(arch2) extver=$(extver) system="$(system)" $< > $@ + +clean: + @rm -fv dl.html diff --git a/jni/pdnsd/doc/html/faq.html b/jni/pdnsd/doc/html/faq.html new file mode 100644 index 00000000..eec65993 --- /dev/null +++ b/jni/pdnsd/doc/html/faq.html @@ -0,0 +1,412 @@ + + + + The pdnsd FAQ + + + + + + + + + + + + + + +
+ pdnsd Homepage + + pdnsd FAQ + + Documentation + + GNU GPL (pdnsd's License) + + Download Section +
+ +

The pdnsd FAQ

+ + + + + + + + + + +
Q: + There are complete and well-tested name servers around, such as the BIND. + These do also perform caching. Why should I use pdnsd? +
A: + pdnsd does not aim to be a complete name server implementation, such as the + BIND. It is optimized for caching, and you can only specify a small subset of all + dns record types pdnsd knows in your local "zone" definitions. + This of course reduces the code size drastically, and such the memory footprint. + There are some features especially interesting for dialin networks, ordinary + (non-server) internet hosts and computers that are often not connected to + to their network, e.g. notebooks (I originally wrote this program for use + with my notebook). + These features are: +
    +
  • permanent disk cache (useful for frequent power-offs/reboots) +
  • usually smaller memory footprint (depends on cache size) (see next question) +
  • offline-detection prevents hangs (e.g. the typical hang on startup of some + Netscape Navigator versions if not dialled in) +
  • better control about timeouts (also to prevent hangs) +
  • better control over the cache +
  • better run-time control +
+
+
+ + + + + + + + + + +
Q: + When I look at the process size with ps, top, gtop, or a similar tool, I see + some processes with a total size well above 3.5 MB. This is much more than + e.g. BIND named (about 1.4 MB). Why? +
A: + Really, it is not. + pdnsd uses multithreading, not multiprocessing. That means that the processes + share most of their process space. In the LinuxThreads library + or NPTL (Native Posix Thread Libary), + which are used by pdnsd on Linux, in fact the total process address space is shared + (although the processes have different stacks, these are in one process + address space). You may check this by looking at the at the process sizes of + the pdnsd threads: all should be the same. The effective size that pdnsd + occupies is thus the size of any of the processes, not the sum of those. + So, pdnsd with empty cache occupies about 800 kB, and the maximum size + should be about the cache size plus this size (in fact, ca 5-10% more). +
+
+ + + + + + + + + + +
Q: + What do I need the status control (option -s) for? +
A: + It enables you to do some things you might or might not need. With it, you can: +
    +
  • query pdnsd's settings at runtime to debug configuration files and + see which servers are regarded to be available +
  • mark servers as available or unavailable, or force a status retest - very + handy if you want to control which servers pdnsd queries, e.g for muliple + dial-up accounts +
  • delete, invalidate or add DNS records - useful e.g. when you want to build + records for dynamically assigned IP addresses or domain names +
  • reload pdnsd's configuration file without restarting pdnsd +
  • print information about the contents of pdnsd's cache. +
+
+
+ + + + + + + + + + +
Q: + What do I need local records (rr- and source-sections in the config file) for? +
A: + Some resolver programs, e.g. nslookup, want to look up the name of the + server they are using before doing anything else. This option is for defining + a PTR record for your IP such that those programs get an answer even if the + name server you are caching is not available or does not offer these records. + By extension, you may also define A and SOA records. This allows you to build + very small zones without having to use a "big" name server. It is NOT + intended to replace such a complete server in anything but VERY small + networks. Alternatively, you may start a named on another host or on the + same host on another port and cache it with pdnsd in addition to other (more + distant) name servers. +
+ The source section allows you to let pdnsd read in your + /etc/hosts file on startup and serve its contents. This file is used by your local + resolver before it even tries the name servers and usually contains + fully-qualified domain names (FQDNs) for all of the internet addresses your host has. + If you source this file, you usually won't need any additional rr sections. Sourcing it also allows + other hosts (eg. in your local network) to access the names defined in your + hosts file. You can of course just add other hosts in your local network to the + servers hosts file, thus making them known to your server's resolver + and pdnsd (if you sourced that file). +
+ If you don't know what this answer was all about, you should just take the + source section in the sample config file that comes with pdnsd, copy it + into your config file and forget about it. +
+
+ + + + + + + + + + +
Q: + When compiling, I get an error message like
Please define __BYTE_ORDER to + be __LITTLE_ENDIAN or __BIG_ENDIAN
What's up? +
A: + Normally, this macros should be defined in your C library's header files. + There are two different methods, most C libraries support both (and pdnsd + honors both): either __BYTE_ORDER is set to __LITTLE_ENDIAN + or __BIG_ENDIAN, or __LITTLE_ENDIAN or __BIG_ENDIAN + are directly defined as macros. +
+ Linux glibc, for example, does set those macros correctly. Never mind. You just have to know + whether your machine is little-endian or big-endian, this means wheter your + machine saves the least significant byte of a word or double-word first in memory (little-endian) or + the most significant first (big-endian). + All intel x86 and Alpha machines are little-endian, for example, while SPARC + and PowerPC architectures are big-endian. + If your machine is little-endian, add the following line to your config.h: +
+ #define __BYTE_ORDER __LITTLE_ENDIAN +
+ Likewise, if your machines byte order is big-endian: +
+ #define __BYTE_ORDER __BIG_ENDIAN +
+ Pathological byte orders like pdp-endian are not yet supported really; + However, for the place the endianess is needed, __LITTLE_ENDIAN should do + (it deals only with 16 bits; for all other occurances, ntoh[sl]/hton[sl] is used). +
+
+ + + + + + + + + + +
Q: + At startup, I get a warning saying:
+ + Uptest command [...] will implicitly be executed as root +
+ What does that mean? +
A: + This warning only occurs if you use the uptest=exec option in your + configuration. It means that the uptest command is run as root + because pdnsd is running as root, and this was not explicitely specified. + The idea is that it may introduce security holes (in the programs being run) + when they run as root, and so they shouldn't do that if possible. + You can specify the user that shall run the command by appending its name + comma-separated as string to the uptest_cmd line:
+ + uptest_cmd="<your command>","<user>"; +
+ If it is correctly running as root, just append the user string "root" to + the command and the warning will not occur again. +
+
+ + + + + + + + + + +
Q: + I cannot run my uptest_cmd command as root (it says permission denied), + although the pdnsd executable is setuid root. Why? +
A: + pdnsd will drop privileges gained through setuid/setgid before executing the + uptest commands (you shouldn't set the pdnsd executable setuid/setgid anyway). + The reason is clear: if you install the pdnsd + executable as setuid root and this wouln't be done, any user could execute + shellcode with root privileges using that option! +
+
+ + + + + + + + + + +
Q: + At startup, I get an error saying:
+ + Bad config file permissions: the file must be only writeable by the user +
+ Why is that? +
A: + pdnsd has an option (uptest=exec) that allows the execution of arbitrary + shell code (for testing whether an interface is up). This must be + of course secured against unauthorized use. One of these + protection is the one that produces the error message: if you routinely run + pdnsd, e.g. at system startup, and your config file is editable for others, + someone could change it and insert shell code that is executed in the next + pdnsd run -- with your user privileges! To prevent this, pdnsd will exit if the config file is writeable + by others than the owner. + To get rid of this message, just do
+ + chmod go-w <filename> +
+ on your config + file (for the default file: chmod go-w /etc/pdnsd.conf). + You should also check that the ownership is set correct. +
+
+ + + + + + + + + + +
Q: + serve_aliases does not seem to work. +
A: + Some resolvers (e.g. of the glibc 2.1) seem sometimes not to look up unmodified names, but the names with + an entry of the search path already appended. Since pdnsd will serve short names with this + option anyway, you can delete the search an domain options from your /etc/resolv.conf. This is reported to + work in some cases. +
+
+ + + + + + + + + + +
Q: + Some queries for domains that have many records (e.g. www.gmx.de) fail mysteriously. +
A: + pdnsd versions prior to 1.1.0 had the tcp server thread disabled by default. Most resolvers + repeat their query using tcp when they receive a truncated answer (the answer is truncated + when it exceeds a length of 512 bytes). You need to recompile pdnsd with the option + --enable-tcp-server to fix this. +
+
+ + + + + + + + + + +
Q: + I am behind some kind of firewall. In the configuration file + I have only listed addresses of name servers on the local (ISP's) network, + but pdnsd is slow and DNS queries frequently time out. +
A: + In some cases pdnsd will not consider the answer of the local name server + authoritative enough, and will try to get answers from the name servers listed in the + authority section of the reply message. If pdnsd is behind a firewall that blocks the + UDP reply packets from remote name servers, pdnsd will wait in vain for a reply. + One solution is to set proxy_only=on + in the servers sections of the configuration file. + This will prevent pdnsd from querying name servers that are not listed in the configuration + file. + Another solution that can be tried is specifying + query_method=tcp_only + in the global section of the configuration file, because a firewall that blocks + UDP packets from outside might still allow outgoing TCP connections to port 53. +
+
+ + + + + + + + + + +
Q: + Is pdnsd vulnerable to DNS cache poisoning as described in + CERT vulnerability note VU#800113? +
A: + Short answer: Yes.
+ Somewhat longer answer: The problem is not so much that pdnsd's implementation is flawed + but rather that the DNS protocol currently being used is fundamentally flawed from + a security viewpoint. As long as a more secure protocol is not in place, + all that the developers of pdnsd can do is to try to tweak the current implementation + to make it as difficult as possible for an attacker to succeed.
+ From version 1.2.7 onwards, the default for the query_port_start option + is 1024, which means that the pdnsd resolver will randomly select source ports + in the range 1024-65535. (In previous versions the default was to let the kernel select + the source ports, which will often result in a more or less predictable sequence of ports.) + It also helps to use a good quality source of random numbers. On platforms where this is + supported, it is preferable to configure with --with-random-device=/dev/urandom. + There is still more that can be done to make pdnsd less vulnerable, but this remains + (as of this writing) a work in progress. +
+ Please note that pdnsd was designed for small (private) networks, and that it is generally + not recommended to let untrusted users access pdnsd. +
+ +
+
Thomas Moestl + and Paul Rombouts +
+
+

+ Last revised: 18 August 2008 by Paul Rombouts +

+ + + diff --git a/jni/pdnsd/doc/html/htmlsubst.pl b/jni/pdnsd/doc/html/htmlsubst.pl new file mode 100644 index 00000000..a9e3e9ff --- /dev/null +++ b/jni/pdnsd/doc/html/htmlsubst.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl -w + +# Primitive ad-hoc script for updating pdnsd html doc files. +# Written by Paul Rombouts. + +use strict; +use integer; +use POSIX qw(strftime); + +my %paramvals=(); + +while(@ARGV && $ARGV[0]=~/^([^=]*)=(.*)$/) { + my $param=$1; my $val=$2; + if($param =~ /^[[:alpha:]]\w*$/) { + $paramvals{$param}=$val; + } + else {warn "Warning: invalid parameter '$param' ignored.\n"} + shift @ARGV; +} + +sub sizeof { + my($arg)=@_; + (my $str= $arg) =~ s/\$(?:([[:alpha:]]\w*)\b|\{([[:alpha:]]\w*)\})/ + defined($paramvals{$+})?$paramvals{$+}:defined($ENV{$+})?$ENV{$+}:''/eg; + my $filename=eval($str); + (-f $filename) or return '???'; + (((-s $filename)+1023)/1024).'kB'; +} + +while(<>) { + s/\$(?:date\b|\{date\})/strftime("%d %b %Y",localtime)/eg; + s/\$sizeof\(([^()]*)\)/sizeof($1)/eg; + s/\$(?:([[:alpha:]]\w*)\b|\{([[:alpha:]]\w*)\})/ + defined($paramvals{$+})?$paramvals{$+}:defined($ENV{$+})?$ENV{$+}:''/eg; + print; +} diff --git a/jni/pdnsd/doc/html/index.html b/jni/pdnsd/doc/html/index.html new file mode 100644 index 00000000..d2e426aa --- /dev/null +++ b/jni/pdnsd/doc/html/index.html @@ -0,0 +1,686 @@ + + + + pdnsd homepage + + + + + + + + + + + + + + + +
+ About pdnsd + + pdnsd FAQ + + Documentation + + GNU GPL (pdnsd's License) + + Download Section +
+

The pdnsd Homepage

+

News

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
2012-03-17Version 1.2.9a-par has been released. + Version 1.2.9a fixes a bug in the 1.2.9 release that causes a build failure when pdnsd is + configured with --enable-strict-rfc2181. + If you do not use this option to compile pdnsd, there is no need to upgrade from 1.2.9 to 1.2.9a. +
2012-02-27Version 1.2.9-par has been released. + Version 1.2.9 supports many more RR types (including those necessary for DNSSEC) and + EDNS (Extension mechanisms for DNS) to enable UDP messages larger than 512 bytes. + It also has support for defining local TXT records and has several new options and bugfixes + (including file descriptor leaks that effect FreeBSD users). +
2011-05-03The latest source code is available from a + git repository.
+ In response to frequent requests I have uploaded a git tree including the latest code + and a fairly extensive history of pdnsd development to + gitorious.org. + Anyone who wants to participate in pdnsd development is free to create a + clone repo on gitorious.org + and push his modifications there. +
2010-02-22Version 1.2.8-par has been released. + The main new feature of version 1.2.8 is automatic discovery of root servers. + Furthermore, there are some additional improvements in the resolver. +
2008-09-04Version 1.2.7-par has been released. + Foremost, this release fixes some security problems. + It contains a fix for a "dangling pointer" bug that could cause pdnsd to + crash when it received a long reply. It also addresses some of the issues + raised in the CERT + vulnerability note VU#800113 by making the default of + query_port_start equal to 1024, thereby ensuring that source + ports are randomly selected by the pdnsd resolver in the range 1024-65535. + This release also fixes problems with compiling pdnsd for the ARM architecture + and for the Darwin platform (Max OS X). +
+ There are a number of (minor) new features. + pdnsd now supports "include" files, essentially configuration files that + only contain definitions for local records. + It is now possible to define interactively, using pdnsd-ctl, + any local record that can be defined in a configuration file. +
2007-09-04Version 1.2.6-par has been released. + pdnsd's license has been upgraded to GPL version 3. + A bug has been fixed which which caused pdnsd to handle NXDOMAIN replies + inefficiently when configured with neg_domain_pol=on. The + code that implements the ping test has been fixed, which was broken for + 64-bit systems. A new option randomize_servers can be used + to give each server in a section of the configuration file an equal + chance of being queried. The new options reject, + reject_policy and reject_recursively make it + possible to check for the presence of certain IP addresses in the + replies of name servers and to avoid some types of unwanted replies. + The pdnsd-ctl 'add a' and 'add aaaa' commands + now allow multiple IP addresses to be specified for the same name. + pdnsd's ability to resolve from root servers has been improved. +
2006-09-02Version 1.2.5-par has been released. + This release introduces a new query method: udp_tcp. + With this method a UDP query is tried first and, if the UDP answer is + truncated, the query is repeated using TCP, which is the behaviour that + seems to be recommended by the DNS standards. There is a new + configuration option use_nss, which can be turned off to + prevent lengthy timeouts and stalls in certain situations. A bug has + been fixed which could cause pdnsd to crash if debug output was + generated before the debug output stream was properly initialized. +
2006-01-09Version 1.2.4-par has been released. + A memory leak and a minor buffer-overflow problem have been fixed. + There is now a fix for some situations that would previously cause pdnsd to + exit prematurely (such as ACPI S3 sleep or trying to attach strace to pdnsd). + Time intervals specified in the configuration file can now be expressed in + minutes, hours, days and weeks as well as seconds. + Support for Apple Mac OS X v10.4 Tiger has been improved. + The "pdnsd-ctl status" command now also provides some + information about the status of the running threads. + There are some further improvements in the debugging information provided by pdnsd.
+ TCP-query support is now compiled in by default (but can still be disabled using + the configure option --disable-tcp-queries). +
2005-07-11Version 1.2.3-par has been released. + New feature in this release: the "pdnsd-ctl empty-cache" command can + be provided with an include/exclude list, allowing the user to specify a + selection of names to be removed, instead of emptying the cache completely.
+ Additional improvements: pdnsd should now remain responsive while executing the + "pdnsd-ctl empty-cache" command. + With the query_method=tcp_udp option pdnsd will now also + try a UDP query after a TCP connection times out, which should allow + pdnsd to resolve the same names with query_method=tcp_udp + as with query_method=udp_only, although perhaps with an + occasional delay. + "pdnsd-ctl config" or "pdnsd-ctl server" + commands should now run without delays, even if pdnsd is performing + ping or query uptests at the time. + Some problems with resolving certain names using root servers have been fixed. +
2005-04-03Version 1.2.2-par has been released. + The main emphasis of this release is improved portability. + A bug has been fixed that prevented pdnsd from compiling successfully on some + 64 bit architectures. + This release has (experimental) support for the Darwin (Apple Mac OS X) platform. + On Linux systems, the configure script will now try to detect automatically whether + the system implements the Native POSIX Thread Library, but the method used may not + necessarily be foolproof. + In addition, the debug features have been improved and should make it easier to find out + why pdnsd considers some queries or replies malformed. +
2004-11-07Version 1.2.1-par has been released. + The main new feature of this release is improved support for non-Linux platforms.
+ This release has (experimental) support for the Cygwin platform, and should also fix + some compilation glitches that have been reported by FreeBSD users. +
2004-10-10Version 1.2-par has been released. + pdnsd is new and improved! Most of the changes effect the internal workings + of pdnsd, but there also a number of interesting new features (well, I think they are interesting).
+ Among the bugs fixed are two rather nasty ones which involve the handling of NXT and NAPTR records + and which can cause pdnsd to crash or abort.
+ The new features include a new server availability test which can be specified with uptest=query, + support for reading the DNS configuration from resolv.conf files, + a new option for optimizing the use of root servers, + a new option that makes defining local records for reverse resolving easier, + support for defining wildcard records, + a new pdnsd-ctl command for reloading the config file without restarting pdnsd, and + a new pdnsd-ctl command for dumping information about the names stored in the cache. + The documentation has also been updated: there is now a pdnsd.conf man page.
+ For a more complete list of the changes I'll have to refer you to README.par and the ChangeLog. +
2004-05-22Version 1.1.11a-par has been released. + This release contains a fix for FreeBSD users that bypasses a problem + with the macro ENONET, which can cause a compilation failure when it is undefined. + Linux users will notice no difference between 1.1.11a-par and 1.1.11-par. +
2004-05-10Version 1.1.11-par has been released. + This version has a rather large number of small changes, which are rather difficult to summarize. + Among the bugs fixed are a race condition in the cache lookup code, a + flaw in the code that caused a busy spin when a remote server answered + with "Not Implemented", and problems with the -4 and -6 command-line + options. Among the improvements are an alternative sorting algorithm + which should allow pdnsd to start up faster when reading a large cache + file from disk, automatic mapping of IPv4 to IPv6 addresses when running + in IPv6 mode, somewhat more efficient memory use, better compression of + the replies and changes in the parallel querying algorithm that should + improve the chances of catching a reply from a remote server.
+ + For a more complete list of the changes I'll have to refer you to README.par and the ChangeLog. +
2004-02-10Version 1.1.10-par has been released. + + The main new feature of this release is a new parser for configuration + files, completely rewritten from scratch in C. The main advantages are: + (f)lex and yacc/bison are no longer needed to build pdnsd, more + informative error messages instead of merely "parse error", + and string literals no longer need to be enclosed in quotes in most + cases.
Furthermore, a bug has been fixed that caused incorrect + IPV6-type PTR records to be generated when sourcing + /etc/hosts like files.
+ + There have been other small changes, more details can be found in the ChangeLog. +
2004-01-08Version 1.1.9-par has been released. + "maintenance" release by Paul Rombouts.
+ + The change of version number is not very significant; the + difference between 1.1.9-par and the previous 1.1.8b1-par8 is marginal. + However, I felt the need to simplify the numbering, because it was + becoming rather baroque.
+ + I've added some missing pieces to the documentation (the pdnsd manual and the man page for pdnsd-ctl). BTW, did you + know that it's possible to define aliases for domain names with pdnsd? I + had plans to implement such a feature when I discovered that pdnsd + already supports it. It was just poorly documented. (If want to try this + for your self, look for the new information about CNAME records under + the rr Section in the manual.)
The + changes to the code consist mostly of optimizations, removal of some + size limits due to fixed-size buffers, and some cleaning up. I've also + tried to make the error responses of pdnsd-ctl more helpful.
+ + More details can be found in the ChangeLog. +
2003-10-10Version 1.1.8b1-par8 has been released. + "maintenance" release by Paul Rombouts.
+ This version introduces a "delegation-only" feature that may be useful + for blocking Verisign's Sitefinder.
+ The parser for the configuration file now tolerates domain names missing + a dot at the end.
+ I have provided alternative implementations for some GNU extensions that I + used in an effort to make the code more portable. In particular, the + code should build on FreeBSD again.
+ More details can be found in the README.par file. +
2003-09-19Version 1.1.8b1-par7 has been released. + "maintenance" release by Paul Rombouts. Besides fixing a number of bugs I have + reworked some of the code for adding and removing entries in the cache in an + effort to improve efficiency and stability.
+ More details can be found in the ChangeLog. +
2003-07-28Version 1.1.8b1-par6 has been released. + "maintenance" release by Paul Rombouts. In addition to some further code cleanup, + the documentation has been revised. +
2003-07-10Version 1.1.8b1-par5 has been released. + A troublesome allocation size error has been discovered in Thomas Moestl's code. + In practice this bug only wastes memory but it could + also potentially lead to memory corruption. Upgrading is recommended. + More details can be found in the ChangeLog. +
2003-06-30Version 1.1.8b1-par4 has been released. + Due to incompatibilities between various implementations of + the pthread library on Linux systems, problems can occur with signal handling in + pdnsd. The usual symptom is failure by pdnsd to save the cache to disk, and + /var/cache/pdnsd/pdnsd.cache remaining empty. If you experience + this kind of trouble, try reconfiguring with different values for the new + --with-thread-lib option. The allowable values are + described in the documentation. +
2003-04-07pdnsd is no longer maintained by Thomas Moestl: + I have not had time to maintain pdnsd for quite a while now, and have been very slow to + respond to issues, or did not respond at all. It is time that I officially announce that + pdnsd is no longer actively maintained; I apologize to all those who reported bugs or + asked questions without receiving any reply. However, Paul A. Rombouts has published + a patch set against the last released version at + http://members.home.nl/p.a.rombouts/pdnsd.html, + which cleans up a lot of code fixes many bugs. +
2002-07-19Documentation update. + Please note that pdnsd should never be installed with setuid or setgid attributes, + as it is not always possible to give up all privileges due to operating system restrictions. + While this was never intended and I don't think that anybody would actually do this, the + documentation was updated to explicitely mention this to avoid misunderstandings. +
2002-01-15Version 1.1.7a has been released. + This fixes a reversed test in an assertion that would cause pdnsd to termintate when the ping uptest + was used. No other changes were made. +
2002-01-15Version 1.1.7 has been released. + This fixes some problems that might be remotely exploitable to gain access as the user pdnsd runs as + (an unprivileged user by default). To do this, an attacker needs to control a name server that is + queried by pdnsd, and send a malicious reply to such a query.
+ Upgrading is strongly recommended!
+ There are also minor bug fixes and stability improvements. +
+ +
+

About pdnsd

+ pdnsd is a proxy DNS server with permanent caching (the cache contents + are written to hard disk on exit) that is designed to cope with unreachable + or down DNS servers (for example in dial-in networking).
+ Since version 1.1.0, pdnsd supports negative caching.
+
+ It is licensed under the GNU General Public License (GPL, + also available in html and + translated into various languages.). + This, in short, means that the sources are distributed togehter with the program, and + that you are free to modify the sources and redistribute them as long as you + also license them under the GPL. You do not need to pay anything for pdnsd. + It also means that there is ABSOLUTELY NO WARRANTY for pdnsd or any part + of it. For details, please read the GPL. +

+ pdnsd can be used with applications that do DNS lookups, e.g. on startup, and + can't be configured to change that behaviour, to prevent the often minute-long + hangs (or even crashes) that result from stalled DNS queries. Some Netscape Navigator + versions for Unix, for example, expose this behaviour. +

+ pdnsd is configurable via a file and supports run-time configuration using the program pdnsd-ctl that comes + with pdnsd. This allows you to set the status flags of servers that pdnsd knows (to influence which servers + pdnsd will query), and the addition, deletion and invalidation of DNS records in pdnsd's cache. +
+ Parallel name server queries are supported. This is a technique that allows + querying several servers at the same time so that very slow or unavailable + servers will not block the answer for one timeout interval. +
+ Since version 1.0.0, pdnsd has full IPv6 support. +

+ There is also a limited support for local zone records, intended for defining + 1.0.0.127.in-addr.arpa. and localhost. , since some clients request that + information and it must be served even if the cached servers are not available + or do not serve these records. pdnsd may also read your /etc/hosts file + (this file is normally used by your local resolver and usually contains + information for localhost as well as for your machines FQDN) and serve its + contents. +

+ pdnsd was started on Linux, and has since been ported to FreeBSD (and Cygwin and Darwin). + 90% of the source code should be easily portable to POSIX- + and BSD-compatible systems, provided that those systems support the POSIX threads (pthreads). + The rest might need OS-specific rewrites. +

+ Currently, pdnsd is only compileable by gcc. This should be easy to fix, but I just + do not have documentation for other compilers. If you are not able or do not want + to use gcc, I would recommend you just try to do the minor changes. +

+

+ pdnsd must be started as root in some cases (raw sockets are needed for icmp + echoes for the option uptest=ping, and the default port is 53, this must be + >1024 to allow non-root execution). However, pdnsd can be configured to change it's user + and group id to those of a non-privileged user after opening the sockets needed for this. +

+ The server should support the full standard DNS queries following the rfcs 1034 + and 1035. As of version 1.0.0, the rfc compliance has been improved again, and pdnsd is now + believed (or hoped?) to be fully rfc-compatible. It completely follows rfc 2181 (except + for one minor issue in the FreeBSD port, see the documentation). + It does not support the + following features, of which most are marked optional, experimental or obsolete + in these rfcs: +

+
    +
  • Inverse queries +
  • Status queries +
  • Completion queries +
  • Namespaces other than IN (Internet) +
  • AXFR and IXFR queries (whole zone transfers); since pdnsd does not maintain zones, that should not violate the standard +
+ The following record types, that are extensions to the original DNS standard, are supported for caching since version 1.2.9 + (if you do not need most of them, you can disable runtime support for the unneeded ones before compiling pdnsd and save a little cache and executable space, see the source file src/rr_types.in): +
    +
  • RP (responsible person, RFC 1183) +
  • AFSDB (AFS database location, RFC 1183) +
  • X25 (X25 address, RFC 1183) +
  • ISDN (ISDN number/address, RFC 1183) +
  • RT (route through, RFC 1183) +
  • NSAP (Network Service Access Protocol address , RFC 1348) +
  • PX (X.400/RFC822 mapping information, RFC 1995) +
  • GPOS (geographic position, deprecated) +
  • AAAA (IPv6 address, RFC 1886) +
  • LOC (location, RFC 1876) +
  • EID (Nimrod EID) +
  • NIMLOC (Nimrod locator) +
  • SRV (service record, RFC 2782) +
  • ATMA (ATM address) +
  • NAPTR (URI mapping, RFC 2168) +
  • KX (key exchange, RFC 2230) +
  • CERT (Certificate record, RFC 4398) +
  • DS (Delegation Signer, RFC 4034) +
  • RRSIG (Resource Record Signature, RFC 4034) +
  • NSEC (Next Secure, RFC 4034) +
  • DNSKEY (record containing the public key for a zone, RFC 4034) +
  • NSEC3 (Next Secure version 3, RFC 5155) +
  • NSEC3PARAM (NSEC3 parameters, RFC 5155) +
+

+ Note: This list is incomplete. For the complete list see the source file src/rr_types.in. +

+ There are FreeBSD and OpenBSD ports available for pdnsd (ports/net/pdnsd for both). + Thanks go to Roman Shterenzon for the FreeBSD port Sebastian Stark for the OpenBSD one! + Thanks to Kiyo Kelvin Lee now also runs on the Cygwin platform! + Thanks goes to Rodney Brown for extending portability to the Darwin (Apple Mac OS X) platform! +

+ If you have questions left, you should take a look into the FAQ. +
+ Bugfixes, patches and compatability fixes for other OSs are very welcome! +

+

Features in detail

+

+ This section describes some of pdnsds features in detail. Most of the options are set + in the config file. For more information on the configuration file, see + the documenation page. +


+ +

Uptests

+ pdnsd provides several methods to test whether a remote DNS server should be regarded as available + (so that pdnsd can query it), in + addition to the obvious "none" test (the server is always regarded as available, + or availability is set on or off using the pdnsd-ctl utility). + These tests are: +
    +
  • ping: a given adress is ping'ed in a given interval. If it there is no response + or the host is unreachable, the server is seen to be not available (for those who don't know: + pinging is sending a certain Internet packet type to a host to which any standard-conformant + host is required to reply). +
  • if: a given network interface is tested whether it is existent, up and running. If + it is not, the server is regarded to be not available. This is especially useful for ppp and + similar interfaces. A special case test for Linux isdn (ippp*) interfaces is integrated, so that the uptests + should also work for these. +
  • dev: this is a variant of the if uptest for use with Linux dial-on-demand ppp interfaces. In addition + to performing an if-style interface uptest, it also tests whether a specified program (e.g. pppd) owns + a lock to a given (modem-) device. +
  • exec: a given shell command line is executed and the exit status of the whole command line (which + is normally the exit status of the last command) is evaluated. If it is not zero, the server is regarded + to be not available. This is a very flexible testing method with which it should be able to perform + virtually any needed test. +
  • query: New in version 1.2: + This works like the ping test, except it sends an (empty) DNS query to the remote server. + If the server sends a well-formed response back within the timeout period (except SERVFAIL), + it will be regarded as available. + This test is useful if a remote server does not respond to ICMP_ECHO requests at all, + which unfortunately is quite common these days. + In many cases this test will be a more reliable indicator of availability + than the ones mentioned above. +
+
+

Local Records ("Zones")

+ As mentioned above, there are only very basic local record types (ie the record types that you may use in record + declarations in your local configuration for records that pdnsd shall serve in addion to the cached ones). + They are organized roughly in zones but have not complete zone declarations, so I generally do not use the + term "zone" for them, but rather "local records". + These are the local record types pdnsd can understand: +
    +
  • SOA (information about the name server) +
  • A (domain-name-to-address mapping) +
  • PTR (pointer, used normally for address-to-domain-name mapping) +
  • NS (name server, generated automatically by pdnsd for any local record set) +
  • CNAME (canonical host name) +
  • MX (mail exchange for the domain) +
  • TXT (arbitrary text strings, often used for Sender Policy Framework) +
+ You can specify these records in the configuration file.
+ You may "source" a file in a format like that used in the /etc/hosts file, that means + that pdnsd reads this file, extracts addresses and domain names from it and automatically generates + A records for name to address mapping, PTR records for address to name mapping and NS records (name + server specifiation) for each entry in the file.
+ Records can also be changed dynamically at run time.
+ A script contributed by Marko Stolle makes pdnsd usable in a DHCP setup using this feature. +
+

System requirements

+ As mentioned, pdnsd currently runs under Linux, FreeBSD and Cygwin. + Other BSD flavours may or may not work (feedback is very welcome!). + The system and software requirements under Linux are: +
    +
  • Kernel version >2.2.0 +
  • glibc version >2.0.1 (aka libc6) with LinuxThreads (normally included) + or NPTL (Native Posix Thread Library, recommended).
    + Due to a bug, pdnsd 0.9.8 does not run with glibc2.1.1. This behaviour was + fixed in pdnsd 0.9.9. +
  • For IPv6: glibc>=2.1 +
+ The system requirements under FreeBSD are: +
    +
  • FreeBSD versions >=2.6 (prior ones may or may not work) +
  • For IPv6: FreeBSD >=4.0 is recommended (no idea if it runs on prior versions) +
+ + The common software requirements for all supported systems are: +
    +
  • GCC, preferably egcs-2.* or 3.* (other compilers are currently not supported; the needed patch for another compiler + should not be difficult, however) +
  • GNU or BSD make +
  • the standard commands install, grep, sed, awk, touch and which (along with the REALLY + standard ones mv, cp, ln, rm, pwd, test, echo, cat, mkdir, chown, chmod, tar). In + any standard Unix installation, this should be no problem. +
  • for hacking and building own packages, you might also need gzip, bzip2, perl and rpmbuild +
+
+

Download

+ If you want to download pdnsd, please visit the download page. +
+

Authors

+

+ pdnsd was originally written by Thomas Moestl, + but is no longer maintained by him. Paul A. Rombouts + has revised large portions of the code and has added a number of new features. + See README.par and the ChangeLog + in the source directory (or /usr/share/doc/pdnsd-<version> + if you have installed a binary package) for more details. + If you have questions about the recent modifications, you can find + the email address of the current maintainer + at the end of README.par. +

+

+ Daniel Smolik has contributed RedHat RPMs (the most recent RPMs are available here).
+ Torben Janssen contributed start scripts for Red Hat Linux.
+ Soenke J. Peters contributed patches and suggestions for Red Hat compatability.
+ Wolfgang Ocker has contributed the code and documentation for the server_ip option.
+ Markus Mohr contributed a Debian rc script.
+ Nikita V. Youschenko contributed extensions to the "if" uptest.
+ Lyonel Vincent extended the serve_aliases option to support an arbitrary number of aliases.
+ Sourav K. Mandal wrote the autoconf scripts and contributed many fixes and suggestions.
+ Stephan Boettcher contributed the SCHEME= option.
+ Ron Yorston contributed the uptest for Linux ppp dial-on-demand devices.
+ Alexandre Nunes fixed some bugs in the autoconf files.
+ Sverker Wiberg contributed fixes for IPv6.
+ Carsten Block contributed configure-able rc scripts.
+ Olaf Kirch contributed a security fix for the run_as code.
+ Paul Wagland contributed various patches for bind9-compatability and other issues.
+ Roman Shterenzon contributed patches and lots of helpful hints for FreeBSD compatability.
+ Bernd Leibing has contributed spec file fixes.
+ Michael Wiedmann has contributed the pdnsd-ctl.8 man page.
+ Marko Stolle has contributed the contrib/pdnsd_update.pl script that makes pdnsd usable in a DHCP setup.
+ P.J. Bostley has contributed patches to get pdnsd working on alpha properly.
+ Christian Engstler contributed patches for SuSE compatability.
+ Bjoern Fischer contributed code to make pdnsd leave the case of names in the cache unchanged.
+ Marko Stolle contributed the contrib/pdnsd_update.pl script that makes pdnsd usable in a DHCP setup.
+ Andrew M. Bishop contributed the support for the label server option and the pdnsd-ctl interface for using it.
+ Frank Elsner contributed rc script fixes.
+ Andreas Steinmetz contributed the code for query_port_start and query_port_end options.
+ Mahesh T. Pai contributed the pdnsd.8 man page.
+ Nikola Kotur contributed the Slackware start-up script.
+ Kiyo Kelvin Lee contributed a patch for Cygwin support.
+ Rodney Brown contributed a patch for Darwin (Apple Mac OS X) support.
+ Jan-Marek Glogowski contributed a patch implementing the use_nss option. +

+

+ Special thanks to Bert Frederiks for letting me do a late-night debugging run on his machine to + spot obscure bugs! +

+

+ Thanks to the following persons for reporting bugs and being helpful:
+ David G. Andersen,
+ Dirk Armbrust,
+ Daniel Black,
+ Kevin A. Burton,
+ Juliusz Chroboczek,
+ Joachim Dorner,
+ Stefan Erhardt,
+ Stefan Förster,
+ Mike Hammer,
+ Jonathan Hudson,
+ Dan Jacobson,
+ Byrial Jensen,
+ Patrick Loschmidt,
+ James MacLean,
+ Fraser McCrossan,
+ Michael Müller,
+ Erich Reitz,
+ Brian Schroeder,
+ Milan P. Stanic,
+ Michael Steiner,
+ Norbert Steinl,
+ Markus Storm,
+ Michael Ströder,
+ Alan Swanson,
+ Eelco Vriezekolk. +

+ +

Links

+ Well, this is the obligatory link section. +
+
+ + + + + + + + +
+ + http://www.gnu.org
+ The GNU homepage +
+
+ + http://freecode.com
+ Freecode (formerly Freshmeat) - large free software index +
+
+ + http://www.freebsd.org
+ The FreeBSD project +
+
+ +
+
+
Thomas Moestl + and Paul A. Rombouts +
+
+

+ Last revised: 17 March 2012 by Paul A. Rombouts +

+ + diff --git a/jni/pdnsd/doc/html2confman.pl b/jni/pdnsd/doc/html2confman.pl new file mode 100644 index 00000000..abade119 --- /dev/null +++ b/jni/pdnsd/doc/html2confman.pl @@ -0,0 +1,161 @@ +#!/usr/bin/perl -w +# +# A Perl script for converting pdnsd html documentation to a man page. +# +# Written by Paul A. Rombouts +# +# This file Copyright 2004 Paul A. Rombouts +# It may be distributed under the GNU Public License, version 2, or +# any higher version. See section COPYING of the GNU Public license +# for conditions under which this file may be redistributed. +# + +use strict; +use POSIX qw(strftime); + + +while(<>) { + if(/[^<]*configuration file/i) { + last; + } +} + +exit unless defined($_); + +while(<>) { + if(/[^<]*layout/i) { + last; + } +} + +exit unless defined($_); + +(my $myname=$0) =~ s{.*/}{}; + +print <) { + if(/.*\bpdnsd-ctl\b/) { + last; + } + s{^\s*((?:<[^<>]+>)*?)[\d.]*\s*(.*)((?:<[^<>]+>)*?)(?:
)?\s*$}{.SS $1$2$3\n}i; + if(s{^\s*\s*}{.TP\n}i) {$taggedparagraph=1} + if(m{^\s*}i) {$taggedparagraph=0} + s{^\s*((?:<[^<>]+>)*?)(.*)((?:<[^<>]+>)*?)(?:
)?\s*$}{.B $1$2$3\n}i if $taggedparagraph; + s{^\s*((?:<[^<>]+>)*?or(?:<[^<>]+>)*?)(?:
)?\s*$}{$1\n.PD 0\n.TP\n.PD\n}i if $taggedparagraph; + if(s{^\s*
}{.DS L\n}i) {$displayed=1}
+    s{^\t}{        } if $displayed;
+    if(s{
\s*$}{\n.DE\n\n}i) {$displayed=0} + elsif(!$displayed) {s{^\s*}{}} + s{^\s*
  • }{.IP\n\\(bu }i; + s{
  • }{\n.IP\n\\(bu }i; + s{
      }{\n}i; + s{
    }{\n}i; + s{}{\\fB}ig; + s{}{\\fP}ig; + s{<(i|em)>}{\\fI}ig; + s{}{\\fP}ig; + unless(s{^\s*(<[^<>]+>)*(
    |

    )(<[^<>]+>)*\s*$}{\n}i) { + s{]*>(.*)

    }{\n$1\n}i; + s{^\s*
    }{.br\n}i; + s{
    \s*
    \s*$}{\n\n}i; + s{
    \s*$}{\n.br\n}i; + s{
    }{\n.br\n}i; + s{^\s*(<[^<>]+>)*\s*$}{}; + } + s{<[^<>]+>}{}g; + s{<}{<}ig; + s{>}{>}ig; + s{"}{"}ig; + s{ }{\\ }ig; + s{/var/cache/pdnsd\b}{\@cachedir\@}g; + s{(? +.UE +and was extensively revised by Paul A. Rombouts +.UR + +.UE +(for versions 1.1.8b1\\-par and later). +.PP +Several others have contributed to \\fBpdnsd\\fP; see files in the source or +\\fB/usr/share/doc/pdnsd/\\fP directory. +.PP +This man page was automatically generated from the html documentation for \\fBpdnsd\\fP, +using a customized Perl script written by Paul A. Rombouts. +ENDOFTRAILER + +if(defined($_)) { + while(<>) { + if(/last\s+revised/i) { + s{^\s*}{}; + s{<[^<>]+>}{}g; + s{<}{<}ig; + s{>}{>}ig; + s{"}{"}ig; + s{ }{\\ }ig; + print ".PP\n"; + print; + last; + } + } +} +exit; diff --git a/jni/pdnsd/doc/pdnsd-ctl.8 b/jni/pdnsd/doc/pdnsd-ctl.8 new file mode 100644 index 00000000..73459f3b --- /dev/null +++ b/jni/pdnsd/doc/pdnsd-ctl.8 @@ -0,0 +1,198 @@ +.\" This manpage has been automatically generated by docbook2man-spec +.\" from a DocBook document. docbook2man-spec can be found at: +.\" +.\" Please send any bug reports, improvements, comments, patches, +.\" etc. to Steve Cheng . +.\" This manpage has been edited manually by Paul A. Rombouts. +.TH "PDNSD\-CTL" "8" "Sep 2008" "pdnsd 1.2.9b-par" "" +.SH NAME +\fBpdnsd\-ctl\fP \- controls pdnsd +.SH SYNOPSIS +.sp +\fBpdnsd\-ctl\fP [\fB\-c\fP \fIcachedir\fP] [\fB\-q\fP] \fIcommand\fP [\fIarguments\fP] +.SH "DESCRIPTION" +.PP +\fBpdnsd\-ctl\fP controls \fBpdnsd\fP, a proxy dns server with permanent caching. +Note that the status control socket must be enabled (by specifying an option on +the pdnsd command line or in the configuration file) before you can use +\fBpdnsd\-ctl\fP. +.PP +.TP +\fB\-c\fP \fIcachedir\fP +Set the cache directory to \fIcachedir\fP (must match pdnsd setting). +This is only necessary if the directory differs from the default specified +at compile time. +.TP +\fB\-q\fP +Be quiet unless output is specified by the command or something goes wrong. +.SH "COMMANDS" +.TP +\fBhelp\fP\ \ \ [no arguments] + +Print a command summary. +.TP +\fBversion\fP\ [no arguments] + +Print version and license info. +.TP +\fBstatus\fP\ [no arguments] + +Print a description of pdnsd's cache status, thread status and configuration. +Also shows which remote name servers are assumed to be available. +.TP +\fBserver\fP\ (\fIindex\fP|\fIlabel\fP) (\fBup\fP|\fBdown\fP|\fBretest\fP) [\fIdns1\fP[,\fIdns2\fP[,...]]] + +Set the status of the servers with the given index or label to up or down, or +force a retest. The index is assigned in the order of definition in pdnsd.conf +starting with 0. Use the status command to view the indexes. You can specify all +instead of an index to perform the action for all servers registered with pdnsd. +.IP +An optional third argument can be given consisting of a list of IP addresses +separated by commas or white-space characters. This list will replace the +addresses of name servers used by pdnsd for the given server section. This +feature is useful for run-time configuration of pdnsd with dynamic DNS data in +scripts called by ppp or DHCP clients. The last argument may also be an empty +string, which causes existing IP addresses to be removed and the corresponding +server section to become inactive. +.TP +\fBrecord\fP\ \fIname\fP (\fBdelete\fP|\fBinvalidate\fP) + +Delete or invalidate the records of the given domain name if it is in the cache. +Invalidation means that the records are marked as timed out, and will be +reloaded if possible. For local records (i.e., records that were given in the +config file using a rr section, records read from a hosts-style file and records +added using pdnsd-ctl), invalidation has no effect. Deletion will work, though. +.TP +\fBsource\fP\ \fIfn\fP \fIowner\fP [\fIttl\fP] [(\fBon\fP|\fBoff\fP)] [\fBnoauth\fP] + +Load a hosts-style file. Works like using the pdnsd source configuration section. +Owner and ttl are used as in the source section. ttl has a default +of 900 (it does not need to be specified). The next to last argument corresponds +to the serve_aliases option, and is off by default. +\fBnoauth\fP is used to make the domains non-authoritative +(this is similar to setting authrec=off in the config file, +please consult the +.BR pdnsd.conf (5) +man page for what that means). +fn is the name of the file, which must be readable by pdnsd. +.TP +\fBadd\fP\ \ \ \ \fBa\fP \fIaddr\fP \fIname\fP [\fIttl\fP] [\fBnoauth\fP] +.TP +\fBadd\fP\ \ \ \ \fBaaaa\fP \fIaddr\fP \fIname\fP [\fIttl\fP] [\fBnoauth\fP] +.TP +\fBadd\fP\ \ \ \ \fBptr\fP \fIhost\fP \fIname\fP [\fIttl\fP] [\fBnoauth\fP] +.TP +\fBadd\fP\ \ \ \ \fBcname\fP \fIhost\fP \fIname\fP [\fIttl\fP] [\fBnoauth\fP] +.TP +\fBadd\fP\ \ \ \ \fBmx\fP \fIhost\fP \fIname\fP \fIpref\fP [\fIttl\fP] [\fBnoauth\fP] + +Add a record of the given type to the pdnsd cache, replacing existing +records for the same name and type. The 2nd argument corresponds +to the value of the option in the rr section that is named like +the first argument. The addr argument may be a list of IP addresses, +separated by commas or white space. +The ttl is optional, the default is 900 seconds. +\fBnoauth\fP is used to make the domains non-authoritative +(this is similar to setting authrec=off in the config file, +please consult the +.BR pdnsd.conf (5) +man page for what that means). +If you want no other record than the newly added in the cache, do +\fBpdnsd\-ctl\fP\ \fBrecord\fP\ \fIname\fP\ \fBdelete\fP +before adding records. +.TP +\fBneg\fP\ \ \ \ \fIname\fP [\fItype\fP] [\fIttl\fP] + +Add a negatively cached record to pdnsd's cache, replacing existing +records for the same name and type. If no type is given, the whole +domain is cached negatively. For negatively cached records, errors are +immediately returned on a query, without querying other servers first. +The ttl is optional, the default is 900 seconds. +.TP +\fBconfig\fP\ \fIfilename\fP + +Reload pdnsd's configuration file. +.br +The config file must be owned by the uid that pdnsd had when it was started, +and be readable by pdnsd's run_as uid. +If no file name is specified, the config file used at start-up is reloaded. +Note that some configuration changes, like the port or IP address pdnsd listens on, +cannot be made this way and you will receive an error message. +In these cases, you will have to restart pdnsd instead. +.TP +\fBinclude\fP\ \fIfilename\fP + +Parse an include file. +.br +The include file may contain the same +type of sections as a config file, expect for global and server +sections, which are not allowed. This command can be used to add data +to the cache without reconfiguring pdnsd. +.TP +\fBeval\fP\ \ \ \fIstring\fP + +Parse a string as if part of an include file. +.br +The string should hold one or more complete configuration sections, +but no global and server sections, which are not allowed. +If multiple strings are given, they will be joined using newline chars +and parsed together. +.TP +\fBempty\-cache\fP\ [[+|-]\fIname\fP ...] + +Delete all entries in the cache matching include/exclude rules. +.br +If no arguments are provided, the cache is completely emptied, +freeing all existing entries. +Note that this also removes local records, as defined by the config file. +To restore local records, run "pdnsd-ctl\ config" immediately afterwards. +.br +If one or more arguments are provided, these are interpreted as +include/exclude names. If an argument starts with a '+' the name is to +be included. If an argument starts with a '-' it is to be excluded. +If an argument does not begin with '+' or '-', a '+' is assumed. +If the domain name of a cache entry ends in one of the names in the +list, the first match will determine what happens. If the matching name +is to be included, the cache entry is deleted, otherwise it remains. +If there are no matches, the default action is not to delete. +.TP +\fBdump\fP\ \ \ [\fIname\fP] + +Print information stored in the cache about \fIname\fP. +If \fIname\fP begins with a dot and is not the root domain, information +about the names in the cache ending in \fIname\fP (including \fIname\fP without +the leading dot) will be printed. +If \fIname\fP is not specified, information about all the names in the cache +will be printed. +.TP +\fBlist\-rrtypes\fP [no arguments] + +List available rr types for the neg command. Note that those are only +used for the neg command, not for add! +.SH "BUGS" +.PP +If you pipe the output of \fBdump\fP command through an application that +reads only part of the output and then blocks (such as more or less), +pdnsd threads trying to add new entries to the cache will be suspended +until the pipe is closed. +It is preferable to capture the output in a file in such a case. +.br +Report any remaining bugs to the authors. +.SH "AUTHORS" +.PP +Thomas Moestl +.UR + +.UE +.br +Paul A. Rombouts +.UR + +.UE +(for versions 1.1.8b1\-par and later) +.PP +Last revised: 04 Sep 2008 by Paul A. Rombouts. +.SH "SEE ALSO" +.PP +.BR pdnsd (8), +.BR pdnsd.conf (5) diff --git a/jni/pdnsd/doc/pdnsd.8.in b/jni/pdnsd/doc/pdnsd.8.in new file mode 100644 index 00000000..ba4330af --- /dev/null +++ b/jni/pdnsd/doc/pdnsd.8.in @@ -0,0 +1,326 @@ +.TH PDNSD 8 "Jul 2007" "pdnsd @fullversion@" "System Administration Commands" + +.SH NAME +\fBpdnsd\fP \- dns proxy daemon + +.SH SYNOPSIS + +\fBpdnsd\fP [\-h] [\-V] [\-s] [\-d] [\-g] [\-t] [\-p \fIfile\fR] [\-v\fIn\fR] [\-m\fIxx\fR] [\-c \fIfile\fR] [\-4] [\-6] [\-a] +.PP +This man page is an extract of the documentation of \fBpdnsd\fP. +For complete, current documentation, refer to the HTML (or plain text) +documentation (which you can find in the \fBdoc/\fP subdirectory of the +source or in a standard documentation directory, typically +\fB/usr/share/doc/pdnsd/\fP if you are using a binary package). + +.SH DESCRIPTION +.PP +\fBpdnsd\fP is a IPv6 capable proxy domain name server (DNS) which +saves the contents of its DNS cache to the disk on exit. + +.SH OPTIONS + +.RS +.TP +.B \-4 +enables IPv4 support. IPv6 support is automatically +disabled (should it be available). On by default. +.TP +.B \-6 +enables IPv6 support. IPv4 support is automatically +disabled (should it be available). Off by default. +.TP +.B \-a +With this option, pdnsd will try to detect automatically if +the system supports IPv6, and fall back to IPv4 otherwise. +.TP +.BR \-V " or " \-\-version +Print version information and exit. +.TP +\fB\-c\fP \fIFILE\fP or \fB\-\-config\-file=\fP\fIFILE\fP +specifies that configuration is to be read from \fIFILE\fP. +Default is \fB@sysconfdir@/pdnsd.conf\fP. +.TP +.BR \-d " or " \-\-daemon +Start \fBpdnsd\fP in daemon mode (as a background process). +.TP +.BR \-g " or " \-\-debug +Print some debug messages on the console or to the file +\fBpdnsd.debug\fP in your cache directory (in daemon mode). +.TP +.BR \-h " or " \-\-help +Print an option summary and exit. +.TP +\fB\-i\fP \fIPREFIX\fP or \fB\-\-ipv4_6_prefix=\fP\fIPREFIX\fP +specifies the prefix pdnsd uses (when running in IPv6 mode) to map IPv4 +addresses in the configuration file to IPv6 addresses. Must be a valid IPv6 +address. Default is ::ffff:0.0.0.0 +.TP +.B \-p \fIFILE\fP +writes the pid the server runs as to the specified filename. Works +only in daemon mode. +.TP +.B \-\-pdnsd\-user +Print the user \fBpdnsd\fP will run as and exit. +.TP +.BR \-s " or " \-\-status +enables the status control socket. Either this option should be passed +to the command line or \fBstatus_ctl=on;\fP should be specified in the +config file if you want to use +.BR pdnsd\-ctl (8) +to control \fBpdnsd\fP at runtime. +.TP +.BR \-t " or " \-\-tcp +enables the TCP server thread. \fBpdnsd\fP will then serve TCP and UDP +queries. +.TP +.BI \-v n +sets the verbosity of \fBpdnsd\fP. \fIn\fP is a numeric argument +between 0 (normal operation) to 3 (many messages for debugging). +.TP +.BI \-m xx +sets the query method \fBpdnsd\fP +uses. Possible values for \fIxx\fP are: +.IP +.B uo +\- pdnsd will use UDP only. This is the fastest method, and should +be supported by all name servers on the Internet. + +.IP +.B to +\- pdnsd will use TCP only. TCP queries usually take more time than +UDP queries, but are more secure against certain attacks, where an +attacker tries to guess your query id and to send forged answers. TCP +queries are not supported by some name servers. + +.IP +.B tu +\- pdnsd will try to use TCP, and will fall back to UDP if its +connection is refused or times out. + +.IP +.B ut +\- pdnsd will try to use UDP, and will repeat the query using TCP +if the UDP reply was truncated (i.e. the tc bit is set). +This is the behaviour recommended by the DNS standards. + +.PP +Additionally, "no" can be prepended to the \-\-status, \-\-daemon, \-\-debug +and \-\-tcp options (e.g. \-\-notcp) to reverse their effect. +.RE + +.SH USAGE +.PP +\fBpdnsd\fP is usually run from a startup script. For \fBpdnsd\fP to +work, You need to:- + +.IP +1. Tell your system to use \fBpdnsd\fP as the primary DNS server by +modifying \fB/etc/resolv.conf\fP. + +.IP +2. Tell \fBpdnsd\fP to use an authentic source for DNS records, by +including the IP addresses of one or more DNS servers, usually your +ISP's DNS servers, in \fB@sysconfdir@/pdnsd.conf\fP. +.PP +For this, put the following line in your \fB/etc/resolv.conf\fP +.PP +.RS +nameserver 127.0.0.X +.RE +.PP +where X can be any number. (I use 3). Comment out all other +entries. You should put the same value in the server_ip= line in +\fBglobal\fP section of \fB@sysconfdir@/pdnsd.conf\fP. +.br +If you want to use \fBpdnsd\fP as the DNS server for a small local network, +you should use the IP address or name of the interface connected to +this network instead of 127.0.0.X. +.RE + +.PP +To tell \fBpdnsd\fP where to get DNS information from, add the +following lines in \fB@sysconfdir@/pdnsd.conf\fP:- + +.PP +.RS +server { +.br + label= "myisp"; + ip=123.456.789.001,123.456.789.002; + proxy_only=on; + timeout=10; +.br +} +.RE +.PP +Note the opening and closing braces. Add more such \fBserver\fP +sections for each set of DNS servers you want \fBpdnsd\fP to query. +Of course the configuration options shown here are just examples. +More examples can be found in \fB@sysconfdir@/pdnsd.conf.sample\fP +or the pdnsd.conf in the documentation directory. +See the +.BR pdnsd.conf (5) +man page for all the possible options and their exact meaning. +.PP +If you use a dial up connection, remember that ppp scripts usually +replace \fB/etc/resolv.conf\fP when connection with the ISP is +established. You need to configure ppp (or whatever you use to +establish a connection) so that \fB/etc/resolv.conf\fP is not replaced +every time a connection is established. Read the documentation for the +scripts run when your network comes up. +.PP +If you use pppconfig, specify `none' in the `nameservers' option in +the `advanced' tab. If you use multiple ISPs, you should do this for +each connection/account. +.PP +If you use multiple ISPs, you should tell \fBpdnsd\fP which DNS servers +have become available by calling \fBpdnsd\-ctl\fP, the \fBpdnsd\fP +control utility, in a script (e.g. \fB/etc/ppp/ip\-up\fP when you use pppd) +that is run when the connection is established. +If the addresses of the DNS servers are obtained through some type of +dynamic configuration protocol (e.g. pppd with the usepeerdns +option or a DHCP client), you can pass the DNS server addresses as an extra +argument to \fBpdnsd\-ctl\fP to configure \fBpdnsd\fP at run time. +See the +.BR pdnsd\-ctl (8) +man page for details. + +.SH FILES + +\fB@sysconfdir@/pdnsd.conf\fP is the pdnsd configuration file. +The file format and configuration options are described in the +.BR pdnsd.conf (5) +man page. You can find examples of almost all options in +\fB@sysconfdir@/pdnsd.conf.sample\fP. +.PP +\fB@cachedir@/pdnsd.cache\fP +.PP +\fB@cachedir@/pdnsd.status\fP is the status control socket, which must be +enabled before you can use \fBpdnsd\-ctl\fP. +.PP +\fB/etc/init.d/pdnsd\fP (the name and location of the start-up script +may be different depending on your distribution.) +.PP +\fB/etc/resolv.conf\fP +.PP +\fB/etc/defaults/pdnsd\fP contains additional parameters or options +which may be passed to pdnsd at boot time. This saves the hassle of +fiddling with initscripts (not available on all distributions). + +.SH BUGS +.PP +The verbosity option +.BI -v n +presently does not seem to have much effect on the amount of debug output. +.br +Report any remaining bugs to the authors. + +.SH CONFORMING TO +.PP +\fBpdnsd\fP should comply with RFCs 1034 and 1035. As of version +1.0.0, RFC compliance has been improved and pdnsd is now believed (or +hoped?) to be fully RFC compatible. It completely follows RFC 2181 +(except for one minor issue in the FreeBSD port, see the +documentation). +.PP +It does \fINOT\fP support the following features, of which most are +marked optional, experimental or obsolete in these RFCs: + + +.IP +\(bu Inverse queries +.IP +\(bu Status queries +.IP +\(bu Completion queries +.IP +\(bu Namespaces other than IN (Internet) +.IP +\(bu AXFR and IXFR queries (whole zone transfers); since pdnsd does not maintain zones, that should not violate the standard + +.PP +The following record types, that are extensions to the original DNS +standard, are supported if given as options at compile time. (if you +do not need them, you do not need to compile support for them into +pdnsd and save cache and executable space): + +.IP +\(bu RP (responsible person, RFC 1183) +.IP +\(bu AFSDB (AFS database location, RFC 1183) +.IP +\(bu X25 (X25 address, RFC 1183) +.IP +\(bu ISDN (ISDN number/address, RFC 1183) +.IP +\(bu RT (route through, RFC 1183) +.IP +\(bu NSAP (Network Service Access Protocol address , RFC 1348) +.IP +\(bu PX (X.400/RFC822 mapping information, RFC 1995) +.IP +\(bu GPOS (geographic position, deprecated) +.IP +\(bu AAAA (IPv6 address, RFC 1886) +.IP +\(bu LOC (location, RFC 1876) +.IP +\(bu EID (Nimrod EID) +.IP +\(bu NIMLOC (Nimrod locator) +.IP +\(bu SRV (service record, RFC 2782) +.IP +\(bu ATMA (ATM address) +.IP +\(bu NAPTR (URI mapping, RFC 2168) +.IP +\(bu KX (key exchange, RFC 2230) + +.SH SEE ALSO +.PP +.BR pdnsd\-ctl (8), +.BR pdnsd.conf (5), +.BR pppconfig (8), +.BR resolv.conf (5) +.PP +More documentation is available in the \fBdoc/\fP subdirectory of the source, +or in \fB/usr/share/doc/pdnsd/\fP if you are using a binary package. + +.SH AUTHORS + +\fBpdnsd\fP was originally written by Thomas Moestl, +.UR +, +.UE +and was extensively revised by Paul A. Rombouts +.UR + +.UE +(for versions 1.1.8b1\-par and later). +.PP +Several others have contributed to \fBpdnsd\fP; see files in the +source or \fB/usr/share/doc/pdnsd/\fP directory. +.PP +This man page was written by Mahesh T. Pai +.UR + +.UE +using the documents in \fB/usr/share/docs/pdnsd/\fP directory for Debian, +but can be used on other distributions too. +.PP +Last revised: 22 Jul 2007 by Paul A. Rombouts. + +.SH COPYRIGHT + +.PP +This man page is a part of the pdnsd package, and may be distributed +in original or modified form under terms of the GNU General Public +License, as published by the Free Software Foundation; either version +3, or (at your option) any later version. + +.PP +You can find a copy of the GNU GPL in the file \fBCOPYING\fP in the source +or the \fB/usr/share/common\-licenses/\fP directory if you are using a +Debian system. diff --git a/jni/pdnsd/doc/pdnsd.conf.5.in b/jni/pdnsd/doc/pdnsd.conf.5.in new file mode 100644 index 00000000..801b5350 --- /dev/null +++ b/jni/pdnsd/doc/pdnsd.conf.5.in @@ -0,0 +1,1328 @@ +.\" Generated automatically from the html documentation by html2confman.pl +.\" +.\" Manpage for pdnsd.conf (pdnsd configuration file) +.\" +.\" Copyright (C) 2000, 2001 Thomas Moestl +.\" Copyright (C) 2003, 2004, 2005, 2006, 2007 Paul A. Rombouts +.\" +.\" This manual is a part of the pdnsd package, and may be distributed in +.\" original or modified form under terms of the GNU General Public +.\" License, as published by the Free Software Foundation; either version +.\" 3, or (at your option) any later version. +.\" You can find a copy of the GNU GPL in the file COPYING in the source +.\" or documentation directory. +.\" +.TH PDNSD.CONF 5 "Apr 2012" "pdnsd @fullversion@" +.SH NAME +pdnsd.conf \- The configuration file for pdnsd +.hw config +.SH DESCRIPTION +.PP +This manual page describes the layout of the +.BR pdnsd (8) +configuration file and the available configuration options. +The default location of the file is @sysconfdir@/pdnsd.conf. This may be changed +with the \fB-c\fP command line option. +An example pdnsd.conf comes with the pdnsd distribution in the documentation directory +or in @sysconfdir@/pdnsd.conf.sample. +.SH "FILE FORMAT" +.PP +The configuration file is divided into sections. Each section is prefixed with +the section name and opening curlies ({) and closed with closing curlies (}). +In each section, configuration options can be given in the form + +\fIoption_name\fP=\fIoption_value\fP; + +Option value may be a string literal, a number, a time specification or a constant. +In previous versions of pdnsd strings had to be enclosed +in quotes ("), but since version 1.1.10 this is no longer necessary, unless +a string contains a special character such as whitespace, a token that normally starts +a comment, or one of ",;{}\". +Since version 1.2.9 a backslash (\) inside a string is interpreted as an escape character, +so it is possible to include special characters in strings (both quoted or unquoted) +by preceding them with a backslash. Some escape sequences are in interpreted as in the C +programming language, e.g. \t becomes a tab, +\n becomes a new-line control char. +.br +A time specification consists a sequence of digits followed by a one-letter suffix. +The following suffixes are recognized: +s (seconds), m (minutes), h (hours), +d (days) and w (weeks). +If the suffix is missing, seconds are assumed. +If several time specifications are concatenated, their values are added together; +e.g. 2h30m is interpreted as 2*60*60 + 30*60 = 9000 seconds. +.br +Some options take more than one value; in this case, the values are separated with commas. +.br +If you may supply one of a set of possible values to an option, this is noted +in the documentation as +(option1|option2|option3|...) +.br +The constants true|false and yes|no +are accepted as synonyms for the constants on|off. +.br +Comments may be enclosed in /* and */, nested comments are possible. If the +# sign or two slashes (//) appear in the configuration file, everything from +these signs to the end of the current line is regarded as a comment and ignored. +.br +There are examples for nearly all options in the sample config file. + +.SS global Section +The global section specifies parameters that affect the overall behaviour of the +server. If you specify multiple global sections, the settings of those later in +the file will overwrite the earlier given values. +.br +These are the possible options: + +.TP +.B perm_cache=(\fInumber\fP|off); +Switch the disk cache off or supply a maximum cache size in kB. If the disk +cache is switched off, 8 bytes will still be written to disk. +The memory cache is always 10kB larger than the file cache. +This value is 2048 (2 MB) by default. +.TP +.B cache_dir=\fIstring\fP; +Set the directory you want to keep the cache in. +The default is "@cachedir@" +(unless pdnsd was compiled with a different default). +.TP +.B server_port=\fInumber\fP; +Set the server port. This is especially useful when you want to start the +server and are not root. Note that you may also not specify uptest=ping in +the server section as non-root. +.br +The default port is 53, the RFC-standard one. Note that you should only use +non-standard ports when you only need clients on your machine to communicate +with the server; others will probably fail if the try to contact the server +on the basis of an NS record, since the A record that supplies the address for +(among others) name servers does not have a port number specification. +.TP +.B server_ip=\fIstring\fP; +or +.PD 0 +.TP +.PD +.B interface=\fIstring\fP; +Set the IP address pdnsd listens on for requests. This can be useful +when the host has several interfaces and you want pdnsd not to listen on +all interfaces. For example, it is possible to bind pdnsd to listen on +127.0.0.2 to allow pdnsd to be a forwarder for BIND. +The default setting for this option is server_ip=any, which means that +pdnsd will listen on all of your local interfaces. +Presently you can only specify one address here; if you want pdnsd to listen on multiple +interfaces but not all you will have to specify server_ip=any +and use firewall rules to restrict access. +.br +The IP address used to need quotation marks around it, but since version 1.1.10 +this is no longer necessary. +.br +If pdnsd has been compiled with both IPv4 and IPv6 support, and you want to +specify an IPv6 address here, then unless pdnsd was compiled to start up in IPv6 mode +by default, you will need to use the \-6 command-line option or +set run_ipv4=off first (see below) in order to ensure that the +IPv6 address is parsed correctly. +.br +If pdnsd is running in IPv6 mode and you specify an IPv4 address here, +it will automatically be mapped to an IPv6 address. +.br +\fINew in version 1.2:\fP You may also give the name of an interface +such as "lo" or "eth0" here, instead of an IP address +(this has been tested on Linux, and may or may not work on other platforms). +pdnsd will not bind to the interface name, but will look up the address of the +interface at start-up and listen on that address. If the address of the interface +changes while pdnsd is running, pdnsd will not notice that. You will need to +restart pdnsd in that case. +.TP +.B outgoing_ip=\fIstring\fP; +or +.PD 0 +.TP +.PD +.B outside_interface=\fIstring\fP; +\fINew in version 1.2.9:\fP +Set the IP address of the interface used by pdnsd for outgoing queries. +This can be useful when the host has several interfaces and you want pdnsd +to send outgoing queries via only one of them. +For example, if pdnsd is running on a host with one interface with IP address +192.168.1.1 connected to the local network, and another with IP address 123.xxx.yyy.zzz +connected to the internet, you may specify server_ip=192.168.1.1 +and outgoing_ip=123.xxx.yyy.zzz to enforce that pdnsd only responds +to queries received from the local network, and only sends outgoing queries via +the interface connected to the internet. +.br +The default setting for this option is any, which means that +the kernel is free to decide which interface to use. +Like with the server_ip option, you may also give the name of an +interface here, instead of an IP address. +.TP +.B linkdown_kluge=(on|off); +This option enables a kluge that some people might need: when all servers are +marked down, with this option set the cache is not even used when a query is +received, and a DNS error is returned in any case. The only exception from this +is that local records (as specified in rr and source +sections are still served normally. +In general, you probably want to get cached entries even when the network is down, +so this defaults to off. +.TP +.B max_ttl=\fItimespec\fP; +This option sets the maximum time a record is held in cache. All dns +resource records have a time to live field that says for what period of time the +record may be cached before it needs to be requeried. If this is more than the +value given with max_ttl, this time to live value is set to max_ttl. +This is done to prevent records from being cached an inappropriate long period of time, because +that is almost never a good thing to do. Default is 604800s (one week). +.TP +.B min_ttl=\fItimespec\fP; +This option sets the minimum time a record is held in cache. All dns +resource records have a time to live field that says for what period of time the +record may be cached before it needs to be requeried. If this is less than the +value given with min_ttl, this time to live value is set to min_ttl. +Default is 120 seconds. +.TP +.B neg_ttl=\fItimespec\fP; +This option sets the time that negatively cached records will remain valid in the +cache if no time to live can be determined. This is always the case when whole +domains are being cached negatively, and additionally when record types are cached +negatively for a domain for which no SOA record is known to pdnsd. If a SOA is present, +the ttl of the SOA is taken. +.TP +.B neg_rrs_pol=(on|off|auth|default); +This sets the RR set policy for negative caching; this tells pdnsd under which circumstances +it should cache a record type negatively for a certain domain. off will +turn the negative caching of record types off, on will always add a negative +cache entry when a name server did not return a record type we asked it for, and auth +will only add such entries if the answer came from an authoritative name server for that +domain. +.br +\fINew in version 1.2.8:\fP The default setting will add a negatively cached record +if either the answer was authoritive or the answer indicated the name server had "recursion available" +while the query explicitly requested such recursion. +.br +The preset is "default" (used to be auth). +.TP +.B neg_domain_pol=(on|off|auth); +This is analogue to neg_rrs_pol for whole domain negative caching. It should be safe +to set this on, because I have not seen a caching server that will falsely claim that a +domain does not exist. +.br +The default is auth. +.TP +.B run_as=\fIstring\fP; +This option allows you to let pdnsd change its user and group id after operations that needed +privileges have been done. This helps minimize security risks and is therefore recommended. The +supplied string gives a user name whose user id and primary group id are taken. +.br +A little more details: after reading the config file, becoming a daemon (if specified) and starting +the server status thread, the main thread changes its gid and uid, as do all newly created threads +thereafter. By taking another uid and gid, those threads run with the privileges of the +specified user. +Under Linux and FreeBSD, the server status thread runs with the original privileges only when the strict_setuid option +is set to off (see below, on by default), because these may be needed +for exec uptests. The manager thread also retains its original privileges in this case. +You should take care that the user you specify has write permissions on your cache file and +status pipe (if you need a status pipe). You should look out for error messages like "permission denied" +and "operation not permitted" to discover permission problems. +.br +.TP +.B strict_setuid=(on|off); +When used together with the run_as option, this option lets you specify that all threads of the +program will run with the privileges of the run_as user. This provides higher security than +the normal run_as +option, but is not always possible. See the run_as option for further discussion. +.br +This option is on by default. +.br +Note that this option has no effect on Non-Linux systems. +.TP +.B paranoid=(on|off); +Normally, pdnsd queries all servers in recursive mode (i.e. instructs servers to query other servers themselves +if possible, +and to give back answers for domains that may not be in its authority), and accepts additional records with information +for servers that are not in the authority of the queried server. This opens the possibility of so-called cache poisoning: +a malicious attacker might set up a dns server that, when queried, returns forged additional records. This way, he might +replace trusted servers with his own ones by making your dns server return bad IP addresses. This option protects +you from cache poisoning by rejecting additional records +that do not describe domains in the queried servers authority space and not doing recursive queries any more. +An exception +to this rule are the servers you specify in your config file, which are trusted. +.br +The penalty is a possible performance decrease, in particular, more queries might be necessary for the same +operation. +.br +You should also notice that there may be other similar security problems, which are essentially problems of +the DNS, i.e. +any "traditional" server has them (the DNS security extensions solve these problems, but are not widely +supported). +One of this vulnerabilities is that an attacker may bombard you with forged answers in hopes that one may match a +query +you have done. If you have done such a query, one in 65536 forged packets will be succesful (i.e. an average packet +count of 32768 is needed for that attack). pdnsd can use TCP for queries, +which has a slightly higher overhead, but is much less vulnerable to such attacks on sane operating systems. Also, pdnsd +chooses random query ids, so that an attacker cannot take a shortcut. If the attacker is able to listen to your network +traffic, this attack is relatively easy, though. +.br +This vulnerability is not pdnsd's fault, and is possible using any conventional +name server (pdnsd is perhaps a little more secured against this type of attacks if you make it use TCP). +.br +The paranoid option is off by default. +.br +.TP +.B ignore_cd=(on|off); +\fINew in version 1.2.8:\fP This option lets you specify that the CD bit of a DNS query will be ignored. +Otherwise pdnsd will reply FORMERR to clients that set this bit in a query. +It is safe to enable this option, as the CD bit refers to 'Checking Disabled' +which means that the client will accept non-authenticated data. +.br +This option is on by default. Turn it off if you want the old behaviour (before version 1.2.8). +.TP +.B scheme_file=\fIstring\fP; +In addition to normal uptests, you may specify that some servers shall only be queried when a certain +pcmcia-cs scheme is active (only under linux). For that, pdnsd needs to know where the file resides that +holds the pcmcia scheme information. Normally, this is either /var/lib/pcmcia/scheme or +/var/state/pcmcia/scheme. +.TP +.B status_ctl=(on|off); +This has the same effect as the \-s command line option: the status control is enabled when +on is specified. +.br +\fIAdded by Paul Rombouts\fP: Note that pdnsd\-ctl allows run-time configuration of pdnsd, +even the IP addesses of the name servers can be changed. If you're not using pdnsd\-ctl and +you want maximum security, you should not enable this option. It is disabled by default. +.TP +.B daemon=(on|off); +This has the same effect as the \-d command line option: the daemon mode is enabled when +on is specified. +.br +Default is off. +.TP +.B tcp_server=(on|off); +tcp_server=on has the same effect as the \-t or \-\-tcp +command-line option: it enables TCP serving. +Similarly, tcp_server=off is like the \-\-notcp command-line option. +.br +Default is on. +.TP +.B pid_file=\fIstring\fP; +This has the same effect as the \-p command line option: you can specify a file that pdnsd +will write its pid into when it starts in daemon mode. +.TP +.B verbosity=\fInumber\fP; +This has the same effect as the \-v command line option: you can set the verbosity of pdnsd's +messages with it. The argument is a number between 0 (few messages) to 3 (most messages). +.TP +.B query_method=(tcp_only|udp_only|tcp_udp|udp_tcp); +This has the same effect as the \-m command line option. +Read the documentation for the command line option on this. +tcp_only corresponds to the to, udp_only to the uo, +tcp_udp to the tu and udp_tcp to the ut +argument of the command line option. +.br +If you use query_method=tcp_udp, it is recommended that you also set the global timeout option to at least twice the longest server timeout. +.TP +.B run_ipv4=(on|off); +This has the same effect as the \-4 or \-6 command line option: +if on is specified, IPv4 support is enabled, and IPv6 support is disabled (if available). +If off is specified, IPv4 will be disabled and IPv6 will be enabled. +For this option to be meaningful, pdnsd needs to be compiled with support for the protocol you choose. +If pdnsd was compiled with both IPv4 and IPv6 support, and you want to include IPv6 addresses +in the configuration file, you will probably need to specify run_ipv4=off first to +ensure that the IPv6 addresses are parsed correctly. +.TP +.B debug=(on|off); +This has the same effect as the \-g command line option: the debugging messages are enabled when +on is specified. +.TP +.B ctl_perms=\fInumber\fP; +This option allows you to set the file permissions that the pdnsd status control socket will have. These +are the same as file permissions. The owner of the file will be the run_as user, or, if none is specified, +the user who started pdnsd. If you want to specify the permissions in octal (as usual), don't forget +the leading zero (0600 instead of 600!). To use the status control, write access is needed. The default +is 0600 (only the owner may read or write). +.br +Please note that the socket is kept in the cache directory, and that the cache directory permissions +might also need to be adjusted. Please ensure that the cache directory is not writeable for untrusted +users. +.TP +.B proc_limit=\fInumber\fP; +With this option, you can set a limit on the pdnsd threads that will be active simultaneously. If +this number is exceeded, queries are queued and may be delayed some time. +See also the procq_limit option. +.br +The default for this option is 40. +.TP +.B procq_limit=\fInumber\fP; +When the query thread limit proc_limit is exceeded, connection attempts to pdnsd will be queued. +With this option, you can set the maximum queue length. +If this length is also exceeded, the incoming queries will be dropped. +That means that tcp connections will be closed and udp queries will just be dropped, which +will probably cause the querying resolver to wait for an answer until it times out. +.br +See also the proc_limit option. A maximum of proc_limit+procq_limit +query threads will exist at any one time (plus 3 to 6 threads that will always +be present depending on your configuration). +.br +The default for this option is 60. +.TP +.B tcp_qtimeout=\fItimespec\fP; +This option sets a timeout for tcp queries. If no full query has been received on a tcp connection +after that time has passed, the connection will be closed. The default is set using the +\-\-with\-tcp\-qtimeout option to configure. +.TP +.B par_queries=\fInumber\fP; +This option used to set the maximum number of remote servers that would be queried simultaneously, +for every query that pdnsd receives. +.br +Since version 1.1.11, the meaning of this option has changed slightly. +It is now the increment with which the number of parallel queries is +increased when the previous set of servers has timed out. +For example, if we have a list \fIserver1, server2, server3,\fP etc. of available servers +and par_queries=2, then pdnsd will first send queries to \fIserver1\fP and \fIserver2\fP, +and listen for responses from these servers. +.br +If these servers do not send a reply within their timeout period, pdnsd will send additional +queries to \fIserver3\fP and \fIserver4\fP, and listen for responses from +\fIserver1, server2, server3\fP and \fIserver4\fP, and so on until a useful reply is +received or the list is exhausted. +.br +In the worst case there will be pending queries to all the servers in the list of available servers. +We may be using more system resources this way (but only if the first servers in the list +are slow or unresponsive), but the advantage is that we have a greater chance of catching a reply. +After all, if we wait longer anyway, why not for more servers. +.br +See also the explanation of the global timeout option below. +.br +1 or 2 are good values for this option. +The default is set at compile time using the \-\-with\-par\-queries option to configure. +.TP +.B timeout=\fItimespec\fP; +This is the global timeout parameter for dns queries. +This specifies the minimum period of time pdnsd will wait after sending the +first query to a remote server before giving up without having +received a reply. The timeout options in the configuration file are +now only minimum timeout intervals. Setting the global timeout option +makes it possible to specify quite short timeout intervals in the +server sections (see below). This will have the effect that pdnsd will start +querying additional servers fairly quickly if the first servers are +slow to respond (but will still continue to listen for responses from +the first ones). This may allow pdnsd to get an answer more quickly in +certain situations. +.br +If you use query_method=tcp_udp it is recommended that +you make the global timeout at least twice as large as the largest +server timeout, otherwise pdnsd may not have time to try a UDP query +if a TCP connection times out. +.br +Default value is 0. +.TP +.B randomize_recs=(on|off); +If this option is turned on, pdnsd will randomly reorder the cached records of one type +when creating an answer. This supports round-robin DNS schemes and increases fail +safety for hosts with multiple IP addresses, so this is usually a good idea. +.br +On by default. +.TP +.B query_port_start=(\fInumber\fP|none); +If a number is given, this defines the start of the port range used for queries of pdnsd. The +value given must be >= 1024. The purpose of this option is to aid certain firewall +configurations that are based on the source port. Please keep in mind that another application +may bind a port in that range, so a stateful firewall using target port and/or process uid may +be more effective. In case a query start port is given pdnsd uses this port as the first port of a +specified port range (see query_port_end) used for queries. +pdnsd will try to randomly select a free port from this range as local port for the query. +.br +To ensure that there are enough ports for pdnsd to use, the range between query_port_start and +query_port_end should be adjusted to at least (par_queries * proc_limit). +A larger range is highly recommended for security reasons, and also because other applications may +allocate ports in that range. If possible, this range should be kept out of the space +that other applications usually use. +.br +The default for this option is 1024. Together with the default value of query_port_end, +this makes it the hardest for an attacker to guess the source port used by the pdnsd resolver. +If you specify none here, pdnsd will let the kernel choose the source port, but +this may leave pdnsd more vulnerable to an attack. +.TP +.B query_port_end=\fInumber\fP; +Used if query_port_start is not none. Defines the last port of the range started by query_port_start +used for querys by pdnsd. The default is 65535, which is also the maximum legal value for this option. +For details see the description of query_port_start. +.TP +.B delegation_only=\fIstring\fP; +\fIAdded by Paul Rombouts\fP: This option specifies a "delegation-only" zone. +This means that if pdnsd receives a query for a name that is in a +subdomain of a "delegation-only" zone but the remote name server +returns an answer with an authority section lacking any NS RRs for +subdomains of that zone, pdnsd will answer NXDOMAIN (unknown domain). +This feature can be used for undoing the undesired effects of DNS +"wildcards". Several "delegation-only" zones may be specified together. +If you specify root servers in a server section it is +important that you set root_server=on in such a section. +.br +Example: + +delegation_only="com","net"; + +This feature is off by default. It is recommended that you only use +this feature if you actually need it, because there is a risk that +some legitimate names will be blocked, especially if the remote +name servers queried by pdnsd return answers with empty authority +sections. +.TP +.B ipv4_6_prefix=\fIstring\fP; +This option has the same effect as the \-i command-line option. +When pdnsd runs in IPv6 mode, this option specifies the prefix pdnsd uses to convert IPv4 addresses in +the configuration file (or addresses specified with pdnsd\-ctl) +to IPv6-mapped addresses. +The string must be a valid IPv6 address. Only the first 96 bits are used. +Note that this only effects the parsing of IPv4 addresses listed after this option. +.br +The default is "::ffff.0.0.0.0". +.TP +.B use_nss=(on|off); +If this option is turned on, pdnsd will call initgroups() to set up the group access list, +whenever pdnsd changes its user and group id (see run_as option). +There is a possible snag, though, if initgroups() uses NSS (Name Service Switch) and +NSS in turn uses DNS. In such a case you may experience lengthy timeouts and stalls. +By setting use_nss=off, you can disable the initgroups() call +(only possible in versions 1.2.5 and later). +.br +This option was contributed by Jan-Marek Glogowski. +.br +On by default. +.TP +.B udpbufsize=\fInumber\fP; +\fINew in version 1.2.9:\fP +This option sets the upper limit on the size of UDP DNS messages. The default is 1024. +.br +See also the edns_query server option below. + +.SS server Section +Each server section specifies a set of name servers that pdnsd should try to get +resource records or authoritative name server information from. The servers are +queried in the order of their appearance (or parallel to a limited extend). +If one fails, the next one is taken and so on. +.br +You probably want to specify the dns server in your LAN, the caching dns servers +of your internet provider or even a list of root servers in one or more server sections. +.br +The supported options in this section are: + +.TP +.B label=\fIstring\fP; +Specify a label for the server section. This can be used to refer to this section +when using pdnsd\-ctl, the pdnsd control utility. +.br +You can give several server sections the same label, but if you want to change the addresses +of a server section (see \fBip\fP option below) during run-time with +"pdnsd\-ctl\ server\ \fIlabel\fP\ up\ \fIdns1\fP,\fIdns2\fP,...", +the label must be unique. +.TP +.B ip=\fIstring\fP; +Give the IP (the address, \fInot\fP the host name) of the server. +.br +Multiple IP addresses can be given per server section. +This can be done by entering multiple lines of the form ip=\fIstring\fP; +or a single line like this: + +ip=\fIstring\fP,\fIstring\fP,\fIstring\fP; + +IP addresses do not have to be specified in the configuration file. +A server section without IP addresses will remain inactive until it is assigned +one or more addresses with pdnsd\-ctl, +the pdnsd control utility. +.br +If pdnsd has been compiled with both IPv4 and IPv6 support, any IPv6 addresses you specify +here will be skipped with a warning message, unless pdnsd is running in IPv6 mode. +Thus, unless pdnsd was compiled to startup in IPv6 mode by default, you need to use the +command-line option \-6 or set run_ipv4=off +first (see global section) in order to ensure +that IPv6 addresses are parsed correctly. +.br +If pdnsd is running in IPv6 mode and you specify an IPv4 address here, +it will automatically be mapped to an IPv6 address. +.TP +.B file=\fIstring\fP; +\fINew in version 1.2:\fP This option allows you to give the name of a resolv.conf-style file. +Of the lines beginning with the nameserver keyword, the second field will be parsed as an +IP address, as if it were specified with the ip= option. The remaining lines will be ignored. +If the contents of the file changes while pdnsd is running, you can make pdnsd aware of the changes through the +use of pdnsd\-ctl, the pdnsd control utility. +This is usually most conveniently done by placing the command "pdnsd\-ctl\ config" in a script +that is automatically run whenever the DNS configuration changes. +.br +For example, suppose you have a ppp client that writes the DNS configuration for your ISP to the file +/etc/ppp/resolv.conf and runs the script /etc/ppp/ip-up when a new +connection is established. One way of ensuring that pdnsd is automatically reconfigured is to +add a server section in the config file with file=/etc/ppp/resolv.conf and to +add the command "pdnsd\-ctl\ config" to /etc/ppp/ip-up. +.TP +.B port=\fInumber\fP; +Give the port the remote name server listens on. Default is 53 (the official +dns port) +.TP +.B uptest=(ping|none|if|dev|diald|exec|query); +Determine the method to check whether the server is available. Currently +defined methods are: +.IP +\(bu \fBping\fP: Send an ICMP_ECHO request to the server. If it doesn't respond +within the timeout, it is regarded to be unavailable until the next probe. +.IP +\(bu \fBnone\fP: The availability status is not changed, only the time stamp is updated. +.IP +\(bu \fBif\fP: Check whether the interface (specified in the interface= option) is +existent, up and running. This currently works for all "ordinary" +network interfaces, interfaces that disappear when down (e.g. ppp?), +and additionally for Linux isdn interfaces (as of kernel 2.2). Note that +you need a /dev/isdninfo device file (major#45, minor#255), or the +isdn uptest will always fail. +.IP +\(bu \fBdev\fP and \fBdiald\fP: Perform an if uptest, and, if that +was succesful, additionally check whether a program is running that +has locked a given (modem-) device. The needed parameters are an interface (specified as for the if +uptest, e.g. "ppp0") and a device relative to /dev (e.g. +"modem" for /dev/modem specified using the device= option. +pdnsd will then look for a pid file for the given interface in /var/lock (e.g. +/var/run/ppp0.pid) and for a lockfile for the given device (e.g. /var/lock/LCK..modem), +and then test whether the locking process is the process that created the pid file and this process is still +alive. If this is the case, the normal if uptest is executed for the given interface. +.br +The dev option is for pppd dial-on-demand, diald is the same for diald users. +.IP +\(bu \fBexec\fP: Executes a given command in the /bin/sh shell +(as /bin/sh \-c ) +and evaluates the result (the return code of the last command) in the shell's way of handling return codes, +i.e. 0 indicates success, all other indicate failure. The shell's process name will be +uptest_sh. The command is given with the uptest_cmd option (see below). +For secuity issues, also see that entry. +.IP +\(bu \fBquery\fP: \fINew in version 1.2:\fP +This works like the ping test, except it sends an (empty) DNS query to the remote server. +If the server sends a well-formed response back within the timeout period (except SERVFAIL), +it will be regarded as available. +This test is useful if a remote server does not respond to ICMP_ECHO requests at all, +which unfortunately is quite common these days. +It can also happen that a remote server is online but ignores empty DNS queries. +Then you will need the set the query_test_name option (see below). +In many cases this test will be a more reliable indicator of availability +than the ones mentioned before. + +The default value is \fBnone\fP. + +\fBNOTE\fP: If you use on-demand dialing, use none, if, +dev, diald or exec, +since ping or query will send packets +in the specified interval and the interface will thus frequently dial! +.TP +.B ping_timeout=\fInumber\fP; +Sets the timeout for the ping test in tenths of seconds +(this unit is used for legacy reasons; actually the current implementation is +only accurate to a second). +.br +The default is 600 (one minute). +.TP +.B ping_ip=\fIstring\fP; +The IP address for the ping test. The default is the IP of the name server. +.TP +.B query_test_name=\fIstring\fP; +\fINew in version 1.2.9:\fP +Sets the name to be queried when using uptest=query availability test. +If the string is the unquoted constant none, +an empty query is used (this the default), otherwise a query of type A will be +sent for the domain name specified here. It is not necessary for the domain name +to exist or have a record of type A in order for the uptest to succeed. +.br +If the the remote server ignores empty queries, you will probably want to set +query_test_name="." (the root domain). +.TP +.B uptest_cmd=\fIstring\fP,\fIstring\fP; +or +.PD 0 +.TP +.PD +.B uptest_cmd=\fIstring\fP; +Sets the command for the uptest=exec function to the first string. +If the second string is given, it specifies a user with whose user +id and primary group id the command is executed. +.br +This is especially useful if you are executing the server as root, +but do not want the uptest to be performed with root privileges. +In fact, you should never execute the uptest as root if you can help +it. +.br +If the server is running setuid or setgid, the privileges thus gained +are attempted to be dropped even before changing identity to the +specified user to prevent setuid/gid security holes (otherwise, any +user might execute commands as root if you setuid the executable). +.br +\fBNote that this is not always possible, and that pdnsd should never +be installed as setuid or setgid.\fP +The command is executed using /bin/sh, so you should be able to use +shell builtin commands. +.TP +.B interval=(\fItimespec\fP|onquery|ontimeout); +Sets the interval for the server up-test. The default is 900 seconds; +however, a test is forced when a query times out and the timestamp is reset then. +.br +If you specify onquery instead of a timeout, the interface will be +tested before every query. This is to prevent automatically dialing +interfaces (diald/pppd or ippp) to dial on dns queries. It is intended to be +used in connection with an interface-testing uptest ;\-) +.br +Note that using uptest=exec, you might run into performance problems +on slow machines when you use that option. +DON'T use onquery with uptest=ping or +uptest=query, as it may cause delays if the server does not answer +(btw, it doesn't make sense anyway). +Note also that using onquery is no guarantee that the interface +will not be used. When another (reachable) dns server tells pdnsd +to query a third dns server for data, pdnsd will do that and has +no means of checking whether this will dial up the interface or not. +This however should be a rare situation. +.br +\fINew in version 1.2.3:\fP +A third possibility is to specify interval=ontimeout. +In this case the server is not tested at startup/reconfiguration, nor at regular intervals, +but only after a DNS query to a server times out. Certain types of network problems +such as a refused connection will also cause the server to be considered unavailable. +However, once a server is declared dead it is never considered again unless it is revived using a +pdnsd\-ctl config or server command. +The idea behind this option is to minimize uptests by assuming all +servers are available until there is reason to believe otherwise. +.TP +.B interface=\fIstring\fP; +The network interface (or network device, e.g. "eth0") for the uptest=if option. +Must be specified if uptest=if is given. +.TP +.B device=\fIstring\fP; +The (modem-) device that is used for the dev uptest. If you use this for a dial-on-demand +ppp uptest (together with uptest=dev), you need to enter the device you are using for your +pppd here, e.g. modem for /dev/modem. +.br +Must be specified if uptest=dev is given. +.TP +.B timeout=\fItimespec\fP; +Set the timeout for the dns query. The default is 120 seconds. You probably want to set this lower. +.br +Timeouts specified in the configuration file are only treated as the +minimum period of time to wait for a reply. A queries to a remote +server are not canceled until a useful reply has been received, or all +the other queries have timed out or failed. +.br +If you have also set the global timeout option, you may consider setting a fairly small value here. +See the explanation of the timeout option in the global +section for what that means. +.TP +.B purge_cache=(on|off); +In every fetched dns record, there is a cache timeout given, which +specifies how long the fetched data may be cached until it needs to be +reloaded. If purge_cache is set to off, the stale records are not purged +(unless the cache size would be exceeded, in this case the oldest records are purged). +Instead, they are still served if they cannot succesfully be +updated (e.g. because all servers are down). +.br +Default is off. +.TP +.B caching=(on|off); +Specifies if caching shall be performed for this server at all. Default is +on. +.TP +.B lean_query=(on|off); +Specifies whether to use the "lean" query mode. In this mode, only the +information actually queried from pdnsd is resolved and cached. This has +the advantage that usually less cache space is used and the query is +usually faster. In 90% of the cases, only address (A) records are needed +anyway. If switched off, pdnsd will always cache all data about a host +it can find and will specifically ask for all available records +(well, at least it is a good approximation for what it really does ;\-) +This will of course increase the answer packet sizes. +.br +Some buggy name servers may not deliver CNAME records when not asked for +all records. I do not know if such servers are around, but if you have +trouble resolving certain host names, try turning this option off. +.br +A last note: If you use multiple pdnsd's that access each other, turning +this option on is probably a big win. +.br +This on by default. +.TP +.B edns_query=(on|off); +\fINew in version 1.2.9:\fP +Specifies whether to use EDNS (Extension mechanisms for DNS) for outgoing queries. +Currently this is only useful for allowing UDP message sizes larger than 512 bytes. +Note that setting this option on can give problems in combination with some legacy +systems or software, including, embarrassingly enough, previous versions of pdnsd. +.br +The default is off, but if your network can handle UDP payloads +significantly larger than 512 bytes, the recommended value is on. +.br +Note that this option only effects outgoing queries. If pdnsd receives a query using +EDNS, it will reply using EDNS regardless of the value of this option. + +See also the udpbufsize option above. +.TP +.B scheme=\fIstring\fP; +You can specify a pcmcia-cs scheme that is used in addition to the uptests. If you specify +a scheme here, the server this section is for will only be queries if the given scheme +is active. Shell wildcards (* and ?) are allowed in the string under their special +meanings. You need to use the scheme_file option on the global +section to make this option work. +.TP +.B preset=(on|off); +This allows you to specify the initial state of a server before any uptest is performed. +on specifies that the server is regarded available. The default is on. +This is especially useful when you set uptest=none; and want to change +the status of a server only via pdnsd\-ctl. +.TP +.B proxy_only=(on|off); +When this option is set to on, answers given by the servers are always accepted, and no +other servers (as, for example, specified in the NS records of the query domain) are +queried. If you do not turn this option on, pdnsd will do such queries in some cases +(in particular when processing ANY queries). +.br +This option is useful when you do not want pdnsd to make connections to outside servers +for some reasons (e.g. when a firewall is blocking such queries). +.br +I recommend that you turn on lean_query when using this option. +.br +Default is off. +.TP +.B root_server=(on|off|discover); +Set this option to on if the servers specified in a section are root servers. +A root server will typically only give the name servers for the top-level domain in its reply. +Setting root_server=on will cause pdnsd to try to use cached information about +top-level domains to reduce to number of queries to root servers, making the resolving of +new names more efficient. +You can get a list of available root servers by running the command +"dig\ .\ ns". +.br +This option is also necessary if you use the delegation_only option. +.br +\fINew in version 1.2.8:\fP This option may also be set to "discover". +This will cause pdnsd to query the servers provided with the ip= option +to obtain the full list of root servers. The root-server addresses will replace the addresses +specified with the ip= option. +This will only be done once on startup, or after a "pdnsd\-ctl\ config" command. +In this case the name servers specified with the ip= option don't have to be +root servers, they just have to know the names and addresses of the root servers. +After root-server discovery pdnsd will behave just as if root_server=on +had been specified. +.br +Default is off. +.TP +.B randomize_servers=(on|off); +\fINew in version 1.2.6:\fP Set this option to on to give each name server +in this section an equal chance of being queried. If this option is off, the name servers +are always queried starting with the first one specified. Even with this option on, the +query order is not truly random. Only the first server is selected randomly; the following +ones are queried in consecutive order, wrapping around to the beginning of the list when +the end is reached. Note that this option only effects the order within a section. The +servers in the first (active) section are always queried before those in the second one, +etc. +.br + The default is off, but if you are resolving from root servers setting this +option on is highly recommended. If root_server=on this option also effects +the query order of the name servers for the top-level domains. +.TP +.B reject=\fIstring\fP; +\fINew in version 1.2.6:\fP This option can be used to make pdnsd reject replies that +contain certain IP addresses. You can specify a single IP address, which will be matched +exactly, or a range of addresses using an address/mask pair. +The mask can be specified as a simple integer, indicating the number of initial 1 bits in +the mask, or in the usual IP address notation. IP addresses may be either IPv4 or IPv6 +(provided there is sufficient support in the C libraries and support for AAAA records was +not disabled). +When addresses in the reject list are compared with those in a reply, only the bits +corresponding to those set in the netmask are significant, the rest are ignored. +.br +Multiple addresses or address/mask pairs may be specified; this can be done by entering +multiple lines of the form reject=\fIstring\fP; +or a single line like this: + +reject=\fIstring\fP,\fIstring\fP,\fIstring\fP; + +How pdnsd reacts when an address in the reply matches one in the reject list, +depends on the reject_policy option, see below. +.TP +.B reject_policy=(fail|negate); +\fINew in version 1.2.6:\fP +This option determines what pdnsd does when an address in the reply from a name server +matches the reject list (see above). If this option is set to +fail, pdnsd will try another server, or, if there no more servers to try, +return the answer SERVFAIL. If this option is set to negate, pdnsd will +immediately return the answer NXDOMAIN (unknown domain) without querying additional +servers. The fail setting is useful if you don't always trust the servers in +this section, but do trust the servers in the following section. The negate +setting can be used to completely censor certain IP addresses. In this case you should put +the same reject list in every server section, and also set the +reject_recursively option (see below) to true. +.br +The default is fail. +.TP +.B reject_recursively=(on|off); +\fINew in version 1.2.6:\fP Normally pdnsd checks for addresses in the +reject list (see above) only when the reply comes directly from a name server +listed in the configuration file. With this option set to on, pdnsd will +also do this check for name servers that where obtained from NS records in the authority +section of a previous reply (which was incomplete and non-authoritative). +.br +Default is off. +.TP +.B policy=(included|excluded|simple_only|fqdn_only); +pdnsd supports inclusion/exclusion lists for server sections: with include= +and exclude= (see below) you can specify domain names for which this server +will be used or will not be used. The first match counts (i.e., the first include or +exclude rule in a server section that matches a domain name is applied, and the +search for other rules is terminated). If no rule matched a given domain name, +the policy= option determines whether this server is used for the +lookup for that domain name; when included is given, the server will +be asked, and when excluded is given, it will not. +If simple_only is given the server will be used if the name to lookup +is a simple (single-label) domain name, on the other hand if fqdn_only +is given the server will be used only for names consisting of two or more labels +(i.e. the name has at least one dot in-between). +.br +If no server is available for a queried domain, pdnsd will return an error message +to the client that usually will stop the client's attempts to resolve a specific +domain from this server (the libc resolver will e.g. return an error to the application that +tried to resolve the domain if no other servers are available in the resolv.conf). +This may be of use sometimes. +.br +\fINote\fP: the simple_only and fqdn_only constants +were added by Paul Rombouts. +They are useful for controlling which name servers (if any) will be used by +pdnsd for resolving simple (single-label) host names. +fqdn_only used to stand for "fully qualified domain name only", but this is +actually a misnomer. The names in queries received by pdnsd are always considered to be +fully qualified. If you do not exactly understand what the options simple_only and +fqdn_only are good for, you are probably better off not using them. +.br +The default for this option is included. +.TP +.B include=\fIstring\fP; +This option adds an entry to the exclusion/inclusion list. If a domain matches +the name given as string, the server is queried if this was the first matching rule +(see also the entry for policy). +.br +If the given name starts with a dot, the whole subdomain +of the given name including the one of that name is matched, e.g. ".foo.bar." +will match the domain names a.foo.bar., a.b.c.foo.bar. and foo.bar. +.br +If it does not start in a dot, only exactly the given name (ignoring the case, of course) +will be matched (hint: if you want to include all subdomains, but not the domain of the given +name itself, place an exact-match exclude rule before the include rule, e.g: +exclude="foo.bar."; include=".foo.bar."; +.br +Previous versions of pdnsd +required that names given with this and the next option ended in a dot, but since +version 1.1.8b1-par8, pdnsd automatically adds a dot at the end if it +is missing. +.br +pdnsd now also accepts a more compact notation for adding several "include" entries in +one line, e.g.: + +include=".foo",".bar",".my.dom"; + +.TP +.B exclude=\fIstring\fP; +This option adds an entry to the exclusion/inclusion list. If a domain matches +the name given as string, the server is not queried if this was the first matching rule +(see also the entry for policy). +.br +If the given name starts with a dot, the whole subdomain +of the given name including the one of that name is matched, e.g. ".foo.bar." +will match the domain names a.foo.bar., a.b.c.foo.bar. and foo.bar. +.br +If it does not start in a dot, only exactly the given name (ignoring the case, of course) +will be matched (hint: if you want to exclude all subdomains, but not the domain of the given +name itself, place an exact-match include rule before the exclude rule, e.g: +include="foo.bar."; exclude=".foo.bar."; +.br +pdnsd now also accepts a more compact notation for adding several "exclude" entries in +one line, e.g.: + +exclude=".foo",".bar",".my.dom"; + + +.SS rr Section +Every rr section specifies a dns resource record that is stored locally. It +allows you to specify own dns records that are served by pdnsd in a limited way. +Only A, PTR, CNAME, MX, NS and SOA records are implemented. +.br +This option is intended to allow you to define RRs for 1.0.0.127.in-addr.arpa. +and localhost. (and perhaps even one or two hosts) without having to start an +extra named if your cached name servers do not serve those records. +It is \fBNOT\fP intended and not capable to work as a full-featured name server. + +.TP +.B name=\fIstring\fP; +Specifies the name of the resource records, i.e. the domain name of +the resource the record describes. This option must be specified +before any a, ptr, cname, +mx, ns or soa records. +Names are interpreted as absolute domain names +(i.e. pdnsd assumes they end in the root domain). +For this and all following arguments that take domain names, you need to +specify domain names in dotted notation (example venera.isi.edu.). +.br +Previous versions of pdnsd +required that domain names given in the configuration file ended in a +dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a +dot at the end if it is missing. +.br +\fINew in version 1.2:\fP It is also possible to specify a name starting +with the label *. Such a name is called a wildcard. The * in a wildcard +can match one or more labels in a queried name, but only whole labels. +Any other * characters in a wildcard, apart from the leading one, +will only match a literal *. +.br +For example, *.mydomain will match a.mydomain or www.a.mydomain, but not +mydomain. *.a*.mydomain will match www.a*.mydomain, but not www.ab.mydomain. +*a.mydomain will only match itself. +.br +Before you can specify an rr section with name=*.mydomain +you must define some records for mydomain, typically NS and/or SOA records. +Example: +.DS L + + rr { + name = mydomain; + ns = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + rr { + name = *.mydomain; + a = 192.168.1.10; + } +.DE + +In this example, www.mydomain and ftp.mydomain will resolve to the numeric +address 192.168.1.10 (unless you add rr sections explicitly +specifying different addresses for www.mydomain or ftp.mydomain). +If you want mydomain also to resolve to a numeric address, +add an A record to the first rr section. +.TP +.B ttl=\fItimespec\fP; +Specifies the ttl (time to live) for all resource records in this section after this entry. +This may be redefined. The default is 86400 seconds (=1 day). +.TP +.B authrec=(on|off); +If this is turned on, pdnsd will create authoritative local records for this rr section. +This means that pdnsd flags the domain record so that records of this domain that are not +present in the cache are treated as non-existent, i.e. no other servers are queried for +that record type, and an response containing none of those records is returned. This is +most time what people want: if you add an A record for a host, and it has no AAAA record +(thus no IPv6 address), you normally don't want other name servers to be queried for it. +.br +This is on by default. +.br +Please note that this only has an effect if it precedes the name option! +.TP +.B reverse=(on|off); +\fINew in version 1.2:\fP If you want a locally defined name to resolve to a numeric address +and vice versa, you can achieve this by setting reverse=on before defining the A record +(see below). The alternative is to define a separate PTR record, but you will +probably find this option much more convenient. +.br +The default is off. +.TP +.B a=\fIstring\fP; +Defines an A (host address) record. The argument is an IPv4 address in dotted notation. +pdnsd will serve this address for the host name given in the name option. +.br +Provided there is sufficient support in the C libraries and support for AAAA records was not +disabled, the argument string may also be an IPv6 address, in which case an AAAA record +will be defined. +.br +This option be may used multiple times within an rr section, causing +multiple addresses to be defined for the name. However, if you put the different addresses +in different rr sections for the same name, the definition in the last +rr section will cancel the definitions in the previous ones. +.TP +.B ptr=\fIstring\fP; +Defines a PTR (domain name pointer) record. The argument is a host name in +dotted notation (see name). The ptr record is for resolving adresses into names. For example, if +you want the adress 127.0.0.1 to resolve into localhost, and localhost into 127.0.0.1, you need something +like the following sections: +.br +.DS L + + rr { + name = localhost; + a = 127.0.0.1; + owner = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + rr { + name = 1.0.0.127.in-addr.arpa; + ptr = localhost; + owner = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } +.DE + +The second section is for reverse resolving and uses the ptr option. +Note that you can get the same effect by specifying only the first rr section +with reverse=on. +.br +There is something special about the name in the second section: +when a resolver wants to get a host name from an internet address, +it composes an address that is built of the IP address in reverse byte order +(1.0.0.127 instead of 127.0.0.1) where each byte of the adress written +as number constitutes a sub-domain under the domain in-addr.arpa. +.br +So, if you want to compose an adress for reverse resolving, take your ip in dotted notation (e.g. 1.2.3.4), +reverse the byte order (4.3.2.1) and append in-addr.arpa. (4.3.2.1.in-addr.arpa.) +Then, define an rr section giving this address as name and the domain name corresponding to +that ip in the ptr option. +.TP +.B cname=\fIstring\fP; +Defines a CNAME (canonical name) record. +The argument should be a fully-qualified host name in dotted notation (see name). +A CNAME is the DNS equivalent of an alias or symbolic link. +.br +A useful application for CNAMEs is giving short, easy to remember nicknames to hosts with complicated names. +For example, you might want the name "news" to refer to your ISP's news server "nntp2.myisp.com". +Instead of adding an A record for "news" with the same address as "nntp2.myisp.com", you could +put in a CNAME pointing to "nntp2.myisp.com", so that if the IP address of the news server changes, +there is no need to update the record for "news". +.br +To implement this with pdnsd, you could add the following section to your configuration file: +.br +.DS L + + rr { + name = news; + cname = nntp2.myisp.com; + owner = localhost; + } +.DE + +.TP +.B mx=\fIstring\fP,\fInumber\fP; +Defines an MX (mail exchange) record. The string is the host name of the mail server in dotted notation (see name). +The number specifies the preference level. +.br +When you send mail to someone, your mail typically goes from your E-mail client to an SMTP server. +The SMTP server then checks for the MX record of the domain in the E-mail address. +For example, with joe@example.com, it would look for the MX record for example.com and find +that the name of mail server for that domain is, say, mail.example.com. +The SMTP server then gets the A record for mail.example.com, and connects to the mail server. +.br +If there are multiple MX records, the SMTP server will pick one based on the preference level +(starting with the lowest preference number, working its way up). +.br +Don't define MX records with pdnsd unless you know what you're doing. +.TP +.B owner=\fIstring\fP; +or +.PD 0 +.TP +.PD +.B ns=\fIstring\fP; +Defines an NS (name server) record. Specifies the name of the host which should be authoritative for the records +you defined in the rr section. This is typically the host pdnsd runs on. +.br +\fINote:\fP In previous versions of pdnsd this option had to be specified before +any a, ptr, cname, mx or soa entries. +In version 1.2, the restrictions on this option are same as the options just mentioned, +and it must listed after the name= option. +This can be a pain if you want to use an old config file which specifies owner= +before name= (sorry about that). +Apart from greater consistency, the advantage is that you can now specify as many NS records as you like (including zero). +.TP +.B soa=\fIstring\fP,\fIstring\fP,\fInumber\fP,\fItimespec\fP,\fItimespec\fP,\fItimespec\fP,\fItimespec\fP; +This defines a soa (start of authority) record. The first string is the +domain name of the server and should be equal to the name you specified as +owner. +.br +The second string specifies the email address of the maintainer of the name +server. It is also specified as a domain name, so you will have to replace the +@ sign in the name with a dot (.) to get the name you have to specify here. +The next parameter (the first number) is the serial number of the record. You +should increment this number if you change the record. +.br +The 4th parameter is the refresh timeout. It specifies after what amount +of time a caching server should attempt to refresh the cached record. +.br +The 5th parameter specifies a time after which a caching server should attempt +to refresh the record after a refresh failure. +.br +The 6th parameter defines the timeout after which a cached record expires if it +has not been refreshed. +.br +The 7th parameter is the ttl that is specified in every rr and should be the +same as given with the ttl option (if you do not specify a ttl, use the default 86400). +.TP +.B txt=\fIstring\fP,...,\fIstring\fP; +\fINew in version 1.2.9:\fP +Defines an TXT record. You can specify one or more strings here. + +.SS neg Section +Every neg section specifies a dns resource record or a dns domain that should be +cached negatively locally. Queries for negatively cached records are always answered +immediatley with an error or an empty answer without querying other hosts as long +as the record is valid. The records defined with neg sections remain +valid until they are explicitely invalidated or deleted by the user using +pdnsd\-ctl. +.br +This is useful if a certain application asks periodically for nonexisting hosts or +RR types and you do not want a query to go out every time the cached record has +timed out. Example: Netscape Communicator will ask for the servers news and mail +on startup if unconfigured. If you do not have a dns search list for your network, +you can inhibit outgoing queries for these by specifying +.br +.DS L + + neg { + name = news; + types = domain; + } + neg { + name = mail; + types = domain; + } +.DE + +in your config file. If you have a search list, you have to repeat that for any +entry in your search list in addition to the entries given above! +.br +In versions 1.1.11 and later, if you negate whole domains this way, all subdomains +will be negated as well. Thus if you specify +.br +neg {name=example.com; types=domain;} in the +config file, this will also negate www.example.com, xxx.adserver.example.com, etc. + +.TP +.B name=\fIstring\fP; +Specifies the name of the domain for which negative cache entries are created. +This option must be specified before the types option. +Names are interpreted as absolute domain names (i.e. pdnsd +assumes they end in the root domain). +You need to specify domain names in dotted notation (example venera.isi.edu.). +.br +Previous versions of pdnsd +required that domain names given in the configuration file ended in a +dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a +dot at the end if it is missing. +.TP +.B ttl=\fItimespec\fP; +Specifies the ttl (time to live) for all resource records in this section after this entry. +This may be redefined. The default is 86400 seconds (=1 day). +.TP +.B types=(domain|\fIrr_type\fP[,\fIrr_type\fP[,\fIrr_type\fP[,...]]]); +Specifies what is to be cached negatively: domain will cache the whole +domain negatively; alternatively, you can specify a comma-separated list of RR types +which are to be cached negatively. You may specify multiple types options, but +domain and the RR types are mutually exclusive. +.br +The RR types are specified using their official names from the RFC's in capitals, +e.g. A, CNAME, NS, PTR, MX, +AAAA, ... +.br +The command pdnsd\-ctl\ list\-rrtypes will give you a complete list +of those types. pdnsd\-ctl is built along with pdnsd +and will be installed in the same directory as the pdnsd binary during make install. + +.SS source Section +Every source section allows you to let pdnsd read the records from a file in an +/etc/hosts-like format. pdnsd will generate records to resolve the entries +address from its host name and vice versa for every entry in the file. This is +normally easier than defining an rr for every of your addresses, since localhost +and your other FQDNs are normally given in /etc/hosts. +.br +The accepted format is as follows: The #\-sign initiates a comment, the rest of +the line from the first occurence of this character on is ignored. Empty lines +are tolerated. +.br +The first entry on a line (predeceded by an arbitrary number of tabs and spaces) +is the IP in dotted notation, the second entry on one line (separated by the +first by an arbitrary number of tabs and spaces) is the FQDN (fully qualified +domain name) for that ip. The rest of the line is ignored by default (in the original +/etc/hosts, it may contain information not needed by pdnsd). + +.TP +.B owner=\fIstring\fP; +Specifies the name of the host pdnsd runs on and that are specified in dns +answers (specifically, nameserver records). +Must be specified before any file entries. +.br +Names are interpreted as absolute domain names (i.e. pdnsd +assumes they end in the root domain). +You need to specify domain names in dotted notation (example venera.isi.edu.). +.br +Previous versions of pdnsd +required that domain names given in the configuration file ended in a +dot, but since version 1.1.8b1-par8, pdnsd automatically assumes a +dot at the end if it is missing. +.TP +.B ttl=\fItimespec\fP; +Specifies the ttl (time to live) for all resource records in this section after +this entry. This may be redefined. The default is 86400 seconds (=1 day). +.TP +.B file=\fIstring\fP; +The string specifies a file name. For every file entry in a source section, +pdnsd will try to load the given file as described above. Failure is indicated +only when the file cannot be opened, malformed entries will be ignored. +.TP +.B serve_aliases=(on|off); +If this is turned on pdnsd will serve the aliases given in a hosts-style file. +These are the third entry in a line of a hosts-style file, which usually give a "short name" for the host. +This may be used to support broken clients without a proper domain-search option. +If no aliases are given in a line of the file, pdnsd behaves as without this option for this line. +.br +This feature was suggested by Bert Frederiks. +.br +It is off by default. +.TP +.B authrec=(on|off); +If this is turned on, pdnsd will create authoritative local records with the data from the hosts file. +Please see the description of the option of the same name in the rr section for a closer description of +what this means. Please note that this only has an effect for files sourced with file options +subsequent to this option. +.br +This is on by default. + +.SS include Section +A configuration file may include other configuration files. +However, only the top-level configuration file may contain global +and server sections, +thus include files are effectively limited to sections that add local definitions to the cache. +.br +Include sections currently only have one type of option, which may be given multiple times within a single section. + +.TP +.B file=\fIstring\fP; +The string specifies a file name. For every file option in an include section, +pdnsd will parse the given file as described above. The file may contain include sections itself, +but as a precaution pdnsd checks that a certain maximum depth is not exceeded to guard against +the possibility of infinite recursion. + +.SH "VERSION" +.PP +This man page is correct for version @fullversion@ of pdnsd. +.SH "SEE ALSO" +.PP +.BR pdnsd (8), +.BR pdnsd\-ctl (8) +.PP +More documentation is available in the \fBdoc/\fP subdirectory of the source, +or in \fB/usr/share/doc/pdnsd/\fP if you are using a binary package. + +.SH AUTHORS + +\fBpdnsd\fP was originally written by Thomas Moestl +.UR + +.UE +and was extensively revised by Paul A. Rombouts +.UR + +.UE +(for versions 1.1.8b1\-par and later). +.PP +Several others have contributed to \fBpdnsd\fP; see files in the source or +\fB/usr/share/doc/pdnsd/\fP directory. +.PP +This man page was automatically generated from the html documentation for \fBpdnsd\fP, +using a customized Perl script written by Paul A. Rombouts. +.PP +Last revised: 19 April 2012 by Paul A. Rombouts diff --git a/jni/pdnsd/doc/pdnsd.conf.in b/jni/pdnsd/doc/pdnsd.conf.in new file mode 100644 index 00000000..e348eb02 --- /dev/null +++ b/jni/pdnsd/doc/pdnsd.conf.in @@ -0,0 +1,143 @@ +// Sample pdnsd configuration file. Must be customized to obtain a working pdnsd setup! +// Read the pdnsd.conf(5) manpage for an explanation of the options. +// Add or remove '#' in front of options you want to disable or enable, respectively. +// Remove '/*' and '*/' to enable complete sections. + +global { + perm_cache=1024; + cache_dir="@cachedir@"; +# pid_file = /var/run/pdnsd.pid; + run_as="@def_id@"; + server_ip = 127.0.0.1; # Use eth0 here if you want to allow other + # machines on your network to query pdnsd. + status_ctl = on; +# paranoid=on; # This option reduces the chance of cache poisoning + # but may make pdnsd less efficient, unfortunately. + query_method=udp_tcp; + min_ttl=15m; # Retain cached entries at least 15 minutes. + max_ttl=1w; # One week. + timeout=10; # Global timeout option (10 seconds). + neg_domain_pol=on; + udpbufsize=1024; # Upper limit on the size of UDP messages. +} + +# The following section is most appropriate if you have a fixed connection to +# the Internet and an ISP which provides good DNS servers. +server { + label= "myisp"; + ip = 192.168.0.1; # Put your ISP's DNS-server address(es) here. +# proxy_only=on; # Do not query any name servers beside your ISP's. + # This may be necessary if you are behind some + # kind of firewall and cannot receive replies + # from outside name servers. + timeout=4; # Server timeout; this may be much shorter + # that the global timeout option. + uptest=if; # Test if the network interface is active. + interface=eth0; # The name of the interface to check. + interval=10m; # Check every 10 minutes. + purge_cache=off; # Keep stale cache entries in case the ISP's + # DNS servers go offline. + edns_query=yes; # Use EDNS for outgoing queries to allow UDP messages + # larger than 512 bytes. May cause trouble with some + # legacy systems. +# exclude=.thepiratebay.org, # If your ISP censors certain names, you may +# .thepiratebay.se, # want to exclude them here, and provide an +# .piratebay.org, # alternative server section below that will +# .piratebay.se; # successfully resolve the names. +} + +/* +# The following section is more appropriate for dial-up connections. +# Read about how to use pdnsd-ctl for dynamic configuration in the documentation. +server { + label= "dialup"; + file = "/etc/ppp/resolv.conf"; # Preferably do not use /etc/resolv.conf + proxy_only=on; + timeout=4; + uptest=if; + interface = ppp0; + interval=10; # Check the interface every 10 seconds. + purge_cache=off; + preset=off; +} +*/ + +/* +# The servers provided by OpenDNS are fast, but they do not reply with +# NXDOMAIN for non-existant domains, instead they supply you with an +# address of one of their search engines. They also lie about the addresses of +# of the search engines of google, microsoft and yahoo. +# If you do not like this behaviour the "reject" option may be useful. +server { + label = "opendns"; + ip = 208.67.222.222, 208.67.220.220; + reject = 208.69.32.0/24, # You may need to add additional address ranges + 208.69.34.0/24, # here if the addresses of their search engines + 208.67.219.0/24; # change. + reject_policy = fail; # If you do not provide any alternative server + # sections, like the following root-server + # example, "negate" may be more appropriate here. + timeout = 4; + uptest = ping; # Test availability using ICMP echo requests. + ping_timeout = 100; # ping test will time out after 10 seconds. + interval = 15m; # Test every 15 minutes. + preset = off; +} +*/ + +/* +# This section is meant for resolving from root servers. +server { + label = "root-servers"; + root_server = discover; # Query the name servers listed below + # to obtain a full list of root servers. + randomize_servers = on; # Give every root server an equal chance + # of being queried. + ip = 198.41.0.4, # This list will be expanded to the full + 192.228.79.201; # list on start up. + timeout = 5; + uptest = query; # Test availability using empty DNS queries. +# query_test_name = .; # To be used if remote servers ignore empty queries. + interval = 30m; # Test every half hour. + ping_timeout = 300; # Test should time out after 30 seconds. + purge_cache = off; +# edns_query = yes; # Use EDNS for outgoing queries to allow UDP messages + # larger than 512 bytes. May cause trouble with some + # legacy systems. + exclude = .localdomain; + policy = included; + preset = off; +} +*/ + +source { + owner=localhost; +# serve_aliases=on; + file="/etc/hosts"; +} + +/* +include {file="/etc/pdnsd.include";} # Read additional definitions from /etc/pdnsd.include. +*/ + +rr { + name=localhost; + reverse=on; + a=127.0.0.1; + owner=localhost; + soa=localhost,root.localhost,42,86400,900,86400,86400; +} + +/* +neg { + name=doubleclick.net; + types=domain; # This will also block xxx.doubleclick.net, etc. +} +*/ + +/* +neg { + name=bad.server.com; # Badly behaved server you don't want to connect to. + types=A,AAAA; +} +*/ diff --git a/jni/pdnsd/doc/txt/doc_makefile b/jni/pdnsd/doc/txt/doc_makefile new file mode 100644 index 00000000..57aa7c11 --- /dev/null +++ b/jni/pdnsd/doc/txt/doc_makefile @@ -0,0 +1,21 @@ +# Makefile for converting pdnsd html documentation to text files. +# This file was based on a Makefile originally written by Thomas Moestl +# and adapted by Paul Rombouts. + + +HTML2TXT=w3m -dump -cols 80 -T text/html + +doc: intro.txt manual.txt faq.txt +.PHONY: doc clean + +intro.txt: ../html/index.html + sed -e 's///-->/g' ../html/index.html | $(HTML2TXT) | sed -e 's/[[:blank:]]\+$$//' > intro.txt + +manual.txt: ../html/doc.html + sed -e 's///-->/g' ../html/doc.html | $(HTML2TXT) | sed -e 's/[[:blank:]]\+$$//' > manual.txt + +faq.txt: ../html/faq.html + sed -e 's///-->/g' ../html/faq.html | $(HTML2TXT) | sed -e 's/[[:blank:]]\+$$//' > faq.txt + +clean: + @rm -fv intro.txt manual.txt faq.txt diff --git a/jni/pdnsd/doc/txt/faq.txt b/jni/pdnsd/doc/txt/faq.txt new file mode 100644 index 00000000..02631610 --- /dev/null +++ b/jni/pdnsd/doc/txt/faq.txt @@ -0,0 +1,227 @@ +The pdnsd FAQ + +Q: There are complete and well-tested name servers around, such as the BIND. + These do also perform caching. Why should I use pdnsd? + + pdnsd does not aim to be a complete name server implementation, such as the + BIND. It is optimized for caching, and you can only specify a small subset + of all dns record types pdnsd knows in your local "zone" definitions. This + of course reduces the code size drastically, and such the memory footprint. + There are some features especially interesting for dialin networks, + ordinary (non-server) internet hosts and computers that are often not + connected to to their network, e.g. notebooks (I originally wrote this + program for use with my notebook). These features are: +A: + * permanent disk cache (useful for frequent power-offs/reboots) + * usually smaller memory footprint (depends on cache size) (see next + question) + * offline-detection prevents hangs (e.g. the typical hang on startup of + some Netscape Navigator versions if not dialled in) + * better control about timeouts (also to prevent hangs) + * better control over the cache + * better run-time control + +------------------------------------------------------------------------------- + + When I look at the process size with ps, top, gtop, or a similar tool, I +Q: see some processes with a total size well above 3.5 MB. This is much more + than e.g. BIND named (about 1.4 MB). Why? + + Really, it is not. pdnsd uses multithreading, not multiprocessing. That + means that the processes share most of their process space. In the + LinuxThreads library or NPTL (Native Posix Thread Libary), which are used + by pdnsd on Linux, in fact the total process address space is shared +A: (although the processes have different stacks, these are in one process + address space). You may check this by looking at the at the process sizes + of the pdnsd threads: all should be the same. The effective size that pdnsd + occupies is thus the size of any of the processes, not the sum of those. + So, pdnsd with empty cache occupies about 800 kB, and the maximum size + should be about the cache size plus this size (in fact, ca 5-10% more). + +------------------------------------------------------------------------------- + +Q: What do I need the status control (option -s) for? + + It enables you to do some things you might or might not need. With it, you + can: + + * query pdnsd's settings at runtime to debug configuration files and see + which servers are regarded to be available +A: * mark servers as available or unavailable, or force a status retest - + very handy if you want to control which servers pdnsd queries, e.g for + muliple dial-up accounts + * delete, invalidate or add DNS records - useful e.g. when you want to + build records for dynamically assigned IP addresses or domain names + * reload pdnsd's configuration file without restarting pdnsd + * print information about the contents of pdnsd's cache. + +------------------------------------------------------------------------------- + +Q: What do I need local records (rr- and source-sections in the config file) + for? + + Some resolver programs, e.g. nslookup, want to look up the name of the + server they are using before doing anything else. This option is for + defining a PTR record for your IP such that those programs get an answer + even if the name server you are caching is not available or does not offer + these records. By extension, you may also define A and SOA records. This + allows you to build very small zones without having to use a "big" name + server. It is NOT intended to replace such a complete server in anything + but VERY small networks. Alternatively, you may start a named on another + host or on the same host on another port and cache it with pdnsd in + addition to other (more distant) name servers. +A: The source section allows you to let pdnsd read in your /etc/hosts file on + startup and serve its contents. This file is used by your local resolver + before it even tries the name servers and usually contains fully-qualified + domain names (FQDNs) for all of the internet addresses your host has. If + you source this file, you usually won't need any additional rr sections. + Sourcing it also allows other hosts (eg. in your local network) to access + the names defined in your hosts file. You can of course just add other + hosts in your local network to the servers hosts file, thus making them + known to your server's resolver and pdnsd (if you sourced that file). + If you don't know what this answer was all about, you should just take the + source section in the sample config file that comes with pdnsd, copy it + into your config file and forget about it. + +------------------------------------------------------------------------------- + + When compiling, I get an error message like +Q: Please define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN + What's up? + + Normally, this macros should be defined in your C library's header files. + There are two different methods, most C libraries support both (and pdnsd + honors both): either __BYTE_ORDER is set to __LITTLE_ENDIAN or + __BIG_ENDIAN, or __LITTLE_ENDIAN or __BIG_ENDIAN are directly defined as + macros. + Linux glibc, for example, does set those macros correctly. Never mind. You + just have to know whether your machine is little-endian or big-endian, this + means wheter your machine saves the least significant byte of a word or + double-word first in memory (little-endian) or the most significant first +A: (big-endian). All intel x86 and Alpha machines are little-endian, for + example, while SPARC and PowerPC architectures are big-endian. If your + machine is little-endian, add the following line to your config.h: + #define __BYTE_ORDER __LITTLE_ENDIAN + Likewise, if your machines byte order is big-endian: + #define __BYTE_ORDER __BIG_ENDIAN + Pathological byte orders like pdp-endian are not yet supported really; + However, for the place the endianess is needed, __LITTLE_ENDIAN should do + (it deals only with 16 bits; for all other occurances, ntoh[sl]/hton[sl] is + used). + +------------------------------------------------------------------------------- + + At startup, I get a warning saying: +Q: Uptest command [...] will implicitly be executed as root + What does that mean? + + This warning only occurs if you use the uptest=exec option in your + configuration. It means that the uptest command is run as root because + pdnsd is running as root, and this was not explicitely specified. The idea + is that it may introduce security holes (in the programs being run) when +A: they run as root, and so they shouldn't do that if possible. You can + specify the user that shall run the command by appending its name + comma-separated as string to the uptest_cmd line: + uptest_cmd="",""; + If it is correctly running as root, just append the user string "root" to + the command and the warning will not occur again. + +------------------------------------------------------------------------------- + +Q: I cannot run my uptest_cmd command as root (it says permission denied), + although the pdnsd executable is setuid root. Why? + + pdnsd will drop privileges gained through setuid/setgid before executing + the uptest commands (you shouldn't set the pdnsd executable setuid/setgid +A: anyway). The reason is clear: if you install the pdnsd executable as setuid + root and this wouln't be done, any user could execute shellcode with root + privileges using that option! + +------------------------------------------------------------------------------- + + At startup, I get an error saying: +Q: Bad config file permissions: the file must be only writeable by the user + Why is that? + + pdnsd has an option (uptest=exec) that allows the execution of arbitrary + shell code (for testing whether an interface is up). This must be of course + secured against unauthorized use. One of these protection is the one that + produces the error message: if you routinely run pdnsd, e.g. at system + startup, and your config file is editable for others, someone could change +A: it and insert shell code that is executed in the next pdnsd run -- with + your user privileges! To prevent this, pdnsd will exit if the config file + is writeable by others than the owner. To get rid of this message, just do + chmod go-w + on your config file (for the default file: chmod go-w /etc/pdnsd.conf). You + should also check that the ownership is set correct. + +------------------------------------------------------------------------------- + +Q: serve_aliases does not seem to work. + + Some resolvers (e.g. of the glibc 2.1) seem sometimes not to look up + unmodified names, but the names with an entry of the search path already +A: appended. Since pdnsd will serve short names with this option anyway, you + can delete the search an domain options from your /etc/resolv.conf. This is + reported to work in some cases. + +------------------------------------------------------------------------------- + +Q: Some queries for domains that have many records (e.g. www.gmx.de) fail + mysteriously. + + pdnsd versions prior to 1.1.0 had the tcp server thread disabled by + default. Most resolvers repeat their query using tcp when they receive a +A: truncated answer (the answer is truncated when it exceeds a length of 512 + bytes). You need to recompile pdnsd with the option --enable-tcp-server to + fix this. + +------------------------------------------------------------------------------- + + I am behind some kind of firewall. In the configuration file I have only +Q: listed addresses of name servers on the local (ISP's) network, but pdnsd is + slow and DNS queries frequently time out. + + In some cases pdnsd will not consider the answer of the local name server + authoritative enough, and will try to get answers from the name servers + listed in the authority section of the reply message. If pdnsd is behind a + firewall that blocks the UDP reply packets from remote name servers, pdnsd + will wait in vain for a reply. One solution is to set proxy_only=on in the +A: servers sections of the configuration file. This will prevent pdnsd from + querying name servers that are not listed in the configuration file. + Another solution that can be tried is specifying query_method=tcp_only in + the global section of the configuration file, because a firewall that + blocks UDP packets from outside might still allow outgoing TCP connections + to port 53. + +------------------------------------------------------------------------------- + +Q: Is pdnsd vulnerable to DNS cache poisoning as described in CERT + vulnerability note VU#800113? + + Short answer: Yes. + Somewhat longer answer: The problem is not so much that pdnsd's + implementation is flawed but rather that the DNS protocol currently being + used is fundamentally flawed from a security viewpoint. As long as a more + secure protocol is not in place, all that the developers of pdnsd can do is + to try to tweak the current implementation to make it as difficult as + possible for an attacker to succeed. + From version 1.2.7 onwards, the default for the query_port_start option is +A: 1024, which means that the pdnsd resolver will randomly select source ports + in the range 1024-65535. (In previous versions the default was to let the + kernel select the source ports, which will often result in a more or less + predictable sequence of ports.) It also helps to use a good quality source + of random numbers. On platforms where this is supported, it is preferable + to configure with --with-random-device=/dev/urandom. There is still more + that can be done to make pdnsd less vulnerable, but this remains (as of + this writing) a work in progress. + Please note that pdnsd was designed for small (private) networks, and that + it is generally not recommended to let untrusted users access pdnsd. + +------------------------------------------------------------------------------- + +Thomas Moestl and Paul Rombouts + + +Last revised: 18 August 2008 by Paul Rombouts + diff --git a/jni/pdnsd/doc/txt/intro.txt b/jni/pdnsd/doc/txt/intro.txt new file mode 100644 index 00000000..db1c89e3 --- /dev/null +++ b/jni/pdnsd/doc/txt/intro.txt @@ -0,0 +1,305 @@ +------------------------------------------------------------------------------- + +About pdnsd + +pdnsd is a proxy DNS server with permanent caching (the cache contents are +written to hard disk on exit) that is designed to cope with unreachable or down +DNS servers (for example in dial-in networking). +Since version 1.1.0, pdnsd supports negative caching. + +It is licensed under the GNU General Public License (GPL). This, in short, +means that the sources are distributed togehter with the program, and that you +are free to modify the sources and redistribute them as long as you also +license them under the GPL. You do not need to pay anything for pdnsd. It also +means that there is ABSOLUTELY NO WARRANTY for pdnsd or any part of it. For +details, please read the GPL. + +pdnsd can be used with applications that do DNS lookups, e.g. on startup, and +can't be configured to change that behaviour, to prevent the often minute-long +hangs (or even crashes) that result from stalled DNS queries. Some Netscape +Navigator versions for Unix, for example, expose this behaviour. + +pdnsd is configurable via a file and supports run-time configuration using the +program pdnsd-ctl that comes with pdnsd. This allows you to set the status +flags of servers that pdnsd knows (to influence which servers pdnsd will +query), and the addition, deletion and invalidation of DNS records in pdnsd's +cache. +Parallel name server queries are supported. This is a technique that allows +querying several servers at the same time so that very slow or unavailable +servers will not block the answer for one timeout interval. +Since version 1.0.0, pdnsd has full IPv6 support. + +There is also a limited support for local zone records, intended for defining +1.0.0.127.in-addr.arpa. and localhost. , since some clients request that +information and it must be served even if the cached servers are not available +or do not serve these records. pdnsd may also read your /etc/hosts file (this +file is normally used by your local resolver and usually contains information +for localhost as well as for your machines FQDN) and serve its contents. + +pdnsd was started on Linux, and has since been ported to FreeBSD (and Cygwin +and Darwin). 90% of the source code should be easily portable to POSIX- and +BSD-compatible systems, provided that those systems support the POSIX threads +(pthreads). The rest might need OS-specific rewrites. + +Currently, pdnsd is only compileable by gcc. This should be easy to fix, but I +just do not have documentation for other compilers. If you are not able or do +not want to use gcc, I would recommend you just try to do the minor changes. + +pdnsd must be started as root in some cases (raw sockets are needed for icmp +echoes for the option uptest=ping, and the default port is 53, this must be > +1024 to allow non-root execution). However, pdnsd can be configured to change +it's user and group id to those of a non-privileged user after opening the +sockets needed for this. + +The server should support the full standard DNS queries following the rfcs 1034 +and 1035. As of version 1.0.0, the rfc compliance has been improved again, and +pdnsd is now believed (or hoped?) to be fully rfc-compatible. It completely +follows rfc 2181 (except for one minor issue in the FreeBSD port, see the +documentation). It does not support the following features, of which most are +marked optional, experimental or obsolete in these rfcs: + + * Inverse queries + * Status queries + * Completion queries + * Namespaces other than IN (Internet) + * AXFR and IXFR queries (whole zone transfers); since pdnsd does not maintain + zones, that should not violate the standard + +The following record types, that are extensions to the original DNS standard, +are supported for caching since version 1.2.9 (if you do not need most of them, +you can disable runtime support for the unneeded ones before compiling pdnsd +and save a little cache and executable space, see the source file src/ +rr_types.in): + + * RP (responsible person, RFC 1183) + * AFSDB (AFS database location, RFC 1183) + * X25 (X25 address, RFC 1183) + * ISDN (ISDN number/address, RFC 1183) + * RT (route through, RFC 1183) + * NSAP (Network Service Access Protocol address , RFC 1348) + * PX (X.400/RFC822 mapping information, RFC 1995) + * GPOS (geographic position, deprecated) + * AAAA (IPv6 address, RFC 1886) + * LOC (location, RFC 1876) + * EID (Nimrod EID) + * NIMLOC (Nimrod locator) + * SRV (service record, RFC 2782) + * ATMA (ATM address) + * NAPTR (URI mapping, RFC 2168) + * KX (key exchange, RFC 2230) + * CERT (Certificate record, RFC 4398) + * DS (Delegation Signer, RFC 4034) + * RRSIG (Resource Record Signature, RFC 4034) + * NSEC (Next Secure, RFC 4034) + * DNSKEY (record containing the public key for a zone, RFC 4034) + * NSEC3 (Next Secure version 3, RFC 5155) + * NSEC3PARAM (NSEC3 parameters, RFC 5155) + +Note: This list is incomplete. For the complete list see the source file src/ +rr_types.in. + +There are FreeBSD and OpenBSD ports available for pdnsd (ports/net/pdnsd for +both). Thanks go to Roman Shterenzon for the FreeBSD port Sebastian Stark for +the OpenBSD one! Thanks to Kiyo Kelvin Lee now also runs on the Cygwin +platform! Thanks goes to Rodney Brown for extending portability to the Darwin +(Apple Mac OS X) platform! + +If you have questions left, you should take a look into the FAQ. +Bugfixes, patches and compatability fixes for other OSs are very welcome! + +Features in detail + +This section describes some of pdnsds features in detail. Most of the options +are set in the config file. For more information on the configuration file, see +the documenation page. + + +Uptests + +pdnsd provides several methods to test whether a remote DNS server should be +regarded as available (so that pdnsd can query it), in addition to the obvious +"none" test (the server is always regarded as available, or availability is set +on or off using the pdnsd-ctl utility). These tests are: + + * ping: a given adress is ping'ed in a given interval. If it there is no + response or the host is unreachable, the server is seen to be not available + (for those who don't know: pinging is sending a certain Internet packet + type to a host to which any standard-conformant host is required to reply). + * if: a given network interface is tested whether it is existent, up and + running. If it is not, the server is regarded to be not available. This is + especially useful for ppp and similar interfaces. A special case test for + Linux isdn (ippp*) interfaces is integrated, so that the uptests should + also work for these. + * dev: this is a variant of the if uptest for use with Linux dial-on-demand + ppp interfaces. In addition to performing an if-style interface uptest, it + also tests whether a specified program (e.g. pppd) owns a lock to a given + (modem-) device. + * exec: a given shell command line is executed and the exit status of the + whole command line (which is normally the exit status of the last command) + is evaluated. If it is not zero, the server is regarded to be not + available. This is a very flexible testing method with which it should be + able to perform virtually any needed test. + * query: New in version 1.2: This works like the ping test, except it sends + an (empty) DNS query to the remote server. If the server sends a + well-formed response back within the timeout period (except SERVFAIL), it + will be regarded as available. This test is useful if a remote server does + not respond to ICMP_ECHO requests at all, which unfortunately is quite + common these days. In many cases this test will be a more reliable + indicator of availability than the ones mentioned above. + + +Local Records ("Zones") + +As mentioned above, there are only very basic local record types (ie the record +types that you may use in record declarations in your local configuration for +records that pdnsd shall serve in addion to the cached ones). They are +organized roughly in zones but have not complete zone declarations, so I +generally do not use the term "zone" for them, but rather "local records". +These are the local record types pdnsd can understand: + + * SOA (information about the name server) + * A (domain-name-to-address mapping) + * PTR (pointer, used normally for address-to-domain-name mapping) + * NS (name server, generated automatically by pdnsd for any local record set) + * CNAME (canonical host name) + * MX (mail exchange for the domain) + * TXT (arbitrary text strings, often used for Sender Policy Framework) + +You can specify these records in the configuration file. +You may "source" a file in a format like that used in the /etc/hosts file, that +means that pdnsd reads this file, extracts addresses and domain names from it +and automatically generates A records for name to address mapping, PTR records +for address to name mapping and NS records (name server specifiation) for each +entry in the file. +Records can also be changed dynamically at run time. +A script contributed by Marko Stolle makes pdnsd usable in a DHCP setup using +this feature. + +System requirements + +As mentioned, pdnsd currently runs under Linux, FreeBSD and Cygwin. Other BSD +flavours may or may not work (feedback is very welcome!). The system and +software requirements under Linux are: + + * Kernel version >2.2.0 + * glibc version >2.0.1 (aka libc6) with LinuxThreads (normally included) or + NPTL (Native Posix Thread Library, recommended). + Due to a bug, pdnsd 0.9.8 does not run with glibc2.1.1. This behaviour was + fixed in pdnsd 0.9.9. + * For IPv6: glibc>=2.1 + +The system requirements under FreeBSD are: + + * FreeBSD versions >=2.6 (prior ones may or may not work) + * For IPv6: FreeBSD >=4.0 is recommended (no idea if it runs on prior + versions) + +The common software requirements for all supported systems are: + + * GCC, preferably egcs-2.* or 3.* (other compilers are currently not + supported; the needed patch for another compiler should not be difficult, + however) + * GNU or BSD make + * the standard commands install, grep, sed, awk, touch and which (along with + the REALLY standard ones mv, cp, ln, rm, pwd, test, echo, cat, mkdir, + chown, chmod, tar). In any standard Unix installation, this should be no + problem. + * for hacking and building own packages, you might also need gzip, bzip2, + perl and rpmbuild + + +Download + +If you want to download pdnsd, please visit the download page. + +Authors + +pdnsd was originally written by Thomas Moestl, but is no longer maintained by +him. Paul A. Rombouts has revised large portions of the code and has added a +number of new features. See README.par and the ChangeLog in the source +directory (or /usr/share/doc/pdnsd- if you have installed a binary +package) for more details. If you have questions about the recent +modifications, you can find the email address of the current maintainer at the +end of README.par. + +Daniel Smolik has contributed RedHat RPMs (the most recent RPMs are available +here). +Torben Janssen contributed start scripts for Red Hat Linux. +Soenke J. Peters contributed patches and suggestions for Red Hat compatability. +Wolfgang Ocker has contributed the code and documentation for the server_ip +option. +Markus Mohr contributed a Debian rc script. +Nikita V. Youschenko contributed extensions to the "if" uptest. +Lyonel Vincent extended the serve_aliases option to support an arbitrary number +of aliases. +Sourav K. Mandal wrote the autoconf scripts and contributed many fixes and +suggestions. +Stephan Boettcher contributed the SCHEME= option. +Ron Yorston contributed the uptest for Linux ppp dial-on-demand devices. +Alexandre Nunes fixed some bugs in the autoconf files. +Sverker Wiberg contributed fixes for IPv6. +Carsten Block contributed configure-able rc scripts. +Olaf Kirch contributed a security fix for the run_as code. +Paul Wagland contributed various patches for bind9-compatability and other +issues. +Roman Shterenzon contributed patches and lots of helpful hints for FreeBSD +compatability. +Bernd Leibing has contributed spec file fixes. +Michael Wiedmann has contributed the pdnsd-ctl.8 man page. +Marko Stolle has contributed the contrib/pdnsd_update.pl script that makes +pdnsd usable in a DHCP setup. +P.J. Bostley has contributed patches to get pdnsd working on alpha properly. +Christian Engstler contributed patches for SuSE compatability. +Bjoern Fischer contributed code to make pdnsd leave the case of names in the +cache unchanged. +Marko Stolle contributed the contrib/pdnsd_update.pl script that makes pdnsd +usable in a DHCP setup. +Andrew M. Bishop contributed the support for the label server option and the +pdnsd-ctl interface for using it. +Frank Elsner contributed rc script fixes. +Andreas Steinmetz contributed the code for query_port_start and query_port_end +options. +Mahesh T. Pai contributed the pdnsd.8 man page. +Nikola Kotur contributed the Slackware start-up script. +Kiyo Kelvin Lee contributed a patch for Cygwin support. +Rodney Brown contributed a patch for Darwin (Apple Mac OS X) support. +Jan-Marek Glogowski contributed a patch implementing the use_nss option. + +Special thanks to Bert Frederiks for letting me do a late-night debugging run +on his machine to spot obscure bugs! + +Thanks to the following persons for reporting bugs and being helpful: +David G. Andersen, +Dirk Armbrust, +Daniel Black, +Kevin A. Burton, +Juliusz Chroboczek, +Joachim Dorner, +Stefan Erhardt, +Stefan F?rster, +Mike Hammer, +Jonathan Hudson, +Dan Jacobson, +Byrial Jensen, +Patrick Loschmidt, +James MacLean, +Fraser McCrossan, +Michael M?ller, +Erich Reitz, +Brian Schroeder, +Milan P. Stanic, +Michael Steiner, +Norbert Steinl, +Markus Storm, +Michael Str?der, +Alan Swanson, +Eelco Vriezekolk. + + +------------------------------------------------------------------------------- + +Thomas Moestl and Paul A. Rombouts + + +Last revised: 17 March 2012 by Paul A. Rombouts + diff --git a/jni/pdnsd/doc/txt/manual.txt b/jni/pdnsd/doc/txt/manual.txt new file mode 100644 index 00000000..c7e3e9d2 --- /dev/null +++ b/jni/pdnsd/doc/txt/manual.txt @@ -0,0 +1,2017 @@ + pdnsd Documentation + +This is the "official" pdnsd documentation and reference written by Thomas +Moestl with revisions by Paul A. Rombouts. +This manual is a part of the pdnsd package, and may be distributed in original +or modified form under terms of the GNU General Public License, as published by +the Free Software Foundation; either version 3, or (at your option) any later +version. +You can find a copy of the GNU GPL in the file COPYING in the source or +documentation directory. +This manual is up-to-date for version 1.2.9b. For older documentation, please +refer to the doc directory of the respective pdnsd package. +If you want a quicker introduction to pdnsd, you can try some of the HOWTOs +available on the web. For Apple Mac users, Brian Wells has published a good +HOWTO at http://web.mac.com/brianwells/main/pdnsd.html. + +0. Installation + +0.1 Installing binary RPM's + +To install a binary RPM, just do + +rpm -i pdnsd-.rpm + +This should install pretty much everything automatically. The only thing left +for you to do is adapt your configuration file (stored in /etc/pdnsd.conf) +according to your needs (see below). In the Red Hat and SuSE RPMs, a start +script is also installed; read the section 0.4, Start at Boot Time about that. + +0.2 Building RPM's + +It is possible to build a binary RPM from a source package using the command + +rpmbuild --rebuild pdnsd-.src.rpm + +or alternatively from a tarball using the command + +rpmbuild -tb pdnsd-.tar.gz + +You can do this as root, but it is safer to build a binary package first as a +normal user, and then, when all has gone well, install the resulting binary +package as root as in the previous section. How to build an RPM package without +being root is described at http://www.ibm.com/developerworks/linux/library/ +l-rpm1/. + +Several pdnsd-specific options are available when building RPM packages: + +--with isdn Has the same effect as --enable-isdn (see below). + +--without poll Has the same effect as --disable-poll (see below). + +--without nptl Has the same effect as --with-thread-lib=linuxthreads ( + see below). + +--with ipv6 Has the same effect as --enable-ipv6 (see below). + +--without tcpqueries Has the same effect as --disable-tcp-queries (see below + ). + +--without debug Has the same effect as --with-debug=0 (see below). + +--define "distro < Has the same effect as --with-distribution= ( +distro>" see below). + +--define "run_as_user Has the same effect as --with-default-id= (see +" below). + For RPMs the default is "pdnsd". + + If the user defined by the previous option does not +--define "run_as_uid < exist when the RPM is installed, the pre-install script +uid>" will try to create a new user with numerical id . + The default is to let the system choose the numerical + id at install time. + +--define "cachedir < Has the same effect as --with-cachedir= (see below +dir>" ). + +You can also configure which compiler flags will be used by setting the +environment variable CFLAGS. Using a bash shell, you can do that on the command +line like this: CFLAGS="-O1 -Wall" rpmbuild ... +This is useful if you prefer a different level of optimization, for instance. + +0.3 Installing from pure sources (tar archives or git repositories) + +0.3.1 Setting up the source code tree + +Source code is available in the form of snapshots (tarballs) or a git +repository with the very latest development code and a (nearly) complete +history of all the revisions. Cloning a git repository is useful if you need a +recent fix or feature that is not yet contained in a main release or you want +to participate in pdnsd development. Otherwise you will probably find the +tarballs more convenient because they are much more compact. + +0.3.1.1 Unpacking a tar archive + +The pdsnsd snapshot releases come in the form of a gzip'ed tar archive. To +decompress it (using a modern tar) do + +tar -xzf pdnsd-.tar.gz + +If your tar doesn't do this, use: + +gzip -dc pdnsd-.tar.gz | tar -xf - + +0.3.1.2 Cloning a git repository + +To clone a git repository you need to install, if not already installed, the +git version control system, which is available as a package in most modern +Linux distributions. Then run the command: + +git clone git://gitorious.org/pdnsd/pdnsd.git pdnsd + +In rare cases, if you are behind some kind of firewall, the special git +protocol can't be used and you will need to fall back to the http protocol. See +the gitorious.org website or git documentation for more information. + +0.3.2 Configuring the source + +Change into the pdnsd source directory and run configure. It takes the +following command line options (if you do not specify an option, defaults will +be used): + + Specify the prefix directory. The pdnsd files are + installed in subdirectories of the prefix, the +--prefix=dir pdnsd and pdnsd-ctl executables are for example + installed in the sbin subdirectory of the prefix. + The default for this is /usr/local; you might want + to set this to /usr (using --prefix=/usr). + + Specify the config directory. pdnsd expects its + pdnsd.conf file to reside there if the -c option is +--sysconfdir=dir not given at startup. The default for this is the + etc subdirectory of your prefix, e.g. /usr/local/ + etc if you did not specify a prefix. To set this + e.g. to /etc, use --sysconfdir=/etc. + +--with-distribution= Specify target distribution (default=Generic; +distro others: RedHat, SuSE, Debian) + See below for the effect of these settings. + + Change compilation target platform (default: + autodetect; others: Linux, BSD, Cygwin). + autodetect will attempt to detect whether you are +--with-target=platform using Linux, *BSD or Cygwin and should normally be + sufficient. If this does not work, try specifying + your system manually (for the Darwin platform + (Apple Mac OS X) specify BSD here). + + Default directory for pdnsd cache (default=/var/ +--with-cachedir=dir cache/pdnsd) + This setting can be changed via config file + settings when pdnsd has been built. + + Number of hash buckets to use (default=1024). The + default should be sufficient for most purposes, but + if you want to store a large number of names in the +--with-hash-buckets=num cache, cache lookups may be faster if the number of + hash buckets is comparable to the number of names + stored in the cache. The number actually used is + the smallest power of two greater or equal to the + number specified here. + + Enable ISDN support + This option will work only on Linux and may cause +--enable-isdn problems with 2.0.x or old 2.2.x kernels. You will + need it for a proper if uptest under Linux for ISDN + ppp devices. + +--disable-ipv4 Disable IPv4 networking support (default=enabled) + + Enable IPv6 networking support. +--enable-ipv6 If your OS does support IPv6 properly, you should + be able to serve also IPv4 queries using this. + Normally, this is disabled and you won't need it. + +--disable-ipv4-startup Disable IPv4 on pdnsd startup by default (default= + enabled) + + Enable IPV6 on pdnsd startup by default (default= + IPv4). These options are only defaults, you can +--enable-ipv6-startup specify on the command line or in the config files + which IP version will really be used. Normally, you + won't need to change these. + +--disable-udp-queries Disable UDP as query method. You shouldn't need to + change this. + + Disable TCP as query method. This only effects the + querying of name servers by pdnsd, not the ability + of pdnsd to answer TCP queries from clients. TCP + queries are slower than UDP queries, but can be +--disable-tcp-queries more secure against certain types of attacks and + are able to handle large answers. For normal use + this can be disabled. (Note that the default has + changed: TCP-query support is now compiled in by + default, but it still depends on the run-time + options whether it is actually used.) + + Specify the query method (default=udponly, others: + tcponly, tcpudp, udptcp). If you have enabled both + UDP and TCP queries, this lets you control which + query method pdnsd will use by default. tcpudp will + try TCP first and fall back to UDP if TCP is not +--with-query-method=qm supported by the server; udptcp will try UDP first + and, if the answer was truncated, will repeat the + query using TCP. udponly and tcponly should be + clear. Note that this only effects the compiled-in + default; the query method can still be changed + using command-line options or options in the + configuration file. + + Disable the TCP server. In this case pdnsd will not +--disable-tcp-server be able to respond to TCP queries from clients. + This may cause problems with very large answers. + + Disable the UDP source address discovery. + You need this only if you have trouble with +--disable-src-addr-disc messages saying "could not discover udp source + address". + For the Cygwin target, this option is disabled by + default. + +--disable-poll Disable poll(2) and use select(2) (default=enabled) + You will normally not need this. + + Since version 1.2.9 this option is obsolete and + ignored. It is now possible to configure for each +--disable-new-rrs RR type separately whether it is cacheable by pdnsd + by editing the file src/rr_types.in. The comments + in this file explain how to do this. + + Enforce strict RFC 2181 compliance. + This will cause pdnsd to reject DNS answers with +--enable-strict-rfc2181 incorrect timestamp settings (multiple RRs of the + same type and for the same domain with different + TTLs). Normally not needed. + + This option is obsolete. Since version 1.2, pdnsd +--enable-underscores places no restrictions on the types of characters + in domain names (there are still a few restrictions + for locally defined names, though). + + Specify random device; default: C Library random() + PRNG + pdnsd uses (pseudo-) random numbers as query IDs + for security reasons (this makes forging DNS + answers more difficult). This option controls where + pdnsd gets these from. The default is the C library + random() function, which is relatively weak. You + can specify a device like /dev/urandom here if you +--with-random-device= like; pdnsd will read random numbers from it +device 16-bit-wise. /dev/urandom is present under Linux + and most BSD derivates. You should not use /dev/ + random - it is more secure, but may block and delay + pdnsd's answers for a long time. + You can specify arc4random to use the BSD + arc4random() library function (default for FreeBSD + target), which is considered safe. + You can also specify random as device to use the C + Library random() function (described above). + + Specify default user for pdnsd (default=nobody). + This is the user that will be entered for the +--with-default-id=user run_as option in the config file (see below) that + will be installed during make install. You can + change this any time in your config file. + + Specify debugging level. Normally you can safely + switch debugging off by setting the level to 0. + This will increase speed (although only marginally) + and save space in the executable (only about 12kB). + However, more significant may be the savings in + stack space, especially if pdnsd is put under heavy + load and there are many simultaneous running + threads. + Presently the only defined debug levels are in the + range 0 - 9. Setting the level to 9 enables hex +--with-debug=level dumps of the queries and replies pdnsd receives and + should normally not be needed. Debug output will + only be generated if you turn on special switches; + it might be useful for debugging your config files, + so I recommend using the default (1). However, if + you use pdnsd under heavy load, a better strategy + may be to compile one version of pdnsd without + debug support (configured with --with-debug=0) for + production use, and one version with with debug + support (e.g. --with-debug=9) for diagnostic + purposes. + +--with-verbosity=level Specify default message verbosity. The default + should be ok. + + Enable RCS IDs in executables (default=disabled). +--enable-rcsids For personal use, there is no need to do this. If + you build rpm's, it might have advantages. + + Enable subsequent tcp queries. The DNS protocol + standard requires that servers must be capable of + answering multiple subsequent queries that are sent + over the same tcp connection, and that the server + may only close the connection by himself after a + certain timeout. This feature is rarely used, but +--enable-tcp-subseq may make denial-of-service attacks easier, as it + allows for an attacker to hold a connection open a + long time (although the attacker's IP is most + likely revealed then). For full standard + compliance, you should use this option. If you do + not use --enable-tcp-server, is option is not + honored. + + Specify default tcp query timeout after which the + connection is closed if no full query has been +--with-tcp-qtimeout=secs received. The default is 30s. You can also change + this option at run time using the tcp_qtimeout + config file option. If you do not use + --enable-tcp-server, is option is not honored. + + Specify the default number of queries that can be + executed in parallel. You can also change this +--with-par-queries=num option at run time using the par_queries config + file option. See the description of that option for + an explanation of what it really does. + The default for this option is 2. + + New in version 1.2.9b: Specify the maximum number + of IP addresses that can be used per nameserver + obtained from NS records (when resolving names + recursively). Just one IP address per nameserver is + sufficient in the vast majority of cases (and this +--with-max-nameserver-ips was the strategy used by pdnsd in previous +=num versions), but in rare cases this will cause + unnecessary resolve failures if the address chosen + for each nameserver happens to be unreachable while + the other addresses would lead to successful + resolution. + The default for this option is 3. + + Added by Paul Rombouts: Use this option if you + experience problems with signal handling under + Linux. The usual symptom is that pdnsd fails to + save the cache to disk, and /var/cache/pdnsd/ + pdnsd.cache remains empty. If you experience this + kind of trouble, try reconfiguring with different + values for the --with-thread-lib option. The + allowable values are linuxthreads (or lt for + short), linuxthreads2 (or lt2 for short), and nptl. + By default the configure script tries to detect +--with-thread-lib=lib automatically whether linuxthreads or nptl is more + appropriate for your system, but the method used is + not foolproof. Look for the line: checking if this + is an NPTL-based system... + If the automatic test mistakenly indentifies the + thread library on your system as NPTL based, you + should reconfigure with --with-thread-lib=lt and + recompile. If the result of the automatic test is + "no" or if --with-thread-lib=lt does not have the + desired effect, try again using --with-thread-lib= + lt2 . + +Normally, you will need only --prefix, --sysconfdir and --with-distribution. If +you specify your distribution using --with-distribution, this has the following +effects: + + * An rc script is copied in the appropriate localtion, which enables pdnsd to + start at machine boot time (see 0.4) + * Distribution-specific portions might be included in the generated + pdnsd.spec file (only important if you want to build rpm archives + yourself). + +If you choose Generic, no rc script is installed, and a generic spec file is +generated. +Further instructions are in the INSTALL document in the pdnsd source directory. +./configure --help will give you a list of all supported command line options. + +Note added by Paul Rombouts: Some people may want change the compiler +optimization flag. I use the -O2 flag, but it might be safer to use a lower +level of optimization or no optimization at all. In that case prefix the +configure command with the desired compiler flags like this (assuming you're +using a bash shell): + +CFLAGS="-O1 -Wall" ./configure ... + + +0.3.3 Building & installing + +Type make in the source directory. Should work by now. +To install, type make install or do the installation by hand (see 0.3.4). +make install will do the following ($prefix is the prefix directory; see +above): + + 1. copies pdnsd to $(prefix)/sbin/ + 2. copies pdnsd-ctl to $(prefix)/sbin/ + 3. copies docs/pdnsd.conf.sample (a sample configuration) to the pdnsd config + directory. + 4. creates your cache directory if it is not there. After installation, you + should check the file permissions and create or edit /etc/pdnsd.conf to fit + your needs (see below). If you use the run_as option, please make sure that + your cache directory is owned by the user you specified with this option! + +You must be root for this installation! +Security notes: never make the pdnsd cache directory writeable for untrusted +users, or you will get several security holes: the users might modify the cache +contents, or plant dangerous links. +If you use a pidfile, you should be aware that you introduce security problems +if you place the pidfile in a directory in a NFS filesystem that is writeable +for untrusted users. Generally, the pidfile directory (typically /var/run) +should not be writeable for untrusted users. + +0.3.4 Manual installation + +For a manual installation, you need to do the following steps: + + 1. Copy pdnsd and pdnsd-ctl from your build directory to an appropriate + location (e.g. /usr/sbin). + 2. Copy docs/pdnsd.conf into the directory you want it to reside (/etc by + default, and change it according to your needs (see below). + 3. Create your caching directory; default is /var/cache/pdnsd (you may change + this in your pdnsd.conf); Permissions should be at max rwxr-xr-x (if you + want to protect your cache and status socket, make it rwx------). + +Thats it! + +0.4 Start at boot time + +In the src/rc folder of the pdnsd distribution are start scripts for pdnsd +designed for different Linux distros. There are scripts for SuSE, Redhat, +Debian, Arch Linux and Slackware now. +The start scripts are automatically installed during RPM install, and also +during make install if you specified your distro. +For Slackware Linux there is a start-up script contributed by Nikola Kotur, but +presently it must be installed manually. See src/rc/README and src/rc/Slackware +/rc.pdnsd for details. + +0.4.1 SuSE Linux startup + +rc/SuSE/pdnsd is a start script for SuSE Linux. It was tested for 6.? but +should run on some versions below. You can do make install as root in the rc/ +SuSE directory to install it, or you can install manually: + +manual installation + +For manual installation, copy rc/SuSE/pdnsd into /sbin/init.d/, go to /sbin/ +init.d/rc2.d/ and create there the following two symlinks: +S11pdnsd to ../pdnsd (do ln -s ../pdnsd S11pdnsd in that dir) +K34pdnsd to ../pdnsd (do ln -s ../pdnsd K34pdnsd in that dir) +The numbers dictate the order different services are started and might need to +be modified. Then edit your /etc/rc.config file and add the line START_PDNSD= +yes to start pdnsd at boot time. + +If you used the make install command, START_PDNSD=yes has been appended to your +/etc/rc.config file, causing pdnsd to be started at boot time. If you don't +want that, change the yes into no. + +This start script was created from /sbin/init.d/skeleton by me, so the most is +copyrighted by SuSE. They put it under the GPL, however, so the license stated +in COPYING also applies to this script. There is NO WARRANTY OF ANY KIND on +these scripts. This is no official SuSE script, and SuSE naturally does NO +support for it. + +0.4.2 Red Hat Linux startup + +rc/Redhat/pdnsd is a start script for Red Hat Linux. It was contibuted by +Torben Janssen. +This was tested for 6.1 but should run on 5.0+. You can do make install as root +in the rc/Redhat directory to install it, or you can install manually: + +manual installation + +For manual installation, copy rc/Redhat/pdnsd into /etc/rc.d/init.d/ +Then go to /etc/rc.d/rc3.d and create there the following symlink: +S78pdnsd -> ../init.d/pdnsd (do ln -f -s ../init.d/pdnsd S78pdnsd in that dir) +Then go to /etc/rc.d/rc0.d and create there the following symlink: +K78pdnsd -> ../init.d/pdnsd (do ln -f -s ../init.d/pdnsd K78pdnsd in that dir) +Then go to /etc/rc.d/rc6.d and create there the following symlink: +K78pdnsd -> ../init.d/pdnsd (do ln -f -s ../init.d/pdnsd K78pdnsd in that dir) + +This script is also covered by license stated in COPYING. Again, there is NO +WARRANTY OF ANY KIND on these scripts. This is no offical Redhat script, and +Redhat naturally does NO support for it + +0.5 Notes for FreeBSD users + +The special handling of ISDN ppp devices is only supported on Linux. It is not +needed in FreeBSD, the normal device handling also works fine with isdn4bsd +devices. +When compiled for FreeBSD, pdnsd as a small RFC compatability issue: RFC2181 +demands answers on dns querys to be sent with the same source address the query +packet went to. In seldom cases, this will not be the case, because the kernel +selects the source address depending on the interface that was used for sending +the answer. +Setting the source address currently does not work for IPv4. I have written a +kernel patch that will provide an easy way to program this. We'll see if or +when it gets commited. + + + +1 Invocation + +When invoking pdnsd, you can specify various options at the command line. +Command line options always override config file options. The various --noX +options are present to override config file options. + +pdnsd --help (or -h) gives you an overview of the pdnsd command line options. + +pdnsd --version (or -V for short) prints licence and version information. + +To start pdnsd as background daemon, specifiy --daemon (or -d for short) on the +command line. Diagnostic and error messages after the actual daemon start will +be printed to the syslog instead of the console. --nodaemon will disable this. + +When starting pdnsd as a daemon, the -p option may be helpful: It writes the +pid of the server process to the file of the name given as argument to this +option. +Example: pdnsd -d -p /var/run/pdnsd.pid + +If you want to specify a configuration file other than /etc/pdnsd.conf, specify +-c or --config-file on the command line, followed by a filename. + +If pdnsd was compiled with debugging support, you may specify -g or --debug on +the command line. This will cause extra diagnostic messages to be printed. When +pdnsd runs in daemon mode, the messages will be written to the pdnsd.debug file +in your cache directory. --nodebug disables debugging. + +pdnsd -vn sets the verbosity level of pdnsd. n is normally a digit from 0 to 3, +where 0 means normal operation, while 3 will most verbose. Level 9 can be used +in combination with the --debug option for very extensive debug information. +Note: The current implementation mostly ignores the verbosity level, so you may +not notice much difference between the various levels. + +The option -s or --status enables the status control socket. This is a named +socket in the cache directory called pdnsd.status. This socket allows run-time +configuration of pdnsd using the utility pdnsd-ctl. See below for more details +about pdnsd-ctl. --nostatus disables status control. See also the configuration +option status_ctl in the global section. + +The option --notcp disables the seldom needed TCP server thread, which may save +you some resources. -t or --tcp will enable it. See also the tcp_server +configuration option. + +Using the -m option, you can select the method pdnsd uses to query other name +servers. Following methods are supported (see also the query_method +configuration option): +-muo: pdnsd will use UDP only. This is the fastest method, and should be +supported by all name servers on the Internet. +-mto: pdnsd will use TCP only. TCP queries usually take longer time than UDP +queries, but are more secure against certain attacks, where an attacker tries +to guess your query id and to send forged answers. TCP queries are not +supported by some name servers. +-mtu: pdnsd will try to use TCP, and will fall back to UDP if its connection is +refused or times out. +-mut: New in version 1.2.5: pdnsd will try to use UDP, and will repeat the +query using TCP if the UDP reply was truncated (i.e. the tc bit is set). This +is the behaviour recommended by the DNS standards. + +The -4 option switches to IPv4 mode, providing pdnsd was compiled with IPv4 +support. +The -6 option switches to IPv6 mode, providing pdnsd was compiled with IPv6 +support. +The -a option is only available when pdnsd was compiled with both IPv4 and IPv6 +support. With this option, pdnsd will try to detect automatically if a system +supports IPv6, and fall back to IPv4 otherwise. + +With -i prefix or --ipv4_6_prefix=prefix you can set the prefix pdnsd uses +(when running in IPv6 mode) to map IPv4 addresses in the configuration file to +IPv6 addresses. There is also a corresponding option for the config file, see +below. Must be a valid IPv6 address. The default is ::ffff:0.0.0.0 + +2 The configuration file + +This section describes the layout of the configuration file and the available +configuration options. The default location of the file is /etc/pdnsd.conf. +This may be changed with the -c command line option. An example pdnsd.conf +comes with the pdnsd distribution in the docs directory and will be installed +to /etc/ by make install. + +2.1 Layout + +The configuration file is divided into sections. Each section is prefixed with +the section name and opening curlies ({) and closed with closing curlies (}). +In each section, configuration options can be given in the form +option_name=option_value; +Option value may be a string literal, a number, a time specification or a +constant. In previous versions of pdnsd strings had to be enclosed in quotes +("), but since version 1.1.10 this is no longer necessary, unless a string +contains a special character such as whitespace, a token that normally starts a +comment, or one of ",;{}\". Since version 1.2.9 a backslash (\) inside a string +is interpreted as an escape character, so it is possible to include special +characters in strings (both quoted or unquoted) by preceding them with a +backslash. Some escape sequences are in interpreted as in the C programming +language, e.g. \t becomes a tab, \n becomes a new-line control char. +A time specification consists a sequence of digits followed by a one-letter +suffix. The following suffixes are recognized: s (seconds), m (minutes), h +(hours), d (days) and w (weeks). If the suffix is missing, seconds are assumed. +If several time specifications are concatenated, their values are added +together; e.g. 2h30m is interpreted as 2*60*60 + 30*60 = 9000 seconds. +Some options take more than one value; in this case, the values are separated +with commas. +If you may supply one of a set of possible values to an option, this is noted +in the documentation as (option1|option2|option3|...) +The constants true|false and yes|no are accepted as synonyms for the constants +on|off. +Comments may be enclosed in /* and */, nested comments are possible. If the # +sign or two slashes (//) appear in the configuration file, everything from +these signs to the end of the current line is regarded as a comment and +ignored. +There are examples for nearly all options in the sample config file. + +2.1.1 global Section + +The global section specifies parameters that affect the overall behaviour of +the server. If you specify multiple global sections, the settings of those +later in the file will overwrite the earlier given values. +These are the possible options: + + +perm_cache=(number|off); +Switch the disk cache off or supply a maximum cache size in kB. If the disk +cache is switched off, 8 bytes will still be written to disk. The memory cache +is always 10kB larger than the file cache. This value is 2048 (2 MB) by +default. + +cache_dir=string; +Set the directory you want to keep the cache in. The default is "/var/cache/ +pdnsd" (unless pdnsd was compiled with a different default). + +server_port=number; +Set the server port. This is especially useful when you want to start the +server and are not root. Note that you may also not specify uptest=ping in the +server section as non-root. +The default port is 53, the RFC-standard one. Note that you should only use +non-standard ports when you only need clients on your machine to communicate +with the server; others will probably fail if the try to contact the server on +the basis of an NS record, since the A record that supplies the address for +(among others) name servers does not have a port number specification. + +server_ip=string; +or +interface=string; +Set the IP address pdnsd listens on for requests. This can be useful when the +host has several interfaces and you want pdnsd not to listen on all interfaces. +For example, it is possible to bind pdnsd to listen on 127.0.0.2 to allow pdnsd +to be a forwarder for BIND. The default setting for this option is server_ip= +any, which means that pdnsd will listen on all of your local interfaces. +Presently you can only specify one address here; if you want pdnsd to listen on +multiple interfaces but not all you will have to specify server_ip=any and use +firewall rules to restrict access. +The IP address used to need quotation marks around it, but since version 1.1.10 +this is no longer necessary. +If pdnsd has been compiled with both IPv4 and IPv6 support, and you want to +specify an IPv6 address here, then unless pdnsd was compiled to start up in +IPv6 mode by default, you will need to use the -6 command-line option or set +run_ipv4=off first (see below) in order to ensure that the IPv6 address is +parsed correctly. +If pdnsd is running in IPv6 mode and you specify an IPv4 address here, it will +automatically be mapped to an IPv6 address. +New in version 1.2: You may also give the name of an interface such as "lo" or +"eth0" here, instead of an IP address (this has been tested on Linux, and may +or may not work on other platforms). pdnsd will not bind to the interface name, +but will look up the address of the interface at start-up and listen on that +address. If the address of the interface changes while pdnsd is running, pdnsd +will not notice that. You will need to restart pdnsd in that case. + +outgoing_ip=string; +or +outside_interface=string; +New in version 1.2.9: Set the IP address of the interface used by pdnsd for +outgoing queries. This can be useful when the host has several interfaces and +you want pdnsd to send outgoing queries via only one of them. For example, if +pdnsd is running on a host with one interface with IP address 192.168.1.1 +connected to the local network, and another with IP address 123.xxx.yyy.zzz +connected to the internet, you may specify server_ip=192.168.1.1 and +outgoing_ip=123.xxx.yyy.zzz to enforce that pdnsd only responds to queries +received from the local network, and only sends outgoing queries via the +interface connected to the internet. +The default setting for this option is any, which means that the kernel is free +to decide which interface to use. Like with the server_ip option, you may also +give the name of an interface here, instead of an IP address. + +linkdown_kluge=(on|off); +This option enables a kluge that some people might need: when all servers are +marked down, with this option set the cache is not even used when a query is +received, and a DNS error is returned in any case. The only exception from this +is that local records (as specified in rr and source sections are still served +normally. In general, you probably want to get cached entries even when the +network is down, so this defaults to off. + +max_ttl=timespec; +This option sets the maximum time a record is held in cache. All dns resource +records have a time to live field that says for what period of time the record +may be cached before it needs to be requeried. If this is more than the value +given with max_ttl, this time to live value is set to max_ttl. This is done to +prevent records from being cached an inappropriate long period of time, because +that is almost never a good thing to do. Default is 604800s (one week). + +min_ttl=timespec; +This option sets the minimum time a record is held in cache. All dns resource +records have a time to live field that says for what period of time the record +may be cached before it needs to be requeried. If this is less than the value +given with min_ttl, this time to live value is set to min_ttl. Default is 120 +seconds. + +neg_ttl=timespec; +This option sets the time that negatively cached records will remain valid in +the cache if no time to live can be determined. This is always the case when +whole domains are being cached negatively, and additionally when record types +are cached negatively for a domain for which no SOA record is known to pdnsd. +If a SOA is present, the ttl of the SOA is taken. + +neg_rrs_pol=(on|off|auth|default); +This sets the RR set policy for negative caching; this tells pdnsd under which +circumstances it should cache a record type negatively for a certain domain. +off will turn the negative caching of record types off, on will always add a +negative cache entry when a name server did not return a record type we asked +it for, and auth will only add such entries if the answer came from an +authoritative name server for that domain. +New in version 1.2.8: The default setting will add a negatively cached record +if either the answer was authoritive or the answer indicated the name server +had "recursion available" while the query explicitly requested such recursion. +The preset is "default" (used to be auth). + +neg_domain_pol=(on|off|auth); +This is analogue to neg_rrs_pol for whole domain negative caching. It should be +safe to set this on, because I have not seen a caching server that will falsely +claim that a domain does not exist. +The default is auth. + +run_as=string; +This option allows you to let pdnsd change its user and group id after +operations that needed privileges have been done. This helps minimize security +risks and is therefore recommended. The supplied string gives a user name whose +user id and primary group id are taken. +A little more details: after reading the config file, becoming a daemon (if +specified) and starting the server status thread, the main thread changes its +gid and uid, as do all newly created threads thereafter. By taking another uid +and gid, those threads run with the privileges of the specified user. Under +Linux and FreeBSD, the server status thread runs with the original privileges +only when the strict_setuid option is set to off (see below, on by default), +because these may be needed for exec uptests. The manager thread also retains +its original privileges in this case. You should take care that the user you +specify has write permissions on your cache file and status pipe (if you need a +status pipe). You should look out for error messages like "permission denied" +and "operation not permitted" to discover permission problems. + +strict_setuid=(on|off); +When used together with the run_as option, this option lets you specify that +all threads of the program will run with the privileges of the run_as user. +This provides higher security than the normal run_as option, but is not always +possible. See the run_as option for further discussion. +This option is on by default. +Note that this option has no effect on Non-Linux systems. + +paranoid=(on|off); +Normally, pdnsd queries all servers in recursive mode (i.e. instructs servers +to query other servers themselves if possible, and to give back answers for +domains that may not be in its authority), and accepts additional records with +information for servers that are not in the authority of the queried server. +This opens the possibility of so-called cache poisoning: a malicious attacker +might set up a dns server that, when queried, returns forged additional +records. This way, he might replace trusted servers with his own ones by making +your dns server return bad IP addresses. This option protects you from cache +poisoning by rejecting additional records that do not describe domains in the +queried servers authority space and not doing recursive queries any more. An +exception to this rule are the servers you specify in your config file, which +are trusted. +The penalty is a possible performance decrease, in particular, more queries +might be necessary for the same operation. +You should also notice that there may be other similar security problems, which +are essentially problems of the DNS, i.e. any "traditional" server has them +(the DNS security extensions solve these problems, but are not widely +supported). One of this vulnerabilities is that an attacker may bombard you +with forged answers in hopes that one may match a query you have done. If you +have done such a query, one in 65536 forged packets will be succesful (i.e. an +average packet count of 32768 is needed for that attack). pdnsd can use TCP for +queries, which has a slightly higher overhead, but is much less vulnerable to +such attacks on sane operating systems. Also, pdnsd chooses random query ids, +so that an attacker cannot take a shortcut. If the attacker is able to listen +to your network traffic, this attack is relatively easy, though. +This vulnerability is not pdnsd's fault, and is possible using any conventional +name server (pdnsd is perhaps a little more secured against this type of +attacks if you make it use TCP). +The paranoid option is off by default. + +ignore_cd=(on|off); +New in version 1.2.8: This option lets you specify that the CD bit of a DNS +query will be ignored. Otherwise pdnsd will reply FORMERR to clients that set +this bit in a query. It is safe to enable this option, as the CD bit refers to +'Checking Disabled' which means that the client will accept non-authenticated +data. +This option is on by default. Turn it off if you want the old behaviour (before +version 1.2.8). + +scheme_file=string; +In addition to normal uptests, you may specify that some servers shall only be +queried when a certain pcmcia-cs scheme is active (only under linux). For that, +pdnsd needs to know where the file resides that holds the pcmcia scheme +information. Normally, this is either /var/lib/pcmcia/scheme or /var/state/ +pcmcia/scheme. + +status_ctl=(on|off); +This has the same effect as the -s command line option: the status control is +enabled when on is specified. +Added by Paul Rombouts: Note that pdnsd-ctl allows run-time configuration of +pdnsd, even the IP addesses of the name servers can be changed. If you're not +using pdnsd-ctl and you want maximum security, you should not enable this +option. It is disabled by default. + +daemon=(on|off); +This has the same effect as the -d command line option: the daemon mode is +enabled when on is specified. +Default is off. + +tcp_server=(on|off); +tcp_server=on has the same effect as the -t or --tcp command-line option: it +enables TCP serving. Similarly, tcp_server=off is like the --notcp command-line +option. +Default is on. + +pid_file=string; +This has the same effect as the -p command line option: you can specify a file +that pdnsd will write its pid into when it starts in daemon mode. + +verbosity=number; +This has the same effect as the -v command line option: you can set the +verbosity of pdnsd's messages with it. The argument is a number between 0 (few +messages) to 3 (most messages). + +query_method=(tcp_only|udp_only|tcp_udp|udp_tcp); +This has the same effect as the -m command line option. Read the documentation +for the command line option on this. tcp_only corresponds to the to, udp_only +to the uo, tcp_udp to the tu and udp_tcp to the ut argument of the command line +option. +If you use query_method=tcp_udp, it is recommended that you also set the global +timeout option to at least twice the longest server timeout. + +run_ipv4=(on|off); +This has the same effect as the -4 or -6 command line option: if on is +specified, IPv4 support is enabled, and IPv6 support is disabled (if +available). If off is specified, IPv4 will be disabled and IPv6 will be +enabled. For this option to be meaningful, pdnsd needs to be compiled with +support for the protocol you choose. If pdnsd was compiled with both IPv4 and +IPv6 support, and you want to include IPv6 addresses in the configuration file, +you will probably need to specify run_ipv4=off first to ensure that the IPv6 +addresses are parsed correctly. + +debug=(on|off); +This has the same effect as the -g command line option: the debugging messages +are enabled when on is specified. + +ctl_perms=number; +This option allows you to set the file permissions that the pdnsd status +control socket will have. These are the same as file permissions. The owner of +the file will be the run_as user, or, if none is specified, the user who +started pdnsd. If you want to specify the permissions in octal (as usual), +don't forget the leading zero (0600 instead of 600!). To use the status +control, write access is needed. The default is 0600 (only the owner may read +or write). +Please note that the socket is kept in the cache directory, and that the cache +directory permissions might also need to be adjusted. Please ensure that the +cache directory is not writeable for untrusted users. + +proc_limit=number; +With this option, you can set a limit on the pdnsd threads that will be active +simultaneously. If this number is exceeded, queries are queued and may be +delayed some time. See also the procq_limit option. +The default for this option is 40. + +procq_limit=number; +When the query thread limit proc_limit is exceeded, connection attempts to +pdnsd will be queued. With this option, you can set the maximum queue length. +If this length is also exceeded, the incoming queries will be dropped. That +means that tcp connections will be closed and udp queries will just be dropped, +which will probably cause the querying resolver to wait for an answer until it +times out. +See also the proc_limit option. A maximum of proc_limit+procq_limit query +threads will exist at any one time (plus 3 to 6 threads that will always be +present depending on your configuration). +The default for this option is 60. + +tcp_qtimeout=timespec; +This option sets a timeout for tcp queries. If no full query has been received +on a tcp connection after that time has passed, the connection will be closed. +The default is set using the --with-tcp-qtimeout option to configure. + +par_queries=number; +This option used to set the maximum number of remote servers that would be +queried simultaneously, for every query that pdnsd receives. +Since version 1.1.11, the meaning of this option has changed slightly. It is +now the increment with which the number of parallel queries is increased when +the previous set of servers has timed out. For example, if we have a list +server1, server2, server3, etc. of available servers and par_queries=2, then +pdnsd will first send queries to server1 and server2, and listen for responses +from these servers. +If these servers do not send a reply within their timeout period, pdnsd will +send additional queries to server3 and server4, and listen for responses from +server1, server2, server3 and server4, and so on until a useful reply is +received or the list is exhausted. +In the worst case there will be pending queries to all the servers in the list +of available servers. We may be using more system resources this way (but only +if the first servers in the list are slow or unresponsive), but the advantage +is that we have a greater chance of catching a reply. After all, if we wait +longer anyway, why not for more servers. +See also the explanation of the global timeout option below. +1 or 2 are good values for this option. The default is set at compile time +using the --with-par-queries option to configure. + +timeout=timespec; +This is the global timeout parameter for dns queries. This specifies the +minimum period of time pdnsd will wait after sending the first query to a +remote server before giving up without having received a reply. The timeout +options in the configuration file are now only minimum timeout intervals. +Setting the global timeout option makes it possible to specify quite short +timeout intervals in the server sections (see below). This will have the effect +that pdnsd will start querying additional servers fairly quickly if the first +servers are slow to respond (but will still continue to listen for responses +from the first ones). This may allow pdnsd to get an answer more quickly in +certain situations. +If you use query_method=tcp_udp it is recommended that you make the global +timeout at least twice as large as the largest server timeout, otherwise pdnsd +may not have time to try a UDP query if a TCP connection times out. +Default value is 0. + +randomize_recs=(on|off); +If this option is turned on, pdnsd will randomly reorder the cached records of +one type when creating an answer. This supports round-robin DNS schemes and +increases fail safety for hosts with multiple IP addresses, so this is usually +a good idea. +On by default. + +query_port_start=(number|none); +If a number is given, this defines the start of the port range used for queries +of pdnsd. The value given must be >= 1024. The purpose of this option is to aid +certain firewall configurations that are based on the source port. Please keep +in mind that another application may bind a port in that range, so a stateful +firewall using target port and/or process uid may be more effective. In case a +query start port is given pdnsd uses this port as the first port of a specified +port range (see query_port_end) used for queries. pdnsd will try to randomly +select a free port from this range as local port for the query. +To ensure that there are enough ports for pdnsd to use, the range between +query_port_start and query_port_end should be adjusted to at least (par_queries +* proc_limit). A larger range is highly recommended for security reasons, and +also because other applications may allocate ports in that range. If possible, +this range should be kept out of the space that other applications usually use. +The default for this option is 1024. Together with the default value of +query_port_end, this makes it the hardest for an attacker to guess the source +port used by the pdnsd resolver. If you specify none here, pdnsd will let the +kernel choose the source port, but this may leave pdnsd more vulnerable to an +attack. + +query_port_end=number; +Used if query_port_start is not none. Defines the last port of the range +started by query_port_start used for querys by pdnsd. The default is 65535, +which is also the maximum legal value for this option. For details see the +description of query_port_start. + +delegation_only=string; +Added by Paul Rombouts: This option specifies a "delegation-only" zone. This +means that if pdnsd receives a query for a name that is in a subdomain of a +"delegation-only" zone but the remote name server returns an answer with an +authority section lacking any NS RRs for subdomains of that zone, pdnsd will +answer NXDOMAIN (unknown domain). This feature can be used for undoing the +undesired effects of DNS "wildcards". Several "delegation-only" zones may be +specified together. If you specify root servers in a server section it is +important that you set root_server=on in such a section. +Example: + +delegation_only="com","net"; + +This feature is off by default. It is recommended that you only use this +feature if you actually need it, because there is a risk that some legitimate +names will be blocked, especially if the remote name servers queried by pdnsd +return answers with empty authority sections. + +ipv4_6_prefix=string; +This option has the same effect as the -i command-line option. When pdnsd runs +in IPv6 mode, this option specifies the prefix pdnsd uses to convert IPv4 +addresses in the configuration file (or addresses specified with pdnsd-ctl) to +IPv6-mapped addresses. The string must be a valid IPv6 address. Only the first +96 bits are used. Note that this only effects the parsing of IPv4 addresses +listed after this option. +The default is "::ffff.0.0.0.0". + +use_nss=(on|off); +If this option is turned on, pdnsd will call initgroups() to set up the group +access list, whenever pdnsd changes its user and group id (see run_as option). +There is a possible snag, though, if initgroups() uses NSS (Name Service +Switch) and NSS in turn uses DNS. In such a case you may experience lengthy +timeouts and stalls. By setting use_nss=off, you can disable the initgroups() +call (only possible in versions 1.2.5 and later). +This option was contributed by Jan-Marek Glogowski. +On by default. + +udpbufsize=number; +New in version 1.2.9: This option sets the upper limit on the size of UDP DNS +messages. The default is 1024. +See also the edns_query server option below. + + +2.1.2 server Section + +Each server section specifies a set of name servers that pdnsd should try to +get resource records or authoritative name server information from. The servers +are queried in the order of their appearance (or parallel to a limited extend). +If one fails, the next one is taken and so on. +You probably want to specify the dns server in your LAN, the caching dns +servers of your internet provider or even a list of root servers in one or more +server sections. +The supported options in this section are: + + +label=string; +Specify a label for the server section. This can be used to refer to this +section when using pdnsd-ctl, the pdnsd control utility. +You can give several server sections the same label, but if you want to change +the addresses of a server section (see ip option below) during run-time with +"pdnsd-ctl server label up dns1,dns2,...", the label must be unique. + +ip=string; +Give the IP (the address, not the host name) of the server. +Multiple IP addresses can be given per server section. This can be done by +entering multiple lines of the form ip=string; or a single line like this: + +ip=string,string,string; + +IP addresses do not have to be specified in the configuration file. A server +section without IP addresses will remain inactive until it is assigned one or +more addresses with pdnsd-ctl, the pdnsd control utility. +If pdnsd has been compiled with both IPv4 and IPv6 support, any IPv6 addresses +you specify here will be skipped with a warning message, unless pdnsd is +running in IPv6 mode. Thus, unless pdnsd was compiled to startup in IPv6 mode +by default, you need to use the command-line option -6 or set run_ipv4=off +first (see global section) in order to ensure that IPv6 addresses are parsed +correctly. +If pdnsd is running in IPv6 mode and you specify an IPv4 address here, it will +automatically be mapped to an IPv6 address. + +file=string; +New in version 1.2: This option allows you to give the name of a +resolv.conf-style file. Of the lines beginning with the nameserver keyword, the +second field will be parsed as an IP address, as if it were specified with the +ip= option. The remaining lines will be ignored. If the contents of the file +changes while pdnsd is running, you can make pdnsd aware of the changes through +the use of pdnsd-ctl, the pdnsd control utility. This is usually most +conveniently done by placing the command "pdnsd-ctl config" in a script that is +automatically run whenever the DNS configuration changes. +For example, suppose you have a ppp client that writes the DNS configuration +for your ISP to the file /etc/ppp/resolv.conf and runs the script /etc/ppp/ +ip-up when a new connection is established. One way of ensuring that pdnsd is +automatically reconfigured is to add a server section in the config file with +file=/etc/ppp/resolv.conf and to add the command "pdnsd-ctl config" to /etc/ppp +/ip-up. + +port=number; +Give the port the remote name server listens on. Default is 53 (the official +dns port) + +uptest=(ping|none|if|dev|diald|exec|query); +Determine the method to check whether the server is available. Currently +defined methods are: + + * ping: Send an ICMP_ECHO request to the server. If it doesn't respond within + the timeout, it is regarded to be unavailable until the next probe. + * none: The availability status is not changed, only the time stamp is + updated. + * if: Check whether the interface (specified in the interface= option) is + existent, up and running. This currently works for all "ordinary" network + interfaces, interfaces that disappear when down (e.g. ppp?), and + additionally for Linux isdn interfaces (as of kernel 2.2). Note that you + need a /dev/isdninfo device file (major#45, minor#255), or the isdn uptest + will always fail. + * dev and diald: Perform an if uptest, and, if that was succesful, + additionally check whether a program is running that has locked a given + (modem-) device. The needed parameters are an interface (specified as for + the if uptest, e.g. "ppp0") and a device relative to /dev (e.g. "modem" for + /dev/modem specified using the device= option. pdnsd will then look for a + pid file for the given interface in /var/lock (e.g. /var/run/ppp0.pid) and + for a lockfile for the given device (e.g. /var/lock/LCK..modem), and then + test whether the locking process is the process that created the pid file + and this process is still alive. If this is the case, the normal if uptest + is executed for the given interface. + The dev option is for pppd dial-on-demand, diald is the same for diald + users. + * exec: Executes a given command in the /bin/sh shell (as /bin/sh -c + ) and evaluates the result (the return code of the last command) + in the shell's way of handling return codes, i.e. 0 indicates success, all + other indicate failure. The shell's process name will be uptest_sh. The + command is given with the uptest_cmd option (see below). For secuity + issues, also see that entry. + * query: New in version 1.2: This works like the ping test, except it sends + an (empty) DNS query to the remote server. If the server sends a + well-formed response back within the timeout period (except SERVFAIL), it + will be regarded as available. This test is useful if a remote server does + not respond to ICMP_ECHO requests at all, which unfortunately is quite + common these days. It can also happen that a remote server is online but + ignores empty DNS queries. Then you will need the set the query_test_name + option (see below). In many cases this test will be a more reliable + indicator of availability than the ones mentioned before. + +The default value is none. + +NOTE: If you use on-demand dialing, use none, if, dev, diald or exec, since +ping or query will send packets in the specified interval and the interface +will thus frequently dial! + +ping_timeout=number; +Sets the timeout for the ping test in tenths of seconds (this unit is used for +legacy reasons; actually the current implementation is only accurate to a +second). +The default is 600 (one minute). + +ping_ip=string; +The IP address for the ping test. The default is the IP of the name server. + +query_test_name=string; +New in version 1.2.9: Sets the name to be queried when using uptest=query +availability test. If the string is the unquoted constant none, an empty query +is used (this the default), otherwise a query of type A will be sent for the +domain name specified here. It is not necessary for the domain name to exist or +have a record of type A in order for the uptest to succeed. +If the the remote server ignores empty queries, you will probably want to set +query_test_name="." (the root domain). + +uptest_cmd=string,string; +or +uptest_cmd=string; +Sets the command for the uptest=exec function to the first string. If the +second string is given, it specifies a user with whose user id and primary +group id the command is executed. +This is especially useful if you are executing the server as root, but do not +want the uptest to be performed with root privileges. In fact, you should never +execute the uptest as root if you can help it. +If the server is running setuid or setgid, the privileges thus gained are +attempted to be dropped even before changing identity to the specified user to +prevent setuid/gid security holes (otherwise, any user might execute commands +as root if you setuid the executable). +Note that this is not always possible, and that pdnsd should never be installed +as setuid or setgid. The command is executed using /bin/sh, so you should be +able to use shell builtin commands. + +interval=(timespec|onquery|ontimeout); +Sets the interval for the server up-test. The default is 900 seconds; however, +a test is forced when a query times out and the timestamp is reset then. +If you specify onquery instead of a timeout, the interface will be tested +before every query. This is to prevent automatically dialing interfaces (diald/ +pppd or ippp) to dial on dns queries. It is intended to be used in connection +with an interface-testing uptest ;-) +Note that using uptest=exec, you might run into performance problems on slow +machines when you use that option. DON'T use onquery with uptest=ping or uptest +=query, as it may cause delays if the server does not answer (btw, it doesn't +make sense anyway). Note also that using onquery is no guarantee that the +interface will not be used. When another (reachable) dns server tells pdnsd to +query a third dns server for data, pdnsd will do that and has no means of +checking whether this will dial up the interface or not. This however should be +a rare situation. +New in version 1.2.3: A third possibility is to specify interval=ontimeout. In +this case the server is not tested at startup/reconfiguration, nor at regular +intervals, but only after a DNS query to a server times out. Certain types of +network problems such as a refused connection will also cause the server to be +considered unavailable. However, once a server is declared dead it is never +considered again unless it is revived using a pdnsd-ctl config or server +command. The idea behind this option is to minimize uptests by assuming all +servers are available until there is reason to believe otherwise. + +interface=string; +The network interface (or network device, e.g. "eth0") for the uptest=if +option. Must be specified if uptest=if is given. + +device=string; +The (modem-) device that is used for the dev uptest. If you use this for a +dial-on-demand ppp uptest (together with uptest=dev), you need to enter the +device you are using for your pppd here, e.g. modem for /dev/modem. +Must be specified if uptest=dev is given. + +timeout=timespec; +Set the timeout for the dns query. The default is 120 seconds. You probably +want to set this lower. +Timeouts specified in the configuration file are only treated as the minimum +period of time to wait for a reply. A queries to a remote server are not +canceled until a useful reply has been received, or all the other queries have +timed out or failed. +If you have also set the global timeout option, you may consider setting a +fairly small value here. See the explanation of the timeout option in the +global section for what that means. + +purge_cache=(on|off); +In every fetched dns record, there is a cache timeout given, which specifies +how long the fetched data may be cached until it needs to be reloaded. If +purge_cache is set to off, the stale records are not purged (unless the cache +size would be exceeded, in this case the oldest records are purged). Instead, +they are still served if they cannot succesfully be updated (e.g. because all +servers are down). +Default is off. + +caching=(on|off); +Specifies if caching shall be performed for this server at all. Default is on. + +lean_query=(on|off); +Specifies whether to use the "lean" query mode. In this mode, only the +information actually queried from pdnsd is resolved and cached. This has the +advantage that usually less cache space is used and the query is usually +faster. In 90% of the cases, only address (A) records are needed anyway. If +switched off, pdnsd will always cache all data about a host it can find and +will specifically ask for all available records (well, at least it is a good +approximation for what it really does ;-) This will of course increase the +answer packet sizes. +Some buggy name servers may not deliver CNAME records when not asked for all +records. I do not know if such servers are around, but if you have trouble +resolving certain host names, try turning this option off. +A last note: If you use multiple pdnsd's that access each other, turning this +option on is probably a big win. +This on by default. + +edns_query=(on|off); +New in version 1.2.9: Specifies whether to use EDNS (Extension mechanisms for +DNS) for outgoing queries. Currently this is only useful for allowing UDP +message sizes larger than 512 bytes. Note that setting this option on can give +problems in combination with some legacy systems or software, including, +embarrassingly enough, previous versions of pdnsd. +The default is off, but if your network can handle UDP payloads significantly +larger than 512 bytes, the recommended value is on. +Note that this option only effects outgoing queries. If pdnsd receives a query +using EDNS, it will reply using EDNS regardless of the value of this option. +See also the udpbufsize option above. + +scheme=string; +You can specify a pcmcia-cs scheme that is used in addition to the uptests. If +you specify a scheme here, the server this section is for will only be queries +if the given scheme is active. Shell wildcards (* and ?) are allowed in the +string under their special meanings. You need to use the scheme_file option on +the global section to make this option work. + +preset=(on|off); +This allows you to specify the initial state of a server before any uptest is +performed. on specifies that the server is regarded available. The default is +on. This is especially useful when you set uptest=none; and want to change the +status of a server only via pdnsd-ctl. + +proxy_only=(on|off); +When this option is set to on, answers given by the servers are always +accepted, and no other servers (as, for example, specified in the NS records of +the query domain) are queried. If you do not turn this option on, pdnsd will do +such queries in some cases (in particular when processing ANY queries). +This option is useful when you do not want pdnsd to make connections to outside +servers for some reasons (e.g. when a firewall is blocking such queries). +I recommend that you turn on lean_query when using this option. +Default is off. + +root_server=(on|off|discover); +Set this option to on if the servers specified in a section are root servers. A +root server will typically only give the name servers for the top-level domain +in its reply. Setting root_server=on will cause pdnsd to try to use cached +information about top-level domains to reduce to number of queries to root +servers, making the resolving of new names more efficient. You can get a list +of available root servers by running the command "dig . ns". +This option is also necessary if you use the delegation_only option. +New in version 1.2.8: This option may also be set to "discover". This will +cause pdnsd to query the servers provided with the ip= option to obtain the +full list of root servers. The root-server addresses will replace the addresses +specified with the ip= option. This will only be done once on startup, or after +a "pdnsd-ctl config" command. In this case the name servers specified with the +ip= option don't have to be root servers, they just have to know the names and +addresses of the root servers. After root-server discovery pdnsd will behave +just as if root_server=on had been specified. +Default is off. + +randomize_servers=(on|off); +New in version 1.2.6: Set this option to on to give each name server in this +section an equal chance of being queried. If this option is off, the name +servers are always queried starting with the first one specified. Even with +this option on, the query order is not truly random. Only the first server is +selected randomly; the following ones are queried in consecutive order, +wrapping around to the beginning of the list when the end is reached. Note that +this option only effects the order within a section. The servers in the first +(active) section are always queried before those in the second one, etc. +The default is off, but if you are resolving from root servers setting this +option on is highly recommended. If root_server=on this option also effects the +query order of the name servers for the top-level domains. + +reject=string; +New in version 1.2.6: This option can be used to make pdnsd reject replies that +contain certain IP addresses. You can specify a single IP address, which will +be matched exactly, or a range of addresses using an address/mask pair. The +mask can be specified as a simple integer, indicating the number of initial 1 +bits in the mask, or in the usual IP address notation. IP addresses may be +either IPv4 or IPv6 (provided there is sufficient support in the C libraries +and support for AAAA records was not disabled). When addresses in the reject +list are compared with those in a reply, only the bits corresponding to those +set in the netmask are significant, the rest are ignored. +Multiple addresses or address/mask pairs may be specified; this can be done by +entering multiple lines of the form reject=string; or a single line like this: + +reject=string,string,string; + +How pdnsd reacts when an address in the reply matches one in the reject list, +depends on the reject_policy option, see below. + +reject_policy=(fail|negate); +New in version 1.2.6: This option determines what pdnsd does when an address in +the reply from a name server matches the reject list (see above). If this +option is set to fail, pdnsd will try another server, or, if there no more +servers to try, return the answer SERVFAIL. If this option is set to negate, +pdnsd will immediately return the answer NXDOMAIN (unknown domain) without +querying additional servers. The fail setting is useful if you don't always +trust the servers in this section, but do trust the servers in the following +section. The negate setting can be used to completely censor certain IP +addresses. In this case you should put the same reject list in every server +section, and also set the reject_recursively option (see below) to true. +The default is fail. + +reject_recursively=(on|off); +New in version 1.2.6: Normally pdnsd checks for addresses in the reject list +(see above) only when the reply comes directly from a name server listed in the +configuration file. With this option set to on, pdnsd will also do this check +for name servers that where obtained from NS records in the authority section +of a previous reply (which was incomplete and non-authoritative). +Default is off. + +policy=(included|excluded|simple_only|fqdn_only); +pdnsd supports inclusion/exclusion lists for server sections: with include= and +exclude= (see below) you can specify domain names for which this server will be +used or will not be used. The first match counts (i.e., the first include or +exclude rule in a server section that matches a domain name is applied, and the +search for other rules is terminated). If no rule matched a given domain name, +the policy= option determines whether this server is used for the lookup for +that domain name; when included is given, the server will be asked, and when +excluded is given, it will not. If simple_only is given the server will be used +if the name to lookup is a simple (single-label) domain name, on the other hand +if fqdn_only is given the server will be used only for names consisting of two +or more labels (i.e. the name has at least one dot in-between). +If no server is available for a queried domain, pdnsd will return an error +message to the client that usually will stop the client's attempts to resolve a +specific domain from this server (the libc resolver will e.g. return an error +to the application that tried to resolve the domain if no other servers are +available in the resolv.conf). This may be of use sometimes. +Note: the simple_only and fqdn_only constants were added by Paul Rombouts. They +are useful for controlling which name servers (if any) will be used by pdnsd +for resolving simple (single-label) host names. fqdn_only used to stand for +"fully qualified domain name only", but this is actually a misnomer. The names +in queries received by pdnsd are always considered to be fully qualified. If +you do not exactly understand what the options simple_only and fqdn_only are +good for, you are probably better off not using them. +The default for this option is included. + +include=string; +This option adds an entry to the exclusion/inclusion list. If a domain matches +the name given as string, the server is queried if this was the first matching +rule (see also the entry for policy). +If the given name starts with a dot, the whole subdomain of the given name +including the one of that name is matched, e.g. ".foo.bar." will match the +domain names a.foo.bar., a.b.c.foo.bar. and foo.bar. +If it does not start in a dot, only exactly the given name (ignoring the case, +of course) will be matched (hint: if you want to include all subdomains, but +not the domain of the given name itself, place an exact-match exclude rule +before the include rule, e.g: exclude="foo.bar."; include=".foo.bar."; +Previous versions of pdnsd required that names given with this and the next +option ended in a dot, but since version 1.1.8b1-par8, pdnsd automatically adds +a dot at the end if it is missing. +pdnsd now also accepts a more compact notation for adding several "include" +entries in one line, e.g.: + +include=".foo",".bar",".my.dom"; + +exclude=string; +This option adds an entry to the exclusion/inclusion list. If a domain matches +the name given as string, the server is not queried if this was the first +matching rule (see also the entry for policy). +If the given name starts with a dot, the whole subdomain of the given name +including the one of that name is matched, e.g. ".foo.bar." will match the +domain names a.foo.bar., a.b.c.foo.bar. and foo.bar. +If it does not start in a dot, only exactly the given name (ignoring the case, +of course) will be matched (hint: if you want to exclude all subdomains, but +not the domain of the given name itself, place an exact-match include rule +before the exclude rule, e.g: include="foo.bar."; exclude=".foo.bar."; +pdnsd now also accepts a more compact notation for adding several "exclude" +entries in one line, e.g.: + +exclude=".foo",".bar",".my.dom"; + + +2.1.3 rr Section + +Every rr section specifies a dns resource record that is stored locally. It +allows you to specify own dns records that are served by pdnsd in a limited +way. Only A, PTR, CNAME, MX, NS and SOA records are implemented. +This option is intended to allow you to define RRs for 1.0.0.127.in-addr.arpa. +and localhost. (and perhaps even one or two hosts) without having to start an +extra named if your cached name servers do not serve those records. It is NOT +intended and not capable to work as a full-featured name server. + + +name=string; +Specifies the name of the resource records, i.e. the domain name of the +resource the record describes. This option must be specified before any a, ptr, +cname, mx, ns or soa records. Names are interpreted as absolute domain names +(i.e. pdnsd assumes they end in the root domain). For this and all following +arguments that take domain names, you need to specify domain names in dotted +notation (example venera.isi.edu.). +Previous versions of pdnsd required that domain names given in the +configuration file ended in a dot, but since version 1.1.8b1-par8, pdnsd +automatically assumes a dot at the end if it is missing. +New in version 1.2: It is also possible to specify a name starting with the +label *. Such a name is called a wildcard. The * in a wildcard can match one or +more labels in a queried name, but only whole labels. Any other * characters in +a wildcard, apart from the leading one, will only match a literal *. +For example, *.mydomain will match a.mydomain or www.a.mydomain, but not +mydomain. *.a*.mydomain will match www.a*.mydomain, but not www.ab.mydomain. +*a.mydomain will only match itself. +Before you can specify an rr section with name=*.mydomain you must define some +records for mydomain, typically NS and/or SOA records. Example: + + rr { + name = mydomain; + ns = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + rr { + name = *.mydomain; + a = 192.168.1.10; + } + +In this example, www.mydomain and ftp.mydomain will resolve to the numeric +address 192.168.1.10 (unless you add rr sections explicitly specifying +different addresses for www.mydomain or ftp.mydomain). If you want mydomain +also to resolve to a numeric address, add an A record to the first rr section. + +ttl=timespec; +Specifies the ttl (time to live) for all resource records in this section after +this entry. This may be redefined. The default is 86400 seconds (=1 day). + +authrec=(on|off); +If this is turned on, pdnsd will create authoritative local records for this rr +section. This means that pdnsd flags the domain record so that records of this +domain that are not present in the cache are treated as non-existent, i.e. no +other servers are queried for that record type, and an response containing none +of those records is returned. This is most time what people want: if you add an +A record for a host, and it has no AAAA record (thus no IPv6 address), you +normally don't want other name servers to be queried for it. +This is on by default. +Please note that this only has an effect if it precedes the name option! + +reverse=(on|off); +New in version 1.2: If you want a locally defined name to resolve to a numeric +address and vice versa, you can achieve this by setting reverse=on before +defining the A record (see below). The alternative is to define a separate PTR +record, but you will probably find this option much more convenient. +The default is off. + +a=string; +Defines an A (host address) record. The argument is an IPv4 address in dotted +notation. pdnsd will serve this address for the host name given in the name +option. +Provided there is sufficient support in the C libraries and support for AAAA +records was not disabled, the argument string may also be an IPv6 address, in +which case an AAAA record will be defined. +This option be may used multiple times within an rr section, causing multiple +addresses to be defined for the name. However, if you put the different +addresses in different rr sections for the same name, the definition in the +last rr section will cancel the definitions in the previous ones. + +ptr=string; +Defines a PTR (domain name pointer) record. The argument is a host name in +dotted notation (see name). The ptr record is for resolving adresses into +names. For example, if you want the adress 127.0.0.1 to resolve into localhost, +and localhost into 127.0.0.1, you need something like the following sections: + + rr { + name = localhost; + a = 127.0.0.1; + owner = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + rr { + name = 1.0.0.127.in-addr.arpa; + ptr = localhost; + owner = localhost; + soa = localhost, root.localhost, 42, 86400, 900, 86400, 86400; + } + +The second section is for reverse resolving and uses the ptr option. Note that +you can get the same effect by specifying only the first rr section with +reverse=on. +There is something special about the name in the second section: when a +resolver wants to get a host name from an internet address, it composes an +address that is built of the IP address in reverse byte order (1.0.0.127 +instead of 127.0.0.1) where each byte of the adress written as number +constitutes a sub-domain under the domain in-addr.arpa. +So, if you want to compose an adress for reverse resolving, take your ip in +dotted notation (e.g. 1.2.3.4), reverse the byte order (4.3.2.1) and append +in-addr.arpa. (4.3.2.1.in-addr.arpa.) Then, define an rr section giving this +address as name and the domain name corresponding to that ip in the ptr option. + +cname=string; +Defines a CNAME (canonical name) record. The argument should be a +fully-qualified host name in dotted notation (see name). A CNAME is the DNS +equivalent of an alias or symbolic link. +A useful application for CNAMEs is giving short, easy to remember nicknames to +hosts with complicated names. For example, you might want the name "news" to +refer to your ISP's news server "nntp2.myisp.com". Instead of adding an A +record for "news" with the same address as "nntp2.myisp.com", you could put in +a CNAME pointing to "nntp2.myisp.com", so that if the IP address of the news +server changes, there is no need to update the record for "news". +To implement this with pdnsd, you could add the following section to your +configuration file: + + rr { + name = news; + cname = nntp2.myisp.com; + owner = localhost; + } + +mx=string,number; +Defines an MX (mail exchange) record. The string is the host name of the mail +server in dotted notation (see name). The number specifies the preference +level. +When you send mail to someone, your mail typically goes from your E-mail client +to an SMTP server. The SMTP server then checks for the MX record of the domain +in the E-mail address. For example, with joe@example.com, it would look for the +MX record for example.com and find that the name of mail server for that domain +is, say, mail.example.com. The SMTP server then gets the A record for +mail.example.com, and connects to the mail server. +If there are multiple MX records, the SMTP server will pick one based on the +preference level (starting with the lowest preference number, working its way +up). +Don't define MX records with pdnsd unless you know what you're doing. + +owner=string; +or +ns=string; +Defines an NS (name server) record. Specifies the name of the host which should +be authoritative for the records you defined in the rr section. This is +typically the host pdnsd runs on. +Note: In previous versions of pdnsd this option had to be specified before any +a, ptr, cname, mx or soa entries. In version 1.2, the restrictions on this +option are same as the options just mentioned, and it must listed after the +name= option. This can be a pain if you want to use an old config file which +specifies owner= before name= (sorry about that). Apart from greater +consistency, the advantage is that you can now specify as many NS records as +you like (including zero). + +soa=string,string,number,timespec,timespec,timespec,timespec; +This defines a soa (start of authority) record. The first string is the domain +name of the server and should be equal to the name you specified as owner. +The second string specifies the email address of the maintainer of the name +server. It is also specified as a domain name, so you will have to replace the +@ sign in the name with a dot (.) to get the name you have to specify here. The +next parameter (the first number) is the serial number of the record. You +should increment this number if you change the record. +The 4th parameter is the refresh timeout. It specifies after what amount of +time a caching server should attempt to refresh the cached record. +The 5th parameter specifies a time after which a caching server should attempt +to refresh the record after a refresh failure. +The 6th parameter defines the timeout after which a cached record expires if it +has not been refreshed. +The 7th parameter is the ttl that is specified in every rr and should be the +same as given with the ttl option (if you do not specify a ttl, use the default +86400). + +txt=string,...,string; +New in version 1.2.9: Defines an TXT record. You can specify one or more +strings here. + + +2.1.4 neg Section + +Every neg section specifies a dns resource record or a dns domain that should +be cached negatively locally. Queries for negatively cached records are always +answered immediatley with an error or an empty answer without querying other +hosts as long as the record is valid. The records defined with neg sections +remain valid until they are explicitely invalidated or deleted by the user +using pdnsd-ctl. +This is useful if a certain application asks periodically for nonexisting hosts +or RR types and you do not want a query to go out every time the cached record +has timed out. Example: Netscape Communicator will ask for the servers news and +mail on startup if unconfigured. If you do not have a dns search list for your +network, you can inhibit outgoing queries for these by specifying + + neg { + name = news; + types = domain; + } + neg { + name = mail; + types = domain; + } + +in your config file. If you have a search list, you have to repeat that for any +entry in your search list in addition to the entries given above! +In versions 1.1.11 and later, if you negate whole domains this way, all +subdomains will be negated as well. Thus if you specify +neg {name=example.com; types=domain;} in the config file, this will also negate +www.example.com, xxx.adserver.example.com, etc. + + +name=string; +Specifies the name of the domain for which negative cache entries are created. +This option must be specified before the types option. Names are interpreted as +absolute domain names (i.e. pdnsd assumes they end in the root domain). You +need to specify domain names in dotted notation (example venera.isi.edu.). +Previous versions of pdnsd required that domain names given in the +configuration file ended in a dot, but since version 1.1.8b1-par8, pdnsd +automatically assumes a dot at the end if it is missing. + +ttl=timespec; +Specifies the ttl (time to live) for all resource records in this section after +this entry. This may be redefined. The default is 86400 seconds (=1 day). + +types=(domain|rr_type[,rr_type[,rr_type[,...]]]); +Specifies what is to be cached negatively: domain will cache the whole domain +negatively; alternatively, you can specify a comma-separated list of RR types +which are to be cached negatively. You may specify multiple types options, but +domain and the RR types are mutually exclusive. +The RR types are specified using their official names from the RFC's in +capitals, e.g. A, CNAME, NS, PTR, MX, AAAA, ... +The command pdnsd-ctl list-rrtypes will give you a complete list of those +types. pdnsd-ctl is built along with pdnsd and will be installed in the same +directory as the pdnsd binary during make install. + + +2.1.5 source Section + +Every source section allows you to let pdnsd read the records from a file in an +/etc/hosts-like format. pdnsd will generate records to resolve the entries +address from its host name and vice versa for every entry in the file. This is +normally easier than defining an rr for every of your addresses, since +localhost and your other FQDNs are normally given in /etc/hosts. +The accepted format is as follows: The #-sign initiates a comment, the rest of +the line from the first occurence of this character on is ignored. Empty lines +are tolerated. +The first entry on a line (predeceded by an arbitrary number of tabs and +spaces) is the IP in dotted notation, the second entry on one line (separated +by the first by an arbitrary number of tabs and spaces) is the FQDN (fully +qualified domain name) for that ip. The rest of the line is ignored by default +(in the original /etc/hosts, it may contain information not needed by pdnsd). + + +owner=string; +Specifies the name of the host pdnsd runs on and that are specified in dns +answers (specifically, nameserver records). Must be specified before any file +entries. +Names are interpreted as absolute domain names (i.e. pdnsd assumes they end in +the root domain). You need to specify domain names in dotted notation (example +venera.isi.edu.). +Previous versions of pdnsd required that domain names given in the +configuration file ended in a dot, but since version 1.1.8b1-par8, pdnsd +automatically assumes a dot at the end if it is missing. + +ttl=timespec; +Specifies the ttl (time to live) for all resource records in this section after +this entry. This may be redefined. The default is 86400 seconds (=1 day). + +file=string; +The string specifies a file name. For every file entry in a source section, +pdnsd will try to load the given file as described above. Failure is indicated +only when the file cannot be opened, malformed entries will be ignored. + +serve_aliases=(on|off); +If this is turned on pdnsd will serve the aliases given in a hosts-style file. +These are the third entry in a line of a hosts-style file, which usually give a +"short name" for the host. This may be used to support broken clients without a +proper domain-search option. If no aliases are given in a line of the file, +pdnsd behaves as without this option for this line. +This feature was suggested by Bert Frederiks. +It is off by default. + +authrec=(on|off); +If this is turned on, pdnsd will create authoritative local records with the +data from the hosts file. Please see the description of the option of the same +name in the rr section for a closer description of what this means. Please note +that this only has an effect for files sourced with file options subsequent to +this option. +This is on by default. + + +2.1.6 include Section + +A configuration file may include other configuration files. However, only the +top-level configuration file may contain global and server sections, thus +include files are effectively limited to sections that add local definitions to +the cache. +Include sections currently only have one type of option, which may be given +multiple times within a single section. + + +file=string; +The string specifies a file name. For every file option in an include section, +pdnsd will parse the given file as described above. The file may contain +include sections itself, but as a precaution pdnsd checks that a certain +maximum depth is not exceeded to guard against the possibility of infinite +recursion. + + +3 pdnsd-ctl + +pdnsd-ctl allows you to configure pdnsd at run time. To make this work, you +have to start pdnsd with the -s option (or use the status_ctl option in the +config file). You also should make sure that you have appropriate permissions +on the control socket (use the ctl_perms option to make this sure) and of your +pdnsd cache directory (pdnsd keeps its socket there). Please make sure the +pdnsd cache directory is not writeable for untrusted users! + +pdnsd-ctl accepts two command-line options starting with a dash. +-c may be used to specify the cache directory (and takes this as argument). The +default for this setting is the pdnsd default cache directory (specified at +compile time). The cache directory for pdnsd-ctl must be the same pdnsd uses! +-q can be used to make the output of pdnsd-ctl less verbose. + +The following table lists the commands that pdnsd-ctl supports. The command +must always be the first command-line option (not starting with a dash), the +arguments to the command must follow in the given order. +In the following table, keywords are in a normal font, while placeholders are +in italics. +Alternatives are specified like (alt1|alt2|alt3). Optional arguments are placed +between square brackets []. + +Command Arguments Description + +help Print a command summary. + +version Print version and license info. + +status Print a description of pdnsd's cache status, thread status + and configuration. Also shows which remote name servers + are assumed to be available. + +server (index|label) (up| Set the status of the server with the given index or label + down|retest) [dns1[, (where the given label matches the one given with the + dns2[,...]]] label option in the respective server section in the + config file) to up or down, or force a retest. The index + is assigned in the order of definition in pdnsd.conf + starting with 0. Use the status command to view the + indices and labels. You can specify all instead of an + index or label to perform the action for all servers + registered with pdnsd. Example: + pdnsd-ctl server 0 retest + An optional third argument consisting of a list of IP + addresses (separated by commas or white-space characters) + can be given. This list will replace the previous list of + addresses of name servers used by pdnsd in the specified + section of the config file. For example in the /etc/ppp/ + ip-up script called by pppd you could place the following + line: + pdnsd-ctl server isplabel up $DNS1,$DNS2 + If white space is used to separate addresses the list will + have to be quoted. Spurious commas and white-space + characters are ignored. The last argument may also be an + empty string, in which case the existing IP addresses are + removed and the corresponding server section becomes + inactive. + +record name (delete| Delete or invalidate the records of the given domain name + invalidate) if it is in the cache. Invalidation means that the records + are marked as timed out, and will be reloaded if possible + (if purge_cache is set to on, they will be deleted in any + case). + For local records (i.e., records that were given in the + config file using a rr section, records read from a + hosts-style file and records added using pdnsd-ctl), + invalidation has no effect. Deletion will work, though. + Example: + pdnsd-ctl record localhost. delete + +source fn owner [ttl] [(on Load a hosts-style file. Works like using the pdnsd source + |off)] [noauth] configuration section. owner and ttl are used as in the + source section. ttl has a default of 900 (it does not need + to be specified). The next to last argument corresponds to + the serve_aliases option, and is off by default (i.e. if + it is not specified). noauth is used to make the domains + non-authoritative - please see the description of the + authrec config file options for a description of what that + means. fn is the filename. The file must be readable by + pdnsd! Example: + pdnsd-ctl source /etc/hosts localhost. 900 off + +add a addr name [ttl] + [noauth] + Add a record of the given type to the pdnsd cache, + replacing existing records for the same name and type. The +add aaaa addr name [ttl 2nd argument corresponds to the value of the option in the + ] [noauth] rr section that is named like the first argument: a is a + record for hostname-to-address mapping, aaaa is the same + thing for IPv6 addresses, and ptr is for +add ptr host name [ttl] address-to-hostname mapping. See the documentation for the + [noauth] rr section for more details. In case of A and AAAA + records, the addr argument may be a list of IP addresses, + separated by commas or white space, causing multiple +add cname host name [ addresses to be defined for the same name. The ttl is + ttl] [noauth] optional, the default is 900 seconds. noauth is used to + make the domains non-authoritative - please see the + description of the authrec config file options for a +add mx host name pref description of what that means. If you want no other + [ttl] [noauth] record than the newly added in the cache, do + pdnsd-ctl record name delete before adding records. This + is also better when overwriting local records. Example: +add ns host name [ttl] pdnsd-ctl add a 127.0.0.1 localhost. 900 + [noauth] + + +neg name [type] [ttl] Add a negatively cached record to pdnsd's cache, replacing + existing records for the same name and type. If no type is + given, the whole domain is cached negatively. For + negatively cached records, errors are immediately returned + on a query, without querying other servers first. The ttl + is optional, the default is 900 seconds. + You can get a list of all types you can pass to this + command using pdnsd-ctl list-rrtypes. The type is treated + case-sensitive! Example: + pdnsd-ctl neg foo.bar A 900 + pdnsd-ctl neg foo.baz 900 + +config [filename] Reload pdnsd's configuration file. + The config file must be owned by the uid that pdnsd had + when it was started, and be readable by pdnsd's run_as + uid. If no file name is specified, the config file used at + start-up is reloaded. + Note that some configuration changes, like the port or IP + address pdnsd listens on, cannot be made this way and you + will receive an error message. In these cases, you will + have to restart pdnsd instead. + +include filename Parse the given file as an include file, see the + documentation on include sections for a description what + this file may contain. + This command is useful for adding definitions to the cache + without reconfiguring pdnsd. + +eval string Parse the given string as if it were part of pdnsd's + configuration file. The string should hold one or more + complete configuration sections. However, global and + server sections are not allowed, just as in include files. + If multiple strings are given, they will be joined using + newline chars and parsed together. + This command is useful for adding records interactively to + the cache that cannot be defined using the "pdnsd-ctl add" + command, (e.g. soa records). + +empty-cache [[+|-]name ...] If no arguments are provided, the cache will be completely + emptied, freeing all existing entries. Note that this also + removes local records, as defined by the config file. To + restore local records, run "pdnsd-ctl config" or + "pdnsd-ctl include filename" immediately afterwards. + The "pdnsd-ctl empty-cache" command now accepts additional + arguments; these are interpreted as include/exclude names. + If an argument starts with a '+' the name will be + included. If an argument starts with a '-' it will be + excluded. If an argument does not begin with '+' or '-', a + '+' is assumed. If the domain name of a cache entry ends + in one of the names in the list, the first match will + determine what happens. If the matching name is to be + included, the cache entry is deleted, otherwise not. If + there are no matches, the default action is not to delete. + Note that if you want to delete exactly one name and no + others, you should use "pdnsd-ctl record name delete", + this is also much more efficient. + Examples: + pdnsd-ctl empty-cache + This command will remove all cache entries. + + pdnsd-ctl empty-cache microsoft.com msft.net + This will remove all entries ending in microsoft.com or + msft.net. + + pdnsd-ctl empty-cache -localdomain -168.192.in-addr.arpa . + This will remove all entries except those ending in + localdomain or 168.192.in-addr.arpa. Note that '.' is the + root domain which matches any domain name. + +dump [name] Print information stored in the cache about name. If name + begins with a dot and is not the root domain, information + about the names in the cache ending in name (including + name without the leading dot) will be printed. If name is + not specified, information about all the names in the + cache will be printed. + For each RR record the time and date that this record has + been added to the cache will be printed in the form mm/dd + HH:MM:SS (locally defined records are printed without a + time stamp). After that the type of record is printed with + the data. For the more common types of RR records the data + will be printed in human readable form, the remaining ones + in a hexadecimal representation. + This command is mainly useful for diagnostic purposes. + Note that if you pipe the output of this command through + an application that reads only part of the output and then + blocks (such as more or less), pdnsd will not be able to + add new entries to the cache until the pipe is closed. It + is preferable to capture the output in a file in such a + case. + +list-rrtypes List available rr types for the neg command. Note that + those are only used for the neg command, not for add! + + + +4 contrib/ + +The contrib directory in the pdnsd distribution contains useful +user-contributed scripts. +So far, there are scripts contributed by Marko Stolle and Paul Rombouts that +make pdnsd usable in a DHCP setup. Please take a look into the README file in +the contrib directory for further information. + + +5 Problems... + +If you have problems with configuring or running pdnsd, be sure to read the FAQ +. If this does not help you, pdnsd crashes or you find bugs, please mail one of +the authors. +Note added by Paul A. Rombouts: Thomas Moestl no longer maintains the code. I +have revised the code and added new features. See README.par and the ChangeLog +in the source directory (or /usr/share/doc/pdnsd- if you have +installed a binary package) for more details. If you have questions about my +modifications, you can find my email address at the end of README.par. + + +6 Hacking + +Here comes some information you might find useful for hacking pdnsd. + +6.1 Source files + +Makefile.am, autoconf/automake/autoheader scripts. Makefile.am's are in +configure.in, most subdirectories. +acconfig.h + +pdnsd.spec.in A template from which configure generates a spec file for + building rpm's for various distributions. + +version Contains only the program version string. Needed for + several templates. + +src/rc/* rc (start-up) scripts for various linux distributions. + + The pdnsd cache subsystem(s) as defined in src/cache.h. +src/cache.c This is the "traditional" pdnsd system which keeps the + cache in memory and uses hash tables for accesses. Sourav + K. Mandal is working on a system using gdbm. + +src/pdnsd-ctl/* Contains the code for pdnsd-ctl, a program that allows you + to control pdnsd at run time. + + The lex/flex source file for the config file lexer. This is +src/conf-lex.l.in a template because there might be inserted "%option + yylineno" for proper flex support. (obsolete, superseded by + src/conf-parser.c) + + This is automatically generated by configure from +src/conf-lex.l conf-lex.l.in. It may be overwritten in any make, so never + modify this, but conf-lex.l.in instead! (obsolete, + superseded by src/conf-parser.c) + +src/conf-parse.y The yacc/bison source of the config file parser. (obsolete, + superseded by src/conf-parser.c) + +src/conf-parser.c, The config file parser written purely in C (versions +src/conf-parser.h, 1.1.10-par and later). +src/conf-keywords.h + +src/conff.c, src/ The configuration handler functions and their prototypes. +conff.h The parser is called from here. + +src/consts.h Some constants used by the parser, config file handler + functions and in the server status thread, among others. + + Define dns message structures, constants, and some common +src/dns.c, src/dns.h dns data handlers. dns.h contains gcc-specific code (in + praticular, "__attribute__((packed))"). + +src/dns_answer.c, Define functions that answer incoming dns queries. +src/dns_answer.h + +src/dns_query.c, src Define functions to manage outgoing dns queries. +/dns_query.h + +src/error.c, src/ Functions for error output to stderr or the syslog, and +error.h debug output to stderr or pdnsd.debug. + +src/hash.c, src/ Contains the code for storing and looking up cache entries +hash.h in the hash table. + +src/helpers.c, src/ Define miscellaneous helper functions. +helpers.h + +src/icmp.c, src/ Define a function for performing a ping test. This contains +icmp.h OS-specific code. + +src/main.c Contains main(), which holds the command line parser, + performs initialisations and signal handling. + + Contains the code for the executable make_hashconvtable, +src/ which is only run once, during build time, to generate the +make_hashconvtable.c file hashconvtable.h, used by src/hash.c (versions + 1.1.10-par and later). (obsolete since version 1.2) + + A perl script for generating src/rr_types.h, a C header +src/ file containing macro definitions and tables needed for +make_rr_types_h.pl handling the RR types known to pdnsd, from the text file + src/rr_types.in. + +src/rr_types.c, src/ These define tables and macros needed for handling the RR +rr_types.h, src/ types known to pdnsd. Since version 1.2.9, rr_types.h is an +rr_types.in automatically generated file, see make_rr_types_h.pl. + +src/netdev.c, src/ Define functions for network device handling. OS-specific. +netdev.h + +src/servers.c, src/ Define functions for the server status thread that performs +servers.h the periodical uptests. + +src/status.c, src/ Define functions for the status control thread. This is +status.h pdnsd's interface to pdnsd-ctl. + + +------------------------------------------------------------------------------- + +Copyright (C) 2000, 2001 Thomas Moestl +Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2012 Paul A. Rombouts + +Last revised: 19 April 2012 by Paul A. Rombouts + diff --git a/jni/pdnsd/file-list.base.in b/jni/pdnsd/file-list.base.in new file mode 100644 index 00000000..409ba338 --- /dev/null +++ b/jni/pdnsd/file-list.base.in @@ -0,0 +1,5 @@ +%defattr(-,root,root) +%doc AUTHORS THANKS COPYING COPYING.BSD ChangeLog ChangeLog.old INSTALL NEWS README README.par README.par.old TODO +%config /etc/pdnsd.conf.sample +%attr(750, @def_id@, @def_id@) %dir @cachedir@ +%attr(640, @def_id@, @def_id@) %config @cachedir@/pdnsd.cache diff --git a/jni/pdnsd/install-sh b/jni/pdnsd/install-sh new file mode 100644 index 00000000..4d4a9519 --- /dev/null +++ b/jni/pdnsd/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/jni/pdnsd/missing b/jni/pdnsd/missing new file mode 100644 index 00000000..894e786e --- /dev/null +++ b/jni/pdnsd/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/jni/pdnsd/pdnsd.spec.in b/jni/pdnsd/pdnsd.spec.in new file mode 100644 index 00000000..6af6cdef --- /dev/null +++ b/jni/pdnsd/pdnsd.spec.in @@ -0,0 +1,244 @@ +# rpmbuild spec file for pdnsd. +# with modifications by Paul Rombouts. + +# Supported rpmbuild --define and --with options include: +# +# --with isdn Configure with --enable-isdn. +# +# --without poll Configure with --disable-poll +# +# --without nptl Configure with --with-thread-lib=linuxthreads. +# +# --with ipv6 Configure with --enable-ipv6. +# +# --without tcpqueries Configure with --disable-tcp-queries. +# +# --without debug Configure with --with-debug=0. +# +# --define "distro " Configure with --with-distribution=. +# +# --define "run_as_user " Configure with --with-default-id=. +# For RPMs the default is "@def_id@". +# +# --define "run_as_uid " If the user defined by the previous option does not exist +# when the RPM is installed, the pre-install script will try +# to create a new user with numerical id . +# +# --define "cachedir " Configure with --with-cachedir=. +# + +%{!?distro: %define distro @distribution@} + +# The default run_as ID to use +%{!?run_as_user: %define run_as_user @def_id@} +# By default, if a new run_as_user is to be created, we let +# useradd choose the numerical uid, unless run_as_uid is defined. +#define run_as_uid 96 +%{!?cachedir: %define cachedir @cachedir@} +%define conffile %{_sysconfdir}/pdnsd.conf + +Summary: A caching dns proxy for small networks or dialin accounts +Name: @PACKAGE@ +Version: @VERSION@ +Release: @packagerelease@ +License: GPLv3 +Group: Daemons +Source: http://members.home.nl/p.a.rombouts/pdnsd/releases/%{name}-%{version}-%{release}.tar.gz +URL: http://members.home.nl/p.a.rombouts/pdnsd.html +Vendor: Paul A. Rombouts +Packager: Paul A. Rombouts +Prefix: %{_prefix} +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +pdnsd is a proxy DNS daemon with permanent (disk-)cache and the ability +to serve local records. It is designed to detect network outages or hangups +and to prevent DNS-dependent applications like Netscape Navigator from hanging. + +The original author of pdnsd is Thomas Moestl, but pdnsd is no longer maintained +by him. This is an extensively revised version by Paul A. Rombouts. +For a description of the changes see http://members.home.nl/p.a.rombouts/pdnsd.html +and the file README.par in %{_docdir}/%{name}-%{version} + +%{!?distro:You can specify the target distribution when you build the source RPM. For instance, if you're building for a Red Hat system call rpmbuild with:} +%{!?distro: --define "distro RedHat"} +%{?distro:This package was built for a %{distro} distribution.} +%{!?_with_isdn:It's possible to rebuild the source RPM with isdn support using the rpmbuild option:} +%{!?_with_isdn: --with isdn} +%{?_with_isdn:This package was built with isdn support enabled.} +%{!?_with_ipv6:It's possible to rebuild the source RPM with ipv6 support using the rpmbuild option:} +%{!?_with_ipv6: --with ipv6} +%{?_with_ipv6:This package was built with ipv6 support.} +%{?_without_poll:This package was built with the select(2) function instead of poll(2).} + +%prep +%setup + +%build +CFLAGS="${CFLAGS:-$RPM_OPT_FLAGS -Wall}" ./configure \ + --prefix=%{_prefix} --sysconfdir=%{_sysconfdir} --mandir=%{_mandir} \ + --with-cachedir="%{cachedir}" \ + %{?distro:--with-distribution=%{distro}} --enable-specbuild \ + --with-default-id=%{run_as_user} \ + %{?_with_isdn:--enable-isdn} \ + %{?_without_poll:--disable-poll} \ + %{?_without_nptl:--with-thread-lib=linuxthreads} \ + %{?_with_ipv6:--enable-ipv6} \ + %{?_without_tcpqueries:--disable-tcp-queries} \ + %{?_without_debug:--with-debug=0} + +make + +%install +%if "%{run_as_user}" != "nobody" +[ "$(id -un)" != root ] || +id -u %{run_as_user} > /dev/null 2>&1 || +/usr/sbin/useradd -c "Proxy DNS daemon" %{?run_as_uid:-u %{run_as_uid}} \ + -s /sbin/nologin -r -d "%{cachedir}" %{run_as_user} || { + set +x + echo "Cannot create user \"%{run_as_user}\"%{?run_as_uid: with uid=%{run_as_uid}}" + echo "Please select another numerical uid and rebuild with --define \"run_as_uid uid\"" + echo "or create a user named \"%{run_as_user}\" by hand and try again." + exit 1 +} +%endif + +rm -rf "$RPM_BUILD_ROOT" +make DESTDIR="$RPM_BUILD_ROOT" install +cp -f file-list.base file-list +find doc contrib -not -type d -not -iname '*makefile' -not -name '*.am' \ + -not -name '*.in' -not -path 'doc/*.pl' | +sed -e 's/^/%doc --parents /' >> file-list +CURDIR=$PWD; cd "$RPM_BUILD_ROOT" +find . -not -type d '(' -not -name 'pdnsd.conf*' -or -name 'pdnsd.conf.[1-9]*' ')' \ + -not -path '.%{_docdir}/*' -not -path './var/*' | +sed -e 's/^\.// + \:/man:{ + /\.gz$/!s/$/.gz/ + }' >> "$CURDIR/file-list" + +%clean +rm -rf "$RPM_BUILD_ROOT" +#rm -rf %{_builddir}/%{name}-%{srcver} + +%files -f file-list + +%pre +# First stop any running pdnsd daemons +%if "%{distro}" == "SuSE" +/sbin/init.d/pdnsd stop >/dev/null 2>&1 +%endif +%if "%{distro}" == "RedHat" +if [ -f /var/lock/subsys/pdnsd ]; then + if /sbin/pidof pdnsd > /dev/null; then + /sbin/service pdnsd stop >/dev/null 2>&1 + if [ "$1" -ge 2 ]; then touch /var/lock/subsys/pdnsd; fi + else + rm -f /var/lock/subsys/pdnsd + fi +fi +%endif + +%if "%{run_as_user}" != "nobody" +# Add the "pdnsd" user +id -u %{run_as_user} > /dev/null 2>&1 || +/usr/sbin/useradd -c "Proxy DNS daemon" %{?run_as_uid:-u %{run_as_uid}} \ + -s /sbin/nologin -r -d "%{cachedir}" %{run_as_user} || { + echo "Cannot create user \"%{run_as_user}\"%{?run_as_uid: with uid=%{run_as_uid}}" + echo "Please create a user named \"%{run_as_user}\" by hand and try again." + exit 1 +} +[ "$(id -gn %{run_as_user})" = %{run_as_user} ] || { + echo "user \"%{run_as_user}\" does not have an corresponding group called \"%{run_as_user}\"" + echo "Please change the initial group of user \"%{run_as_user}\" to \"%{run_as_user}\" and try again." + exit 1 +} + +if [ -f "%{conffile}" ] && + grep -v -e '^[[:blank:]]*\(#\|\/\/\)' "%{conffile}" | + grep -q -e '\ "%{conffile}" && + echo "In %{conffile} runs_as=\"nobody\" has been replaced by run_as=\"%{run_as_user}\"" +fi +%endif + +if [ -f "%{cachedir}/pdnsd.cache" ]; then + chown -c %{run_as_user}:%{run_as_user} "%{cachedir}/pdnsd.cache" +fi + +%post +%if "%{distro}" == "SuSE" +if [ -w /etc/rc.config ]; then + grep "START_PDNSD" /etc/rc.config > /dev/null + if [ $? -ne 0 ] ; then + echo -e \ +"\n\n#\n# Set to yes to start pdnsd at boot time\n#\nSTART_PDNSD=yes" \ +>> /etc/rc.config + fi +fi +%endif +%if "%{distro}" == "RedHat" +if [ "$1" = 1 ]; then + /sbin/chkconfig --add pdnsd +fi +%endif + +%preun +%if "%{distro}" == "RedHat" +if [ "$1" = 0 ]; then + /sbin/service pdnsd stop >/dev/null 2>&1 + /sbin/chkconfig --del pdnsd +fi +%endif + +%postun +%if "%{distro}" == "RedHat" +if [ "$1" -ge 1 ]; then + /sbin/service pdnsd condrestart >/dev/null 2>&1 +fi +%endif + +%changelog +* Tue Jan 31 2012 Paul A. Rombouts +- Prevent makefiles and perl scripts from being installed + in the documentation directory. +* Sat Jan 28 2012 Paul A. Rombouts +- Update the (Source) URLs. +* Sat Aug 4 2007 Paul Rombouts +- License is now GPL version 3 +* Fri Mar 24 2006 Paul Rombouts +- Instead of using a fixed default value for run_as_uid, + I let useradd choose the uid if run_as_uid is undefined. +* Thu Dec 29 2005 Paul Rombouts +- TCP-query support is now compiled in by default, + but can be disabled using "--without tcpqueries". +* Sun Jul 20 2003 Paul Rombouts +- Changed default run_as ID from "nobody" to "pdnsd" +* Fri Jun 20 2003 Paul Rombouts +- Added configuration option for NPTL. +* Sat Jun 07 2003 Paul Rombouts +- Added automatic definition of distro using _vendor macro. +* Thu May 22 2003 Paul Rombouts +- Ensured that modification times of acconfig.h and configure.in + are not changed by patching to avoid unwanted reconfigure during make phase. +* Tue May 20 2003 Paul Rombouts +- Applied my customized patch file. See READ.par for details. +* Sun May 16 2001 Thomas Moestl +- Make use of chkconfig for Red Hat (patch by Christian Engstler) +* Sun Mar 25 2001 Thomas Moestl +- Merged SuSE fixes by Christian Engstler +* Fri Feb 09 2001 Thomas Moestl +- Merged in a spec fix for mapage inclusion contributed by Sourav K. + Mandal +* Sun Nov 26 2000 Thomas Moestl +- Added some patches contributed by Bernd Leibing +* Tue Aug 15 2000 Thomas Moestl +- Added the distro for configure +* Tue Jul 11 2000 Sourav K. Mandal +- autoconf/automake modifications diff --git a/jni/pdnsd/src/Makefile.am b/jni/pdnsd/src/Makefile.am new file mode 100644 index 00000000..959e669e --- /dev/null +++ b/jni/pdnsd/src/Makefile.am @@ -0,0 +1,24 @@ + +sbin_PROGRAMS = pdnsd + +pdnsd_CFLAGS = -DCONFDIR='"$(sysconfdir)"' $(thread_CFLAGS) + +pdnsd_SOURCES = conf-parser.c conff.c consts.c debug.c dns.c dns_answer.c \ + dns_query.c error.c helpers.c icmp.c list.c main.c netdev.c rr_types.c \ + status.c servers.c thread.c cache.c hash.c conf-parser.h \ + conf-keywords.h conff.h consts.h debug.h dns.h dns_answer.h \ + dns_query.h error.h helpers.h icmp.h ipvers.h list.h netdev.h \ + rr_types.h servers.h status.h thread.h cache.h hash.h pdnsd_assert.h \ + freebsd_netinet_ip_icmp.h + +EXTRA_DIST = make_rr_types_h.pl rr_types.in + +## Try to do this last + +SUBDIRS = . pdnsd-ctl rc test + +$(pdnsd_OBJECTS): rr_types.h + +rr_types.h: make_rr_types_h.pl rr_types.in + perl make_rr_types_h.pl rr_types.in > rr_types.h + diff --git a/jni/pdnsd/src/Makefile.in b/jni/pdnsd/src/Makefile.in new file mode 100644 index 00000000..75569a40 --- /dev/null +++ b/jni/pdnsd/src/Makefile.in @@ -0,0 +1,921 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +sbin_PROGRAMS = pdnsd$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" +PROGRAMS = $(sbin_PROGRAMS) +am_pdnsd_OBJECTS = pdnsd-conf-parser.$(OBJEXT) pdnsd-conff.$(OBJEXT) \ + pdnsd-consts.$(OBJEXT) pdnsd-debug.$(OBJEXT) \ + pdnsd-dns.$(OBJEXT) pdnsd-dns_answer.$(OBJEXT) \ + pdnsd-dns_query.$(OBJEXT) pdnsd-error.$(OBJEXT) \ + pdnsd-helpers.$(OBJEXT) pdnsd-icmp.$(OBJEXT) \ + pdnsd-list.$(OBJEXT) pdnsd-main.$(OBJEXT) \ + pdnsd-netdev.$(OBJEXT) pdnsd-rr_types.$(OBJEXT) \ + pdnsd-status.$(OBJEXT) pdnsd-servers.$(OBJEXT) \ + pdnsd-thread.$(OBJEXT) pdnsd-cache.$(OBJEXT) \ + pdnsd-hash.$(OBJEXT) +pdnsd_OBJECTS = $(am_pdnsd_OBJECTS) +pdnsd_LDADD = $(LDADD) +pdnsd_LINK = $(CCLD) $(pdnsd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(pdnsd_SOURCES) +DIST_SOURCES = $(pdnsd_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pdnsd_CFLAGS = -DCONFDIR='"$(sysconfdir)"' $(thread_CFLAGS) +pdnsd_SOURCES = conf-parser.c conff.c consts.c debug.c dns.c dns_answer.c \ + dns_query.c error.c helpers.c icmp.c list.c main.c netdev.c rr_types.c \ + status.c servers.c thread.c cache.c hash.c conf-parser.h \ + conf-keywords.h conff.h consts.h debug.h dns.h dns_answer.h \ + dns_query.h error.h helpers.h icmp.h ipvers.h list.h netdev.h \ + rr_types.h servers.h status.h thread.h cache.h hash.h pdnsd_assert.h \ + freebsd_netinet_ip_icmp.h + +EXTRA_DIST = make_rr_types_h.pl rr_types.in +SUBDIRS = . pdnsd-ctl rc test +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +pdnsd$(EXEEXT): $(pdnsd_OBJECTS) $(pdnsd_DEPENDENCIES) + @rm -f pdnsd$(EXEEXT) + $(pdnsd_LINK) $(pdnsd_OBJECTS) $(pdnsd_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-cache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-conf-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-conff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-consts.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-dns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-dns_answer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-dns_query.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-helpers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-icmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-netdev.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-rr_types.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-servers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-thread.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +pdnsd-conf-parser.o: conf-parser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-conf-parser.o -MD -MP -MF $(DEPDIR)/pdnsd-conf-parser.Tpo -c -o pdnsd-conf-parser.o `test -f 'conf-parser.c' || echo '$(srcdir)/'`conf-parser.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-conf-parser.Tpo $(DEPDIR)/pdnsd-conf-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conf-parser.c' object='pdnsd-conf-parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-conf-parser.o `test -f 'conf-parser.c' || echo '$(srcdir)/'`conf-parser.c + +pdnsd-conf-parser.obj: conf-parser.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-conf-parser.obj -MD -MP -MF $(DEPDIR)/pdnsd-conf-parser.Tpo -c -o pdnsd-conf-parser.obj `if test -f 'conf-parser.c'; then $(CYGPATH_W) 'conf-parser.c'; else $(CYGPATH_W) '$(srcdir)/conf-parser.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-conf-parser.Tpo $(DEPDIR)/pdnsd-conf-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conf-parser.c' object='pdnsd-conf-parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-conf-parser.obj `if test -f 'conf-parser.c'; then $(CYGPATH_W) 'conf-parser.c'; else $(CYGPATH_W) '$(srcdir)/conf-parser.c'; fi` + +pdnsd-conff.o: conff.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-conff.o -MD -MP -MF $(DEPDIR)/pdnsd-conff.Tpo -c -o pdnsd-conff.o `test -f 'conff.c' || echo '$(srcdir)/'`conff.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-conff.Tpo $(DEPDIR)/pdnsd-conff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conff.c' object='pdnsd-conff.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-conff.o `test -f 'conff.c' || echo '$(srcdir)/'`conff.c + +pdnsd-conff.obj: conff.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-conff.obj -MD -MP -MF $(DEPDIR)/pdnsd-conff.Tpo -c -o pdnsd-conff.obj `if test -f 'conff.c'; then $(CYGPATH_W) 'conff.c'; else $(CYGPATH_W) '$(srcdir)/conff.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-conff.Tpo $(DEPDIR)/pdnsd-conff.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='conff.c' object='pdnsd-conff.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-conff.obj `if test -f 'conff.c'; then $(CYGPATH_W) 'conff.c'; else $(CYGPATH_W) '$(srcdir)/conff.c'; fi` + +pdnsd-consts.o: consts.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-consts.o -MD -MP -MF $(DEPDIR)/pdnsd-consts.Tpo -c -o pdnsd-consts.o `test -f 'consts.c' || echo '$(srcdir)/'`consts.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-consts.Tpo $(DEPDIR)/pdnsd-consts.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='consts.c' object='pdnsd-consts.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-consts.o `test -f 'consts.c' || echo '$(srcdir)/'`consts.c + +pdnsd-consts.obj: consts.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-consts.obj -MD -MP -MF $(DEPDIR)/pdnsd-consts.Tpo -c -o pdnsd-consts.obj `if test -f 'consts.c'; then $(CYGPATH_W) 'consts.c'; else $(CYGPATH_W) '$(srcdir)/consts.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-consts.Tpo $(DEPDIR)/pdnsd-consts.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='consts.c' object='pdnsd-consts.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-consts.obj `if test -f 'consts.c'; then $(CYGPATH_W) 'consts.c'; else $(CYGPATH_W) '$(srcdir)/consts.c'; fi` + +pdnsd-debug.o: debug.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-debug.o -MD -MP -MF $(DEPDIR)/pdnsd-debug.Tpo -c -o pdnsd-debug.o `test -f 'debug.c' || echo '$(srcdir)/'`debug.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-debug.Tpo $(DEPDIR)/pdnsd-debug.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='debug.c' object='pdnsd-debug.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-debug.o `test -f 'debug.c' || echo '$(srcdir)/'`debug.c + +pdnsd-debug.obj: debug.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-debug.obj -MD -MP -MF $(DEPDIR)/pdnsd-debug.Tpo -c -o pdnsd-debug.obj `if test -f 'debug.c'; then $(CYGPATH_W) 'debug.c'; else $(CYGPATH_W) '$(srcdir)/debug.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-debug.Tpo $(DEPDIR)/pdnsd-debug.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='debug.c' object='pdnsd-debug.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-debug.obj `if test -f 'debug.c'; then $(CYGPATH_W) 'debug.c'; else $(CYGPATH_W) '$(srcdir)/debug.c'; fi` + +pdnsd-dns.o: dns.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns.o -MD -MP -MF $(DEPDIR)/pdnsd-dns.Tpo -c -o pdnsd-dns.o `test -f 'dns.c' || echo '$(srcdir)/'`dns.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns.Tpo $(DEPDIR)/pdnsd-dns.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns.c' object='pdnsd-dns.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns.o `test -f 'dns.c' || echo '$(srcdir)/'`dns.c + +pdnsd-dns.obj: dns.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns.obj -MD -MP -MF $(DEPDIR)/pdnsd-dns.Tpo -c -o pdnsd-dns.obj `if test -f 'dns.c'; then $(CYGPATH_W) 'dns.c'; else $(CYGPATH_W) '$(srcdir)/dns.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns.Tpo $(DEPDIR)/pdnsd-dns.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns.c' object='pdnsd-dns.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns.obj `if test -f 'dns.c'; then $(CYGPATH_W) 'dns.c'; else $(CYGPATH_W) '$(srcdir)/dns.c'; fi` + +pdnsd-dns_answer.o: dns_answer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns_answer.o -MD -MP -MF $(DEPDIR)/pdnsd-dns_answer.Tpo -c -o pdnsd-dns_answer.o `test -f 'dns_answer.c' || echo '$(srcdir)/'`dns_answer.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns_answer.Tpo $(DEPDIR)/pdnsd-dns_answer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns_answer.c' object='pdnsd-dns_answer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns_answer.o `test -f 'dns_answer.c' || echo '$(srcdir)/'`dns_answer.c + +pdnsd-dns_answer.obj: dns_answer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns_answer.obj -MD -MP -MF $(DEPDIR)/pdnsd-dns_answer.Tpo -c -o pdnsd-dns_answer.obj `if test -f 'dns_answer.c'; then $(CYGPATH_W) 'dns_answer.c'; else $(CYGPATH_W) '$(srcdir)/dns_answer.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns_answer.Tpo $(DEPDIR)/pdnsd-dns_answer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns_answer.c' object='pdnsd-dns_answer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns_answer.obj `if test -f 'dns_answer.c'; then $(CYGPATH_W) 'dns_answer.c'; else $(CYGPATH_W) '$(srcdir)/dns_answer.c'; fi` + +pdnsd-dns_query.o: dns_query.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns_query.o -MD -MP -MF $(DEPDIR)/pdnsd-dns_query.Tpo -c -o pdnsd-dns_query.o `test -f 'dns_query.c' || echo '$(srcdir)/'`dns_query.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns_query.Tpo $(DEPDIR)/pdnsd-dns_query.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns_query.c' object='pdnsd-dns_query.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns_query.o `test -f 'dns_query.c' || echo '$(srcdir)/'`dns_query.c + +pdnsd-dns_query.obj: dns_query.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-dns_query.obj -MD -MP -MF $(DEPDIR)/pdnsd-dns_query.Tpo -c -o pdnsd-dns_query.obj `if test -f 'dns_query.c'; then $(CYGPATH_W) 'dns_query.c'; else $(CYGPATH_W) '$(srcdir)/dns_query.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-dns_query.Tpo $(DEPDIR)/pdnsd-dns_query.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dns_query.c' object='pdnsd-dns_query.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-dns_query.obj `if test -f 'dns_query.c'; then $(CYGPATH_W) 'dns_query.c'; else $(CYGPATH_W) '$(srcdir)/dns_query.c'; fi` + +pdnsd-error.o: error.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-error.o -MD -MP -MF $(DEPDIR)/pdnsd-error.Tpo -c -o pdnsd-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-error.Tpo $(DEPDIR)/pdnsd-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='error.c' object='pdnsd-error.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-error.o `test -f 'error.c' || echo '$(srcdir)/'`error.c + +pdnsd-error.obj: error.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-error.obj -MD -MP -MF $(DEPDIR)/pdnsd-error.Tpo -c -o pdnsd-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-error.Tpo $(DEPDIR)/pdnsd-error.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='error.c' object='pdnsd-error.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-error.obj `if test -f 'error.c'; then $(CYGPATH_W) 'error.c'; else $(CYGPATH_W) '$(srcdir)/error.c'; fi` + +pdnsd-helpers.o: helpers.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-helpers.o -MD -MP -MF $(DEPDIR)/pdnsd-helpers.Tpo -c -o pdnsd-helpers.o `test -f 'helpers.c' || echo '$(srcdir)/'`helpers.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-helpers.Tpo $(DEPDIR)/pdnsd-helpers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpers.c' object='pdnsd-helpers.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-helpers.o `test -f 'helpers.c' || echo '$(srcdir)/'`helpers.c + +pdnsd-helpers.obj: helpers.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-helpers.obj -MD -MP -MF $(DEPDIR)/pdnsd-helpers.Tpo -c -o pdnsd-helpers.obj `if test -f 'helpers.c'; then $(CYGPATH_W) 'helpers.c'; else $(CYGPATH_W) '$(srcdir)/helpers.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-helpers.Tpo $(DEPDIR)/pdnsd-helpers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='helpers.c' object='pdnsd-helpers.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-helpers.obj `if test -f 'helpers.c'; then $(CYGPATH_W) 'helpers.c'; else $(CYGPATH_W) '$(srcdir)/helpers.c'; fi` + +pdnsd-icmp.o: icmp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-icmp.o -MD -MP -MF $(DEPDIR)/pdnsd-icmp.Tpo -c -o pdnsd-icmp.o `test -f 'icmp.c' || echo '$(srcdir)/'`icmp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-icmp.Tpo $(DEPDIR)/pdnsd-icmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='icmp.c' object='pdnsd-icmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-icmp.o `test -f 'icmp.c' || echo '$(srcdir)/'`icmp.c + +pdnsd-icmp.obj: icmp.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-icmp.obj -MD -MP -MF $(DEPDIR)/pdnsd-icmp.Tpo -c -o pdnsd-icmp.obj `if test -f 'icmp.c'; then $(CYGPATH_W) 'icmp.c'; else $(CYGPATH_W) '$(srcdir)/icmp.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-icmp.Tpo $(DEPDIR)/pdnsd-icmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='icmp.c' object='pdnsd-icmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-icmp.obj `if test -f 'icmp.c'; then $(CYGPATH_W) 'icmp.c'; else $(CYGPATH_W) '$(srcdir)/icmp.c'; fi` + +pdnsd-list.o: list.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-list.o -MD -MP -MF $(DEPDIR)/pdnsd-list.Tpo -c -o pdnsd-list.o `test -f 'list.c' || echo '$(srcdir)/'`list.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-list.Tpo $(DEPDIR)/pdnsd-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='list.c' object='pdnsd-list.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-list.o `test -f 'list.c' || echo '$(srcdir)/'`list.c + +pdnsd-list.obj: list.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-list.obj -MD -MP -MF $(DEPDIR)/pdnsd-list.Tpo -c -o pdnsd-list.obj `if test -f 'list.c'; then $(CYGPATH_W) 'list.c'; else $(CYGPATH_W) '$(srcdir)/list.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-list.Tpo $(DEPDIR)/pdnsd-list.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='list.c' object='pdnsd-list.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-list.obj `if test -f 'list.c'; then $(CYGPATH_W) 'list.c'; else $(CYGPATH_W) '$(srcdir)/list.c'; fi` + +pdnsd-main.o: main.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-main.o -MD -MP -MF $(DEPDIR)/pdnsd-main.Tpo -c -o pdnsd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-main.Tpo $(DEPDIR)/pdnsd-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='pdnsd-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c + +pdnsd-main.obj: main.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-main.obj -MD -MP -MF $(DEPDIR)/pdnsd-main.Tpo -c -o pdnsd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-main.Tpo $(DEPDIR)/pdnsd-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='pdnsd-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` + +pdnsd-netdev.o: netdev.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-netdev.o -MD -MP -MF $(DEPDIR)/pdnsd-netdev.Tpo -c -o pdnsd-netdev.o `test -f 'netdev.c' || echo '$(srcdir)/'`netdev.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-netdev.Tpo $(DEPDIR)/pdnsd-netdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='netdev.c' object='pdnsd-netdev.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-netdev.o `test -f 'netdev.c' || echo '$(srcdir)/'`netdev.c + +pdnsd-netdev.obj: netdev.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-netdev.obj -MD -MP -MF $(DEPDIR)/pdnsd-netdev.Tpo -c -o pdnsd-netdev.obj `if test -f 'netdev.c'; then $(CYGPATH_W) 'netdev.c'; else $(CYGPATH_W) '$(srcdir)/netdev.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-netdev.Tpo $(DEPDIR)/pdnsd-netdev.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='netdev.c' object='pdnsd-netdev.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-netdev.obj `if test -f 'netdev.c'; then $(CYGPATH_W) 'netdev.c'; else $(CYGPATH_W) '$(srcdir)/netdev.c'; fi` + +pdnsd-rr_types.o: rr_types.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-rr_types.o -MD -MP -MF $(DEPDIR)/pdnsd-rr_types.Tpo -c -o pdnsd-rr_types.o `test -f 'rr_types.c' || echo '$(srcdir)/'`rr_types.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-rr_types.Tpo $(DEPDIR)/pdnsd-rr_types.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rr_types.c' object='pdnsd-rr_types.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-rr_types.o `test -f 'rr_types.c' || echo '$(srcdir)/'`rr_types.c + +pdnsd-rr_types.obj: rr_types.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-rr_types.obj -MD -MP -MF $(DEPDIR)/pdnsd-rr_types.Tpo -c -o pdnsd-rr_types.obj `if test -f 'rr_types.c'; then $(CYGPATH_W) 'rr_types.c'; else $(CYGPATH_W) '$(srcdir)/rr_types.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-rr_types.Tpo $(DEPDIR)/pdnsd-rr_types.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rr_types.c' object='pdnsd-rr_types.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-rr_types.obj `if test -f 'rr_types.c'; then $(CYGPATH_W) 'rr_types.c'; else $(CYGPATH_W) '$(srcdir)/rr_types.c'; fi` + +pdnsd-status.o: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-status.o -MD -MP -MF $(DEPDIR)/pdnsd-status.Tpo -c -o pdnsd-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-status.Tpo $(DEPDIR)/pdnsd-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='pdnsd-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-status.o `test -f 'status.c' || echo '$(srcdir)/'`status.c + +pdnsd-status.obj: status.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-status.obj -MD -MP -MF $(DEPDIR)/pdnsd-status.Tpo -c -o pdnsd-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-status.Tpo $(DEPDIR)/pdnsd-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='status.c' object='pdnsd-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-status.obj `if test -f 'status.c'; then $(CYGPATH_W) 'status.c'; else $(CYGPATH_W) '$(srcdir)/status.c'; fi` + +pdnsd-servers.o: servers.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-servers.o -MD -MP -MF $(DEPDIR)/pdnsd-servers.Tpo -c -o pdnsd-servers.o `test -f 'servers.c' || echo '$(srcdir)/'`servers.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-servers.Tpo $(DEPDIR)/pdnsd-servers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='servers.c' object='pdnsd-servers.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-servers.o `test -f 'servers.c' || echo '$(srcdir)/'`servers.c + +pdnsd-servers.obj: servers.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-servers.obj -MD -MP -MF $(DEPDIR)/pdnsd-servers.Tpo -c -o pdnsd-servers.obj `if test -f 'servers.c'; then $(CYGPATH_W) 'servers.c'; else $(CYGPATH_W) '$(srcdir)/servers.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-servers.Tpo $(DEPDIR)/pdnsd-servers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='servers.c' object='pdnsd-servers.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-servers.obj `if test -f 'servers.c'; then $(CYGPATH_W) 'servers.c'; else $(CYGPATH_W) '$(srcdir)/servers.c'; fi` + +pdnsd-thread.o: thread.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-thread.o -MD -MP -MF $(DEPDIR)/pdnsd-thread.Tpo -c -o pdnsd-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-thread.Tpo $(DEPDIR)/pdnsd-thread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='pdnsd-thread.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-thread.o `test -f 'thread.c' || echo '$(srcdir)/'`thread.c + +pdnsd-thread.obj: thread.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-thread.obj -MD -MP -MF $(DEPDIR)/pdnsd-thread.Tpo -c -o pdnsd-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-thread.Tpo $(DEPDIR)/pdnsd-thread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread.c' object='pdnsd-thread.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-thread.obj `if test -f 'thread.c'; then $(CYGPATH_W) 'thread.c'; else $(CYGPATH_W) '$(srcdir)/thread.c'; fi` + +pdnsd-cache.o: cache.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-cache.o -MD -MP -MF $(DEPDIR)/pdnsd-cache.Tpo -c -o pdnsd-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-cache.Tpo $(DEPDIR)/pdnsd-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='pdnsd-cache.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-cache.o `test -f 'cache.c' || echo '$(srcdir)/'`cache.c + +pdnsd-cache.obj: cache.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-cache.obj -MD -MP -MF $(DEPDIR)/pdnsd-cache.Tpo -c -o pdnsd-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-cache.Tpo $(DEPDIR)/pdnsd-cache.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='pdnsd-cache.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-cache.obj `if test -f 'cache.c'; then $(CYGPATH_W) 'cache.c'; else $(CYGPATH_W) '$(srcdir)/cache.c'; fi` + +pdnsd-hash.o: hash.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-hash.o -MD -MP -MF $(DEPDIR)/pdnsd-hash.Tpo -c -o pdnsd-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-hash.Tpo $(DEPDIR)/pdnsd-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='pdnsd-hash.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-hash.o `test -f 'hash.c' || echo '$(srcdir)/'`hash.c + +pdnsd-hash.obj: hash.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -MT pdnsd-hash.obj -MD -MP -MF $(DEPDIR)/pdnsd-hash.Tpo -c -o pdnsd-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pdnsd-hash.Tpo $(DEPDIR)/pdnsd-hash.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hash.c' object='pdnsd-hash.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pdnsd_CFLAGS) $(CFLAGS) -c -o pdnsd-hash.obj `if test -f 'hash.c'; then $(CYGPATH_W) 'hash.c'; else $(CYGPATH_W) '$(srcdir)/hash.c'; fi` + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-sbinPROGRAMS + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic \ + clean-sbinPROGRAMS ctags ctags-recursive distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am \ + uninstall-sbinPROGRAMS + + +$(pdnsd_OBJECTS): rr_types.h + +rr_types.h: make_rr_types_h.pl rr_types.in + perl make_rr_types_h.pl rr_types.in > rr_types.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/cache.c b/jni/pdnsd/src/cache.c new file mode 100644 index 00000000..4fbb7fb9 --- /dev/null +++ b/jni/pdnsd/src/cache.c @@ -0,0 +1,2723 @@ +/* cache.c - Keep the dns caches. + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2004, 2005, 2007, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cache.h" +#include "hash.h" +#include "conff.h" +#include "helpers.h" +#include "dns.h" +#include "error.h" +#include "debug.h" +#include "thread.h" +#include "ipvers.h" + + +/* A version identifier to prevent reading incompatible cache files */ +static const char cachverid[] = {'p','d','1','3'}; + +/* CACHE STRUCTURE CHANGES IN PDNSD 1.0.0 + * Prior to version 1.0.0, the cache was managed at domain granularity (all records of a domain were handled as a unit), + * which was suboptimal after the lean query feature and the additional record management were included. + * From 1.0.0 on, the cache management was switched to act with RR set granularity. The API of the cache handlers was + * slightly modified, in particular the rr_bucket_t was modified and some parameter list were changed. The cache + * file format had to be changed and is incompatible now. This means that post-1.0.0p1 versions will not read the cache + * files of older versions and vice versa. In addition, cache files from 1.0.0p5 on are incompatible to those of 1.0.0p1 + * to 1.0.0p4. Better delete them before upgrading. + * The "cent" lists common to old versions have vanished; the only access point to the cent's is the hash. + * However, there are now double linked rrset lists. Thus, rrs can be acces through the hash or through the rrset lists. + * The rrset list entries need some additional entries to manage the deletion from rrs lists as well as from the cents. + * + * Nearly all cache functions had to be changed significantly or even to be rewritten for that. Expect some beta time + * because of that. + * There are bonuses visible to the users resulting from this changes however: more consistent cache handling (under + * some circumstances, rrs could be in the cache more than once) and reduced memory requirements, as no rr needs + * to have stored its oname any more. There are more pointers however, and in some cases (CNAMES) the memory require- + * ments for some records may increase. The total should be lower, however. + * + * RRSET_L LIST STRUCTURE: + * The rrset_l rrset list is a simple double-linked list. The oldest entries are at the first positions, the list is sorted + * by age in descending order. Search is done only on insert. + * The rationale for this form is: + * - the purging operation needs to be fast (this way, the first records are the oldest and can easily be purged) + * - the append operation is common and needs to be fast (in normal operation, an appended record was just retrieved + * and therefore is the newest, so it can be appended at the end of the list without search. Only in the case of + * reading a disk cache file, searches are necessary) + * The rrset list is excusively used for purging purposes. + * + * THE DISK CACHE FILES: + * The disk cache file consists of cent's, i.e. structures for every known hostnames with a header and rrs attached to it. + * Therefore, the rr's are not ordered by their age and a search must be performed to insert the into the rr_l in the + * right positions. This operations has some costs (although not all too much), but the other way (rrs stored in order + * of their age and the cent headers separated from them), the rrs would need to be attached to the cent headers, which + * would be even more costly, also in means of disk space. + * + * CHANGES AFTER 1.0.0p1 + * In 1.0.0p5, the cache granularity was changed from rr level to rr set level. This was done because rfc2181 demands + * rr set consistency constraints on rr set level and if we are doing so we can as well save space (and eliminate some + * error-prone algorithms). + * + * CHANGES FOR 1.1.0p1 + * In this version, negative caching support was introduced. Following things were changed for that: + * - new members ts, ttl and flags in dns_cent_t and dns_file_t + * - new caching flag CF_NEGATIVE + * - all functions must accept and deal correctly with empty cents with DF_NEGATIVE set. + * - all functions must accept and deal correctly with empty rrsets with CF_NEGATIVE set. + */ + + +/* + * This is the size the memory cache may exceed the size of the permanent cache. + */ +#define MCSZ 10240 + +/* Some structs used for storing cache entries in a file. */ +typedef struct { + unsigned short rdlen; +/* data (with length rdlen) follows here;*/ +} rr_fbucket_t; + +typedef struct { + unsigned char tp; /* RR type */ + unsigned char num_rr; /* Number of records in RR set. */ + unsigned short flags; /* Flags for RR set. */ + time_t ttl; + time_t ts; +} __attribute__((packed)) +rr_fset_t; + +#if NRRTOT>255 +#warning "Number of cache-able RR types is greater than 255. This can give problems when saving the cache to file." +#endif + +typedef struct { + unsigned char qlen; /* Length of the domain name which follows after the struct. */ + unsigned char num_rrs; /* Number of RR-sets. */ + unsigned short flags; /* Flags for the whole cent. */ + unsigned char c_ns,c_soa; /* Number of trailing name elements in qname to use to find NS or SOA + records to add to the authority section of a response. */ + /* ttl and ts follow but only for negatively cached domains. */ + /* qname (with length qlen) follows here. */ +} __attribute__((packed)) +dns_file_t; + + +/* TTL and timestamp for negatively cached domains. */ +typedef struct { + time_t ttl; + time_t ts; +} __attribute__((packed)) +dom_fttlts_t; + +/* + * This has two modes: Normally, we have rrset, cent and idx filled in; + * for negatively cached cents, we have rrset set to NULL and idx set to -1. + */ +typedef struct rr_lent_s { + struct rr_lent_s *next; + struct rr_lent_s *prev; + rr_set_t *rrset; + dns_cent_t *cent; + int idx; /* This is the array index, not the type of the RR-set. */ +} rr_lent_t; + + +static rr_lent_t *rrset_l=NULL; +static rr_lent_t *rrset_l_tail=NULL; + +/* + * We do not count the hash table sizes here. Those are very small compared + * to the cache entries. + */ +static volatile long cache_size=0; +static volatile long ent_num=0; + +static volatile int cache_w_lock=0; +static volatile int cache_r_lock=0; + +pthread_mutex_t lock_mutex = PTHREAD_MUTEX_INITIALIZER; +/* + * These are condition variables for lock coordination, so that normal lock + * routines do not need to loop. Basically, a process wanting to acquire a lock + * tries first to lock, and if the lock is busy, sleeps on one of the conds. + * If the r lock count has gone to zero one process sleeping on the rw cond + * will be awankened. + * If the rw lock is lifted, either all threads waiting on the r lock or one + * thread waiting on the rw lock is/are awakened. This is determined by policy. + */ +pthread_cond_t rw_cond = PTHREAD_COND_INITIALIZER; +pthread_cond_t r_cond = PTHREAD_COND_INITIALIZER; + +/* This is to suspend the r lock to avoid lock contention by reading threads */ +static volatile int r_pend=0; +static volatile int rw_pend=0; +static volatile int r_susp=0; + +/* This threshold is used to temporarily suspend r locking to give rw locking + * a chance. */ +#define SUSP_THRESH(r_pend) (r_pend/2+2) + +/* + * This is set to 1 once the lock is intialized. This must happen before we get + * multiple threads. + */ +volatile short int use_cache_lock=0; + +/* + This is set to 0 while cache is read from disk. + This must be set to 1 before we start adding new entries. +*/ +static short int insert_sort=1; + + +#ifdef ALLOC_DEBUG +#define cache_free(ptr) { if (dbg) pdnsd_free(ptr); else free(ptr); } +#define cache_malloc(sz) ((dbg)?(pdnsd_malloc(sz)):(malloc(sz))) +#define cache_calloc(n,sz) ((dbg)?(pdnsd_calloc(n,sz)):(calloc(n,sz))) +#define cache_realloc(ptr,sz) ((dbg)?(pdnsd_realloc(ptr,sz)):(realloc(ptr,sz))) +#else +#define cache_free(ptr) {free(ptr);} +#define cache_malloc(sz) (malloc(sz)) +#define cache_calloc(n,sz) (calloc(n,sz)) +#define cache_realloc(ptr,sz) (realloc(ptr,sz)) +#endif + + +/* + * Prototypes for internal use + */ +static void purge_cache(long sz, int lazy); +static void del_cache_ent(dns_cent_t *cent,dns_hash_loc_t *loc); +static void remove_rrl(rr_lent_t *le DBGPARAM); + +/* + * Locking functions. + */ + +/* + * Lock/unlock cache for reading. Concurrent reads are allowed, while writes are forbidden. + * DO NOT MIX THE LOCK TYPES UP WHEN LOCKING/UNLOCKING! + * + * We use a mutex to lock the access to the locks ;-). + * This is because we do not allow read and write to interfere (for which a normal mutex would be + * fine), but we also want to allow concurrent reads. + * We use condition variables, and readlock contention protection. + */ +static void lock_cache_r(void) +{ + if (!use_cache_lock) + return; + pthread_mutex_lock(&lock_mutex); + r_pend++; + while(((rw_pend>SUSP_THRESH(r_pend))?(r_susp=1):r_susp) || cache_w_lock) { + /* This will unlock the mutex while sleeping and relock it before exit */ + pthread_cond_wait(&r_cond, &lock_mutex); + } + cache_r_lock++; + r_pend--; + pthread_mutex_unlock(&lock_mutex); +} + +static void unlock_cache_r(void) +{ + if (!use_cache_lock) + return; + pthread_mutex_lock(&lock_mutex); + if (cache_r_lock>0) + cache_r_lock--; + /* wakeup threads waiting to write */ + if (!cache_r_lock) + pthread_cond_signal(&rw_cond); + pthread_mutex_unlock(&lock_mutex); +} + +/* + * Lock/unlock cache for reading and writing. Concurrent reads and writes are forbidden. + * Do this only if you actually modify the cache. + * DO NOT MIX THE LOCK TYPES UP WHEN LOCKING/UNLOCKING! + * (cant say it often enough) + */ +static void lock_cache_rw(void) +{ + if (!use_cache_lock) + return; + pthread_mutex_lock(&lock_mutex); + rw_pend++; + while(cache_w_lock || cache_r_lock) { + /* This will unlock the mutex while sleeping and relock it before exit */ + pthread_cond_wait(&rw_cond, &lock_mutex); + } + cache_w_lock=1; + rw_pend--; + pthread_mutex_unlock(&lock_mutex); +} + +/* Lock cache for reading and writing, or time out after tm seconds. */ +static int timedlock_cache_rw(int tm) +{ + int retval=0; + struct timeval now; + struct timespec timeout; + + if (!use_cache_lock) + return 0; + pthread_mutex_lock(&lock_mutex); + gettimeofday(&now,NULL); + timeout.tv_sec = now.tv_sec + tm; + timeout.tv_nsec = now.tv_usec * 1000; + rw_pend++; + while(cache_w_lock || cache_r_lock) { + /* This will unlock the mutex while sleeping and relock it before exit */ + if(pthread_cond_timedwait(&rw_cond, &lock_mutex, &timeout) == ETIMEDOUT) + goto cleanup_return; + } + cache_w_lock=1; + retval=1; + cleanup_return: + rw_pend--; + pthread_mutex_unlock(&lock_mutex); + return retval; +} + +static void unlock_cache_rw(void) +{ + if (!use_cache_lock) + return; + pthread_mutex_lock(&lock_mutex); + cache_w_lock=0; + /* always reset r suspension (r locking code will set it again) */ + r_susp=0; + /* wakeup threads waiting to read or write */ + if (r_pend==0 || rw_pend>SUSP_THRESH(r_pend)) + pthread_cond_signal(&rw_cond); /* schedule another rw proc */ + else + pthread_cond_broadcast(&r_cond); /* let 'em all read */ + pthread_mutex_unlock(&lock_mutex); +} + + +/* + If there are other threads waiting to read from or write to + the cache, give up the read/write lock on the cache to give another + thread a chance; then try to get the lock back again. + This can be called regularly during a process that takes + a lot of processor time but has low priority, in order to improve + overall responsiveness. +*/ +static void yield_lock_cache_rw() +{ + if (!use_cache_lock || (!r_pend && !rw_pend)) + return; + + /* Give up the lock */ + pthread_mutex_lock(&lock_mutex); + cache_w_lock=0; + /* always reset r suspension (r locking code will set it again) */ + r_susp=0; + /* wakeup threads waiting to read or write */ + if (r_pend==0 || rw_pend>SUSP_THRESH(r_pend)) + pthread_cond_signal(&rw_cond); /* schedule another rw proc */ + else + pthread_cond_broadcast(&r_cond); /* let 'em all read */ + pthread_mutex_unlock(&lock_mutex); + + usleep_r(1000); + + /* Now try to get the lock back again */ + pthread_mutex_lock(&lock_mutex); + rw_pend++; + while(cache_w_lock || cache_r_lock) { + /* This will unlock the mutex while sleeping and relock it before exit */ + pthread_cond_wait(&rw_cond, &lock_mutex); + } + cache_w_lock=1; + rw_pend--; + pthread_mutex_unlock(&lock_mutex); +} + +/* These are a special version of the ordinary read lock functions. The lock "soft" to avoid deadlocks: they will give up + * after a certain number of bad trials. You have to check the exit status though. + * To avoid blocking mutexes, we cannot use condition variables here. Never mind, these are only used on + * exit. */ +static int softlock_cache_r(void) +{ + if (!use_cache_lock) + return 0; + { + int lk=0,tr=0; + + for(;;) { + if (!softlock_mutex(&lock_mutex)) + return 0; + if(!cache_w_lock) { + lk=1; + cache_r_lock++; + } + pthread_mutex_unlock(&lock_mutex); + if (lk) break; + if (++tr>=SOFTLOCK_MAXTRIES) + return 0; + usleep_r(1000); /*give contol back to the scheduler instead of hammering the lock close*/ + } + } + return 1; +} + +/* On unlocking, we do not wake others. We are about to exit! */ +static int softunlock_cache_r(void) +{ + if (!use_cache_lock) + return 0; + if (!softlock_mutex(&lock_mutex)) + return 0; + if (cache_r_lock>0) + cache_r_lock--; + pthread_mutex_unlock(&lock_mutex); + return 1; +} + +static int softlock_cache_rw(void) +{ + if (!use_cache_lock) + return 0; + { + int lk=0,tr=0; + + for(;;) { + if (!softlock_mutex(&lock_mutex)) + return 0; + if (!(cache_w_lock || cache_r_lock)) { + lk=1; + cache_w_lock=1; + } + pthread_mutex_unlock(&lock_mutex); + if(lk) break; + if (++tr>=SOFTLOCK_MAXTRIES) + return 0; + usleep_r(1000); /*give contol back to the scheduler instead of hammering the lock close*/ + } + } + return 1; +} + +static int softunlock_cache_rw(void) +{ + if (!use_cache_lock) + return 0; + if (!softlock_mutex(&lock_mutex)) + return 0; + cache_w_lock=0; + pthread_mutex_unlock(&lock_mutex); + return 1; +} + +/* + * Serial numbers: Serial numbers are used when additional records are added to the cache: serial numbers are unique to each + * query, so we can determine whether data was added by the query just executed (records can coexist) or not (records must + * be replaced). A serial of 0 is special and will not be used by any query. All records added added authoritatively (as + * chunk) or read from a file can have no query in process and therefore have serial 0, which is != any other serial. + */ +#if 0 +unsigned long l_serial=1; + +unsigned long get_serial() +{ + unsigned long rv; + lock_cache_rw(); + rv=l_serial++; + unlock_cache_rw(); + return rv; +} +#endif + +/* + * Cache/cent handlers + */ + +/* Initialize the cache. Call only once. */ +#if 0 +void init_cache() +{ + mk_hash_ctable(); + mk_dns_hash(); +} +#endif + +/* Initialize the cache lock. Call only once. */ +/* This is now defined as an inline function in cache.h */ +#if 0 +void init_cache_lock() +{ + + use_cache_lock=1; +} +#endif + +/* Empty the cache, freeing all entries that match the include/exclude list. */ +int empty_cache(slist_array sla) +{ + int i; + + /* Wait at most 60 seconds to obtain a lock. */ + if(!timedlock_cache_rw(60)) + return 0; + + for(i=0; ; ) { + if(sla) + free_dns_hash_selected(i,sla); + else + free_dns_hash_bucket(i); + if(++i>=HASH_NUM_BUCKETS) + break; + /* Give another thread a chance */ + yield_lock_cache_rw(); + } + + unlock_cache_rw(); + return 1; +} + +/* Delete the cache. Call only once */ +void destroy_cache() +{ + /* lock the cache, in case that any thread is still accessing. */ + if(!softlock_cache_rw()) { + log_error("Lock failed; could not destroy cache on exit."); + return; + } + free_dns_hash(); +#if DEBUG>0 + if(ent_num || cache_size) { + DEBUG_MSG("After destroying cache, %ld entries (%ld bytes) remaining.\n",ent_num,cache_size); + } +#endif + +#if 0 +#if (TARGET!=TARGET_LINUX) + /* under Linux, this frees no resources but may hang on a crash */ + pthread_mutex_destroy(&lock_mutex); + pthread_cond_destroy(&rw_cond); + pthread_cond_destroy(&r_cond); +#endif +#endif +} + +/* Make a flag value for a dns_cent_t (dns cache entry) from a server record */ +/* Now defined as inline function in cache.h */ +#if 0 +unsigned int mk_flag_val(servparm_t *server) +{ + unsigned int fl=0; + if (!server->purge_cache) + fl|=CF_NOPURGE; + if (server->nocache) + fl|=CF_NOCACHE; + if (server->rootserver) + fl|=CF_ROOTSERV; + return fl; +} +#endif + +/* Initialize a dns cache record (dns_cent_t) with the query name (in + * transport format), a flag value, a timestamp indicating + * the time the query was done, and a TTL. The timestamp and TTL + * are only used if DF_NEGATIVE is set in the flags. Otherwise, + * the timestamps of the individual records are used. DF_NEGATIVE + * is used for whole-domain negative caching. + * By convention, ttl and ts should be set to 0, unless the + * DF_NEGATIVE bit is set. */ +int init_cent(dns_cent_t *cent, const unsigned char *qname, time_t ttl, time_t ts, unsigned flags DBGPARAM) +{ + int i; + size_t namesz=rhnlen(qname); + + cent->qname=cache_malloc(namesz); + if (cent->qname == NULL) + return 0; + memcpy(cent->qname,qname,namesz); + cent->cs=sizeof(dns_cent_t)+namesz; + cent->num_rrs=0; + cent->flags=flags; + if(flags&DF_NEGATIVE) { + cent->neg.lent=NULL; + cent->neg.ttl=ttl; + cent->neg.ts=ts; + } + else { + for(i=0; irr.rrmu[i]=NULL; + cent->rr.rrext=NULL; + } + cent->c_ns=cundef; + cent->c_soa=cundef; + return 1; +} + +/* + * Create a rr record holder using the given values. + */ +static rr_bucket_t *create_rr(unsigned dlen, void *data DBGPARAM) +{ + rr_bucket_t *rrb; + rrb=(rr_bucket_t *)cache_malloc(sizeof(rr_bucket_t)+dlen); + if (rrb == NULL) + return NULL; + rrb->next=NULL; + + rrb->rdlen=dlen; + memcpy(rrb->data,data,dlen); + return rrb; +} + +/* + * Adds an empty rrset_t with the requested data to a cent. This is exactly what you need to + * do to create a negatively cached cent. + */ +static int add_cent_rrset_by_index(dns_cent_t *cent, unsigned int idx, time_t ttl, time_t ts, unsigned flags DBGPARAM) +{ + rr_set_t **rrext, **rrsetpa, *rrset; + + /* If we add a rrset, even a negative one, the domain is not negative any more. */ + if (cent->flags&DF_NEGATIVE) { + int i; + /* need to remove the cent from the lent list. */ + if (cent->neg.lent) + remove_rrl(cent->neg.lent DBGARG); + cent->flags &= ~DF_NEGATIVE; + for(i=0; irr.rrmu[i]=NULL; + cent->rr.rrext=NULL; + } + + if(idx < NRRMU) + rrsetpa = ¢->rr.rrmu[idx]; + else { + idx -= NRRMU; + PDNSD_ASSERT(idx < NRREXT, "add_cent_rrset_by_index: rr-set index out of range"); + rrext = cent->rr.rrext; + if(!rrext) { + int i; + cent->rr.rrext = rrext = cache_malloc(sizeof(rr_set_t*)*NRREXT); + if(!rrext) + return 0; + for(i=0; ics += sizeof(rr_set_t*)*NRREXT; + } + rrsetpa = &rrext[idx]; + } + +#if 0 + if(*rrsetpa) del_rrset(*rrsetpa); +#endif + *rrsetpa = rrset = cache_malloc(sizeof(rr_set_t)); + if (!rrset) + return 0; + rrset->lent=NULL; + rrset->ttl=ttl; + rrset->ts=ts; + rrset->flags=flags; + rrset->rrs=NULL; + cent->cs += sizeof(rr_set_t); + ++cent->num_rrs; + return 1; +} + +int add_cent_rrset_by_type(dns_cent_t *cent, int type, time_t ttl, time_t ts, unsigned flags DBGPARAM) +{ + int tpi = type - T_MIN; + + PDNSD_ASSERT(tpi>=0 && tpinext=rrset->rrs; + rrset->rrs=rr; + } + else { + /* append at the end */ + rr->next=(*rtail)->next; + (*rtail)->next=rr; + } + if(rtail) *rtail=rr; + cent->cs += sizeof(rr_bucket_t)+rr->rdlen; +#if DEBUG>0 + if(debug_p) { + rrset = RRARR_INDEX(cent,idx); + if (rrset->flags&CF_NEGATIVE) { + char cflagstr[CFLAGSTRLEN]; + DEBUG_MSG("Tried to add rr to a rrset with CF_NEGATIVE set! flags=%s\n",cflags2str(rrset->flags,cflagstr)); + } + } +#endif + return 1; + + cleanup_return: + free_rr(*rr); + free(rr); + return 0; +} + + +/* Add an rr to a cache entry, giving the ttl, the data length, the rr type + * and a pointer to the data. A record is allocated, and the data is copied into + * it. Do this for all rrs in a cache entry. + * The return value will be 1 in case of success, or 0 in case of a memory allocation + * problem. + */ +int add_cent_rr(dns_cent_t *cent, int type, time_t ttl, time_t ts, unsigned flags, + unsigned dlen, void *data DBGPARAM) +{ + int tpi; + unsigned int idx; + rr_set_t *rrset; + rr_bucket_t *rtail, *rrb; + + if ((cent->flags&DF_LOCAL) && !(flags&CF_LOCAL)) + return 1; /* ignore. Local has precedence. */ + + tpi = type - T_MIN; + PDNSD_ASSERT(tpi>=0 && tpittl) + /* The ttl timestamps should be identical. + In case they are not, we will use the smallest one. */ + rrset->ttl= ttl; + + /* OK, some stupid nameservers feel inclined to return the same address twice. Grmbl... */ + rrb=rrset->rrs; + while (rrb) { + if (rrb->rdlen==dlen && memcmp(rrb->data,data,dlen)==0) + return 1; + rtail=rrb; + rrb=rrb->next; + } + } + return add_cent_rr_int(cent,idx,ttl,ts,flags,dlen,data,&rtail DBGARG); +} + +/* Free a complete rrset including all memory. Returns the size of the memory freed */ +int del_rrset(rr_set_t *rrs DBGPARAM) +{ + int rv=sizeof(rr_set_t); + rr_bucket_t *rrb,*rrn; + + if(rrs->lent) remove_rrl(rrs->lent DBGARG); + rrb=rrs->rrs; + while (rrb) { + rv+=sizeof(rr_bucket_t)+rrb->rdlen; + rrn=rrb->next; + free_rr(*rrb); + cache_free(rrb); + rrb=rrn; + } + cache_free(rrs); + return rv; +} + +/* Remove a complete rrset from a cent, freeing the memory. + The second argument should be an RR-set array index, not an RR type! + Returns the size of the memory freed */ +static int del_cent_rrset_by_index(dns_cent_t *cent, int i DBGPARAM) +{ + int rv=0; + rr_set_t **rrspa = RRARR_INDEX_PA_TESTEXT(cent,i); + + if(rrspa) { + rr_set_t *rrs = *rrspa; + if(rrs) { + rv= del_rrset(rrs DBGARG); + *rrspa=NULL; + --cent->num_rrs; + cent->cs -= rv; + cent->flags &= ~DF_AUTH; + } + } + return rv; +} + +#if 0 +static int del_cent_rrset_by_type(dns_cent_t *cent, int type DBGPARAM) +{ + return del_cent_rrset_by_index(cent, rrlkuptab[type-T_MIN] DBGARG); +} +#endif + +#if 0 +/* Free the pointers contained in an rr record. If the rr record is on the heap, + * don't forget to delete itself. This is done extra mainly for extensibility + * -- This is not here any more. The definition is actually an empty macro in + * cache.h. + */ +void free_rr(rr_bucket_t rr) +{ +} +#endif + +/* Free all data referred by a cache entry. */ +void free_cent(dns_cent_t *cent DBGPARAM) +{ + cache_free(cent->qname); + if(cent->flags&DF_NEGATIVE) { + if(cent->neg.lent) + remove_rrl(cent->neg.lent DBGARG); + } + else { + int i; + for (i=0; irr.rrmu[i]; + if (rrs) del_rrset(rrs DBG0); + } + { + rr_set_t **rrext = cent->rr.rrext; + if(rrext) { + for(i=0; iflags&DF_NEGATIVE)) { + for (i=0; irr.rrmu[i]; + if (rrs) { + cent->cs -= del_rrset(rrs DBG0); + /* cent->rr.rrmu[i]=NULL; */ + } + } + { + rr_set_t **rrext = cent->rr.rrext; + if(rrext) { + for(i=0; ics -= del_rrset(rrs DBG0); + } + cache_free(rrext); + /* cent->rr.rrext=NULL; */ + cent->cs -= sizeof(rr_set_t*)*NRREXT; + } + } + cent->num_rrs=0; + cent->flags |= DF_NEGATIVE; + cent->neg.lent=NULL; + } + + cent->neg.ttl=ttl; + cent->neg.ts=ts; +} + +inline static time_t get_rrlent_ts(rr_lent_t *le) +{ + return (le->rrset)?(le->rrset->ts):(le->cent->neg.ts); +} + +/* insert a rrset into the rr_l list. This modifies the rr_set_t if rrs is not NULL! + * The rrset address needs to be constant afterwards. + * idx is the internally used RR-set index, not the RR type! + * Call with locks applied. */ +static int insert_rrl(rr_set_t *rrs, dns_cent_t *cent, int idx) +{ + time_t ts; + rr_lent_t *le,*ne; + + /* No need to add local records to the rr_l list, because purge_cache() ignores them anyway. */ + if((rrs && (rrs->flags&CF_LOCAL)) || (cent->flags&DF_LOCAL)) + return 1; + + if (!(ne=malloc(sizeof(rr_lent_t)))) + return 0; + ne->rrset=rrs; + ne->cent=cent; + ne->idx=idx; + ne->next=NULL; + ne->prev=NULL; + + if(insert_sort) { + /* Since the append at the and is a very common case (and we want this case to be fast), we search back-to-forth. + * Since rr_l is a list and we don't really have fast access to all elements, we do not perform an advanced algorithm + * like binary search.*/ + ts=get_rrlent_ts(ne); + le=rrset_l_tail; + while (le) { + if (ts>=get_rrlent_ts(le)) goto found; + le=le->prev; + } + /* not found, so it needs to be inserted at the start of the list. */ + ne->next=rrset_l; + if (rrset_l) + rrset_l->prev=ne; + else + rrset_l_tail=ne; + rrset_l=ne; + goto finish; + found: + ne->next=le->next; + ne->prev=le; + if (le->next) + le->next->prev=ne; + else + rrset_l_tail=ne; + le->next=ne; + finish:; + } + else { + /* simply append at the end, sorting will be done later with a more efficient algorithm. */ + ne->prev=rrset_l_tail; + if(rrset_l_tail) + rrset_l_tail->next=ne; + else + rrset_l=ne; + rrset_l_tail=ne; + } + + if (rrs) + rrs->lent=ne; + else + cent->neg.lent=ne; + + return 1; +} + +/* Remove a rr from the rr_l list. Call with locks applied. */ +static void remove_rrl(rr_lent_t *le DBGPARAM) +{ + rr_lent_t *next=le->next,*prev=le->prev; + if (next) + next->prev=prev; + else + rrset_l_tail=prev; + if (prev) + prev->next=next; + else + rrset_l=next; + cache_free(le); +} + + +/* Merge two sorted rr_l lists to make a larger sorted list. + The lists are sorted according to increasing time-stamp. + The back links are ignored, these must be fixed using a separate pass. +*/ +static rr_lent_t *listmerge(rr_lent_t *p, rr_lent_t *q) +{ + + if(!p) + return q; + else if(!q) + return p; + else { + rr_lent_t *l=NULL, **s= &l; + + for(;;) { + if(get_rrlent_ts(p) <= get_rrlent_ts(q)) { + *s= p; + s= &p->next; + p= *s; + if(!p) { + *s= q; + break; + } + } + else { /* get_rrlent_ts(p) > get_rrlent_ts(q) */ + *s= q; + s= &q->next; + q= *s; + if(!q) { + *s= p; + break; + } + } + } + + return l; + } +} + +/* Sort the rr_l list using merge sort, which can be more efficient than insertion sort used by rr_insert(). + This algorithm is adapted from the GNU C++ STL implementation for list containers. + Call with locks applied. + Written by Paul Rombouts. +*/ +static void sort_rrl() +{ + /* Do nothing unless the list has length >= 2. */ + if(rrset_l && rrset_l->next) { + /* First sort the list ignoring the back links, these will be fixed later. */ +# define NTMPSORT 32 + /* Because we use an array of fixed length, the length of the list we can sort + is bounded by pow(2,NTMPSORT)-1. */ + rr_lent_t *tmp[NTMPSORT]; /* tmp[i] will either be NULL or point to a sorted list of length pow(2,i). */ + rr_lent_t **fill= tmp, **end=tmp+NTMPSORT, **counter; + rr_lent_t *rem= rrset_l, *carry; + + do { + carry=rem; rem=rem->next; + carry->next=NULL; + for(counter = tmp; counter!=fill && *counter!=NULL; ++counter) { + carry=listmerge(*counter,carry); + *counter=NULL; + } + + PDNSD_ASSERT(counter!=end, "sort_rrl: tmp array overflowed"); + + *counter=carry; + + if(counter==fill) ++fill; + } + while(rem); + + /* Merge together all the remaining list fragments contained in array tmp. */ + carry= tmp[0]; + counter= tmp; + while(++counter!=fill) + carry=listmerge(*counter,carry); + + rrset_l= carry; + + { + /* Restore the backward links. */ + rr_lent_t *p,*q=NULL; + for(p=rrset_l; p; p=p->next) {p->prev=q; q=p;} + rrset_l_tail=q; + } + } +} + + +/* Copy a rr_bucket_t into newly allocated memory */ +inline static rr_bucket_t *copy_rr(rr_bucket_t *rr DBGPARAM) +{ + rr_bucket_t *rrn; + rrn=cache_malloc(sizeof(rr_bucket_t)+rr->rdlen); + if (rrn == NULL) + return NULL; + memcpy(rrn,rr,sizeof(rr_bucket_t)+rr->rdlen); + rrn->next=NULL; + return rrn; +} + + +/* Copy an RR set into newly allocated memory */ +static rr_set_t *copy_rrset(rr_set_t *rrset DBGPARAM) +{ + rr_set_t *rrsc=cache_malloc(sizeof(rr_set_t)); + rr_bucket_t *rr,**rrp; + if (rrsc) { + *rrsc=*rrset; + rrsc->lent=NULL; + rrp=&rrsc->rrs; + rr=rrset->rrs; + while(rr) { + rr_bucket_t *rrc=copy_rr(rr DBGARG); + *rrp=rrc; + if (!rrc) goto cleanup_return; + rrp=&rrc->next; + rr=rr->next; + } + } + return rrsc; + +cleanup_return: + del_rrset(rrsc DBG0); + return NULL; +} + + +/* Copy a cache entry into newly allocated memory */ +dns_cent_t *copy_cent(dns_cent_t *cent DBGPARAM) +{ + dns_cent_t *copy; + + /* + * We do not debug cache internals with it, as mallocs seem to be + * "lost" when they enter the cache for a longer time. + */ + if (!(copy=cache_malloc(sizeof(dns_cent_t)))) + return NULL; + + { + /* copy the name */ + size_t namesz=rhnlen(cent->qname); + if (!(copy->qname=cache_malloc(namesz))) + goto free_return_null; + + memcpy(copy->qname,cent->qname,namesz); + } + copy->cs= cent->cs; + copy->num_rrs= cent->num_rrs; + copy->flags= cent->flags; + copy->c_ns = cent->c_ns; + copy->c_soa= cent->c_soa; + if(cent->flags&DF_NEGATIVE) { + copy->neg.lent=NULL; + copy->neg.ttl= cent->neg.ttl; + copy->neg.ts = cent->neg.ts; + } + else { + int i, ilim; + for (i=0; irr.rrmu[i]=NULL; + copy->rr.rrext=NULL; + + ilim = NRRMU; + if(cent->rr.rrext) { + rr_set_t **rrextc; + ilim = NRRTOT; + copy->rr.rrext = rrextc = cache_malloc(sizeof(rr_set_t*)*NRREXT); + if(!rrextc) goto free_cent_return_null; + + for (i=0; ilent=NULL; + rrp=&rrsc->rrs; + rr=rrset->rrs; + while(rr) { + rr_bucket_t *rrc=copy_rr(rr DBGARG); + *rrp=rrc; + if (!rrc) goto free_cent_return_null; + rrp=&rrc->next; + rr=rr->next; + } + } + } + } + return copy; + + free_cent_return_null: + free_cent(copy DBGARG); + free_return_null: + cache_free(copy); + return NULL; +} + +/* + * Remove all timed out entries of the RR set with the given index. + * idx is the internally used RR-set index, not the RR type! + * Follow some rules based on flags etc. + * This will either delete the whole rrset, or will leave it as a whole (RFC2181 seems to + * go in that direction) + * This was pretty large once upon a time ;-), but now, since we operate in rrsets, was + * shrunk drastically. + * If test is zero and the record is in the cache, we need rw-locks applied. + * If test is nonzero, nothing will actually be deleted. + * Substracts the size of the freed memory from cache_size (if test is zero). + * Returns 1 if the rrset has been (or would have been) deleted. + */ +static int purge_rrset(dns_cent_t *cent, int idx, int test) +{ + rr_set_t *rrs= RRARR_INDEX_TESTEXT(cent,idx); + if (rrs && !(rrs->flags&CF_NOPURGE || rrs->flags&CF_LOCAL) && timedout(rrs)) { + /* well, it must go. */ + if(!test) + cache_size -= del_cent_rrset_by_index(cent,idx DBG0); + return 1; + } + return 0; +} + +/* + Remove all timed out entries of alls RR sets of a cache entry. + The test flag works the same as in purge_rrset(). + Substracts the size of the freed memory from cache_size, just as purge_rrset(). + *numrrsrem is set to the number of remaining RR sets (or the number that would have remained). + Returns the number of items (RR sets or RR set arrays) that have been (or would have been) deleted. +*/ +static int purge_all_rrsets(dns_cent_t *cent, int test, int *numrrsrem) +{ + int rv=0, numrrs=0, numrrext=0; + + if(!(cent->flags&DF_NEGATIVE)) { + int i, ilim= RRARR_LEN(cent); + for(i=0; iflags&CF_NOPURGE || rrs->flags&CF_LOCAL) && timedout(rrs)) { + /* well, it must go. */ + if(!test) + cache_size -= del_cent_rrset_by_index(cent, i DBG0); + ++rv; + } + else { + ++numrrs; + if(i>=NRRMU) ++numrrext; + } + } + } + + /* If the array of less frequently used RRs has become empty, free it. */ + if(cent->rr.rrext && numrrext==0) { + if(!test) { + cache_free(cent->rr.rrext); + cent->rr.rrext=NULL; + cent->cs -= sizeof(rr_set_t*)*NRREXT; + cache_size -= sizeof(rr_set_t*)*NRREXT; + } + ++rv; + } + } + + if(numrrsrem) *numrrsrem=numrrs; + return rv; +} + + +/* + * Purge a cent, deleting timed-out rrs (following the constraints noted in "purge_rrset"). + * Since the cent may actually become empty and be deleted, you may not use it after this call until + * you refetch its address from the hash (if it is still there). + * If test is zero and the record is in the cache, we need rw-locks applied. + * If test is nonzero, nothing will actually be deleted. + * Substracts the size of the freed memory from cache_size (if test is zero). + * If delete is nonzero and the cent was purged empty and no longer needed, it is removed from the cache. + * Returns -1 if the cent was (or would have been) completely removed, + * otherwise returns the number of items that were (or would have been) deleted. + */ +static int purge_cent(dns_cent_t *cent, int delete, int test) +{ + int npurge, numrrs; + + npurge = purge_all_rrsets(cent,test, &numrrs); + + /* If the cache entry was purged empty, delete it from the cache. */ + if (delete && numrrs==0 + && (!(cent->flags&DF_NEGATIVE) || + (!(cent->flags&DF_LOCAL) && timedout_nxdom(cent)))) + { + if(!test) + del_cache_ent(cent,NULL); /* this will subtract the cent's left size from cache_size */ + return -1; + } + + if(!(cent->flags&DF_LOCAL)) { + /* Set stale references to NS or SOA records back to undefined. */ + unsigned scnt=rhnsegcnt(cent->qname); + if(cent->c_ns!=cundef) { + rr_set_t *rrset=NULL; + if(cent->c_ns==scnt) + rrset=getrrset_NS(cent); + else if(cent->c_nsqname,scnt-cent->c_ns),NULL); + if(ce) rrset=getrrset_NS(ce); + } + if(!rrset || !rrset->rrs || (!(rrset->flags&CF_LOCAL) && timedout(rrset))) { + if(!test) + cent->c_ns=cundef; + ++npurge; + } + } + if(cent->c_soa!=cundef) { + rr_set_t *rrset=NULL; + if(cent->c_soa==scnt) + rrset=getrrset_SOA(cent); + else if(cent->c_soaqname,scnt-cent->c_soa),NULL); + if(ce) rrset=getrrset_SOA(ce); + } + if(!rrset || !rrset->rrs || (!(rrset->flags&CF_LOCAL) && timedout(rrset))) { + if(!test) + cent->c_soa=cundef; + ++npurge; + } + } + } + + return npurge; +} + +/* + * Bring cache to a size below or equal the cache size limit (sz). There are two strategies: + * - for cached sets with CF_NOPURGE not set: delete if timed out + * - additional: delete oldest sets. + */ +static void purge_cache(long sz, int lazy) +{ + rr_lent_t *le; + + /* Walk the cache list from the oldest entries to the newest, deleting timed-out + * records. + * XXX: We walk the list a second time if this did not free up enough space - this + * should be done better. */ + le=rrset_l; + while (le && (!lazy || cache_size>sz)) { + /* Note by Paul Rombouts: + * If data integrity is ensured, at most one node is removed from the rrset_l + * per iteration, and this node is the one referenced by le. */ + rr_lent_t *next=le->next; + if (!((le->rrset && (le->rrset->flags&CF_LOCAL)) || + (le->cent->flags&DF_LOCAL))) { + dns_cent_t *ce = le->cent; + if (le->rrset) + purge_rrset(ce, le->idx,0); + /* Side effect: if purge_rrset called del_cent_rrset then le has been freed. + * ce, however, is still guaranteed to be valid. */ + if (ce->num_rrs==0 && (!(ce->flags&DF_NEGATIVE) || + (!(ce->flags&DF_LOCAL) && timedout_nxdom(ce)))) + del_cache_ent(ce,NULL); + } + le=next; + } + if (cache_size<=sz) + return; + + /* we are still above the desired cache size. Well, delete records from the oldest to + * the newest. This is the case where nopurge records are deleted anyway. Only local + * records are kept in any case.*/ + if(!insert_sort) { + sort_rrl(); + insert_sort=1; /* use insertion sort from now on */ + } + + le=rrset_l; + while (le && cache_size>sz) { + rr_lent_t *next=le->next; + if (!((le->rrset && (le->rrset->flags&CF_LOCAL)) || + (le->cent->flags&DF_LOCAL))) { + dns_cent_t *ce = le->cent; + if (le->rrset) + cache_size -= del_cent_rrset_by_index(ce, le->idx DBG0); + /* this will also delete negative cache entries */ + if (ce->num_rrs==0) + del_cache_ent(ce,NULL); + } + le=next; + } +} + +#define log_warn_read_error(f,item) \ + log_warn("%s encountered while reading %s from disk cache file.", \ + ferror(f)?"Error":feof(f)?"EOF":"Incomplete item",item) + +/* + * Load cache from disk and rebuild the hash tables. + */ +void read_disk_cache() +{ + /* The locks are done when we add items. */ + dns_cent_t ce; + int dtsz=512; + unsigned char *data; + unsigned long cnt; + FILE *f; + + char path[strlen(global.cache_dir)+sizeof("/pdnsd.cache")]; + + stpcpy(stpcpy(path,global.cache_dir),"/pdnsd.cache"); + + if (!(f=fopen(path,"r"))) { + log_warn("Could not open disk cache file %s: %s",path,strerror(errno)); + return; + } + + if (!(data = malloc(dtsz))) { + goto fclose_exit; + } + + /* Don't use insertion sort while reading caches entries from disk, because this can be + noticeably inefficient with large cache files. + Entries are simply appended at the end of the rr_l list. + The rr_l list is sorted using a more efficient merge sort after we are done reading. + */ + insert_sort=0; + + { + unsigned nb; + char buf[sizeof(cachverid)]; + + /* check cache version identifier */ + nb=fread(buf,1,sizeof(cachverid),f); + if (nb!=sizeof(cachverid)) { + /* Don't complain about empty files */ + if(nb!=0 || !feof(f)) { + log_warn_read_error(f,"cache version identifier"); + } + goto free_data_fclose; + } + if(memcmp(buf,cachverid,sizeof(cachverid))) { + log_warn("Cache file %s ignored because of incompatible version identifier",path); + goto free_data_fclose; + } + } + + if (fread(&cnt,sizeof(cnt),1,f)!=1) { + log_warn_read_error(f,"entry count"); + goto free_data_fclose; + } + + for(;cnt>0;--cnt) { + dns_file_t fe; + dom_fttlts_t fttlts = {0,0}; + unsigned char nb[256]; + unsigned num_rrs; + unsigned char prevtp; + if (fread(&fe,sizeof(fe),1,f)!=1) { + log_warn_read_error(f,"cache entry header"); + goto free_data_fclose; + } + if(fe.flags&DF_NEGATIVE) { + if (fread(&fttlts,sizeof(fttlts),1,f)!=1) { + log_warn_read_error(f,"cache TTL and timestamp"); + goto free_data_fclose; + } + } + if (fe.qlen) { + int i; + /* Because of its type qlen should be <=255. */ + if (fread(nb,fe.qlen,1,f)!=1) { + log_warn_read_error(f,"domain name"); + goto free_data_fclose; + } + for(i=0;i63 || (i += lb+1)>fe.qlen) { + log_warn("Invalid domain name encountered while reading disk cache file."); + goto free_data_fclose; + } + } + } + nb[fe.qlen]='\0'; + if (!init_cent(&ce, nb, fttlts.ttl, fttlts.ts, fe.flags DBG0)) { + goto free_data_fclose_exit; + } + ce.c_ns=fe.c_ns; ce.c_soa=fe.c_soa; + + /* now, read the rr's */ + prevtp=0; + for (num_rrs=fe.num_rrs;num_rrs;--num_rrs) { + rr_fset_t sh; + unsigned num_rr; + if (fread(&sh,sizeof(sh),1,f)!=1) { + log_warn_read_error(f,"rr header"); + goto free_cent_data_fclose; + } + if(PDNSD_NOT_CACHED_TYPE(sh.tp)) { + log_warn("Invalid rr type encountered while reading disk cache file."); + goto free_data_fclose; + } + if(sh.tp<=prevtp) { + log_warn("Unexpected rr type encountered (not in strict ascending order) while reading disk cache file."); + goto free_data_fclose; + } + prevtp=sh.tp; + /* Add the rrset header in any case (needed for negative caching) */ + if(!add_cent_rrset_by_type(&ce, sh.tp, sh.ttl, sh.ts, sh.flags DBG0)) { + goto free_cent_data_fclose_exit; + } + for (num_rr=sh.num_rr;num_rr;--num_rr) { + rr_fbucket_t rr; + if (fread(&rr,sizeof(rr),1,f)!=1) { + log_warn_read_error(f,"rr data length"); + goto free_cent_data_fclose; + } + if (rr.rdlen>dtsz) { + unsigned char *tmp; + dtsz=rr.rdlen; + tmp=realloc(data,dtsz); + if (!tmp) { + goto free_cent_data_fclose_exit; + } + data=tmp; + } + if (rr.rdlen && fread(data,rr.rdlen,1,f)!=1) { + log_warn_read_error(f,"rr data"); + goto free_cent_data_fclose; + } + if (!add_cent_rr(&ce,sh.tp,sh.ttl,sh.ts,sh.flags,rr.rdlen,data DBG0)) { + goto free_cent_data_fclose_exit; + } + } + } + add_cache(&ce); + free_cent(&ce DBG0); + } +#ifdef DEBUG_HASH + free(data); + fclose(f); + dumphash(); + goto sort_return; +#else + goto free_data_fclose; +#endif + + free_cent_data_fclose: + free_cent(&ce DBG0); + free_data_fclose: + free(data); + fclose(f); +#ifdef DEBUG_HASH + sort_return: +#endif + /* Do we need read/write locks to sort the rr_l list? + As long as at most one thread is sorting, it is OK for the other threads + to read the cache, providing they do not add or delete anything. + */ + lock_cache_r(); + if(!insert_sort) { + sort_rrl(); + insert_sort=1; + } + unlock_cache_r(); + return; + + free_cent_data_fclose_exit: + free_cent(&ce DBG0); + free_data_fclose_exit: + free(data); + fclose_exit: + fclose(f); + log_error("Out of memory in reading cache file. Exiting."); + pdnsd_exit(); +} + +/* write an rr to the file f */ +static int write_rrset(int tp, rr_set_t *rrs, FILE *f) +{ + rr_bucket_t *rr; + rr_fset_t sh; + rr_fbucket_t rf; + unsigned num_rr; + + sh.tp=tp; + + num_rr=0; + for(rr=rrs->rrs; rr && num_rr<255; rr=rr->next) ++num_rr; + sh.num_rr=num_rr; + sh.flags=rrs->flags; + sh.ttl=rrs->ttl; + sh.ts=rrs->ts; + + if (fwrite(&sh,sizeof(sh),1,f)!=1) { + log_error("Error while writing rr header to disk cache: %s", strerror(errno)); + return 0; + } + + rr=rrs->rrs; + for(; num_rr; --num_rr) { + rf.rdlen=rr->rdlen; + if (fwrite(&rf,sizeof(rf),1,f)!=1 || (rf.rdlen && fwrite((rr->data),rf.rdlen,1,f)!=1)) { + log_error("Error while writing rr data to disk cache: %s", strerror(errno)); + return 0; + } + rr=rr->next; + } + + return 1; +} + + +/* + * Write cache to disk on termination. The hash table is lost and needs to be regenerated + * on reload. + * + * The locks are not very fine grained here, but I don't think this needs fixing as this routine + * is only called on exit. + * + */ +void write_disk_cache() +{ + int j, jlim; + dns_cent_t *le; + unsigned long en=0; + dns_hash_pos_t pos; + FILE *f; + unsigned long num_rrs_errs=0; +# define MAX_NUM_RRS_ERRS 10 + + char path[strlen(global.cache_dir)+sizeof("/pdnsd.cache")]; + + stpcpy(stpcpy(path,global.cache_dir),"/pdnsd.cache"); + + DEBUG_MSG("Writing cache to %s\n",path); + + if (!softlock_cache_rw()) { + goto lock_failed; + } + /* purge cache down to allowed size*/ + purge_cache((long)global.perm_cache*1024, 0); + if (!softunlock_cache_rw()) { + goto lock_failed; + } + + if (!softlock_cache_r()) { + goto lock_failed; + } + + if (!(f=fopen(path,"w"))) { + log_warn("Could not open disk cache file %s: %s",path,strerror(errno)); + goto softunlock_return; + } + + /* Write the cache version identifier */ + if (fwrite(cachverid,sizeof(cachverid),1,f)!=1) { + log_error("Error while writing cache version identifier to disk cache: %s", strerror(errno)); + goto fclose_unlock; + } + + for (le=fetch_first(&pos); le; le=fetch_next(&pos)) { + /* count the rr's */ + if(le->flags&DF_NEGATIVE) { + if(!(le->flags&DF_LOCAL)) + ++en; + } + else { + jlim= RRARR_LEN(le); + for (j=0; jflags&CF_LOCAL)) { + ++en; + break; + } + } + } + } + if (fwrite(&en,sizeof(en),1,f)!=1) { + log_error("Error while writing entry count to disk cache: %s", strerror(errno)); + goto fclose_unlock; + } + + for (le=fetch_first(&pos); le; le=fetch_next(&pos)) { + /* now, write the rr's */ + if(le->flags&DF_NEGATIVE) { + if(!(le->flags&DF_LOCAL)) + goto write_rrs; + } + else { + jlim= RRARR_LEN(le); + for (j=0; jflags&CF_LOCAL)) { + goto write_rrs; + } + } + } + continue; + write_rrs: + { + dns_file_t df; + int num_rrs; + const unsigned short *iterlist; + df.qlen=rhnlen(le->qname)-1; /* Don't include the null byte at the end */ + df.num_rrs=0; + df.flags=le->flags; + df.c_ns=le->c_ns; df.c_soa=le->c_soa; + num_rrs=0; + jlim=RRARR_LEN(le); + for (j=0; jflags&CF_LOCAL)) + ++df.num_rrs; + } + } + if(num_rrs!=le->num_rrs && ++num_rrs_errs<=MAX_NUM_RRS_ERRS) { + unsigned char buf[DNSNAMEBUFSIZE]; + log_warn("Counted %d rr record types for %s but cached counter=%d", + num_rrs,rhn2str(le->qname,buf,sizeof(buf)),le->num_rrs); + } + if (fwrite(&df,sizeof(df),1,f)!=1) { + log_error("Error while writing cache entry header to disk cache: %s", strerror(errno)); + goto fclose_unlock; + } + if(le->flags&DF_NEGATIVE) { + dom_fttlts_t fttlts= {le->neg.ttl,le->neg.ts}; + if (fwrite(&fttlts,sizeof(fttlts),1,f)!=1) { + log_error("Error while writing cache TTL and timestamp to disk cache: %s", strerror(errno)); + goto fclose_unlock; + } + } + if (df.qlen && fwrite(le->qname,df.qlen,1,f)!=1) { + log_error("Error while writing domain name to disk cache: %s", strerror(errno)); + goto fclose_unlock; + } + + jlim= NRRITERLIST(le); + iterlist= RRITERLIST(le); + for (j=0; jflags&CF_LOCAL)) { + if(!write_rrset(tp,rrset,f)) + goto fclose_unlock; + } + } + } + } + if(fclose(f)) { + log_error("Could not close cache file %s after writing cache: %s", path,strerror(errno)); + } + softunlock_cache_r(); + DEBUG_MSG("Finished writing cache to disk.\n"); + return; + + fclose_unlock: + fclose(f); + softunlock_return: + softunlock_cache_r(); + return; + + lock_failed: + crash_msg("Lock failed; could not write disk cache."); +} + +/* + * Conflict Resolution. + * The first function is the actual checker; the latter two are wrappers for the respective + * function for convenience only. + * + * We check for conflicts by checking the new data rrset by rrset against the cent. + * This is not bad when considering that new records are hopefully consistent; if they are not, + * we might end up deleteing too much of the old data, which is probably added back through the + * new query, though. + * Having checked additions rrset by rrset, we are at least sure that the resulting record is OK. + * cr_check_add returns 1 if the addition is OK, 0 otherwise. + * This is for records that are already in the cache! + * + * idx is the internally used RR-set index, not the RR type! + */ +static int cr_check_add(dns_cent_t *cent, int idx, time_t ttl, time_t ts, unsigned flags) +{ + time_t nttl; + const struct rr_infos *rri; + + if (flags & CF_NEGATIVE) + return 1; /* no constraints here. */ + + nttl = 0; + rri = &rr_info[idx]; + + if (!(flags & CF_LOCAL)) { + int i, ilim, ncf; + + if(cent->flags & DF_LOCAL) + return 0; /* Local has precedence. */ + + ncf = 0; ilim = RRARR_LEN(cent); + for (i = 0; i < ilim; ++i) { + rr_set_t *rrs= RRARR_INDEX(cent,i); + /* Should be symmetric; check both ways anyway. */ + if (rrs && !(rrs->flags & CF_NEGATIVE) && + ((rri->class & rr_info[i].excludes) || + (rri->excludes & rr_info[i].class))) + { + time_t rttl; + if (rrs->flags & CF_LOCAL) + return 0; /* old was authoritative. */ + ++ncf; + rttl = rrs->ttl + rrs->ts - time(NULL); + if(rttl > 0) nttl += rttl; + } + } + if (ncf == 0) /* no conflicts */ + return 1; + /* Medium ttl of conflicting records */ + nttl /= ncf; + } + if ((flags & CF_LOCAL) || ttl > nttl) { + int i, ilim= RRARR_LEN(cent); + + /* Remove the old records, so that the new one can be added. */ + for (i = 0; i < ilim; ++i) { + rr_set_t *rrs= RRARR_INDEX(cent,i); + /* Should be symmetric; check both ways anyway. */ + if (rrs && !(rrs->flags & CF_NEGATIVE) && + ((rri->class & rr_info[i].excludes) || + (rri->excludes & rr_info[i].class))) { + del_cent_rrset_by_index(cent, i DBG0); + } + } + return 1; + } + /* old records precede */ + return 0; +} + + +inline static void adjust_ttl(rr_set_t *rrset) +{ + if (rrset->flags&CF_NOCACHE) { + rrset->flags &= ~CF_NOCACHE; + rrset->ttl=0; + } + else { + time_t min_ttl= global.min_ttl, neg_ttl=global.neg_ttl; + if((rrset->flags&CF_NEGATIVE) && neg_ttlttlttl=min_ttl; + else { + time_t max_ttl= global.max_ttl; + if(rrset->ttl>max_ttl) + rrset->ttl=max_ttl; + } + } +} + + +/* Only use for negatively cached domains, thus only + if the DF_NEGATIVE bit is set! */ +inline static void adjust_dom_ttl(dns_cent_t *cent) +{ + if (cent->flags&DF_NOCACHE) { + cent->flags &= ~DF_NOCACHE; + cent->neg.ttl=0; + } + else { + time_t min_ttl= global.min_ttl, neg_ttl=global.neg_ttl; + if(/* (cent->flags&DF_NEGATIVE) && */ neg_ttlneg.ttlneg.ttl=min_ttl; + else { + time_t max_ttl= global.max_ttl; + if(cent->neg.ttl>max_ttl) + cent->neg.ttl=max_ttl; + } + } +} + +/* + * Add a ready built dns_cent_t to the hashes, purge if necessary to not exceed cache size + * limits, and add the entries to the hashes. + * As memory is already reserved for the rrs, we only need to wrap up the dns_cent_t and + * alloc memory for it. + * New entries are appended, so we easiliy know the oldest for purging. For fast acces, + * we use hashes instead of ordered storage. + * + * This does not free the argument, and it uses a copy of it, so the caller must do free_cent() + * on it. + * + * The new entries rr sets replace the old ones, i.e. old rr sets with the same key are deleted + * before the new ones are added. + */ +void add_cache(dns_cent_t *cent) +{ + dns_cent_t *ce; + dns_hash_loc_t loc; + int i,ilim; + + lock_cache_rw(); + retry: + if (!(ce=dns_lookup(cent->qname,&loc))) { + /* if the new entry doesn't contain any information, + don't try to add it to the cache because purge_cache() will not + be able to get rid of it. + */ + if(cent->num_rrs==0 && !(cent->flags&DF_NEGATIVE)) + goto purge_cache_return; + + if(!(ce=copy_cent(cent DBG0))) + goto warn_unlock_cache_return; + + if(!(ce->flags&DF_NEGATIVE)) { + ilim= RRARR_LEN(ce); + /* Add the rrs to the rr list */ + for (i=0; iflags&DF_NEGATIVE) { + /* the new entry is negative. So, we need to delete the whole cent, + * and then generate a new one. */ + ilim= RRARR_LEN(ce); + for (i=0; iflags&CF_LOCAL) { + goto unlock_cache_return; /* Do not clobber local records */ + } + } + del_cache_ent(ce,&loc); + goto retry; + } + purge_cent(ce, 0,0); + /* We have a record; add the rrsets replacing old ones */ + cache_size-=ce->cs; + + ilim= RRARR_LEN(cent); + for (i=0; iflags&CF_LOCAL) && (cerrs->flags&CF_LOCAL)) || + ((centrrs->flags&CF_ADDITIONAL) && (!(cerrs->flags&CF_ADDITIONAL) || + (!(centrrs->flags&CF_ROOTSERV) && + (cerrs->flags&CF_ROOTSERV))) && + !timedout(cerrs))))) + { + rr_bucket_t *rr,*rtail; + + del_cent_rrset_by_index(ce,i DBG0); + + if (!cr_check_add(ce, i, centrrs->ttl, centrrs->ts, centrrs->flags)) + continue; /* the new record has been deleted as a conflict resolution measure. */ + + /* pre-initialize a rrset_t for the case we have a negative cached + * rrset, in which case no further rrs will be added. */ + if (!add_cent_rrset_by_index(ce, i, centrrs->ttl, centrrs->ts, centrrs->flags DBG0)) { + goto addsize_unlock_cache_return; + } + rtail=NULL; + for (rr=centrrs->rrs; rr; rr=rr->next) { + if (!add_cent_rr_int(ce,i,centrrs->ttl, centrrs->ts, centrrs->flags, + rr->rdlen, rr->data, &rtail DBG0)) + { + /* cleanup this entry */ + goto cleanup_cent_unlock_cache_return; + } + } + cerrs= RRARR_INDEX(ce,i); + adjust_ttl(cerrs); + if (!insert_rrl(cerrs,ce,i)) { + goto cleanup_cent_unlock_cache_return; + } + } + } + } + ce->flags |= (cent->flags&(DF_AUTH|DF_WILD)); + if(cent->c_ns!=cundef && (ce->c_ns==cundef || ce->c_nsc_ns)) + ce->c_ns=cent->c_ns; + if(cent->c_soa!=cundef && (ce->c_soa==cundef || ce->c_soac_soa)) + ce->c_soa=cent->c_soa; + } + + cache_size += ce->cs; + purge_cache_return: + purge_cache((long)global.perm_cache*1024+MCSZ, 1); + goto unlock_cache_return; + + cleanup_cent_unlock_cache_return: + del_cent_rrset_by_index(ce, i DBG0); + addsize_unlock_cache_return: + cache_size += ce->cs; + goto warn_unlock_cache_return; + + free_cent_unlock_cache_return: + free_cent(ce DBG0); + pdnsd_free(ce); + warn_unlock_cache_return: + log_warn("Out of cache memory."); + unlock_cache_return: + unlock_cache_rw(); +} + +/* + Convert A (and AAAA) records in a ready built cache entry to PTR records suitable for reverse resolving + of numeric addresses and add them to the cache. +*/ +int add_reverse_cache(dns_cent_t * cent) +{ + int tp=T_A; + rr_set_t *rrset= getrrset_A(cent); + + for(;;) { + if(rrset) { + rr_bucket_t *rr; + for(rr=rrset->rrs; rr; rr=rr->next) { + dns_cent_t ce; + unsigned char buf[DNSNAMEBUFSIZE],rhn[DNSNAMEBUFSIZE]; + if(!a2ptrstr((pdnsd_ca *)(rr->data),tp,buf) || !str2rhn(buf,rhn)) + return 0; + if(!init_cent(&ce, rhn, 0, 0, cent->flags DBG0)) + return 0; + if(!add_cent_rr(&ce,T_PTR,rrset->ttl,rrset->ts,rrset->flags,rhnlen(cent->qname),cent->qname DBG0)) { + free_cent(&ce DBG0); + return 0; + } +#ifdef RRMUINDEX_NS + ce.rr.rrmu[RRMUINDEX_NS]=cent->rr.rrmu[RRMUINDEX_NS]; +#endif +#ifdef RRMUINDEX_SOA + ce.rr.rrmu[RRMUINDEX_SOA]=cent->rr.rrmu[RRMUINDEX_SOA]; +#endif + add_cache(&ce); +#ifdef RRMUINDEX_NS + ce.rr.rrmu[RRMUINDEX_NS]=NULL; +#endif +#ifdef RRMUINDEX_SOA + ce.rr.rrmu[RRMUINDEX_SOA]=NULL; +#endif + free_cent(&ce DBG0); + } + } +#if ALLOW_LOCAL_AAAA + if(tp==T_AAAA) + break; + tp=T_AAAA; + rrset= getrrset_AAAA(cent); +#else + break; +#endif + } + return 1; +} + + +/* + Delete a cent from the cache. Call with write locks applied. + Does not delete corresponding entry in hash table, call del_cache_ent() + or del_cache() for that. +*/ +void del_cent(dns_cent_t *cent) +{ + cache_size -= cent->cs; + + /* free the data referred by the cent and the cent itself */ + free_cent(cent DBG0); + free(cent); + + --ent_num; +} + +/* + * Delete a cent from the cache. Call with write locks applied. + */ +static void del_cache_ent(dns_cent_t *cent,dns_hash_loc_t *loc) +{ + dns_cent_t *data; + + /* Delete from the hash */ + if(loc) + data=del_dns_hash_ent(loc); + else + data=del_dns_hash(cent->qname); + if(!data) { + log_warn("Cache entry not found by del_dns_hash() in %s, line %d",__FILE__,__LINE__); + } + else if(data!=cent) { + log_warn("pointer returned by del_dns_hash() does not match cache entry in %s, line %d",__FILE__,__LINE__); + } + del_cent(cent); +} + +/* Delete a cached record. Performs locking. Call this from the outside, NOT del_cache_ent */ +void del_cache(const unsigned char *name) +{ + dns_cent_t *cent; + + lock_cache_rw(); + if ((cent=del_dns_hash(name))) { + del_cent(cent); + } + unlock_cache_rw(); +} + + +/* Invalidate a record by resetting the fetch time to 0. This means that it will be refreshed + * if possible (and will only be served when purge_cache=off;) */ +void invalidate_record(const unsigned char *name) +{ + dns_cent_t *ce; + int i, ilim; + + lock_cache_rw(); + if ((ce=dns_lookup(name,NULL))) { + if(!(ce->flags&DF_NEGATIVE)) { + ilim= RRARR_LEN(ce); + for (i=0; its=0; + rrs->flags &= ~CF_AUTH; + } + } + } + else { + /* set the cent time to 0 (for the case that this was negative) */ + ce->neg.ts=0; + } + ce->flags &= ~DF_AUTH; + } + unlock_cache_rw(); +} + + +/* + Set flags of the cache entry with the specified name. + Don't use this to set the DF_NEGATIVE flag, or you will + risk leaving the cache in an inconsistent state. + Returns 0 if the cache entry cannot be found, otherwise 1. + */ +int set_cent_flags(const unsigned char *name, unsigned flags) +{ + dns_cent_t *ret; + lock_cache_rw(); + ret=dns_lookup(name,NULL); + if (ret) { + ret->flags |= flags; + } + unlock_cache_rw(); + return ret!=NULL; +} + +unsigned char *getlocalowner(unsigned char *name,int tp) +{ + unsigned char *ret=NULL; + dns_cent_t *ce; + unsigned lb; + + lock_cache_r(); + if((lb = *name)) { + while(name += lb+1, lb = *name) { + if((ce=dns_lookup(name,NULL))) { + if(!(ce->flags&DF_LOCAL)) + break; + if(have_rr(ce,tp)) { + ret=name; + break; + } + } + } + } + unlock_cache_r(); + + return ret; +} + + +/* Lookup an entry in the cache using name (in length byte - string notation). + * For thread safety, a copy must be returned, so delete it after use, by first doing + * free_cent to remove the rrs and then by freeing the returned pointer. + * If wild is nonzero, and name can't be found in the cache, lookup_cache() + * will search up the name hierarchy for a record with the DF_NEGATIVE or DF_WILD flag set. + */ +dns_cent_t *lookup_cache(const unsigned char *name, int *wild) +{ + int purge=0; + dns_cent_t *ret; + + /* First try with only read access to the cache. */ + lock_cache_r(); + ret=dns_lookup(name,NULL); + if(wild) { + *wild=0; + if(!ret) { + const unsigned char *nm=name; + unsigned lb=*nm; + if(lb) { + while(nm += lb+1, lb = *nm) { + if ((ret=dns_lookup(nm,NULL))) { + if(ret->flags&DF_NEGATIVE) + /* use this entry */ + *wild=w_neg; + else if(ret->flags&DF_WILD) { + unsigned char buf[DNSNAMEBUFSIZE]; + buf[0]=1; buf[1]='*'; + /* When we get here, at least one element of name + has been removed, so assuming name is not longer + than DNSNAMEBUFSIZE bytes, the remainder is guaranteed to + fit into DNSNAMEBUFSIZE-2 bytes */ + rhncpy(&buf[2],nm); + ret=dns_lookup(buf,NULL); + if(ret) + *wild=w_wild; + } + else if(ret->flags&DF_LOCAL) + *wild=w_locnerr; + else + ret=NULL; + break; + } + } + } + } + } + if (ret) { + if(!(purge=purge_cent(ret, 1,1))) /* test only, don't remove anything yet! */ + ret=copy_cent(ret DBG1); + } + unlock_cache_r(); + + if(purge) { + /* we need exclusive read and write access before we delete anything. */ + lock_cache_rw(); + ret=dns_lookup(name,NULL); + if(wild) { + *wild=0; + if(!ret) { + const unsigned char *nm=name; + unsigned lb=*nm; + if(lb) { + while(nm += lb+1, lb = *nm) { + if ((ret=dns_lookup(nm,NULL))) { + if(ret->flags&DF_NEGATIVE) + /* use this entry */ + *wild=w_neg; + else if(ret->flags&DF_WILD) { + unsigned char buf[DNSNAMEBUFSIZE]; + buf[0]=1; buf[1]='*'; + rhncpy(&buf[2],nm); + ret=dns_lookup(buf,NULL); + if(ret) + *wild=w_wild; + } + else if(ret->flags&DF_LOCAL) + *wild=w_locnerr; + else + ret=NULL; + break; + } + } + } + } + } + if (ret) { + if(purge_cent(ret, 1,0)<0) + ret=NULL; + else + ret=copy_cent(ret DBG1); + } + unlock_cache_rw(); + } + + return ret; +} + +/* lookup_cache_local_rrset() check if there is locally defined RR set of a specific RR type + for name, and if so, returns a copy of the RR set. After use, the copy should be cleaned + up using del_rrset(). + This is potentially much more efficient than using lookup_cache(), if the name is likely + to have a cache entry, but unlikely to have locally defined RR sets. +*/ +rr_set_t *lookup_cache_local_rrset(const unsigned char *name, int type) +{ + rr_set_t *ret=NULL; + dns_cent_t *cent; + + lock_cache_r(); + cent= dns_lookup(name,NULL); + if(cent) { + rr_set_t *rrset=getrrset(cent,type); + if(rrset && (rrset->flags&CF_LOCAL)) { + ret= copy_rrset(rrset); + } + } + unlock_cache_r(); + + return ret; +} + + +#if 0 +/* Add an rr to an existing cache entry or create a new entry if necessary. + * The rr is treated with the precedence of an additional or off-topic record, ie. regularly retrieved + * have precedence. + * You cannot add a negative additional record. Makes no sense anyway. */ +int add_cache_rr_add(const unsigned char *name, int tp, time_t ttl, time_t ts, unsigned flags, unsigned dlen, void *data, unsigned long serial) +{ + dns_hash_loc_t loc; + dns_cent_t *ret; + rr_set_t *rrs; + int rv=0; + + lock_cache_rw(); + if (!(ret=dns_lookup(name,&loc))) { + if (!(ret=cache_malloc(sizeof(dns_cent_t)))) + goto unlock_return; + if(!init_cent(ret, name, 0, 0, 0 DBG0)) { + pdnsd_free(ret); + goto unlock_return; + } + if(!add_dns_hash(ret,&loc)) { + free_cent(ret DBG0); + pdnsd_free(ret); + goto unlock_return; + } + ++ent_num; + } + else { + /* purge the record. */ + purge_cent(ret,0,0); + cache_size-=ret->cs; + } + rrs=getrrset(ret,tp); + if (rrs && + ((rrs->flags&CF_NEGATIVE && !(rrs->flags&CF_LOCAL)) || + (rrs->flags&CF_NOPURGE && timedout(rrs)) || + (rrs->flags&CF_ADDITIONAL && rrs->serial!=serial) || + (rrs->serial==serial && rrs->ttl!=(ttlglobal.max_ttl?global.max_ttl:ttl))))) { + del_cent_rrset_by_type(ret,tp DBG0); + rrs=NULL; + } + if (rrs==NULL || rrs->serial==serial) { + if (cr_check_add(ret,rrlkuptab[tp-T_MIN],ttl,ts,flags)) { + if (add_cent_rr(ret,tp,ttl,ts,flags,dlen,data,serial DBG0)) { + rr_set_t *rrsnew; + if (!rrs && (rrsnew=getrrset(ret,tp)) && !insert_rrl(rrsnew,ret,rrlkuptab[tp-T_MIN])) { + del_cent_rrset_by_type(ret,tp DBG0); + } + else { + cache_size+=ret->cs; + purge_cent(ret,1,0); + rv=1; + goto unlock_return; + } + } + } + } else { + rv=1; + } + cache_size+=ret->cs; + + unlock_return: + unlock_cache_rw(); + return rv; +} +#endif + +/* Report the cache status to the file descriptor f, for the status fifo (see status.c) */ +int report_cache_stat(int f) +{ + /* Cache size and entry counters are volatile (and even the entries + in the global struct can change), so make copies to get consistent data. + Even better would be to use locks, but that could be rather costly. */ + long csz= cache_size, en= ent_num; + long pc= global.perm_cache; + long mc= pc*1024+MCSZ; + + fsprintf_or_return(f,"\nCache status:\n=============\n"); + fsprintf_or_return(f,"%ld kB maximum disk cache size.\n",pc); + fsprintf_or_return(f,"%ld of %ld bytes (%.3g%%) memory cache used in %ld entries" + " (avg %.5g bytes/entry).\n", + csz, mc, (((double)csz)/mc)*100, en, + ((double)csz)/en); + return 0; +} + + +#define timestamp2str(ts,now,buf) \ +{ \ + struct tm tstm; \ + if(!((ts) && localtime_r(&(ts), &tstm) && \ + strftime(buf, sizeof(buf), \ + ((ts)<=(now) && (now)-(ts)<365*24*60*60/2)?" %m/%d %T":"%Y/%m/%d %T", \ + &tstm)>0)) \ + strcpy(buf," "); \ +} + +/* Dump contents of a cache entry to file descriptor fd. + Returns 1 on success, -1 if there is an IO error. +*/ +static int dump_cent(int fd, dns_cent_t *cent) +{ + time_t now; + char tstr[sizeof "2000/12/31 23:59:59"],dbuf[1024]; + + fsprintf_or_return(fd,"%s\n",rhn2str(cent->qname,ucharp dbuf,sizeof(dbuf))); + now=time(NULL); + + if(cent->flags&DF_NEGATIVE) { + timestamp2str(cent->neg.ts,now,tstr); + fsprintf_or_return(fd,"%s (domain negated)\n",tstr); + } + else { + int i, n= NRRITERLIST(cent); + const unsigned short *iterlist= RRITERLIST(cent); + for(i=0; its,now,tstr); + if(rrset->flags&CF_NEGATIVE) { + fsprintf_or_return(fd,"%s %-7s (negated)\n",tstr,rrnames[tp-T_MIN]); + } + else { + rr_bucket_t *rr; + for(rr=rrset->rrs; rr; rr=rr->next) { + switch (tp) { + case T_CNAME: + case T_MB: + case T_MD: + case T_MF: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + rhn2str((unsigned char *)(rr->data),ucharp dbuf,sizeof(dbuf)); + break; +#if IS_CACHED_MINFO || IS_CACHED_RP +#if IS_CACHED_MINFO + case T_MINFO: +#endif +#if IS_CACHED_RP + case T_RP: +#endif + { + unsigned char *p=(unsigned char *)(rr->data); + int n; + rhn2str(p,ucharp dbuf,sizeof(dbuf)); + n=strlen(dbuf); + dbuf[n++] = ' '; + if(n>=sizeof(dbuf)) + goto hex_dump; + rhn2str(skiprhn(p),ucharp dbuf+n,sizeof(dbuf)-n); + } + break; +#endif + case T_MX: +#if IS_CACHED_AFSDB + case T_AFSDB: +#endif +#if IS_CACHED_RT + case T_RT: +#endif +#if IS_CACHED_KX + case T_KX: +#endif + { + unsigned char *p=(unsigned char *)(rr->data); + unsigned pref; + int n; + GETINT16(pref,p); + n=sprintf(dbuf,"%u ",pref); + if(n<0) goto hex_dump; + rhn2str(p,ucharp dbuf+n,sizeof(dbuf)-n); + } + break; + case T_SOA: + { + unsigned char *p=(unsigned char *)(rr->data); + char *q; + int n,rem; + uint32_t serial,refresh,retry,expire,minimum; + rhn2str(p,ucharp dbuf,sizeof(dbuf)); + n=strlen(dbuf); + dbuf[n++] = ' '; + if(n>=sizeof(dbuf)) + goto hex_dump; + q=dbuf+n; + rem=sizeof(dbuf)-n; + p=skiprhn(p); + rhn2str(p,ucharp q,rem); + n=strlen(q); + q[n++] = ' '; + if(n>=rem) + goto hex_dump; + q += n; + rem -= n; + p=skiprhn(p); + GETINT32(serial,p); + GETINT32(refresh,p); + GETINT32(retry,p); + GETINT32(expire,p); + GETINT32(minimum,p); + n=snprintf(q,rem,"%lu %lu %lu %lu %lu", + (unsigned long)serial,(unsigned long)refresh, + (unsigned long)retry,(unsigned long)expire, + (unsigned long)minimum); + if(n<0 || n>=rem) + goto hex_dump; + } + break; +#if IS_CACHED_HINFO || IS_CACHED_TXT || IS_CACHED_SPF +#if IS_CACHED_HINFO + case T_HINFO: +#endif +#if IS_CACHED_TXT + case T_TXT: +#endif +#if IS_CACHED_SPF + case T_SPF: +#endif + { + /* TXT records are not necessarily validated + before they are stored in the cache, so + we need to be careful. */ + unsigned char *p=(unsigned char *)(rr->data); + char *q=dbuf; + int j=0,n,rem=sizeof(dbuf); + while(jrdlen) { + unsigned lb; + if(rem<3) + goto hex_dump; + if(j) { + *q++ = ' '; + --rem; + } + *q++ = '"'; + --rem; + lb=*p++; + if((j += lb+1)>rr->rdlen) + goto hex_dump; + n=escapestr(charp p,lb,q,rem); + if(n<0 || n+1>=rem) + goto hex_dump; + q += n; + *q++ = '"'; + rem -= n+1; + p += lb; + } + *q=0; + } + break; +#endif +#if IS_CACHED_PX + case T_PX: + { + unsigned char *p=(unsigned char *)(rr->data); + char *q; + unsigned pref; + int n,rem; + GETINT16(pref,p); + n=sprintf(dbuf,"%u ",pref); + if(n<0) goto hex_dump; + q=dbuf+n; + rem=sizeof(dbuf)-n; + rhn2str(p,ucharp q,rem); + n=strlen(q); + q[n++] = ' '; + if(n>=rem) + goto hex_dump; + rhn2str(skiprhn(p),ucharp q+n,rem-n); + } + break; +#endif +#if IS_CACHED_SRV + case T_SRV: + { + unsigned char *p=(unsigned char *)(rr->data); + unsigned priority,weight,port; + int n; + GETINT16(priority,p); + GETINT16(weight,p); + GETINT16(port,p); + n=sprintf(dbuf,"%u %u %u ",priority,weight,port); + if(n<0) goto hex_dump; + rhn2str(p,ucharp dbuf+n,sizeof(dbuf)-n); + } + break; +#endif +#if IS_CACHED_NXT + case T_NXT: + { + unsigned char *p=(unsigned char *)(rr->data); + int n,rlen; + rhn2str(p,ucharp dbuf,sizeof(dbuf)); + n=strlen(dbuf); + dbuf[n++] = ' '; + if(n>=sizeof(dbuf)) + goto hex_dump; + rlen=rhnlen(p); + hexdump(p+rlen,rr->rdlen-rlen,dbuf+n,sizeof(dbuf)-n); + } + break; +#endif +#if IS_CACHED_NAPTR + case T_NAPTR: + { + unsigned char *p=(unsigned char *)(rr->data); + char *q; + unsigned order,pref; + int n,rem,j; + GETINT16(order,p); + GETINT16(pref,p); + n=sprintf(dbuf,"%u %u ",order,pref); + if(n<0) goto hex_dump; + q=dbuf+n; + rem=sizeof(dbuf)-n; + for (j=0;j<3;++j) { + unsigned lb; + if(rem<2) + goto hex_dump; + *q++ = '"'; + --rem; + lb=*p++; + n=escapestr(charp p,lb,q,rem); + if(n<0 || n+2>=rem) + goto hex_dump; + q += n; + *q++ = '"'; + *q++ = ' '; + rem -= n+2; + p += lb; + } + rhn2str(p,ucharp q,rem); + } + break; +#endif +#if IS_CACHED_LOC + case T_LOC: + /* Binary data length has not necessarily been validated */ + if(rr->rdlen!=16) + goto hex_dump; + if(!loc2str(rr->data,dbuf,sizeof(dbuf))) + goto hex_dump; + break; +#endif + case T_A: + if (!inet_ntop(AF_INET,rr->data,dbuf,sizeof(dbuf))) + goto hex_dump; + break; +#if IS_CACHED_AAAA && defined(AF_INET6) + case T_AAAA: + if (!inet_ntop(AF_INET6,rr->data,dbuf,sizeof(dbuf))) + goto hex_dump; + break; +#endif + default: + hex_dump: + hexdump(rr->data,rr->rdlen,dbuf,sizeof(dbuf)); + } + fsprintf_or_return(fd,"%s %-7s %s\n",tstr,rrnames[tp-T_MIN],dbuf); + } + } + } + } + } + fsprintf_or_return(fd,"\n"); + return 1; +} + +/* Dump cache contents to file descriptor fd. + If name is not null, restricts information to that name, + otherwise dumps information about all names found in the cache. + Returns 1 on success, 0 if the name is not found, -1 is there is an IO error. + Mainly for debugging purposes. +*/ +int dump_cache(int fd, const unsigned char *name, int exact) +{ + int rv=0; + lock_cache_r(); + if(name && exact) { + dns_cent_t *cent=dns_lookup(name,NULL); + if(cent) + rv=dump_cent(fd,cent); + } + else { + dns_cent_t *cent; + dns_hash_pos_t pos; + for (cent=fetch_first(&pos); cent; cent=fetch_next(&pos)) { + unsigned int nrem; + if(!name || (domain_match(name,cent->qname,&nrem,NULL),nrem==0)) + if((rv=dump_cent(fd,cent))<0) + break; + } + } + unlock_cache_r(); + return rv; +} + + +#if DEBUG>0 + +/* Added by Paul Rombouts: This is only used in debug messages. */ +const char cflgnames[NCFLAGS*3]={'N','E','G','L','O','C','A','U','T','N','O','C','A','D','D','N','O','P','R','T','S'}; +const char dflgnames[NDFLAGS*3]={'N','E','G','L','O','C','A','U','T','N','O','C','W','L','D'}; + +char *flags2str(unsigned flags,char *buf,int nflags,const char *flgnames) +{ + char *p=buf; + int i,nflgchars=3*nflags; + for(i=0;ibuf) *p++='|'; + p=mempcpy(p,&flgnames[i],3); + } + flags >>= 1; + } + if(p==buf) + *p++='0'; + *p=0; + return buf; +} +#endif diff --git a/jni/pdnsd/src/cache.h b/jni/pdnsd/src/cache.h new file mode 100644 index 00000000..5056dec7 --- /dev/null +++ b/jni/pdnsd/src/cache.h @@ -0,0 +1,306 @@ +/* cache.h - Definitions for the dns cache + + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2003, 2004, 2005, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _CACHE_H_ +#define _CACHE_H_ + +#include +#include "ipvers.h" +#include +#include "list.h" +#include "dns.h" +#include "conff.h" + +struct rr_lent_s; + +/* + * These values are converted to host byte order. the data is _not_. + */ +typedef struct rr_b_s { + struct rr_b_s *next; /* this is the next pointer in the dns_cent_t list. */ + unsigned rdlen; +#if ALLOW_LOCAL_AAAA || defined(ENABLE_IPV6) + struct in6_addr data[0]; /* dummy for alignment */ +#else + struct in_addr data[0]; +#endif +} rr_bucket_t; + +typedef struct { + struct rr_lent_s *lent; /* this points to the list entry */ + time_t ttl; + time_t ts; + unsigned short flags; + rr_bucket_t *rrs; +} rr_set_t; + + +typedef struct { + unsigned char *qname; /* Name of the domain in length byte - string notation. */ + size_t cs; /* Size of the cache entry, including RR sets. */ + unsigned short num_rrs; /* The number of RR sets. When this decreases to 0, the cent is deleted. */ + unsigned short flags; /* Flags for the whole domain. */ + union { + struct { /* Fields used only for negatively cached domains. */ + struct rr_lent_s *lent; /* list entry for the whole cent. */ + time_t ttl; /* TTL for negative caching. */ + time_t ts; /* Timestamp. */ + } neg; + struct { /* Fields used only for domains that actually exist. */ + rr_set_t *(rrmu[NRRMU]); /* The most used records. + Use the the value obtained from rrlkuptab[] as index. */ + rr_set_t **rrext; /* Pointer (may be NULL) to an array of size NNRREXT storing the + less frequently used records. */ + } rr; + }; + unsigned char c_ns,c_soa; /* Number of trailing name elements in qname to use to find NS or SOA + records to add to the authority section of a response. */ +} dns_cent_t; + +/* This value is used to represent an undefined c_ns or c_soa field. */ +#define cundef 0xff + +/* + * the flag values for RR sets in the cache + */ +#define CF_NEGATIVE 1 /* this one is for per-RRset negative caching*/ +#define CF_LOCAL 2 /* Local zone entry */ +#define CF_AUTH 4 /* authoritative record */ +#define CF_NOCACHE 8 /* Only hold for the cache latency time period, then purge. + * Not really written to cache, but used by add_cache. */ +#define CF_ADDITIONAL 16 /* This was fetched as an additional or "off-topic" record. */ +#define CF_NOPURGE 32 /* Do not purge this record */ +#define CF_ROOTSERV 64 /* This record was directly obtained from a root server */ + +#define CFF_NOINHERIT (CF_LOCAL|CF_AUTH|CF_ADDITIONAL|CF_ROOTSERV) /* not to be inherited on requery */ + +/* + * the flag values for whole domains in the cache + */ +#define DF_NEGATIVE 1 /* this one is for whole-domain negative caching (created on NXDOMAIN)*/ +#define DF_LOCAL 2 /* local record (in conj. with DF_NEGATIVE) */ +#define DF_AUTH 4 /* authoritative record */ +#define DF_NOCACHE 8 /* Only hold for the cache latency time period, then purge. + * Only used for negatively cached domains. + * Not really written to cache, but used by add_cache. */ +#define DF_WILD 16 /* subdomains of this domain have wildcard records */ + +/* #define DFF_NOINHERIT (DF_NEGATIVE) */ /* not to be inherited on requery */ + +enum {w_wild=1, w_neg, w_locnerr}; /* Used to distinguish different types of wildcard records. */ + +#if DEBUG>0 +#define NCFLAGS 7 +#define NDFLAGS 5 +#define CFLAGSTRLEN (NCFLAGS*4) +#define DFLAGSTRLEN (NDFLAGS*4) +extern const char cflgnames[]; +extern const char dflgnames[]; +char *flags2str(unsigned flags,char *buf,int nflags,const char *flgnames); +#define cflags2str(flags,buf) flags2str(flags,buf,NCFLAGS,cflgnames) +#define dflags2str(flags,buf) flags2str(flags,buf,NDFLAGS,dflgnames) +#endif + +/* + * This is the time in secs any record remains at least in the cache before it is purged. + * (exception is that the cache is full) + */ +#define CACHE_LAT 120 +#define CLAT_ADJ(ttl) ((ttl)ts+CLAT_ADJ((rrset)->ttl)neg.ts+CLAT_ADJ((cent)->neg.ttl)purge_cache) + fl|=CF_NOPURGE; + if (server->nocache) + fl|=CF_NOCACHE; + if (server->rootserver) + fl|=CF_ROOTSERV; + return fl; +} + +int init_cent(dns_cent_t *cent, const unsigned char *qname, time_t ttl, time_t ts, unsigned flags DBGPARAM); +int add_cent_rrset_by_type(dns_cent_t *cent, int type, time_t ttl, time_t ts, unsigned flags DBGPARAM); +int add_cent_rr(dns_cent_t *cent, int type, time_t ttl, time_t ts, unsigned flags,unsigned dlen, void *data DBGPARAM); +int del_rrset(rr_set_t *rrs DBGPARAM); +void free_cent(dns_cent_t *cent DBGPARAM); +void free_cent0(void *ptr); +void negate_cent(dns_cent_t *cent, time_t ttl, time_t ts); +void del_cent(dns_cent_t *cent); + +/* Because this is empty by now, it is defined as an empty macro to save overhead.*/ +/*void free_rr(rr_bucket_t cent);*/ +#define free_rr(x) + +dns_cent_t *copy_cent(dns_cent_t *cent DBGPARAM); + +#if 0 +unsigned long get_serial(void); +#endif + +/* Get pointer to rrset given cache entry and rr type value. */ +inline static rr_set_t *getrrset(dns_cent_t *cent, int type) + __attribute__((always_inline)); +inline static rr_set_t *getrrset(dns_cent_t *cent, int type) +{ + if(!(cent->flags&DF_NEGATIVE)) { + int tpi= type - T_MIN; + + if(tpi>=0 && tpirr.rrmu[idx]; + else { + idx -= NRRMU; + if(idx < NRREXT) { + rr_set_t **rrext= cent->rr.rrext; + if(rrext) + return rrext[idx]; + } + } + } + } + + return NULL; +} + +/* This version of getrrset is slightly more efficient, + but also more dangerous, because it performs less checks. + It is safe to use if T_MIN <= type <= T_MAX and cent + is not negative. +*/ +inline static rr_set_t *getrrset_eff(dns_cent_t *cent, int type) + __attribute__((always_inline)); +inline static rr_set_t *getrrset_eff(dns_cent_t *cent, int type) +{ + unsigned int idx = rrlkuptab[type-T_MIN]; + if(idx < NRRMU) + return cent->rr.rrmu[idx]; + else { + idx -= NRRMU; + if(idx < NRREXT) { + rr_set_t **rrext= cent->rr.rrext; + if(rrext) + return rrext[idx]; + } + } + + return NULL; +} + + +/* have_rr() tests whether a cache entry has at least one record of a given type. + Only use if T_MIN <= type <=T_MAX +*/ +inline static int have_rr(dns_cent_t *cent, int type) + __attribute__((always_inline)); +inline static int have_rr(dns_cent_t *cent, int type) +{ + rr_set_t *rrset; + return !(cent->flags&DF_NEGATIVE) && (rrset=getrrset_eff(cent, type)) && rrset->rrs; +} + +/* Some quick and dirty and hopefully fast macros. */ +#define PDNSD_NOT_CACHED_TYPE(type) ((type)T_MAX || rrlkuptab[(type)-T_MIN]>=NRRTOT) + +/* This is useful for iterating over all the RR types in a cache entry in strict ascending order. */ +#define NRRITERLIST(cent) ((cent)->flags&DF_NEGATIVE?0:(cent)->rr.rrext?NRRTOT:NRRMU) +#define RRITERLIST(cent) ((cent)->flags&DF_NEGATIVE?NULL:(cent)->rr.rrext?rrcachiterlist:rrmuiterlist) + +/* The following macros use array indices as arguments, not RR type values! */ +#define GET_RRSMU(cent,i) (!((cent)->flags&DF_NEGATIVE)?(cent)->rr.rrmu[i]:NULL) +#define GET_RRSEXT(cent,i) (!((cent)->flags&DF_NEGATIVE) && (cent)->rr.rrext?(cent)->rr.rrext[i]:NULL) +#define HAVE_RRMU(cent,i) (!((cent)->flags&DF_NEGATIVE) && (cent)->rr.rrmu[i] && (cent)->rr.rrmu[i]->rrs) +#define HAVE_RREXT(cent,i) (!((cent)->flags&DF_NEGATIVE) && (cent)->rr.rrext && (cent)->rr.rrext[i] && (cent)->rr.rrext[i]->rrs) + +#define RRARR_LEN(cent) ((cent)->flags&DF_NEGATIVE?0:(cent)->rr.rrext?NRRTOT:NRRMU) + +/* This allows us to index the RR-set arrays in a cache entry as if they formed one contiguous array. */ +#define RRARR_INDEX_TESTEXT(cent,i) ((cent)->flags&DF_NEGATIVE?NULL:(i)rr.rrmu[i]:(cent)->rr.rrext?(cent)->rr.rrext[(i)-NRRMU]:NULL) +/* This gets the address where the pointer to an RR-set is stored in a cache entry, + given the cache entry and an RR-set index. + Address may be NULL if no storage space for the type has been allocated. */ +#define RRARR_INDEX_PA_TESTEXT(cent,i) ((cent)->flags&DF_NEGATIVE?NULL:(i)rr.rrmu[i]:(cent)->rr.rrext?&(cent)->rr.rrext[(i)-NRRMU]:NULL) + +/* The following macros should only be used if 0 <= i < RRARR_LEN(cent) ! */ +#define RRARR_INDEX(cent,i) ((i)rr.rrmu[i]:(cent)->rr.rrext[(i)-NRRMU]) +#define RRARR_INDEX_PA(cent,i) ((i)rr.rrmu[i]:&(cent)->rr.rrext[(i)-NRRMU]) + +#endif diff --git a/jni/pdnsd/src/conf-keywords.h b/jni/pdnsd/src/conf-keywords.h new file mode 100644 index 00000000..2bcdacfe --- /dev/null +++ b/jni/pdnsd/src/conf-keywords.h @@ -0,0 +1,238 @@ +/* conf-keywords.h - Tables used by parser of configuration file. + Based on information previously contained in conf-lex.y and conf-parse.y + + Copyright (C) 2004,2005,2006,2007,2008,2009,2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +enum { + ERROR, + + GLOBAL, + SERVER, + RR, + NEG, + SOURCE, + INCLUDE_F, + + PERM_CACHE, + CACHE_DIR, + SERVER_PORT, + SERVER_IP, + OUTGOING_IP, + SCHEME_FILE, + LINKDOWN_KLUGE, + MAX_TTL, + MIN_TTL, + RUN_AS, + STRICT_SETUID, + USE_NSS, + PARANOID, + IGNORE_CD, + STATUS_CTL, + DAEMON, + C_TCP_SERVER, + PID_FILE, + C_VERBOSITY, + C_QUERY_METHOD, + RUN_IPV4, + IPV4_6_PREFIX, + C_DEBUG, + C_CTL_PERMS, + C_PROC_LIMIT, + C_PROCQ_LIMIT, + TCP_QTIMEOUT, + C_PAR_QUERIES, + C_RAND_RECS, + NEG_TTL, + NEG_RRS_POL, + NEG_DOMAIN_POL, + QUERY_PORT_START, + QUERY_PORT_END, + UDP_BUFSIZE, + DELEGATION_ONLY, + + IP, + PORT, + SCHEME, + UPTEST, + TIMEOUT, + PING_TIMEOUT, + PING_IP, + UPTEST_CMD, + QUERY_TEST_NAME, + INTERVAL, + INTERFACE, + DEVICE, + PURGE_CACHE, + CACHING, + LEAN_QUERY, + EDNS_QUERY, + PRESET, + PROXY_ONLY, + ROOT_SERVER, + RANDOMIZE_SERVERS, + INCLUDE, + EXCLUDE, + POLICY, + REJECTLIST, + REJECTPOLICY, + REJECTRECURSIVELY, + LABEL, + + A, + PTR, + MX, + SOA, + CNAME, + TXT, + SPF, + NAME, + OWNER, + TTL, + TYPES, + FILET, + SERVE_ALIASES, + AUTHREC, + REVERSE +}; + + +/* Table for looking up section headers. Order alphabetically! */ +static const namevalue_t section_headers[]= { + {"global", GLOBAL}, + {"include", INCLUDE_F}, + {"neg", NEG}, + {"rr", RR}, + {"server", SERVER}, + {"source", SOURCE} +}; + +/* Table for looking up global options. Order alphabetically! */ +static const namevalue_t global_options[]= { + {"cache_dir", CACHE_DIR}, + {"ctl_perms", C_CTL_PERMS}, + {"daemon", DAEMON}, + {"debug", C_DEBUG}, + {"delegation_only", DELEGATION_ONLY}, + {"ignore_cd", IGNORE_CD}, + {"interface", SERVER_IP}, + {"ipv4_6_prefix", IPV4_6_PREFIX}, + {"linkdown_kluge", LINKDOWN_KLUGE}, + {"max_ttl", MAX_TTL}, + {"min_ttl", MIN_TTL}, + {"neg_domain_pol", NEG_DOMAIN_POL}, + {"neg_rrs_pol", NEG_RRS_POL}, + {"neg_ttl", NEG_TTL}, + {"outgoing_ip", OUTGOING_IP}, + {"outside_interface", OUTGOING_IP}, + {"par_queries", C_PAR_QUERIES}, + {"paranoid", PARANOID}, + {"perm_cache", PERM_CACHE}, + {"pid_file", PID_FILE}, + {"proc_limit", C_PROC_LIMIT}, + {"procq_limit", C_PROCQ_LIMIT}, + {"query_method", C_QUERY_METHOD}, + {"query_port_end", QUERY_PORT_END}, + {"query_port_start", QUERY_PORT_START}, + {"randomize_recs", C_RAND_RECS}, + {"run_as", RUN_AS}, + {"run_ipv4", RUN_IPV4}, + {"scheme_file", SCHEME_FILE}, + {"server_ip", SERVER_IP}, + {"server_port", SERVER_PORT}, + {"status_ctl", STATUS_CTL}, + {"strict_setuid", STRICT_SETUID}, + {"tcp_qtimeout", TCP_QTIMEOUT}, + {"tcp_server", C_TCP_SERVER}, + {"timeout", TIMEOUT}, + {"udpbufsize", UDP_BUFSIZE}, + {"use_nss", USE_NSS}, + {"verbosity", C_VERBOSITY} +}; + +/* Table for looking up server options. Order alphabetically! */ +static const namevalue_t server_options[]= { + {"caching", CACHING}, + {"device", DEVICE}, + {"edns_query", EDNS_QUERY}, + {"exclude", EXCLUDE}, + {"file", FILET}, + {"include", INCLUDE}, + {"interface", INTERFACE}, + {"interval", INTERVAL}, + {"ip", IP}, + {"label", LABEL}, + {"lean_query", LEAN_QUERY}, + {"ping_ip", PING_IP}, + {"ping_timeout", PING_TIMEOUT}, + {"policy", POLICY}, + {"port", PORT}, + {"preset", PRESET}, + {"proxy_only", PROXY_ONLY}, + {"purge_cache", PURGE_CACHE}, + {"query_test_name", QUERY_TEST_NAME}, + {"randomize_servers", RANDOMIZE_SERVERS}, + {"reject", REJECTLIST}, + {"reject_policy", REJECTPOLICY}, + {"reject_recursively", REJECTRECURSIVELY}, + {"root_server", ROOT_SERVER}, + {"scheme", SCHEME}, + {"timeout", TIMEOUT}, + {"uptest", UPTEST}, + {"uptest_cmd", UPTEST_CMD} +}; + +/* Table for looking up rr options. Order alphabetically! */ +static const namevalue_t rr_options[]= { + {"a", A}, + {"authrec", AUTHREC}, + {"cname", CNAME}, + {"mx", MX}, + {"name", NAME}, + {"ns", OWNER}, + {"owner", OWNER}, + {"ptr", PTR}, + {"reverse", REVERSE}, + {"soa", SOA}, + {"spf", SPF}, + {"ttl", TTL}, + {"txt", TXT} +}; + +/* Table for looking up source options. Order alphabetically! */ +static const namevalue_t source_options[]= { + {"authrec", AUTHREC}, + {"file", FILET}, + {"ns", OWNER}, + {"owner", OWNER}, + {"serve_aliases", SERVE_ALIASES}, + {"ttl", TTL} +}; + +/* Table for looking up include options. Order alphabetically! */ +static const namevalue_t include_options[]= { + {"file", FILET} +}; + +/* Table for looking up neg options. Order alphabetically! */ +static const namevalue_t neg_options[]= { + {"name", NAME}, + {"ttl", TTL}, + {"types", TYPES} +}; diff --git a/jni/pdnsd/src/conf-parser.c b/jni/pdnsd/src/conf-parser.c new file mode 100644 index 00000000..9cf9180e --- /dev/null +++ b/jni/pdnsd/src/conf-parser.c @@ -0,0 +1,2118 @@ +/* conf-parser.c - Parser for pdnsd config files. + Based on the files conf-lex.l and conf-parse.y written by + Thomas Moestl. + This version was rewritten in C from scratch by Paul A. Rombouts + and doesn't require (f)lex or yacc/bison. + + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011 Paul A. Rombouts. + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include "ipvers.h" +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(HAVE_STRUCT_IFREQ) +#include +#endif +#include "conff.h" +#include "consts.h" +#include "cache.h" +#include "dns.h" +#include "helpers.h" +#include "rr_types.h" +#include "netdev.h" +#include "conf-keywords.h" +#include "conf-parser.h" + + +/* Check that include files are not nested deeper than MAXINCLUDEDEPTH, + as a precaution against infinite recursion. */ +#define MAXINCLUDEDEPTH 100 + +static char *report_error (const char *conftype, unsigned linenr, const char *msg) +{ + char *retval; + if(linenr) { + if(asprintf(&retval, "Error in %s (line %u): %s",conftype,linenr,msg)<0) + retval=NULL; + } + else { + if(asprintf(&retval, "Error in %s: %s",conftype,msg)<0) + retval=NULL; + } + + return retval; +} + +static char *report_errorf (const char *conftype, unsigned linenr, const char *frm,...) printfunc(3, 4); +static char *report_errorf (const char *conftype, unsigned linenr, const char *frm,...) +{ + char *msg,*retval; int mlen; + va_list va; + va_start(va,frm); + mlen=vasprintf(&msg,frm,va); + va_end(va); + if(mlen<0) return NULL; + retval=report_error(conftype,linenr,msg); + free(msg); + return retval; +} + +/* return pointer to next character in linebuffer after skipping blanks and comments */ +static char* getnextp(char **buf, size_t *n, FILE* in, char *p, unsigned *linenr, char **errstr) +{ + if(!p) goto nextline; + tryagain: + if(!*p) { + nextline: + do { + if(!in || getline(buf,n,in)<0) { + *errstr=NULL; + return NULL; + } + ++*linenr; + p=*buf; + } while(!*p); + } + if(isspace(*p)) { + ++p; goto tryagain; + } + if(*p=='#') { + skip_rest_of_line: + if(*linenr) + goto nextline; + else { + p=strchr(p,'\n'); + if(p) { + ++p; + goto tryagain; + } + else + goto nextline; + } + } + if(*p=='/') { + if(*(p+1)=='/') + goto skip_rest_of_line; + if(*(p+1)=='*') { + int lev=1; + p +=2; + for(;;) { + while(*p) { + if(*p=='/' && *(p+1)=='*') { + ++lev; + p +=2; + continue; + } + else if(*p=='*' && *(p+1)=='/') { + p +=2; + if(--lev==0) goto tryagain; + continue; + } + ++p; + } + if(!in || getline(buf,n,in)<0) { + *errstr="comment without closing */"; + return NULL; + } + ++*linenr; + p=*buf; + } + } + } + + return p; +} + +static char translescapedchar(char c) +{ + switch(c) { + case 'f': return '\f'; + case 'n': return '\n'; + case 'r': return '\r'; + case 't': return '\t'; + case 'v': return '\v'; + } + return c; +} + +/* Scan a buffer for a string and copy the decoded (i.e. unescaped) version into + another buffer. + + A string either begins after and ends before a double-quote ("), + or simply consists of a sequence of "non-special" characters, + starting at the current position. + A back-slash (\) acts as an escape character, preventing any character + following it from terminating the string. Thus, for example, + back-slash double-quote (\") may be used to include double-quotes + in a string. + A number of escape sequences are interpreted as in C, e.g. + \t, \n, \r yield control-chars as in C. + + char **curp should point to the position in the buffer where + the scanning should begin. It will be updated to point + to the first character past the scanned string. + + char *outbuf is used to store the decoded string. + size_t outbufsz should be the size of outbuf. + + The return value is the length of the decoded string, unless an error occurs, + in which case -1 is returned and *errstr is assigned an error message. + The returned length may be larger than outbufsz, in which case the buffer + is filled with only the first outbufsz chars of the string. +*/ +static int scan_string(char **curp,char *outbuf, unsigned outbufsz, char **errstr) +{ + char *cur=*curp; + unsigned i=0; + + if(*cur=='"') { + /* Double-quoted string. */ + ++cur; /* Skip opening quote. */ + for(;; ++i,++cur) { + if(!*cur) goto noclosingquote; + if(*cur=='"') break; + if(*cur=='\\') { + if(!*++cur) goto nofollowingchar; + if(i=sizeof(buf)) \ + {CLEANUP_HANDLERS; goto string_too_long;} \ + } +# define REPORT_ERROR(msg) (*errstr=report_error(conftype,linenr,msg)) +# if !defined(CPP_C99_VARIADIC_MACROS) + /* GNU C Macro Varargs style. */ +# define REPORT_ERRORF(args...) (*errstr=report_errorf(conftype,linenr,args)) +#else + /* ANSI C99 style. */ +# define REPORT_ERRORF(...) (*errstr=report_errorf(conftype,linenr,__VA_ARGS__)) +# endif +# define PARSERROR {CLEANUP_HANDLERS; goto free_linebuf_return;} +# define OUTOFMEMERROR {CLEANUP_HANDLERS; goto out_of_memory;} +# define CLEANUP_GOTO(lab) {CLEANUP_HANDLERS; goto lab;} + + *errstr=NULL; + if(in) { + linebuf=malloc(buflen); + if(!linebuf) { + /* If malloc() just failed, allocating space for an error message is unlikely to succeed. */ + return 0; + } + if(global) + conftype="config file"; + else + conftype="include file"; + } + else + conftype="config string"; + + p=prestr; + while((p=getnextp(&linebuf,&buflen,in,p,&linenr,&getnextperr))) { + if(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + sechdr=lookup_keyword(ps,len,section_headers); + if(!sechdr) { + REPORT_ERRORF("invalid section header: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='{') goto expected_bropen; + ++p; + SKIP_BLANKS(p); + + switch(sechdr) { + case GLOBAL: + if(!global) { + REPORT_ERROR(in?"global section not allowed in include file": + "global section not allowed in eval string"); + PARSERROR; + } + + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,global_options); + if(!option) { + REPORT_ERRORF("invalid option for global section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') goto expected_equals; + ++p; + SKIP_BLANKS(p); + + switch(option) { + pdnsd_a *ipaddrp; + + case PERM_CACHE: + if (isalpha(*p)) { + int cnst; + SCAN_ALPHANUM(ps,p,len); + cnst=lookup_const(ps,len); + if(cnst==C_OFF) { + global->perm_cache=0; + } + else + goto bad_perm_cache_option; + } + else if(isdigit(*p)) { + global->perm_cache=strtol(p,&p,0); + } + else { + bad_perm_cache_option: + REPORT_ERROR("bad qualifier in perm_cache= option."); + PARSERROR; + } + break; + + case CACHE_DIR: + SCAN_STRING(p,strbuf,len); + STRNDUP(global->cache_dir,strbuf,len); + break; + + case SERVER_PORT: + SCAN_UNSIGNED_NUM(global->port,p,"server_port option") + break; + + case OUTGOING_IP: + ipaddrp= &global->out_a; + goto scan_ip_or_interface; + + case SERVER_IP: + ipaddrp= &global->a; + scan_ip_or_interface: + SCAN_STRING(p,strbuf,len); + { + const char *err; + if ((err=parse_ip(strbuf,ipaddrp))) { +#if defined(HAVE_STRUCT_IFREQ) && defined(IFNAMSIZ) && defined(SIOCGIFADDR) + if(!strcmp(err,"bad IP address") && lenipv4= ((struct sockaddr_in *)&req.ifr_addr)->sin_addr; +# endif +# ifdef ENABLE_IPV6 + ELSE_IPV6 + ipaddrp->ipv6= ((struct sockaddr_in6 *)&req.ifr_addr)->sin6_addr; +# endif + close(fd); + } + else { + REPORT_ERRORF("Failed to get IP address of %s: %s",req.ifr_name,strerror(errno)); + if(fd!=-1) close(fd); + PARSERROR; + } + } + else +#endif + { + REPORT_ERRORF("%s for the %s= option.",err,option==SERVER_IP?"server_ip":"outgoing_ip"); + PARSERROR; + } + } + } + break; + + case SCHEME_FILE: + SCAN_STRING(p,strbuf,len); + STRNDUP(global->scheme_file, strbuf,len); + break; + + case LINKDOWN_KLUGE: + ASSIGN_ON_OFF(global->lndown_kluge,p,C_ON,"bad qualifier in linkdown_kluge= option."); + break; + + case MAX_TTL: + SCAN_TIMESECS(global->max_ttl,p,"max_ttl option"); + break; + + case MIN_TTL: + SCAN_TIMESECS(global->min_ttl,p,"min_ttl option"); + break; + + case RUN_AS: + SCAN_STRING(p,strbuf,len); + STRNCP(global->run_as, strbuf,len, "run_as"); + break; + + case STRICT_SETUID: + ASSIGN_ON_OFF(global->strict_suid, p,C_ON,"bad qualifier in strict_setuid= option."); + break; + + case USE_NSS: + ASSIGN_ON_OFF(global->use_nss, p,C_ON,"bad qualifier in use_nss= option."); + break; + + case PARANOID: + ASSIGN_ON_OFF(global->paranoid, p,C_ON,"bad qualifier in paranoid= option."); + break; + + case IGNORE_CD: { + int ignore_cd; + ASSIGN_ON_OFF(ignore_cd, p,C_ON,"bad qualifier in ignore_cd= option."); + fprintf(stderr, "Warning: ignore_cd option in configuration file is obsolete and currently has no effect.\n"); + } + break; + + case STATUS_CTL: { + int cnst; + ASSIGN_CONST(cnst, p,cnst==C_ON || cnst==C_OFF ,"bad qualifier in status_pipe= option."); + if(!cmdline.stat_pipe) global->stat_pipe=(cnst==C_ON); + } + break; + + case DAEMON: { + int cnst; + ASSIGN_CONST(cnst, p,cnst==C_ON || cnst==C_OFF ,"bad qualifier in daemon= option."); + if(!cmdline.daemon) global->daemon=(cnst==C_ON); + } + break; + + case C_TCP_SERVER: { + int cnst; + ASSIGN_CONST(cnst, p,cnst==C_ON || cnst==C_OFF ,"bad qualifier in tcp_server= option."); + if(!cmdline.notcp) { + global->notcp=(cnst==C_OFF); +#ifdef NO_TCP_SERVER + if(!global->notcp) { + REPORT_ERROR("pdnsd was compiled without TCP server support. tcp_server=on is not allowed."); + PARSERROR; + } +#endif + } + } + break; + + case PID_FILE: + SCAN_STRING(p,strbuf,len); + if(!cmdline.pidfile) {STRNDUP(global->pidfile,strbuf,len);} + break; + + case C_VERBOSITY: { + int val; + SCAN_UNSIGNED_NUM(val,p,"verbosity option"); + if(!cmdline.verbosity) global->verbosity=val; + } + break; + + case C_QUERY_METHOD: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==TCP_ONLY || cnst==UDP_ONLY || cnst==TCP_UDP || cnst==UDP_TCP,"bad qualifier in query_method= option."); +#ifdef NO_TCP_QUERIES + if (cnst==TCP_ONLY) { + REPORT_ERROR("the tcp_only option is only available when pdnsd is compiled with TCP support."); + PARSERROR; + } + else +#endif +#ifdef NO_UDP_QUERIES + if (cnst==UDP_ONLY) { + REPORT_ERROR("the udp_only option is only available when pdnsd is compiled with UDP support."); + PARSERROR; + } + else +#endif +#if defined(NO_TCP_QUERIES) || defined(NO_UDP_QUERIES) + if (cnst==TCP_UDP) { + REPORT_ERROR("the tcp_udp option is only available when pdnsd is compiled with both TCP and UDP support."); + PARSERROR; + } + else if (cnst==UDP_TCP) { + REPORT_ERROR("the udp_tcp option is only available when pdnsd is compiled with both TCP and UDP support."); + PARSERROR; + } + else +#endif + if(!cmdline.query_method) global->query_method=cnst; + } + break; + + case RUN_IPV4: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF,"bad qualifier in run_ipv4= option."); +#ifndef ENABLE_IPV4 + if(cnst==C_ON) { + REPORT_ERROR("You can only set run_ipv4=on when pdnsd is compiled with IPv4 support."); + PARSERROR; + } +#endif +#ifndef ENABLE_IPV6 + if(cnst==C_OFF) { + REPORT_ERROR("You can only set run_ipv4=off when pdnsd is compiled with IPv6 support."); + PARSERROR; + } +#endif +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + if(!cmdlineipv) { + run_ipv4=(cnst==C_ON); cmdlineipv=-1; + } + else if(cmdlineipv<0 && run_ipv4!=(cnst==C_ON)) { + REPORT_ERROR(cmdlineipv==-1? + "IPv4/IPv6 conflict: you are trying to set run_ipv4 to a value that conflicts with a previous run_ipv4 setting.": + "You must set the run_ipv4 option before specifying IP addresses."); + PARSERROR; + } +#endif + } + break; + + case IPV4_6_PREFIX: + SCAN_STRING(p,strbuf,len); +#ifdef ENABLE_IPV6 + if(!cmdline.prefix) { + if(inet_pton(AF_INET6,strbuf,&global->ipv4_6_prefix)<=0) { + REPORT_ERROR("ipv4_6_prefix: argument not a valid IPv6 address."); + PARSERROR; + } + } +#else + fprintf(stderr,"pdnsd was compiled without IPv6 support. ipv4_6_prefix option in config file will be ignored.\n"); +#endif + break; + + case C_DEBUG: { + int cnst; + ASSIGN_CONST(cnst, p,cnst==C_ON || cnst==C_OFF ,"bad qualifier in debug= option."); + if(!cmdline.debug) { + global->debug=(cnst==C_ON); +#if !DEBUG + if(global->debug) + fprintf(stderr,"pdnsd was compiled without debugging support. debug=on has no effect.\n"); +#endif + } + } + break; + + case C_CTL_PERMS: + SCAN_UNSIGNED_NUM(global->ctl_perms, p,"ctl_perms option"); + break; + + case C_PROC_LIMIT: + SCAN_UNSIGNED_NUM(global->proc_limit, p,"proc_limit option"); + break; + + case C_PROCQ_LIMIT: + SCAN_UNSIGNED_NUM(global->procq_limit, p,"procq_limit option"); + break; + + case TCP_QTIMEOUT: + SCAN_TIMESECS(global->tcp_qtimeout, p,"tcp_qtimeout option"); + break; + + case TIMEOUT: + SCAN_TIMESECS(global->timeout, p,"global timeout option"); + break; + + case C_PAR_QUERIES: { + int val; + SCAN_UNSIGNED_NUM(val, p,"par_queries option"); + if(val<=0) { + REPORT_ERROR("bad value for par_queries."); + PARSERROR; + } else { + global->par_queries=val; + } + } + break; + + case C_RAND_RECS: + ASSIGN_ON_OFF(global->rnd_recs, p,C_ON,"bad qualifier in randomize_recs= option."); + break; + + case NEG_TTL: + SCAN_TIMESECS(global->neg_ttl, p,"neg_ttl option"); + break; + + case NEG_RRS_POL: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF || cnst==C_DEFAULT || cnst==C_AUTH, + "bad qualifier in neg_rrs_pol= option."); + global->neg_rrs_pol=cnst; + } + break; + + case NEG_DOMAIN_POL: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF || cnst==C_AUTH,"bad qualifier in neg_domain_pol= option."); + global->neg_domain_pol=cnst; + } + break; + + case QUERY_PORT_START: { + int val; + if(isalpha(*p)) { + int cnst; + SCAN_ALPHANUM(ps,p,len); + cnst=lookup_const(ps,len); + if(cnst==C_NONE) + val=-1; + else + goto bad_port_start_option; + } + else if(isdigit(*p)) { + val=strtol(p,&p,0); + if(val>65535) { + REPORT_ERROR("value for query_port_start out of range."); + PARSERROR; + } + else if(val<1024) + fprintf(stderr,"Warning: query_port_start=%i but source ports <1204 can only be used as root.\n", + val); + } + else { + bad_port_start_option: + REPORT_ERROR("bad qualifier in query_port_start= option."); + PARSERROR; + } + global->query_port_start=val; + } + break; + + case QUERY_PORT_END: { + int val; + SCAN_UNSIGNED_NUM(val,p,"query_port_end option"); + if(val>65535) { + REPORT_ERROR("value for query_port_end out of range."); + PARSERROR; + } + global->query_port_end=val; + } + break; + + case UDP_BUFSIZE: { + int val; + SCAN_UNSIGNED_NUM(val,p,"udpbufsize"); + if(val<512 || val>65535-(20+8)) { + REPORT_ERROR("value for udpbufsize out of range."); + PARSERROR; + } + global->udpbufsize=val; + } + break; + + case DELEGATION_ONLY: + SCAN_STRING_LIST(&global->deleg_only_zones,p,strbuf,len,zone_add) + break; + + default: /* we should never get here */ + goto internal_parse_error; + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') goto expected_semicolon; + ++p; + SKIP_BLANKS(p); + } + + if(*p!='}') goto expected_closing_brace; + if (global->query_port_end < global->query_port_start) { + REPORT_ERROR("query_port_end may not be smaller than query_port_start."); + PARSERROR; + } + break; + + case SERVER: { + servparm_t server; + + if(!servers) { + REPORT_ERROR(in?"server section not allowed in include file": + "server section not allowed in eval string"); + PARSERROR; + } + + server=serv_presets; +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER (free_servparm(&server)) + + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,server_options); + if(!option) { + REPORT_ERRORF("invalid option for server section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') CLEANUP_GOTO(expected_equals); + ++p; + SKIP_BLANKS(p); + + switch(option) { + case IP: + SCAN_STRING_LIST(&server.atup_a,p,strbuf,len,addr_add_); + break; + + case FILET: + SCAN_STRING(p,strbuf,len); + { + char *errmsg; + if (!read_resolv_conf(strbuf, &server.atup_a, &errmsg)) { + if(errmsg) {REPORT_ERROR(errmsg); free(errmsg);} + else *errstr=NULL; + PARSERROR; + } + } + break; + + case PORT: + SCAN_UNSIGNED_NUM(server.port,p,"port option"); + break; + + case SCHEME: + SCAN_STRING(p,strbuf,len); + STRNCP(server.scheme, strbuf,len, "scheme"); + break; + + case UPTEST: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_PING || cnst==C_NONE || cnst==C_IF || cnst==C_EXEC || cnst==C_DEV || cnst==C_DIALD || cnst==C_QUERY,"bad qualifier in uptest= option."); + server.uptest=cnst; + } + break; + + case TIMEOUT: + SCAN_TIMESECS(server.timeout,p,"timeout option"); + break; + + case PING_TIMEOUT: + SCAN_UNSIGNED_NUM(server.ping_timeout,p,"ping_timeout option"); + break; + + case PING_IP: + SCAN_STRING(p,strbuf,len); + { + const char *err; + if ((err=parse_ip(strbuf,&server.ping_a))) { + REPORT_ERRORF("%s for the ping_ip= option.",err); + PARSERROR; + } + } + break; + + case UPTEST_CMD: + SCAN_STRING(p,strbuf,len); + STRNDUP(server.uptest_cmd, strbuf,len); + SKIP_BLANKS(p); + if(*p==',') { + ++p; + SKIP_BLANKS(p); + SCAN_STRING(p,strbuf,len); + STRNCP(server.uptest_usr, strbuf,len, "second argument of uptest_cmd"); + } + break; + + case QUERY_TEST_NAME: + if(isalpha(*p)) { + int cnst; + SCAN_ALPHANUM(ps,p,len); + if(*p!='.' && *p!='-') { + cnst=lookup_const(ps,len); + if(cnst==C_NONE) { + if(server.query_test_name) + free(server.query_test_name); + server.query_test_name=NULL; + break; + } + } + p=ps; /* reset current char pointer and try again. */ + } + { + unsigned char tname[DNSNAMEBUFSIZE], *copy; + unsigned sz; + + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,tname); + sz=rhnlen(tname); + copy= malloc(sz); + if(!copy) { + OUTOFMEMERROR; + } + memcpy(copy,tname,sz); + if(server.query_test_name) + free(server.query_test_name); + server.query_test_name=copy; + } + break; + + case INTERVAL: + if(isalpha(*p)) { + int cnst; + SCAN_ALPHANUM(ps,p,len); + cnst=lookup_const(ps,len); + if(cnst==C_ONQUERY) { + server.interval=-1; + } + else if(cnst==C_ONTIMEOUT) { + server.interval=-2; + } + else { + goto bad_interval_option; + } + } + else if(isdigit(*p)) { + char *err; + server.interval=strtotime(p,&p,&err); + if(err) { + REPORT_ERRORF("bad time specification in interval= option: %s",err); + PARSERROR; + } + } + else { + bad_interval_option: + REPORT_ERROR("bad qualifier in interval= option."); + PARSERROR; + } + break; + + case INTERFACE: + SCAN_STRING(p,strbuf,len); + STRNCP(server.interface, strbuf,len, "interface"); + break; + + case DEVICE: + SCAN_STRING(p,strbuf,len); + STRNCP(server.device, strbuf,len, "device"); + break; + + case PURGE_CACHE: + ASSIGN_ON_OFF(server.purge_cache,p,C_ON,"bad qualifier in purge_cache= option."); + break; + + case CACHING: + ASSIGN_ON_OFF(server.nocache,p,C_OFF,"bad qualifier in caching= option."); + break; + + case LEAN_QUERY: + ASSIGN_ON_OFF(server.lean_query,p,C_ON,"bad qualifier in lean_query= option."); + break; + + case EDNS_QUERY: + ASSIGN_ON_OFF(server.edns_query,p,C_ON,"bad qualifier in edns_query= option."); + break; + + case PRESET: + ASSIGN_ON_OFF(server.preset,p,C_ON,"bad qualifier in preset= option."); + break; + + case PROXY_ONLY: + ASSIGN_ON_OFF(server.is_proxy,p,C_ON,"bad qualifier in proxy_only= option."); + break; + + case ROOT_SERVER: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF || cnst==C_DISCOVER,"bad qualifier in root_server= option."); + server.rootserver= (cnst==C_DISCOVER? 2: cnst==C_ON); + } + break; + + case RANDOMIZE_SERVERS: + ASSIGN_ON_OFF(server.rand_servers,p,C_ON,"bad qualifier in randomize_servers= option."); + break; + + case POLICY: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_INCLUDED || cnst==C_EXCLUDED || cnst==C_SIMPLE_ONLY || cnst==C_FQDN_ONLY,"bad qualifier in policy= option."); + server.policy=cnst; + } + break; + + case INCLUDE: + SCAN_STRING_LIST(&server.alist,p,strbuf,len,include_list_add) + break; + + case EXCLUDE: + SCAN_STRING_LIST(&server.alist,p,strbuf,len,exclude_list_add) + break; + + case REJECTLIST: + SCAN_STRING_LIST(&server,p,strbuf,len,reject_add_); + break; + + case REJECTPOLICY: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_FAIL || cnst==C_NEGATE,"bad qualifier in reject_policy= option."); + server.rejectpolicy=cnst; + } + break; + + case REJECTRECURSIVELY: + ASSIGN_ON_OFF(server.rejectrecursively,p,C_ON,"bad qualifier in reject_recursively= option."); + break; + + case LABEL: + SCAN_STRING(p,strbuf,len); + STRNDUP(server.label,strbuf,len); + break; + + default: /* we should never get here */ + CLEANUP_GOTO(internal_parse_error); + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') CLEANUP_GOTO(expected_semicolon); + ++p; + SKIP_BLANKS(p); + } + + if(*p!='}') CLEANUP_GOTO(expected_closing_brace); + if (server.uptest==C_EXEC) { + if (!server.uptest_cmd) { + REPORT_ERROR("you must specify uptest_cmd if you specify uptest=exec!"); + PARSERROR; + } + } + if (server.is_proxy && server.rootserver) { + REPORT_ERROR("A server may not be specified as both a proxy and a root-server."); + PARSERROR; + } + if(server.rootserver && (server.policy==C_SIMPLE_ONLY || server.policy==C_FQDN_ONLY)) + fprintf(stderr,"Warning: using policy=%s with a root-server usually makes no sense.", + const_name(server.policy)); + if (DA_NEL(server.atup_a)) { + check_localaddrs(&server); + if(!DA_NEL(server.atup_a)) { + REPORT_ERROR("Server section contains only local IP addresses.\n" + "Bind pdnsd to a different local IP address or specify different port numbers" + " in global section and server section if you want pdnsd to query servers on" + " the same machine."); + PARSERROR; + } + } + { + int j,n=DA_NEL(server.atup_a); + for(j=0;jis_up=server.preset; + /* A negative test interval means don't test at startup or reconfig. */ + if(server.interval<0) at->i_ts=time(NULL); + } + } + if(server.interval==-1) global->onquery=1; + + if (!(*servers=DA_GROW1_F(*servers,(void(*)(void*))free_servparm))) { + OUTOFMEMERROR; + } + DA_LAST(*servers)= server; +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER + } + break; + + case RR: { + /* Initialize c_cent to all zeros. + Then it should be safe to call free_cent() on it, even before calling init_cent(). */ + dns_cent_t c_cent={0}; + time_t c_ttl=86400; + unsigned c_flags=DF_LOCAL; + unsigned char reverse=0; + +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER (free_cent(&c_cent DBG0)) + + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,rr_options); + if(!option) { + REPORT_ERRORF("invalid option for rr section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') CLEANUP_GOTO(expected_equals); + ++p; + SKIP_BLANKS(p); + + switch(option) { + int tp; const char *tpname; + case NAME: { + unsigned char c_name[DNSNAMEBUFSIZE]; + if (c_cent.qname) { + REPORT_ERROR("You may specify only one name in a rr section."); + PARSERROR; + } + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,c_name); + if (!init_cent(&c_cent, c_name, 0, 0, c_flags DBG0)) + goto out_of_memory; + } + break; + + case TTL: + SCAN_TIMESECS(c_ttl,p, "ttl option"); + break; + + case AUTHREC: { + int cnst; + if (c_cent.qname) { + REPORT_ERROR("The authrec= option has no effect unless it precedes name= in a rr section."); + PARSERROR; + } + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF,"Bad qualifier in authrec= option."); + c_flags=(cnst==C_ON)?DF_LOCAL:0; + } + break; + + case REVERSE: + ASSIGN_ON_OFF(reverse,p,C_ON,"bad qualifier in reverse= option."); + break; + + case A: { + unsigned int sz; + pdnsd_ca c_a; + + if (!c_cent.qname) + goto no_name_spec; + SCAN_STRING(p,strbuf,len); + if (inet_aton(strbuf,&c_a.ipv4)) { + tp=T_A; + sz=sizeof(struct in_addr); + } + else +#if ALLOW_LOCAL_AAAA + if (inet_pton(AF_INET6,strbuf,&c_a.ipv6)>0) { + tp=T_AAAA; + sz=sizeof(struct in6_addr); + } + else +#endif + { + REPORT_ERROR("bad IP address in a= option."); + PARSERROR; + } + + if(!add_cent_rr(&c_cent,tp,c_ttl,0,CF_LOCAL,sz,&c_a DBG0)) + goto add_rr_failed; + } + break; + + case OWNER: + tp=T_NS; + goto scan_name; + case CNAME: + tp=T_CNAME; + goto scan_name; + case PTR: + tp=T_PTR; + scan_name: + { + unsigned char c_name[DNSNAMEBUFSIZE]; + + if (!c_cent.qname) + goto no_name_spec; + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,c_name); + if(!add_cent_rr(&c_cent,tp,c_ttl,0,CF_LOCAL,rhnlen(c_name),c_name DBG0)) + goto add_rr_failed; + } + break; + + case MX: { + unsigned char *cp; + unsigned pref; + unsigned char c_mx[2+DNSNAMEBUFSIZE]; + + if (!c_cent.qname) + goto no_name_spec; + cp=c_mx+2; + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,cp); + SKIP_COMMA(p,"missing second argument (preference level) of mx= option"); + SCAN_UNSIGNED_NUM(pref,p,"second argument of mx= option"); + cp=c_mx; + PUTINT16(pref,cp); + if(!add_cent_rr(&c_cent,T_MX,c_ttl,0,CF_LOCAL,2+rhnlen(cp),c_mx DBG0)) + goto add_rr_failed; + } + break; + + case SOA: { + unsigned int blen,rlen; + unsigned char *bp; + uint32_t val; + unsigned char buf[2*DNSNAMEBUFSIZE+20]; + + if (!c_cent.qname) + goto no_name_spec; + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,buf); + rlen=rhnlen(buf); + blen=rlen; + bp=buf+rlen; + SKIP_COMMA(p,"missing 2nd argument of soa= option"); + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,bp); + rlen=rhnlen(bp); + blen += rlen; + bp += rlen; + SKIP_COMMA(p,"missing 3rd argument of soa= option"); + SCAN_UNSIGNED_NUM(val,p,"3rd argument of soa= option"); + PUTINT32(val,bp); + SKIP_COMMA(p,"missing 4th argument of soa= option"); + SCAN_TIMESECS(val,p,"4th argument of soa= option"); + PUTINT32(val,bp); + SKIP_COMMA(p,"missing 5th argument of soa= option"); + SCAN_TIMESECS(val,p,"5th argument of soa= option"); + PUTINT32(val,bp); + SKIP_COMMA(p,"missing 6th argument of soa= option"); + SCAN_TIMESECS(val,p,"6th argument of soa= option"); + PUTINT32(val,bp); + SKIP_COMMA(p,"missing 7th argument of soa= option"); + SCAN_TIMESECS(val,p,"7th argument of soa= option"); + PUTINT32(val,bp); + blen += 20; + if(!add_cent_rr(&c_cent,T_SOA,c_ttl,0,CF_LOCAL,blen,buf DBG0)) + goto add_rr_failed; + } + break; + case SPF: +#if IS_CACHED_SPF + tp=T_SPF; tpname="spf"; + goto define_txt_rr; +#else + REPORT_ERROR("Missing support for caching SPF records in rr section"); + PARSERROR; +#endif + case TXT: +#if IS_CACHED_TXT + tp=T_TXT; tpname="txt"; +#else + REPORT_ERROR("Missing support for caching TXT records in rr section"); + PARSERROR; +#endif +#if IS_CACHED_TXT || IS_CACHED_SPF +#if IS_CACHED_SPF + define_txt_rr: +#endif + { + unsigned char *rbuf; + unsigned sz,allocsz; + int rv; + + if (!c_cent.qname) + goto no_name_spec; + rbuf=NULL; + sz=allocsz=0; +# undef CLEANUP_HANDLER2 +# define CLEANUP_HANDLER2 (free(rbuf)) + + for(;;) { + unsigned char *newbuf,*cp; + unsigned newsz=sz+256; + int n; + if(newsz>allocsz) { + allocsz += 512; + newbuf=realloc(rbuf,allocsz); + if(!newbuf) { + OUTOFMEMERROR; + } + rbuf=newbuf; + } + cp = rbuf+sz; + n=scan_string(&p, charp (cp+1), 255, &scanstrerr); + if(n==-1) { + REPORT_ERRORF("%s in %s= option", scanstrerr, tpname); + PARSERROR; + } + if(n>255) { + REPORT_ERRORF("string longer than 255 bytes in %s= option", tpname); + PARSERROR; + } + *cp=n; + sz += n+1; + if(sz>0xffff) { + REPORT_ERRORF("data exceeds maximum size (65535 bytes) in %s= option", tpname); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!=',') break; + ++p; + SKIP_BLANKS(p); + } + rv=add_cent_rr(&c_cent,tp,c_ttl,0,CF_LOCAL,sz,rbuf DBG0); + CLEANUP_HANDLER2; +# undef CLEANUP_HANDLER2 +# define CLEANUP_HANDLER2 + if(!rv) + goto add_rr_failed; + } + break; +#endif + default: /* we should never get here */ + CLEANUP_GOTO(internal_parse_error); + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') CLEANUP_GOTO(expected_semicolon); + ++p; + SKIP_BLANKS(p); + } + + if(*p!='}') CLEANUP_GOTO(expected_closing_brace); + if (!c_cent.qname) + goto no_name_spec; + if(c_cent.qname[0]==1 && c_cent.qname[1]=='*') { + /* Wild card record. Set the DF_WILD flag for the name with '*.' removed. */ + if(!set_cent_flags(&c_cent.qname[2],DF_WILD)) { + unsigned char buf[DNSNAMEBUFSIZE]; + rhn2str(c_cent.qname,buf,sizeof(buf)); + REPORT_ERRORF("You must define some records for '%s'" + " before you can define records for the wildcard name '%s'", + &buf[2],buf); + PARSERROR; + } + } + + add_cache(&c_cent); + if(reverse) { + if(!add_reverse_cache(&c_cent)) { + REPORT_ERROR("Can't convert IP address in a= option" + " into form suitable for reverse resolving."); + PARSERROR; + } + } + CLEANUP_HANDLER; + break; + + add_rr_failed: + OUTOFMEMERROR; +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER + } + + case SOURCE: { + unsigned char c_owner[DNSNAMEBUFSIZE]; + time_t c_ttl; + unsigned c_flags; + unsigned char c_aliases; + + c_owner[0]='\0'; + c_ttl=86400; + c_flags=DF_LOCAL; + c_aliases=0; + + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,source_options); + if(!option) { + REPORT_ERRORF("invalid option for source section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') goto expected_equals; + ++p; + SKIP_BLANKS(p); + + switch(option) { + case OWNER: + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,c_owner); + break; + + case TTL: + SCAN_TIMESECS(c_ttl,p,"ttl option"); + break; + + case FILET: + if (!c_owner[0]) { + REPORT_ERROR("you must specify owner before file= in source records."); + PARSERROR; + } + SCAN_STRING(p,strbuf,len); + { + char *errmsg; + if (!read_hosts(strbuf, c_owner, c_ttl, c_flags, c_aliases, &errmsg)) { + if(errmsg) { REPORT_ERROR(errmsg); free(errmsg); } + else *errstr=NULL; + PARSERROR; + } + } + break; + + case SERVE_ALIASES: + ASSIGN_ON_OFF(c_aliases,p,C_ON,"Bad qualifier in serve_aliases= option."); + break; + + case AUTHREC: { + int cnst; + ASSIGN_CONST(cnst,p,cnst==C_ON || cnst==C_OFF,"Bad qualifier in authrec= option."); + c_flags=(cnst==C_ON)?DF_LOCAL:0; + } + break; + + default: /* we should never get here */ + goto internal_parse_error; + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') goto expected_semicolon; + ++p; + SKIP_BLANKS(p); + } + } + break; + + case INCLUDE_F: { + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,include_options); + if(!option) { + REPORT_ERRORF("invalid option for include section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') goto expected_equals; + ++p; + SKIP_BLANKS(p); + + switch(option) { + case FILET: + if(includedepth>=MAXINCLUDEDEPTH) { + REPORT_ERRORF("maximum include depth (%d) exceeded.",MAXINCLUDEDEPTH); + PARSERROR; + } + SCAN_STRING(p,strbuf,len); + { + char *errmsg; + if (!read_config_file(strbuf, NULL, NULL, includedepth+1, &errmsg)) { + if(errmsg) { + if(linenr) { + if(asprintf(errstr, "In file %s included at line %u:\n%s",strbuf,linenr,errmsg)<0) + *errstr=NULL; + } + else { + if(asprintf(errstr, "In file %s:\n%s",strbuf,errmsg)<0) + *errstr=NULL; + } + free(errmsg); + } + else + *errstr=NULL; + PARSERROR; + } + } + break; + + default: /* we should never get here */ + goto internal_parse_error; + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') goto expected_semicolon; + ++p; + SKIP_BLANKS(p); + } + } + break; + + case NEG: { + unsigned char c_name[DNSNAMEBUFSIZE]; + time_t c_ttl; + unsigned char htp,hdtp; + + htp=0; + hdtp=0; + c_name[0]='\0'; + c_ttl=86400; + + while(isalpha(*p)) { + SCAN_ALPHANUM(ps,p,len); + option=lookup_keyword(ps,len,neg_options); + if(!option) { + REPORT_ERRORF("invalid option for neg section: %.*s",(int)len,ps); + PARSERROR; + } + SKIP_BLANKS(p); + if(*p!='=') goto expected_equals; + ++p; + SKIP_BLANKS(p); + + switch(option) { + case NAME: + SCAN_STRING(p,strbuf,len); + PARSESTR2RHN(ucharp strbuf,len,c_name); + break; + + case TTL: + SCAN_TIMESECS(c_ttl,p, "ttl option"); + break; + + case TYPES: + if (!c_name[0]) { + REPORT_ERROR("you must specify a name before the types= option."); + PARSERROR; + } + if (isalpha(*p)) { + int cnst; + dns_cent_t c_cent /* ={0} */; + SCAN_ALPHANUM(ps,p,len); + cnst=lookup_const(ps,len); + if(cnst==C_DOMAIN) { + if (htp) { + REPORT_ERROR("You may not specify types=domain together with other types!"); + PARSERROR; + } + hdtp=1; + if (!init_cent(&c_cent, c_name, c_ttl, 0, DF_LOCAL|DF_NEGATIVE DBG0)) + goto out_of_memory; + } + else if(cnst==0) { + if (hdtp) { + REPORT_ERROR("You may not specify types=domain together with other types!"); + PARSERROR; + } + htp=1; + if (!init_cent(&c_cent, c_name, 0, 0, 0 DBG0)) + goto out_of_memory; +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER (free_cent(&c_cent DBG0)) + for(;;) { + { + TEMPSTRNCPY(buf,ps,len); + cnst=rr_tp_byname(buf); + } + if(cnst==-1) { + REPORT_ERRORF("unrecognized rr type '%.*s' used as argument for types= option.",(int)len,ps); + PARSERROR; + } + if(PDNSD_NOT_CACHED_TYPE(cnst)) { + REPORT_ERRORF("illegal rr type '%.*s' used as argument for types= option.",(int)len,ps); + PARSERROR; + } + if (!getrrset_eff(&c_cent,cnst) && !add_cent_rrset_by_type(&c_cent,cnst,c_ttl,0,CF_LOCAL|CF_NEGATIVE DBG0)) { + OUTOFMEMERROR; + } + SKIP_BLANKS(p); + if(*p!=',') break; + ++p; + SKIP_BLANKS(p); + if (!isalpha(*p)) + {CLEANUP_GOTO(bad_types_option);} + SCAN_ALPHANUM(ps,p,len); + } + } + else + goto bad_types_option; + + add_cache(&c_cent); + CLEANUP_HANDLER; +# undef CLEANUP_HANDLER +# define CLEANUP_HANDLER + } + else { + bad_types_option: + REPORT_ERROR("Bad argument for types= option."); + PARSERROR; + } + break; + + default: /* we should never get here */ + goto internal_parse_error; + } /* end of switch(option) */ + + SKIP_BLANKS(p); + if(*p!=';') goto expected_semicolon; + ++p; + SKIP_BLANKS(p); + } + } + break; + + default: /* we should never get here */ + goto internal_parse_error; + } /* end of switch(sechdr) */ + + if(*p!='}') goto expected_closing_brace; + ++p; + } + else { + REPORT_ERROR("expected section header"); + PARSERROR; + } + } + + if(!in || feof(in)) { + if(getnextperr) { + REPORT_ERROR(getnextperr); + PARSERROR; + } + retval=1; /* success */ + } + else + goto input_error; + + goto free_linebuf_return; + + expected_bropen: + REPORT_ERROR("expected opening brace after section name"); + PARSERROR; + + expected_closing_brace: + REPORT_ERROR("expected beginning of new option or closing brace"); + PARSERROR; + + expected_equals: + REPORT_ERROR("expected equals sign after option name"); + PARSERROR; + + expected_semicolon: + REPORT_ERROR("too many arguments to option or missing semicolon"); + PARSERROR; + + string_err: + REPORT_ERROR(scanstrerr); + PARSERROR; + + string_too_long: + REPORT_ERROR("string length exceeds buffer size"); + PARSERROR; + + no_name_spec: + REPORT_ERROR("you must specify a name before a,ptr,cname,mx,ns(owner) and soa records."); + PARSERROR; + + internal_parse_error: + if(asprintf(errstr,"Internal inconsistency detected while parsing line %u of %s.\n" + "Please consider reporting this error to one of the maintainers.\n",linenr,conftype)<0) + *errstr=NULL; + PARSERROR; + + out_of_memory: + /* If malloc() just failed, allocating space for an error message is unlikely to succeed. */ + *errstr=NULL; + PARSERROR; + + unexpected_eof: + if(!in || feof(in)) { + REPORT_ERROR(getnextperr?getnextperr:in?"unexpected end of file":"unexpected end of input string"); + } + else + input_error: { + if(asprintf(errstr,"Error while reading config file: %s",strerror(errno))<0) + *errstr=NULL; + } + + free_linebuf_return: + free(linebuf); + return retval; + +#undef SKIP_BLANKS +#undef SCAN_STRING +#undef REPORT_ERROR +#undef REPORT_ERRORF +#undef PARSERROR +#undef OUTOFMEMERROR +#undef CLEANUP_GOTO +} + + +/* Convert a string representation of an IP address into a binary format. */ +static const char* parse_ip(const char *ipstr, pdnsd_a *a) +{ +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + if(!cmdlineipv) cmdlineipv=-2; +#endif + { + if(!strcmp(ipstr,"any")) { +#ifdef ENABLE_IPV4 + if (run_ipv4) + a->ipv4.s_addr=INADDR_ANY; +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 + a->ipv6=in6addr_any; +#endif + } + else if(!str2pdnsd_a(ipstr,a)) { +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + if(run_ipv4 && inet_pton(AF_INET6,ipstr,&a->ipv6)>0) { + return "You should set run_ipv4=off or use the command-line option -6" + " before specifying an IPv6 address"; + } +#endif + return "bad IP address"; + } + } + return NULL; +} + +/* Add an IP address to the list of name servers. */ +static const char *addr_add(atup_array *ata, const char *ipstr) +{ + atup_t *at; + pdnsd_a addr; + +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + if(!cmdlineipv) cmdlineipv=-2; +#endif + { + if(!str2pdnsd_a(ipstr,&addr)) { +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + if(run_ipv4 && inet_pton(AF_INET6,ipstr,&addr.ipv6)>0) { + fprintf(stderr,"IPv6 address \"%s\" in config file ignored while running in IPv4 mode.\n",ipstr); + return NULL; + } +#endif + return "bad IP address"; + } + } + + if (!(*ata=DA_GROW1(*ata))) { + return "out of memory!"; + } + at=&DA_LAST(*ata); + SET_PDNSD_A2(&at->a, &addr); + at->is_up=0; + at->i_ts=0; + return NULL; +} + + +/* Helper functions for making netmasks */ +inline static uint32_t mk_netmask4(int len) +{ + uint32_t m; + + if(len<=0) + return 0; + + m= ~(uint32_t)0; + return (len<32)? htonl(m<<(32-len)): m; +} + +#if ALLOW_LOCAL_AAAA +inline static void mk_netmask6(struct in6_addr *m, int len) +{ + uint32_t *ma = (uint32_t *)m; + ma[0] = mk_netmask4(len); + ma[1] = mk_netmask4(len -= 32); + ma[2] = mk_netmask4(len -= 32); + ma[3] = mk_netmask4(len -= 32); +} +#endif + +/* Add an IP address/mask to the reject lists. */ +static const char *reject_add(servparm_t *serv, const char *ipstr) +{ + char *slash=strchr(ipstr,'/'); int mlen=0; + + if(slash) { + *slash++=0; + + if(*slash && isdigit(*slash)) { + char *endptr; + int l = strtol(slash,&endptr,10); + if(!*endptr) { + mlen=l; + slash=NULL; + } + } + } + else + mlen=128; /* Works for both IPv4 and IPv6 */ + + { + addr4maskpair_t am; + + am.mask.s_addr = mk_netmask4(mlen); + if(inet_aton(ipstr,&am.a) && (!slash || inet_aton(slash,&am.mask))) { + if(!(serv->reject_a4=DA_GROW1(serv->reject_a4))) + return "out of memory!"; + + DA_LAST(serv->reject_a4) = am; + return NULL; + } + } +#if ALLOW_LOCAL_AAAA + { + addr6maskpair_t am; + + mk_netmask6(&am.mask,mlen); + if(inet_pton(AF_INET6,ipstr,&am.a)>0 && (!slash || inet_pton(AF_INET6,slash,&am.mask)>0)) { + if(!(serv->reject_a6=DA_GROW1(serv->reject_a6))) + return "out of memory!"; + + DA_LAST(serv->reject_a6) = am; + return NULL; + } + } +#endif + + return "bad IP address"; +} + +/* Try to avoid the possibility that pdnsd will query itself. */ +static void check_localaddrs(servparm_t *serv) +{ + if(serv->port == global.port) { + atup_array ata=serv->atup_a; + int i,j=0,n=DA_NEL(ata); + for(i=0;ia))) { + char buf[ADDRSTR_MAXLEN]; + fprintf(stderr,"Local name-server address \"%s\" ignored in config file.\n", + pdnsd_a2str(PDNSD_A2_TO_A(&at->a),buf,ADDRSTR_MAXLEN)); + continue; + } + } + else { + if(equiv_inaddr2(&global.a,&at->a)) { + char buf[ADDRSTR_MAXLEN]; + fprintf(stderr,"Ignoring name-server address \"%s\" in config file (identical to server_ip address).\n", + pdnsd_a2str(PDNSD_A2_TO_A(&at->a),buf,ADDRSTR_MAXLEN)); + continue; + } + } + if(jatup_a=DA_RESIZE(ata,j); + } +} + +/* Read the name server addresses from a resolv.conf-style file. */ +static int read_resolv_conf(const char *fn, atup_array *ata, char **errstr) +{ + int rv=0; + FILE *f; + char *buf; + size_t buflen=256; + unsigned linenr=0; + + if (!(f=fopen(fn,"r"))) { + if(asprintf(errstr, "Failed to open %s: %s", fn, strerror(errno))<0) + *errstr=NULL; + return 0; + } + buf=malloc(buflen); + if(!buf) { + *errstr=NULL; + goto fclose_return; + } + while(getline(&buf,&buflen,f)>=0) { + size_t len; + char *p,*ps; + ++linenr; + p=buf; + for(;; ++p) { + if(!*p) goto nextline; + if(!isspace(*p)) break; + } + ps=p; + do { + if(!*++p) goto nextline; + } while(!isspace(*p)); + len=p-ps; + if(len==strlitlen("nameserver") && !strncmp(ps,"nameserver",len)) { + const char *errmsg; + do { + if(!*++p) goto nextline; + } while (isspace(*p)); + ps=p; + do { + ++p; + } while(*p && !isspace(*p)); + len=p-ps; + { + TEMPSTRNCPY(ipstr,ps,len); + errmsg=addr_add(ata, ipstr); + } + if(errmsg) { + if(asprintf(errstr, "%s in line %u of file %s", errmsg,linenr,fn)<0) + *errstr=NULL; + goto cleanup_return; + } + } + nextline:; + } + if (feof(f)) + rv=1; + else if(asprintf(errstr, "Failed to read %s: %s", fn, strerror(errno))<0) + *errstr=NULL; + cleanup_return: + free(buf); + fclose_return: + fclose(f); + return rv; +} + +static const char *slist_add(slist_array *sla, const char *nm, unsigned int len, int tp) +{ + slist_t *sl; + int exact=1; + const char *err; + size_t sz; + unsigned char rhn[DNSNAMEBUFSIZE]; + + if (len>1 && *nm=='.') { + exact=0; + ++nm; + --len; + } + if((err=parsestr2rhn(ucharp nm,len,rhn))) + return err; + sz=rhnlen(rhn); + if (!(*sla=DA_GROW1_F(*sla,free_slist_domain))) { + return "out of memory!"; + } + sl=&DA_LAST(*sla); + + sl->exact=exact; + sl->rule=tp; + if (!(sl->domain=malloc(sz))) + return "out of memory!"; + memcpy(sl->domain,rhn,sz); + return NULL; +} + +static const char *zone_add(zone_array *za, const char *zone, unsigned int len) +{ + zone_t z; + const char *err; + size_t sz; + unsigned char rhn[DNSNAMEBUFSIZE]; + + if((err=parsestr2rhn(ucharp zone,len,rhn))) + return err; + sz=rhnlen(rhn); + if(!(*za=DA_GROW1_F(*za,free_zone)) || !(DA_LAST(*za)=z=malloc(sz))) + return "out of memory!"; + memcpy(z,rhn,sz); + return NULL; +} + diff --git a/jni/pdnsd/src/conf-parser.h b/jni/pdnsd/src/conf-parser.h new file mode 100644 index 00000000..d3a3e99d --- /dev/null +++ b/jni/pdnsd/src/conf-parser.h @@ -0,0 +1,29 @@ +/* conf-parser.h - definitions for parser of pdnsd config files. + The parser was rewritten in C from scratch and doesn't require (f)lex + or yacc/bison. + + Copyright (C) 2004,2008 Paul A. Rombouts. + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#ifndef CONF_PARSER_H +#define CONF_PARSER_H + +int confparse(FILE* in, char *prestr, globparm_t *global, servparm_array *servers, int includedepth, char **errstr); + +#endif /* CONF_PARSER_H */ diff --git a/jni/pdnsd/src/conff.c b/jni/pdnsd/src/conff.c new file mode 100644 index 00000000..db6c5d19 --- /dev/null +++ b/jni/pdnsd/src/conff.c @@ -0,0 +1,544 @@ +/* conff.c - Maintain configuration information + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipvers.h" +#include "conff.h" +#include "consts.h" +#include "helpers.h" +#include "conf-parser.h" +#include "servers.h" +#include "icmp.h" + + +globparm_t global={ + perm_cache: 2048, + cache_dir: NULL, + pidfile: NULL, + port: 53, + a: PDNSD_A_INITIALIZER, + out_a: PDNSD_A_INITIALIZER, +#ifdef ENABLE_IPV6 + ipv4_6_prefix: IN6ADDR_ANY_INIT, +#endif + max_ttl: 604800, + min_ttl: 120, + neg_ttl: 900, + neg_rrs_pol: C_DEFAULT, + neg_domain_pol: C_AUTH, + verbosity: VERBOSITY, + run_as: "", + daemon: 0, + debug: 0, + stat_pipe: 0, + notcp: 0, + strict_suid: 1, + use_nss: 1, + paranoid: 0, + lndown_kluge: 0, + onquery: 0, + rnd_recs: 1, + ctl_perms: 0600, + scheme_file: NULL, + proc_limit: 40, + procq_limit: 60, + tcp_qtimeout: TCP_TIMEOUT, + timeout: 0, + par_queries: PAR_QUERIES, + query_method: M_PRESET, + query_port_start: 1024, + query_port_end: 65535, + udpbufsize: 1024, + deleg_only_zones: NULL +}; + +servparm_t serv_presets={ + port: 53, + uptest: C_NONE, + timeout: 120, + interval: 900, + ping_timeout: 600, + scheme: "", + uptest_cmd: NULL, + uptest_usr: "", + interface: "", + device: "", + query_test_name: NULL, + label: NULL, + purge_cache: 0, + nocache: 0, + lean_query: 1, + edns_query: 0, + is_proxy: 0, + rootserver: 0, + rand_servers: 0, + preset: 1, + rejectrecursively: 0, + rejectpolicy: C_FAIL, + policy: C_INCLUDED, + alist: NULL, + atup_a: NULL, + reject_a4: NULL, +#if ALLOW_LOCAL_AAAA + reject_a6: NULL, +#endif + ping_a: PDNSD_A_INITIALIZER +}; + +servparm_array servers=NULL; + +static void free_zones(zone_array za); +static void free_server_data(servparm_array sa); +static int report_server_stat(int f,int i); + + +/* + * Read a configuration file, saving the results in a (separate) global section and servers array, + * and the cache. + * + * char *nm should contain the name of the file to read. If it is NULL, the name of the config file + * read during startup is used. + * + * globparm_t *global should point to a struct which will be used to store the data of the + * global section(s). If it is NULL, no global sections are allowed in the + * file. + * + * servparm_array *servers should point to a dynamic array which will be grown to store the data + * of the server sections. If it is NULL, no server sections are allowed + * in the file. + * + * char **errstr is used to return a possible error message. + * In case of failure, *errstr will refer to a newly allocated string. + * + * read_config_file returns 1 on success, 0 on failure. + */ +int read_config_file(const char *nm, globparm_t *global, servparm_array *servers, int includedepth, char **errstr) +{ + int retval=0; + const char *conftype= (global?"config":"include"); + FILE *in; + + if (nm==NULL) + nm=conf_file; + + if (!(in=fopen(nm,"r"))) { + if(asprintf(errstr,"Error: Could not open %s file %s: %s",conftype,nm,strerror(errno))<0) + *errstr=NULL; + return 0; + } + + retval=confparse(in,NULL,global,servers,includedepth,errstr); +close_file: + if(fclose(in) && retval) { + if(asprintf(errstr,"Error: Could not close %s file %s: %s", + conftype,nm,strerror(errno))<0) + *errstr=NULL; + return 0; + } + if(retval && servers && !DA_NEL(*servers)) { + if(asprintf(errstr,"Error: no server sections defined in config file %s",nm)<0) + *errstr=NULL; + return 0; + } + return retval; +} + +/* + * Re-Read the configuration file. + * Return 1 on success, 0 on failure. + * In case of failure, the old configuration will be unchanged (although the cache may not) and + * **errstr will refer to a newly allocated string containing an error message. + */ +int reload_config_file(const char *nm, char **errstr) +{ + globparm_t global_new; + servparm_array servers_new; + + global_new=global; + global_new.cache_dir=NULL; + global_new.pidfile=NULL; + global_new.scheme_file=NULL; + global_new.deleg_only_zones=NULL; + global_new.onquery=0; + servers_new=NULL; + if(read_config_file(nm,&global_new,&servers_new,0,errstr)) { + if(global_new.cache_dir && strcmp(global_new.cache_dir,global.cache_dir)) { + *errstr=strdup("Cannot reload config file: the specified cache_dir directory has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.pidfile && (!global.pidfile || strcmp(global_new.pidfile,global.pidfile))) { + *errstr=strdup("Cannot reload config file: the specified pid_file has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.scheme_file && strcmp(global_new.scheme_file,global.scheme_file)) { + *errstr=strdup("Cannot reload config file: the specified scheme_file has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.port!=global.port) { + *errstr=strdup("Cannot reload config file: the specified server_port has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(!ADDR_EQUIV(&global_new.a,&global.a)) { + *errstr=strdup("Cannot reload config file: the specified interface address (server_ip) has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } +#ifdef ENABLE_IPV6 + if(!IN6_ARE_ADDR_EQUAL(&global_new.ipv4_6_prefix,&global.ipv4_6_prefix)) { + *errstr=strdup("Cannot reload config file: the specified ipv4_6_prefix has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } +#endif + if(strcmp(global_new.run_as,global.run_as)) { + *errstr=strdup("Cannot reload config file: the specified run_as id has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.daemon!=global.daemon) { + *errstr=strdup("Cannot reload config file: the daemon option has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.debug!=global.debug) { + *errstr=strdup("Cannot reload config file: the debug option has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.stat_pipe!=global.stat_pipe) { + *errstr=strdup("Cannot reload config file: the status_ctl option has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.notcp!=global.notcp) { + *errstr=strdup("Cannot reload config file: the tcp_server option has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.strict_suid!=global.strict_suid) { + *errstr=strdup("Cannot reload config file: the strict_setuid option has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(global_new.ctl_perms!=global.ctl_perms) { + *errstr=strdup("Cannot reload config file: the specified ctl_perms has changed.\n" + "Try restarting pdnsd instead."); + goto cleanup_return; + } + if(ping_isocket==-1 +#ifdef ENABLE_IPV6 + && ping6_isocket==-1 +#endif + ) { + int i,n=DA_NEL(servers_new); + for (i=0;idomain); +} + +void free_slist_array(slist_array sla) +{ + int j,m=DA_NEL(sla); + for(j=0;juptest_cmd); + free(serv->query_test_name); + free(serv->label); + da_free(serv->atup_a); + free_slist_array(serv->alist); + da_free(serv->reject_a4); +#if ALLOW_LOCAL_AAAA + da_free(serv->reject_a6); +#endif +} + +static void free_server_data(servparm_array sa) +{ + int i,n=DA_NEL(sa); + for(i=0;ireject_a4!=NULL || (s)->reject_a6!=NULL) +#else +#define serv_has_rejectlist(s) ((s)->reject_a4!=NULL) +#endif + + +/* Report the current status of server i to the file descriptor f. + Call with locks applied. +*/ +static int report_server_stat(int f,int i) +{ + servparm_t *st=&DA_INDEX(servers,i); + int j,m; + + fsprintf_or_return(f,"Server %i:\n------\n",i); + fsprintf_or_return(f,"\tlabel: %s\n",st->label?st->label:"(none)"); + m=DA_NEL(st->atup_a); + if(st->rootserver>1 && m) + fsprintf_or_return(f,"\tThe following name servers will be used for discovery of rootservers only:\n"); + for(j=0;jatup_a,j); + {char buf[ADDRSTR_MAXLEN]; + fsprintf_or_return(f,"\tip: %s\n",pdnsd_a2str(PDNSD_A2_TO_A(&at->a),buf,ADDRSTR_MAXLEN));} + fsprintf_or_return(f,"\tserver assumed available: %s\n",at->is_up?"yes":"no"); + } + fsprintf_or_return(f,"\tport: %hu\n",st->port); + fsprintf_or_return(f,"\tuptest: %s\n",const_name(st->uptest)); + fsprintf_or_return(f,"\ttimeout: %li\n",(long)st->timeout); + if(st->interval>0) { + fsprintf_or_return(f,"\tuptest interval: %li\n",(long)st->interval); + } else { + fsprintf_or_return(f,"\tuptest interval: %s\n", + st->interval==-1?"onquery": + st->interval==-2?"ontimeout": + "(never retest)"); + } + fsprintf_or_return(f,"\tping timeout: %li\n",(long)st->ping_timeout); + {char buf[ADDRSTR_MAXLEN]; + fsprintf_or_return(f,"\tping ip: %s\n",is_inaddr_any(&st->ping_a)?"(using server ip)":pdnsd_a2str(&st->ping_a,buf,ADDRSTR_MAXLEN));} + if(st->interface[0]) { + fsprintf_or_return(f,"\tinterface: %s\n",st->interface); + } + if(st->device[0]) { + fsprintf_or_return(f,"\tdevice (for special Linux ppp device support): %s\n",st->device); + } + if(st->uptest_cmd) { + fsprintf_or_return(f,"\tuptest command: %s\n",st->uptest_cmd); + fsprintf_or_return(f,"\tuptest user: %s\n",st->uptest_usr[0]?st->uptest_usr:"(process owner)"); + } + if(st->query_test_name) { + unsigned char nmbuf[DNSNAMEBUFSIZE]; + fsprintf_or_return(f,"\tname used in query uptest: %s\n", + rhn2str(st->query_test_name,nmbuf,sizeof(nmbuf))); + } + if (st->scheme[0]) { + fsprintf_or_return(f,"\tscheme: %s\n", st->scheme); + } + fsprintf_or_return(f,"\tforce cache purging: %s\n",st->purge_cache?"on":"off"); + fsprintf_or_return(f,"\tserver is cached: %s\n",st->nocache?"off":"on"); + fsprintf_or_return(f,"\tlean query: %s\n",st->lean_query?"on":"off"); + fsprintf_or_return(f,"\tUse EDNS in outgoing queries: %s\n",st->edns_query?"on":"off"); + fsprintf_or_return(f,"\tUse only proxy?: %s\n",st->is_proxy?"on":"off"); + fsprintf_or_return(f,"\tAssumed root server: %s\n",st->rootserver?(st->rootserver==1?"yes":"discover"):"no"); + fsprintf_or_return(f,"\tRandomize server query order: %s\n",st->rand_servers?"yes":"no"); + fsprintf_or_return(f,"\tDefault policy: %s\n",const_name(st->policy)); + fsprintf_or_return(f,"\tPolicies:%s\n", st->alist?"":" (none)"); + for (j=0;jalist);++j) { + slist_t *sl=&DA_INDEX(st->alist,j); + unsigned char buf[DNSNAMEBUFSIZE]; + fsprintf_or_return(f,"\t\t%s: %s%s\n", + sl->rule==C_INCLUDED?"include":"exclude", + sl->exact?"":".", + rhn2str(sl->domain,buf,sizeof(buf))); + } + if(serv_has_rejectlist(st)) { + fsprintf_or_return(f,"\tAddresses which should be rejected in replies:\n"); + m=DA_NEL(st->reject_a4); + for (j=0;jreject_a4,j); + char abuf[ADDRSTR_MAXLEN],mbuf[ADDRSTR_MAXLEN]; + fsprintf_or_return(f,"\t\t%s/%s\n",inet_ntop(AF_INET,&am->a,abuf,sizeof(abuf)), + inet_ntop(AF_INET,&am->mask,mbuf,sizeof(mbuf))); + } +#if ALLOW_LOCAL_AAAA + m=DA_NEL(st->reject_a6); + for (j=0;jreject_a6,j); + char abuf[INET6_ADDRSTRLEN],mbuf[INET6_ADDRSTRLEN]; + fsprintf_or_return(f,"\t\t%s/%s\n",inet_ntop(AF_INET6,&am->a,abuf,sizeof(abuf)), + inet_ntop(AF_INET6,&am->mask,mbuf,sizeof(mbuf))); + } +#endif + fsprintf_or_return(f,"\tReject policy: %s\n",const_name(st->rejectpolicy)); + fsprintf_or_return(f,"\tReject recursively: %s\n",st->rejectrecursively?"yes":"no"); + } + return 0; +} diff --git a/jni/pdnsd/src/conff.h b/jni/pdnsd/src/conff.h new file mode 100644 index 00000000..a07b1561 --- /dev/null +++ b/jni/pdnsd/src/conff.h @@ -0,0 +1,190 @@ +/* conff.h - Definitions for configuration management. + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef CONFF_H +#define CONFF_H + +/* XXX should use the system defined ones. */ +/* #define MAXPATH 1024 */ +/* #define MAXIFNAME 31 */ + +#include +#include +#include +#include +#include +#include "ipvers.h" +#include "list.h" + +/* From main.c */ +#if DEBUG>0 +extern short int debug_p; +#else +#define debug_p 0 +#endif +extern short int stat_pipe; +extern pthread_t main_thrid; +extern uid_t init_uid; +extern char *conf_file; + +/* ----------- */ + +typedef DYNAMIC_ARRAY(pdnsd_a) *addr_array; +typedef DYNAMIC_ARRAY(pdnsd_a2) *addr2_array; + +typedef struct { + time_t i_ts; + char is_up; + pdnsd_a2 a; +} atup_t; +typedef DYNAMIC_ARRAY(atup_t) *atup_array; + +typedef struct { + unsigned char *domain; + short exact; + short rule; +} slist_t; +typedef DYNAMIC_ARRAY(slist_t) *slist_array; + +typedef struct { + struct in_addr a,mask; +} addr4maskpair_t; + +typedef DYNAMIC_ARRAY(addr4maskpair_t) *a4_array; + +#if ALLOW_LOCAL_AAAA +typedef struct { + struct in6_addr a,mask; +} addr6maskpair_t; + +typedef DYNAMIC_ARRAY(addr6maskpair_t) *a6_array; +#endif + +typedef struct { + unsigned short port; + short uptest; + time_t timeout; + time_t interval; + time_t ping_timeout; + char scheme[32]; + char *uptest_cmd; + char uptest_usr[21]; + char interface[IFNAMSIZ]; + char device[IFNAMSIZ]; + unsigned char *query_test_name; + char *label; + char purge_cache; + char nocache; + char lean_query; + char edns_query; + char is_proxy; + char rootserver; + char rand_servers; + char preset; + char rejectrecursively; + short rejectpolicy; + short policy; + slist_array alist; + atup_array atup_a; + a4_array reject_a4; +#if ALLOW_LOCAL_AAAA + a6_array reject_a6; +#endif + pdnsd_a ping_a; +} servparm_t; +typedef DYNAMIC_ARRAY(servparm_t) *servparm_array; + +typedef unsigned char *zone_t; +typedef DYNAMIC_ARRAY(zone_t) *zone_array; + +typedef struct { + long perm_cache; + char *cache_dir; + char *pidfile; + int port; + pdnsd_a a; + pdnsd_a out_a; +#ifdef ENABLE_IPV6 + struct in6_addr ipv4_6_prefix; +#endif + time_t max_ttl; + time_t min_ttl; + time_t neg_ttl; + short neg_rrs_pol; + short neg_domain_pol; + short verbosity; + char run_as[21]; + char daemon; + char debug; + char stat_pipe; + char notcp; + char strict_suid; + char use_nss; + char paranoid; + char lndown_kluge; + char onquery; + char rnd_recs; + int ctl_perms; + char *scheme_file; + int proc_limit; + int procq_limit; + time_t tcp_qtimeout; + time_t timeout; + int par_queries; + int query_method; + int query_port_start; + int query_port_end; + int udpbufsize; + zone_array deleg_only_zones; +} globparm_t; + +typedef struct { + char +#ifdef ENABLE_IPV6 + prefix, +#endif + pidfile, + verbosity, + pdnsduser, + daemon, + debug, + stat_pipe, + notcp, + query_method; +} cmdlineflags_t; + +extern globparm_t global; +extern cmdlineflags_t cmdline; +extern servparm_t serv_presets; + +extern servparm_array servers; + +int read_config_file(const char *nm, globparm_t *global, servparm_array *servers, int includedepth, char **errstr); +int reload_config_file(const char *nm, char **errstr); +void free_zone(void *ptr); +void free_slist_domain(void *ptr); +void free_slist_array(slist_array sla); +void free_servparm(servparm_t *serv); + +int report_conf_stat(int f); +#endif diff --git a/jni/pdnsd/src/consts.c b/jni/pdnsd/src/consts.c new file mode 100644 index 00000000..c875a091 --- /dev/null +++ b/jni/pdnsd/src/consts.c @@ -0,0 +1,133 @@ +/* consts.c - Common config constants & handling + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2005, 2006, 2007, 2009 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include "consts.h" +#include "rr_types.h" + + +/* Order alphabetically!! */ +static const namevalue_t const_dic[]={ + {"auth", C_AUTH}, + {"default", C_DEFAULT}, + {"dev", C_DEV}, + {"diald", C_DIALD}, + {"discover", C_DISCOVER}, + {"domain", C_DOMAIN}, + {"excluded", C_EXCLUDED}, + {"exec", C_EXEC}, + {"fail", C_FAIL}, + {"false", C_OFF}, + {"fqdn_only", C_FQDN_ONLY}, + {"if", C_IF}, + {"included", C_INCLUDED}, + {"negate", C_NEGATE}, + {"no", C_OFF}, + {"none", C_NONE}, + {"off", C_OFF}, + {"on", C_ON}, + {"onquery", C_ONQUERY}, + {"ontimeout", C_ONTIMEOUT}, + {"ping", C_PING}, + {"query", C_QUERY}, + {"simple_only", C_SIMPLE_ONLY}, + {"tcp_only", TCP_ONLY}, + {"tcp_udp", TCP_UDP}, + {"true", C_ON}, + {"udp_only", UDP_ONLY}, + {"udp_tcp", UDP_TCP}, + {"yes", C_ON} +}; + +/* Added by Paul Rombouts */ +static const char *const const_names[]={ + "error", + "on", + "off", + "default", + "discover", + "none", + "if", + "exec", + "ping", + "query", + "onquery", + "ontimeout", + "udp_only", + "tcp_only", + "tcp_udp", + "udp_tcp", + "dev", + "diald", + "included", + "excluded", + "simple_only", + "fqdn_only", + "auth", + "domain", + "fail", + "negate" +}; + +/* compare two strings. + The first one is given as pointer to a char array of length len (which + should not contain any null chars), + the second one as a pointer to a null terminated char array. +*/ +inline static int keyncmp(const char *key1, int len, const char *key2) +{ + int cmp=strncmp(key1,key2,len); + if(cmp) return cmp; + return -(int)((unsigned char)(key2[len])); +} + +int binsearch_keyword(const char *name, int len, const namevalue_t dic[], int range) +{ + int i=0,j=range; + + while(i0) + i=k+1; + else + return dic[k].val; + } + + return 0; +} + + +int lookup_const(const char *name, int len) +{ + return binsearch_keyword(name,len,const_dic,sizeof(const_dic)/sizeof(namevalue_t)); +} + +/* Added by Paul Rombouts */ +const char *const_name(int c) +{ + return (c>=0 && c. +*/ + + +#ifndef CONSTS_H +#define CONSTS_H + +#include + +#define C_RRTOFFS 64 + +enum { + C_ERR, + C_ON, + C_OFF, + C_DEFAULT, + C_DISCOVER, + C_NONE, + C_IF, + C_EXEC, + C_PING, + C_QUERY, + C_ONQUERY, + C_ONTIMEOUT, + UDP_ONLY, + TCP_ONLY, + TCP_UDP, + UDP_TCP, + C_DEV, + C_DIALD, + C_INCLUDED, + C_EXCLUDED, + C_SIMPLE_ONLY, + C_FQDN_ONLY, + C_AUTH, + C_DOMAIN, + C_FAIL, + C_NEGATE +}; + +typedef struct { + const char *name; + int val; +} namevalue_t; + +int binsearch_keyword(const char *name, int len, const namevalue_t dic[], int range); +int lookup_const(const char *name, int len); +const char *const_name(int c); /* Added by Paul Rombouts */ + +#endif diff --git a/jni/pdnsd/src/debug.c b/jni/pdnsd/src/debug.c new file mode 100644 index 00000000..dd7f244d --- /dev/null +++ b/jni/pdnsd/src/debug.c @@ -0,0 +1,64 @@ +/* debug.c - Various debugging facilities + * Copyright (C) 2001 Thomas Moestl + * + * This file is part of the pdnsd package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "helpers.h" +#include "error.h" + + +/* + * This is indeed very primitive (it does not track allocation failures + * and so on). It should be expanded some time. + */ +#ifdef ALLOC_DEBUG +void *DBGcalloc(size_t n, size_t sz, char *file, int line) +{ + DEBUG_MSG("+ calloc, %s:%d\n", file, line); + return calloc(n, sz); +} + +void *DBGmalloc(size_t sz, char *file, int line) +{ + DEBUG_MSG("+ malloc, %s:%d\n", file, line); + return malloc(sz); +} + +void *DBGrealloc(void *ptr, size_t sz, char *file, int line) +{ + if (ptr == NULL && sz != 0) + DEBUG_MSG("+ realloc, %s:%d\n", file, line); + if (ptr != NULL && sz == 0) + DEBUG_MSG("- realloc(0), %s:%d\n", file, line); + return realloc(ptr, sz); +} +void DBGfree(void *ptr, char *file, int line) +{ + DEBUG_MSG("- free, %s:%d\n", file, line); + free(ptr); +} +#endif diff --git a/jni/pdnsd/src/debug.h b/jni/pdnsd/src/debug.h new file mode 100644 index 00000000..02f0e5d4 --- /dev/null +++ b/jni/pdnsd/src/debug.h @@ -0,0 +1,52 @@ +/* debug.h - Various debugging facilities + * Copyright (C) 2001 Thomas Moestl + * + * This file is part of the pdnsd package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef DEBUG_H +#define DEBUG_H + +/* + * A hand-rolled alloc debug factility, because most available libraries have + * problems with at least one thread implementation. + */ +#ifdef ALLOC_DEBUG +void *DBGcalloc(size_t n, size_t sz, char *file, int line); +void *DBGmalloc(size_t sz, char *file, int line); +void *DBGrealloc(void *ptr, size_t sz, char *file, int line); +void DBGfree(void *ptr, char *file, int line); + +#define pdnsd_calloc(n,sz) DBGcalloc(n,sz,__FILE__,__LINE__) +#define pdnsd_malloc(sz) DBGmalloc(sz,__FILE__,__LINE__) +#define pdnsd_realloc(ptr,sz) DBGrealloc(ptr,sz,__FILE__,__LINE__) +#define pdnsd_free(ptr) DBGfree(ptr,__FILE__,__LINE__) +#else +#define pdnsd_calloc calloc +#define pdnsd_malloc malloc +#define pdnsd_realloc realloc +#define pdnsd_free free +#endif + +#endif /* def DEBUG_H */ diff --git a/jni/pdnsd/src/dns.c b/jni/pdnsd/src/dns.c new file mode 100644 index 00000000..a02d7fde --- /dev/null +++ b/jni/pdnsd/src/dns.c @@ -0,0 +1,617 @@ +/* dns.c - Declarations for dns handling and generic dns functions + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include "error.h" +#include "helpers.h" +#include "dns.h" + + +/* Decompress a name record, taking the whole message as msg, returning its results in tgt + * (which should be able hold at least DNSNAMEBUFSIZE chars), + * taking sz as the remaining msg size (it is returned decremented by the name length, ready for further use) and + * a source pointer (it is returned pointing to the location after the name). msgsize is the size of the whole message, + * len is the total name length. + * msg and msgsz are needed for decompression (see rfc1035). The returned data is decompressed, but still in the + * rr name form (length byte - string of that length, terminated by a 0 length byte). + * + * Returned is a dns return code, with one exception: RC_TRUNC, as defined in dns.h, indicates that the message is + * truncated at the name (which needs a special return code, as it might or might not be fatal). + */ +int decompress_name(unsigned char *msg, size_t msgsz, unsigned char **src, size_t *sz, unsigned char *tgt, unsigned int *len) +{ + unsigned int lb,offs; + unsigned int hops=0,tpos=0; + unsigned char *lptr=*src; + size_t oldsz=*sz; + size_t newsz=oldsz; + + if (newsz==0) + goto name_outside_data; + if (lptr-msg>=msgsz) + goto name_outside_msg; + + for(;;) { + newsz--; + lb=*lptr++; + + if(lb>0x3f) { + if (lb<0xc0) /* The two highest bits must be either 00 or 11 */ + goto unsupported_lbl_bits; + if (newsz==0) + goto name_outside_data; + if (lptr-msg>=msgsz) + goto name_outside_msg; + newsz--; + offs=((lb&0x3f)<<8)|(*lptr); + if (offs>=msgsz) + goto offset_outside_msg; + lptr=msg+offs; + goto jumped; + } + tgt[tpos++]=lb; + if (lb==0) + break; + + if (newsz<=lb) + goto name_outside_data; + if (lptr+lb-msg>=msgsz) + goto name_outside_msg; + if (tpos+lb>DNSNAMEBUFSIZE-1) /* terminating null byte has to follow */ + goto name_buf_full; + newsz -= lb; + do { + /* if (!*lptr || *lptr=='.') + return RC_FORMAT; */ + tgt[tpos++]=*lptr++; + } while(--lb); + } + goto return_OK; + + jumped: + ++hops; + for(;;) { + lb=*lptr++; + + while(lb>0x3f) { + if (lb<0xc0) /* The two highest bits must be either 00 or 11 */ + goto unsupported_lbl_bits; + if (lptr-msg>=msgsz) + goto name_outside_msg; + if (++hops>255) + goto too_many_hops; + offs=((lb&0x3f)<<8)|(*lptr); + if (offs>=msgsz) + goto offset_outside_msg; + lptr=msg+offs; + lb=*lptr++; + } + tgt[tpos++]=lb; + if (lb==0) + break; + + if (lptr+lb-msg>=msgsz) + goto name_outside_msg; + if(tpos+lb>DNSNAMEBUFSIZE-1) /* terminating null byte has to follow */ + goto name_buf_full; + do { + /* if (!*lptr || *lptr=='.') + return RC_FORMAT; */ + tgt[tpos++]=*lptr++; + } while(--lb); + } + return_OK: + *src += oldsz-newsz; + *sz = newsz; + if(len) *len=tpos; + return RC_OK; + + name_outside_data: + DEBUG_MSG("decompress_name: compressed name extends outside data field.\n"); + return RC_TRUNC; + + name_outside_msg: + DEBUG_MSG("decompress_name: compressed name extends outside message.\n"); + return RC_FORMAT; + + unsupported_lbl_bits: + DEBUG_MSG(lb==0x41?"decompress_name: Bit-string labels not supported.\n": + "decompress_name: unsupported label type.\n"); + return RC_FORMAT; + + offset_outside_msg: + DEBUG_MSG("decompress_name: offset points outside message.\n"); + return RC_FORMAT; + + name_buf_full: + DEBUG_MSG("decompress_name: decompressed name larger than %u bytes.\n", DNSNAMEBUFSIZE); + return RC_FORMAT; + + too_many_hops: + DEBUG_MSG("decompress_name: too many offsets in compressed name.\n"); + return RC_FORMAT; +} + +#if 0 +/* Compare two names (ordinary C-strings) back-to-forth and return the longest match. + The comparison is done at name granularity. + The return value is the length of the match in name elements. + *os (*od) is set to the offset in the domain name ms (md) of the match. + */ +int domain_name_match(const unsigned char *ms, const unsigned char *md, int *os, int *od) +{ + int i,j,k=0,offs,offd; + + offs=i=strlen(ms); offd=j=strlen(md); + if(i && ms[i-1]=='.') --offs; + if(j && md[j-1]=='.') --offd; + + if(i==0 || (i==1 && *ms=='.') || j==0 || (j==1 && *md=='.')) + /* Special case: root domain */ + ; + else { + --i; if(ms[i]=='.') --i; + --j; if(md[j]=='.') --j; + while(tolower(ms[i]) == tolower(md[j])) { + if(ms[i]=='.') { + ++k; + offs=i+1; offd=j+1; + } + if(i==0 || j==0) { + if((i==0 || ms[i-1]=='.') && (j==0 || md[j-1]=='.')) { + ++k; + offs=i; offd=j; + } + break; + } + --i; --j; + } + } + if(os) *os=offs; + if(od) *od=offd; + return k; +} +#endif + +/* Compare the names (in length byte-string notation) back-to-forth and return the longest match. + The comparison is done at name granularity. + The return value is the length of the match in name elements. + *os (*od) is set to the offset in the domain name ms (md) of the match. + */ +unsigned int domain_match(const unsigned char *ms, const unsigned char *md, unsigned int *os, unsigned int *od) +{ + unsigned int i,j,k,n,ns=0,nd=0,offs,offd; + unsigned char lb,ls[128],ld[128]; + + /* first collect all length bytes */ + i=0; + while((lb=ms[i])) { + PDNSD_ASSERT(ns<128, "domain_match: too many name segments"); + ls[ns++]=lb; + i += ((unsigned)lb)+1; + } + + j=0; + while((lb=md[j])) { + PDNSD_ASSERT(nd<128, "domain_match: too many name segments"); + ld[nd++]=lb; + j += ((unsigned)lb)+1; + } + + n=ns; if(n>nd) n=nd; + + for(k=1; offs=i,offd=j,k<=n; ++k) { + lb=ls[ns-k]; + if(lb!=ld[nd-k]) goto mismatch; + for(;lb;--lb) + if(tolower(ms[--i]) != tolower(md[--j])) goto mismatch; + --i; --j; + } + mismatch: + + if(os) *os=offs; + if(od) *od=offd; + return k-1; +} + +/* compress the domain name in in and put the result (of maximum length of rhnlen(in)) and + * fill cb with compression information for further strings.*cb may be NULL initially. + * offs is the offset the generated string will be placed in the packet. + * retval: 0 - error, otherwise length + * When done, just free() cb (if it is NULL, free will behave correctly). + * It is guaranteed (and insured by assertions) that the output is smaller or equal in + * size to the input. + */ +unsigned int compress_name(unsigned char *in, unsigned char *out, unsigned int offs, dlist *cb) +{ + compel_t *ci; + unsigned int longest=0,lrem=0,coffs=0; + unsigned int rl=0; + unsigned ilen = rhnlen(in); + unsigned short add=1; + + PDNSD_ASSERT(ilen<=DNSNAMEBUFSIZE, "compress_name: name too long"); + + /* part 1: compression */ + for (ci=dlist_first(*cb); ci; ci=dlist_next(ci)) { + unsigned int rv,rem,to; + if ((rv=domain_match(in, ci->s, &rem,&to))>longest) { + /* + * This has some not obvious implications that should be noted: If a + * domain name as saved in the list has been compressed, we only can + * index the non-compressed part. We rely here that the first occurence + * can't be compressed. So we take the first occurence of a given length. + * This works perfectly, but watch it if you change something. + */ + unsigned int newoffs= ci->index + to; + /* Only use if the offset is not too large. */ + if(newoffs<=0x3fff) { + longest=rv; + lrem=rem; + coffs= newoffs; + } + } + } + if (longest>0) { + PDNSD_ASSERT(lrem+2 <= ilen, "compress_name: length increased"); + memcpy(out, in,lrem); + out[lrem]=0xc0|((coffs&0x3f00)>>8); + out[lrem+1]=coffs&0xff; + rl=lrem+2; + add= lrem!=0; + } + else { + memcpy(out,in,ilen); + rl=ilen; + } + + /* part 2: addition to the cache structure */ + if (add) { + if (!(*cb=dlist_grow(*cb,sizeof(compel_t)+ilen))) + return 0; + ci=dlist_last(*cb); + ci->index=offs; + memcpy(ci->s,in,ilen); + } + return rl; +} + +/* Convert a numeric IP address into a domain name representation + (C string) suitable for PTR records. + buf is assumed to be at least DNSNAMEBUFSIZE bytes in size. +*/ +int a2ptrstr(pdnsd_ca *a, int tp, unsigned char *buf) +{ + if(tp==T_A) { + unsigned char *p=(unsigned char *)&a->ipv4.s_addr; + int n=snprintf(charp buf,DNSNAMEBUFSIZE,"%u.%u.%u.%u.in-addr.arpa.",p[3],p[2],p[1],p[0]); + if(n<0 || n>=DNSNAMEBUFSIZE) + return 0; + } + else +#if ALLOW_LOCAL_AAAA + if(tp==T_AAAA) { + unsigned char *p=(unsigned char *)&a->ipv6; + int i,offs=0; + for (i=15;i>=0;--i) { + unsigned char bt=p[i]; + int n=snprintf(charp(buf+offs), DNSNAMEBUFSIZE-offs,"%x.%x.",bt&0xf,(bt>>4)&0xf); + if(n<0) return 0; + offs+=n; + if(offs>=DNSNAMEBUFSIZE) return 0; + } + if(!strncp(charp(buf+offs),"ip6.arpa.",DNSNAMEBUFSIZE-offs)) + return 0; + } + else +#endif + return 0; + return 1; +} + +/* + * Add records for a host as read from a hosts-style file. + * Returns 1 on success, 0 in an out of memory condition, and -1 when there was a problem with + * the record data. + */ +static int add_host(unsigned char *pn, unsigned char *rns, pdnsd_ca *a, int tp, int a_sz, time_t ttl, unsigned flags, int reverse) +{ + dns_cent_t ce; + + if (!init_cent(&ce, pn, 0, 0, flags DBG0)) + return 0; + if (!add_cent_rr(&ce,tp,ttl,0,CF_LOCAL,a_sz,a DBG0)) + goto free_cent_return0; + if (!add_cent_rr(&ce,T_NS,ttl,0,CF_LOCAL,rhnlen(rns),rns DBG0)) + goto free_cent_return0; + add_cache(&ce); + free_cent(&ce DBG0); + if (reverse) { + unsigned char b2[DNSNAMEBUFSIZE],rhn[DNSNAMEBUFSIZE]; + if(!a2ptrstr(a,tp,b2)) + return -1; + if (!str2rhn(b2,rhn)) + return -1; + if (!init_cent(&ce, rhn, 0, 0, flags DBG0)) + return 0; + if (!add_cent_rr(&ce,T_PTR,ttl,0,CF_LOCAL,rhnlen(pn),pn DBG0)) + goto free_cent_return0; + if (!add_cent_rr(&ce,T_NS,ttl,0,CF_LOCAL,rhnlen(rns),rns DBG0)) + goto free_cent_return0; + add_cache(&ce); + free_cent(&ce DBG0); + } + return 1; + + free_cent_return0: + free_cent(&ce DBG0); + return 0; +} + +/* + * Read a file in /etc/hosts-format and add generate rrs for it. + * Errors are largely ignored so that we can skip entries we do not understand + * (but others possibly do). + */ +int read_hosts(const char *fn, unsigned char *rns, time_t ttl, unsigned flags, int aliases, char **errstr) +{ + int rv=0; + FILE *f; + char *buf; + size_t buflen=256; + + if (!(f=fopen(fn,"r"))) { + if(asprintf(errstr, "Failed to source %s: %s", fn, strerror(errno))<0) *errstr=NULL; + return 0; + } + buf=malloc(buflen); + if(!buf) { + *errstr=NULL; + goto fclose_return; + } + while(getline(&buf,&buflen,f)>=0) { + unsigned int len; + unsigned char *p,*pn,*pi; + unsigned char rhn[DNSNAMEBUFSIZE]; + int tp,sz; + pdnsd_ca a; + + p= ucharp strchr(buf,'#'); + if(p) *p=0; + p= ucharp buf; + for(;;) { + if(!*p) goto nextline; + if(!isspace(*p)) break; + ++p; + } + pi=p; + do { + if(!*++p) goto nextline; + } while(!isspace(*p)); + *p=0; + do { + if(!*++p) goto nextline; + } while (isspace(*p)); + pn=p; + do { + ++p; + } while(*p && !isspace(*p)); + len=p-pn; + if (parsestr2rhn(pn,len,rhn)!=NULL) + continue; + if (inet_aton(charp pi,&a.ipv4)) { + tp=T_A; + sz=sizeof(struct in_addr); + } else { +#if ALLOW_LOCAL_AAAA /* We don't read them otherwise, as the C library may not be able to to that.*/ + if (inet_pton(AF_INET6,charp pi,&a.ipv6)>0) { + tp=T_AAAA; + sz=sizeof(struct in6_addr); + } else +#endif + continue; + } + { + int res=add_host(rhn, rns, &a, tp,sz, ttl, flags, 1); + if(res==0) { + *errstr= NULL; + goto cleanup_return; + } + else if(res<0) + continue; + } + if(aliases) { + for(;;) { + for(;;) { + if(!*p) goto nextline; + if(!isspace(*p)) break; + ++p; + } + pn=p; + do { + ++p; + } while(*p && !isspace(*p)); + len=p-pn; + if (parsestr2rhn(pn,len,rhn)!=NULL) + break; + if (add_host(rhn, rns, &a, tp,sz, ttl, flags, 0) == 0) { + *errstr= NULL; + goto cleanup_return; + } + } + } + nextline:; + } + if (feof(f)) + rv=1; + else if(asprintf(errstr, "Failed to source %s: %s", fn, strerror(errno))<0) *errstr=NULL; + cleanup_return: + free(buf); + fclose_return: + fclose(f); + return rv; +} + + +/* Get the name of an RR type given its value. */ +const char *getrrtpname(int tp) +{ + return tp>=T_MIN && tp<=T_MAX? rrnames[tp-T_MIN]: "[unknown]"; +} + +#if DEBUG>0 +/* + * Const decoders for debugging display + */ +static const char *const c_names[C_NUM] = {"IN","CS","CH","HS"}; +static const char *const qt_names[QT_NUM]={"IXFR","AXFR","MAILB","MAILA","*"}; + +const char *get_cname(int id) +{ + if (id>=C_MIN && id<=C_MAX) + return c_names[id-C_MIN]; + if (id==QC_ALL) + return "*"; + return "[unknown]"; +} + +const char *get_tname(int id) +{ + if (id>=T_MIN && id<=T_MAX) + return rrnames[id-T_MIN]; + else if (id>=QT_MIN && id<=QT_MAX) + return qt_names[id-QT_MIN]; + return "[unknown]"; +} + + +#define NRC 17 +static const char *const e_names[NRC]={ + "no error", + "query format error", + "server failed", + "non-existent domain", + "not supported", + "query refused", + "name exists when it should not", + "RR set exists when it should not", + "RR set that should exist does not", + "server not authoritative for zone", + "name not contained in zone", + "11", + "12", + "13", + "14", + "15", + "bad OPT version" +}; + +const char *get_ename(int id) +{ + if (id>=0 && idaa) + p=mempcpy(p, " AA", 3); + if (hdr->tc) + p=mempcpy(p, " TC", 3); + if (hdr->rd) + p=mempcpy(p, " RD", 3); + if (hdr->ra) + p=mempcpy(p, " RA", 3); + if (hdr->z) + p=mempcpy(p, " Z", 2); + if (hdr->ad) + p=mempcpy(p, " AD", 3); + if (hdr->cd) + p=mempcpy(p, " CD", 3); + *p=0; + + return buf; +} + +#endif + + +#if DEBUG>=9 +/* Based on debug code contributed by Kiyo Kelvin Lee. */ + +void debug_dump_dns_msg(void *data, size_t len) +{ + unsigned char *udata = (unsigned char *)data; +# define dmpchksz 16 + char buf[dmpchksz*4+2]; + size_t i, j, k, l; + + DEBUG_MSG("pointer=%p len=%lu\n", udata, (unsigned long)len); + + for (i = 0; i < len; i += dmpchksz) { + char *cp = buf; + k = l = i + dmpchksz; + if(k > len) k = len; + for (j = i; j < k; ++j) { + int n = sprintf(cp, "%02x ", udata[j]); + cp += n; + } + for (; j < l; ++j) { + *cp++ = ' '; + *cp++ = ' '; + *cp++ = ' '; + } + *cp++ = ' '; + for (j = i; j < k; ++j) { + *cp++ = isprint(udata[j]) ? udata[j] : '.'; + } + PDNSD_ASSERT(cp < buf + sizeof(buf), "debug_dump_dns_msg: line buffer overflowed"); + *cp = '\0'; + DEBUG_MSG("%s\n", buf); + } + + if(len >= sizeof(dns_hdr_t)) { + dns_hdr_t *hdr = (dns_hdr_t *)data; + + DEBUG_MSG( + "id=%04x qr=%x opcode=%x aa=%x tc=%x rd=%x " + "ra=%x z=%x ad=%x cd=%x rcode=%x\n", + ntohs(hdr->id), hdr->qr, hdr->opcode, hdr->aa, hdr->tc, hdr->rd, + hdr->ra, hdr->z, hdr->ad, hdr->cd, hdr->rcode); + DEBUG_MSG( + "qdcount=%04x ancount=%04x nscount=%04x arcount=%04x\n", + ntohs(hdr->qdcount), ntohs(hdr->ancount), ntohs(hdr->nscount), ntohs(hdr->arcount)); + } +} +#endif diff --git a/jni/pdnsd/src/dns.h b/jni/pdnsd/src/dns.h new file mode 100644 index 00000000..0f6a4ac1 --- /dev/null +++ b/jni/pdnsd/src/dns.h @@ -0,0 +1,309 @@ +/* dns.h - Declarations for dns handling and generic dns functions + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef DNS_H +#define DNS_H + +#include +#include +#include +#include +#include +#include +#include "rr_types.h" +#include "list.h" +#include "ipvers.h" + +#if (TARGET==TARGET_BSD) +# if !defined(__BIG_ENDIAN) +# if defined(BIG_ENDIAN) +# define __BIG_ENDIAN BIG_ENDIAN +# elif defined(_BIG_ENDIAN) +# define __BIG_ENDIAN _BIG_ENDIAN +# endif +# endif +# if !defined(__LITTLE_ENDIAN) +# if defined(LITTLE_ENDIAN) +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# elif defined(_LITTLE_ENDIAN) +# define __LITTLE_ENDIAN _LITTLE_ENDIAN +# endif +# endif +# if !defined(__BYTE_ORDER) +# if defined(BYTE_ORDER) +# define __BYTE_ORDER BYTE_ORDER +# elif defined(_BYTE_ORDER) +# define __BYTE_ORDER _BYTE_ORDER +# endif +# endif +#endif + +/* Deal with byte orders */ +#ifndef __BYTE_ORDER +# if defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN) +# error Fuzzy endianness system! Both __LITTLE_ENDIAN and __BIG_ENDIAN have been defined! +# endif +# if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) +# error Strange Endianness-less system! Neither __LITTLE_ENDIAN nor __BIG_ENDIAN has been defined! +# endif +# if defined(__LITTLE_ENDIAN) +# define __BYTE_ORDER __LITTLE_ENDIAN +# elif defined(__BIG_ENDIAN) +# define __BYTE_ORDER __BIG_ENDIAN +# endif +#endif + +/* special rr type codes for queries */ +#define QT_MIN 251 +#define QT_IXFR 251 +#define QT_AXFR 252 +#define QT_MAILB 253 +#define QT_MAILA 254 +#define QT_ALL 255 +#define QT_MAX 255 +#define QT_NUM 5 + +/* rr classes */ +#define C_MIN 1 +#define C_IN 1 +#define C_CS 2 +#define C_CH 3 +#define C_HS 4 +#define C_MAX 4 +#define C_NUM 4 + +/* special classes for queries */ +#define QC_ALL 255 + +/* status codes */ +#define RC_OK 0 +#define RC_FORMAT 1 +#define RC_SERVFAIL 2 +#define RC_NAMEERR 3 +#define RC_NOTSUPP 4 +#define RC_REFUSED 5 +#define RC_BADVERS 16 + +/* + * special internal retvals + */ +#define RC_NOTCACHED 0xfffa +#define RC_CACHED 0xfffb +#define RC_STALE 0xfffc +#define RC_TCPREFUSED 0xfffd +#define RC_TRUNC 0xfffe +#define RC_FATALERR 0xffff + +/* query/response */ +#define QR_QUERY 0 +#define QR_RESP 1 + +/*opcodes */ +#define OP_QUERY 0 +#define OP_IQUERY 1 +#define OP_STATUS 2 + +#if 0 +typedef struct { + /* the name is the first field. It has variable length, so it can't be put in the struct */ + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlength; + /* rdata follows */ +} __attribute__((packed)) rr_hdr_t; + +#define sizeof_rr_hdr_t (sizeof rr_hdr_t) +#else + +/* We will not actually use the rr_hdr_t type, only its size: + sizeof(rr_hdr_t) = 2 + 2 + 4 + 2 */ +#define sizeof_rr_hdr_t 10 +#endif + +#define sizeof_opt_pseudo_rr (1+sizeof_rr_hdr_t) + +#if 0 +typedef struct { + /* The server name and maintainer mailbox are the first two fields. It has variable length, */ + /* so they can't be put in the struct */ + uint32_t serial; + uint32_t refresh; + uint32_t retry; + uint32_t expire; + uint32_t minimum; +} __attribute__((packed)) soa_r_t; + + +typedef struct { +/* char qname[];*/ + uint16_t qtype; + uint16_t qclass; +} __attribute__((packed)) std_query_t; +#endif + + +typedef struct { + uint16_t id; +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int rd:1; + unsigned int tc:1; + unsigned int aa:1; + unsigned int opcode:4; + unsigned int qr:1; + unsigned int rcode:4; + unsigned int cd:1; + unsigned int ad:1; + unsigned int z :1; + unsigned int ra:1; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int qr:1; + unsigned int opcode:4; + unsigned int aa:1; + unsigned int tc:1; + unsigned int rd:1; + unsigned int ra:1; + unsigned int z :1; + unsigned int ad:1; + unsigned int cd:1; + unsigned int rcode:4; +#else +# error "Please define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN" +#endif + uint16_t qdcount; + uint16_t ancount; + uint16_t nscount; + uint16_t arcount; +} __attribute__((packed)) dns_hdr_t; + + +/* A structure that can also be used for DNS messages over TCP. */ +typedef struct { +#ifndef NO_TCP_QUERIES + uint16_t len; +#endif + dns_hdr_t hdr; +} __attribute__((packed)) dns_msg_t; + +#ifdef NO_TCP_QUERIES +# define dnsmsghdroffset 0 +#else +# define dnsmsghdroffset 2 +#endif + + +/* Structure for storing EDNS (Extension mechanisms for DNS) information. */ +typedef struct { + unsigned short udpsize; + unsigned short rcode; + unsigned short version; + unsigned char do_flg; +} edns_info_t; + + +/* Macros to retrieve or store integer data that is not necessarily aligned. + Also takes care of network to host byte order. + The pointer cp is advanced and should be of type void* or char*. + These are actually adapted versions of the NS_GET16 and NS_GET32 + macros in the arpa/nameser.h include file in the BIND 9 source. +*/ + +#define GETINT16(s,cp) do { \ + register uint16_t t_s; \ + register const unsigned char *t_cp = (const unsigned char *)(cp); \ + t_s = (uint16_t)*t_cp++ << 8; \ + t_s |= (uint16_t)*t_cp++; \ + (s) = t_s; \ + (cp) = (void *)t_cp; \ +} while (0) + +#define GETINT32(l,cp) do { \ + register uint32_t t_l; \ + register const unsigned char *t_cp = (const unsigned char *)(cp); \ + t_l = (uint32_t)*t_cp++ << 24; \ + t_l |= (uint32_t)*t_cp++ << 16; \ + t_l |= (uint32_t)*t_cp++ << 8; \ + t_l |= (uint32_t)*t_cp++; \ + (l) = t_l; \ + (cp) = (void *)t_cp; \ +} while (0) + +#define PUTINT16(s,cp) do { \ + register uint16_t t_s = (uint16_t)(s); \ + register unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp++ = t_s; \ + (cp) = (void *)t_cp; \ +} while (0) + +#define PUTINT32(l,cp) do { \ + register uint32_t t_l = (uint32_t)(l); \ + register unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp++ = t_l; \ + (cp) = (void *)t_cp; \ +} while (0) + + +/* Size (number of bytes) of buffers used to hold domain names. */ +#define DNSNAMEBUFSIZE 256 + +/* Recursion depth. */ +#define MAX_HOPS 20 + +/* + * Types for compression buffers. + */ +typedef struct { + unsigned int index; + unsigned char s[0]; +} compel_t; + + + +int decompress_name(unsigned char *msg, size_t msgsz, unsigned char **src, size_t *sz, unsigned char *tgt, unsigned int *len); +/* int domain_name_match(const unsigned char *ms, const unsigned char *md, int *os, int *od); */ +unsigned int domain_match(const unsigned char *ms, const unsigned char *md, unsigned int *os, unsigned int *od); +unsigned int compress_name(unsigned char *in, unsigned char *out, unsigned int offs, dlist *cb); +int a2ptrstr(pdnsd_ca *a, int tp, unsigned char *buf); +int read_hosts(const char *fn, unsigned char *rns, time_t ttl, unsigned flags, int aliases, char **errstr); + +const char *getrrtpname(int tp); +#if DEBUG>0 +const char *get_cname(int id); +const char *get_tname(int id); +const char *get_ename(int id); +#define DNSFLAGSMAXSTRSIZE (7*3+1) +char *dnsflags2str(dns_hdr_t *hdr, char *buf); +#endif + +#if DEBUG>=9 +void debug_dump_dns_msg(void *data, size_t len); +#define DEBUG_DUMP_DNS_MSG(d,l) {if(debug_p && global.verbosity>=9) debug_dump_dns_msg(d,l);} +#else +#define DEBUG_DUMP_DNS_MSG(d,l) +#endif + +#endif diff --git a/jni/pdnsd/src/dns_answer.c b/jni/pdnsd/src/dns_answer.c new file mode 100644 index 00000000..6a2a5b50 --- /dev/null +++ b/jni/pdnsd/src/dns_answer.c @@ -0,0 +1,2170 @@ +/* dns_answer.c - Receive and process incoming dns queries. + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +/* + * STANDARD CONFORMITY + * + * There are several standard conformity issues noted in the comments. + * Some additional comments: + * + * I always set RA but I ignore RD largely (in everything but CNAME recursion), + * not because it is not supported, but because I _always_ do a recursive + * resolve in order to be able to cache the results. + */ + +#include +#include "ipvers.h" +#include +#include +#include +#ifdef HAVE_SYS_POLL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" +#include "list.h" +#include "dns.h" +#include "dns_answer.h" +#include "dns_query.h" +#include "helpers.h" +#include "cache.h" +#include "error.h" +#include "debug.h" + + +/* + * This is for error handling to prevent spewing the log files. + * Maximums of different message types are set. + * Races do not really matter here, so no locks. + */ +#define TCP_MAX_ERRS 10 +#define UDP_MAX_ERRS 10 +#define MEM_MAX_ERRS 10 +#define THRD_MAX_ERRS 10 +#define MISC_MAX_ERRS 10 +static volatile unsigned long da_tcp_errs=0; +static volatile unsigned long da_udp_errs=0; +static volatile unsigned long da_mem_errs=0; +static volatile unsigned long da_thrd_errs=0; +#if DEBUG>0 +static volatile unsigned long da_misc_errs=0; +#endif +static volatile int procs=0; /* active query processes */ +static volatile int qprocs=0; /* queued query processes */ +static volatile unsigned long dropped=0,spawned=0; +static volatile unsigned thrid_cnt=0; +static pthread_mutex_t proc_lock = PTHREAD_MUTEX_INITIALIZER; + +#ifdef SOCKET_LOCKING +static pthread_mutex_t s_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + +typedef union { +#ifdef ENABLE_IPV4 +# if (TARGET==TARGET_LINUX) + struct in_pktinfo pi4; +# else + struct in_addr ai4; +# endif +#endif +#ifdef ENABLE_IPV6 + struct in6_pktinfo pi6; +#endif +} pkt_info_t; + + +typedef struct { + union { +#ifdef ENABLE_IPV4 + struct sockaddr_in sin4; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; +#endif + } addr; + + pkt_info_t pi; + + int sock; + int proto; + size_t len; + unsigned char buf[0]; /* Actual size determined by global.udpbufsize */ +} udp_buf_t; + + +/* ALLOCINITIALSIZE should be at least sizeof(dns_msg_t) = 2+12 */ +#define ALLOCINITIALSIZE 256 +/* This mask corresponds to a chunk size of 128 bytes. */ +#define ALLOCCHUNKSIZEMASK ((size_t)0x7f) + +typedef struct { + unsigned short qtype; + unsigned short qclass; + unsigned char query[0]; +} dns_queryel_t; + + +#define S_ANSWER 1 +#define S_AUTHORITY 2 +#define S_ADDITIONAL 3 + +typedef struct { + unsigned short tp,dlen; + unsigned char nm[0]; + /* unsigned char data[0]; */ +} sva_t; + + +/* + * Mark an additional record as added to avoid double records. + */ +static int sva_add(dlist *sva, const unsigned char *rhn, unsigned short tp, unsigned short dlen, void* data) +{ + if (sva) { + size_t rlen=rhnlen(rhn); + sva_t *st; + if (!(*sva=dlist_grow(*sva,sizeof(sva_t)+rlen+dlen))) { + return 0; + } + st=dlist_last(*sva); + st->tp=tp; + st->dlen=dlen; + memcpy(mempcpy(st->nm,rhn,rlen),data,dlen); + } + return 1; +} + +/* ans_ttl computes the ttl value to return to the client. + This is the ttl value stored in the cache entry minus the time + the cache entry has lived in the cache. + Local cache entries are an exception, they never "age". +*/ +inline static time_t ans_ttl(rr_set_t *rrset, time_t queryts) +{ + time_t ttl= rrset->ttl; + + if (!(rrset->flags&CF_LOCAL)) { + time_t tpassed= queryts - rrset->ts; + if(tpassed<0) tpassed=0; + ttl -= tpassed; + if(ttl<0) ttl=0; + } + return ttl; +} + +/* follow_cname_chain takes a cache entry and a buffer (must be at least DNSNAMEBUFSIZE bytes), + and copies the name indicated by the first cname record in the cache entry. + The name is returned in length-byte string notation. + follow_cname_chain returns 1 if a cname record is found, otherwise 0. +*/ +inline static int follow_cname_chain(dns_cent_t *c, unsigned char *name) +{ + rr_set_t *rrset=getrrset_CNAME(c); + rr_bucket_t *rr; + if (!rrset || !(rr=rrset->rrs)) + return 0; + PDNSD_ASSERT(rr->rdlen <= DNSNAMEBUFSIZE, "follow_cname_chain: record too long"); + memcpy(name,rr->data,rr->rdlen); + return 1; +} + + +/* + * Add data from a rr_bucket_t (as in cache) into a dns message in ans. Ans is grown + * to fit, sz is the old size of the packet (it is modified so at the end of the procedure + * it is the new size), type is the rr type and ltime is the time in seconds the record is + * old. + * cb is the buffer used for message compression. *cb should be NULL when you call compress_name + * or add_to_response the first time. + * It gets filled with a pointer to compression information that can be reused in subsequent calls + * to add_to_response. + * sect is the section (S_ANSWER, S_AUTHORITY or S_ADDITIONAL) in which the record + * belongs logically. Note that you still have to add the rrs in the right order (answer rrs first, + * then authority and last additional). + */ +static int add_rr(dns_msg_t **ans, size_t *sz, size_t *allocsz, + unsigned char *rrn, unsigned short type, uint32_t ttl, + unsigned int dlen, void *data, char section, unsigned *udp, dlist *cb) +{ + size_t osz= *sz; + unsigned int ilen,blen,rdlen; + unsigned char *rrht; + + { + unsigned int nlen; + unsigned char nbuf[DNSNAMEBUFSIZE]; + + if (!(nlen=compress_name(rrn,nbuf,*sz,cb))) + return 0; + + /* This buffer is usually over-allocated due to compression. + Never mind, just a few bytes, and the buffer is freed soon. */ + { + size_t newsz= dnsmsghdroffset + *sz + nlen + sizeof_rr_hdr_t + dlen; + if(newsz > *allocsz) { + /* Need to allocate more space. + To avoid frequent reallocs, we allocate + a multiple of a certain chunk size. */ + size_t newallocsz= (newsz+ALLOCCHUNKSIZEMASK)&(~ALLOCCHUNKSIZEMASK); + dns_msg_t *newans=(dns_msg_t *)pdnsd_realloc(*ans,newallocsz); + if (!newans) + return 0; + *ans=newans; + *allocsz=newallocsz; + } + } + memcpy((unsigned char *)(&(*ans)->hdr)+ *sz, nbuf, nlen); + *sz += nlen; + } + + /* the rr header will be filled in later. Just reserve some space for it. */ + rrht= ((unsigned char *)(&(*ans)->hdr)) + *sz; + *sz += sizeof_rr_hdr_t; + + switch (type) { + case T_CNAME: + case T_MB: + case T_MD: + case T_MF: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + if (!(rdlen=compress_name(((unsigned char *)data), ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + PDNSD_ASSERT(rdlen <= dlen, "T_CNAME/T_MB/...: got longer"); + *sz+=rdlen; + break; +#if IS_CACHED_MINFO || IS_CACHED_RP +#if IS_CACHED_MINFO + case T_MINFO: +#endif +#if IS_CACHED_RP + case T_RP: +#endif + if (!(rdlen=compress_name(((unsigned char *)data), ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + *sz+=rdlen; + ilen=rhnlen((unsigned char *)data); + PDNSD_ASSERT(rdlen <= ilen, "T_MINFO/T_RP: got longer"); + if (!(blen=compress_name(((unsigned char *)data)+ilen, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen+=blen; + PDNSD_ASSERT(rdlen <= dlen, "T_MINFO/T_RP: got longer"); + *sz+=blen; + break; +#endif + case T_MX: +#if IS_CACHED_AFSDB + case T_AFSDB: +#endif +#if IS_CACHED_RT + case T_RT: +#endif +#if IS_CACHED_KX + case T_KX: +#endif + PDNSD_ASSERT(dlen > 2, "T_MX/T_AFSDB/...: rr botch"); + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),(unsigned char *)data,2); + *sz+=2; + if (!(blen=compress_name(((unsigned char *)data)+2, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen=2+blen; + PDNSD_ASSERT(rdlen <= dlen, "T_MX/T_AFSDB/...: got longer"); + *sz+=blen; + break; + case T_SOA: + if (!(rdlen=compress_name(((unsigned char *)data), ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + *sz+=rdlen; + ilen=rhnlen((unsigned char *)data); + PDNSD_ASSERT(rdlen <= ilen, "T_SOA: got longer"); + if (!(blen=compress_name(((unsigned char *)data)+ilen, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen+=blen; + *sz+=blen; + ilen+=rhnlen(((unsigned char *)data)+ilen); + PDNSD_ASSERT(rdlen <= ilen, "T_SOA: got longer"); + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),((unsigned char *)data)+ilen,20); + rdlen+=20; + PDNSD_ASSERT(rdlen <= dlen, "T_SOA: rr botch"); + *sz+=20; + break; +#if IS_CACHED_PX + case T_PX: + PDNSD_ASSERT(dlen > 2, "T_PX: rr botch"); + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),(unsigned char *)data,2); + *sz+=2; + ilen=2; + if (!(blen=compress_name(((unsigned char *)data)+ilen, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen=2+blen; + *sz+=blen; + ilen+=rhnlen(((unsigned char *)data)+ilen); + PDNSD_ASSERT(rdlen <= ilen, "T_PX: got longer"); + if (!(blen=compress_name(((unsigned char *)data)+ilen, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen+=blen; + PDNSD_ASSERT(rdlen <= dlen, "T_PX: got longer"); + *sz+=blen; + break; +#endif +#if IS_CACHED_SRV + case T_SRV: + PDNSD_ASSERT(dlen > 6, "T_SRV: rr botch"); + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),(unsigned char *)data,6); + *sz+=6; + if (!(blen=compress_name(((unsigned char *)data)+6, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen=6+blen; + PDNSD_ASSERT(rdlen <= dlen, "T_SRV: got longer"); + *sz+=blen; + break; +#endif +#if IS_CACHED_NXT + case T_NXT: + if (!(blen=compress_name(((unsigned char *)data), ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen=blen; + *sz+=blen; + ilen=rhnlen((unsigned char *)data); + PDNSD_ASSERT(rdlen <= ilen, "T_NXT: got longer"); + PDNSD_ASSERT(dlen >= ilen, "T_NXT: rr botch"); + if (dlen > ilen) { + unsigned int wlen = dlen - ilen; + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),((unsigned char *)data)+ilen,wlen); + *sz+=wlen; + rdlen+=wlen; + } + break; +#endif +#if IS_CACHED_NAPTR + case T_NAPTR: + PDNSD_ASSERT(dlen > 4, "T_NAPTR: rr botch"); + ilen=4; + { + int j; + for (j=0;j<3;j++) { + ilen += ((unsigned)*(((unsigned char *)data)+ilen)) + 1; + PDNSD_ASSERT(dlen > ilen, "T_NAPTR: rr botch 2"); + } + } + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),((unsigned char *)data),ilen); + (*sz)+=ilen; + + if (!(blen=compress_name(((unsigned char *)data)+ilen, ((unsigned char *)(&(*ans)->hdr))+(*sz),*sz,cb))) + return 0; + rdlen=ilen+blen; + PDNSD_ASSERT(rdlen <= dlen, "T_NAPTR: got longer"); + *sz+=blen; + break; +#endif + default: + memcpy(((unsigned char *)(&(*ans)->hdr))+(*sz),((unsigned char *)data),dlen); + rdlen=dlen; + *sz+=dlen; + } + + if (udp && *sz>*udp && section==S_ADDITIONAL) /* only add the record if we do not increase the length over 512 */ + *sz=osz; /* (or possibly more if the request used EDNS) in additionals for udp answer. */ + else { + PUTINT16(type,rrht); + PUTINT16(C_IN,rrht); + PUTINT32(ttl,rrht); + PUTINT16(rdlen,rrht); + + switch (section) { + case S_ANSWER: + (*ans)->hdr.ancount=htons(ntohs((*ans)->hdr.ancount)+1); + break; + case S_AUTHORITY: + (*ans)->hdr.nscount=htons(ntohs((*ans)->hdr.nscount)+1); + break; + case S_ADDITIONAL: + (*ans)->hdr.arcount=htons(ntohs((*ans)->hdr.arcount)+1); + break; + } + } + + return 1; +} + +/* Add an OPT pseudo RR containing EDNS info. + Can only be added to the additional section! +*/ +int add_opt_pseudo_rr(dns_msg_t **ans, size_t *sz, size_t *allocsz, + unsigned short udpsize, unsigned short rcode, + unsigned short ednsver, unsigned short Zflags) +{ + unsigned char *ptr; + size_t newsz= dnsmsghdroffset + *sz + sizeof_opt_pseudo_rr; + if(newsz > *allocsz) { + /* Need to allocate more space. + To avoid frequent reallocs, we allocate + a multiple of a certain chunk size. */ + size_t newallocsz= (newsz+ALLOCCHUNKSIZEMASK)&(~ALLOCCHUNKSIZEMASK); + dns_msg_t *newans=(dns_msg_t *)pdnsd_realloc(*ans,newallocsz); + if (!newans) + return 0; + *ans=newans; + *allocsz=newallocsz; + } + + ptr= ((unsigned char *)(&(*ans)->hdr)) + *sz; + *ptr++ = 0; /* Empty name */ + PUTINT16(T_OPT,ptr); /* type field */ + PUTINT16(udpsize,ptr); /* class field */ + *ptr++ = rcode>>4; /* 4 byte TTL field */ + *ptr++ = ednsver; + PUTINT16(Zflags,ptr); + PUTINT16(0,ptr); /* rdlen field */ + /* Empty RDATA. */ + + *sz += sizeof_opt_pseudo_rr; + /* Increment arcount field in dns header. */ + (*ans)->hdr.arcount = htons(ntohs((*ans)->hdr.arcount)+1); + return 1; +} + +/* Remove the last entry in the additional section, + assuming it is an OPT pseudo RR of fixed size. + Returns the new message size if successful, or + zero if an inconsistency is detected. +*/ +size_t remove_opt_pseudo_rr(dns_msg_t *ans, size_t sz) +{ + uint16_t acnt=ntohs(ans->hdr.arcount), type; + unsigned char *ptr; + /* First do some sanity checks. */ + if(!(acnt>0 && sz >= sizeof(dns_hdr_t)+sizeof_opt_pseudo_rr)) + return 0; + sz -= sizeof_opt_pseudo_rr; + ptr= ((unsigned char *)(&ans->hdr)) + sz; + if(*ptr++) + return 0; /* Name must be empty. */ + GETINT16(type,ptr); + if(type!=T_OPT) + return 0; /* RR type must be OPT. */ + /* Decrement arcount field in dns header. */ + ans->hdr.arcount = htons(acnt-1); + return sz; +} + +typedef struct rre_s { + unsigned short tp; + unsigned short tsz; /* Size of tnm field */ + uint32_t ttl; /* ttl of the record in the answer (if tp==T_NS or T_SOA) */ + unsigned char tnm[0]; /* Name for the domain a record refers to */ + /* unsigned char nm[0]; */ /* Name of the domain the record is for (if tp==T_NS or T_SOA) */ +} rr_ext_t; + + +/* types for the tp field */ +/* #define RRETP_NS T_NS */ /* For name server: add to authority, add address to additional. */ +/* #define RRETP_SOA T_SOA */ /* For SOA record: add to authority. */ +#define RRETP_ADD 0 /* For other records: add the address of buf to additional */ + +static int add_ar(dlist *ar,unsigned short tp, unsigned short tsz,void *tnm,unsigned char *nm, uint32_t ttl) +{ + rr_ext_t *re; + unsigned char *p; + size_t nmsz=0,size=sizeof(rr_ext_t)+tsz; + if(tp==T_NS || tp==T_SOA) { + nmsz=rhnlen(nm); + size += nmsz; + } + if (!(*ar=dlist_grow(*ar,size))) + return 0; + re=dlist_last(*ar); + re->tp=tp; + re->tsz=tsz; + re->ttl=ttl; + p=mempcpy(re->tnm,tnm,tsz); + if(tp==T_NS || tp==T_SOA) { + memcpy(p,nm,nmsz); + } + return 1; +} + + +/* Select a random rr record from a list. */ +inline static rr_bucket_t *randrr(rr_bucket_t *rrb) +{ + rr_bucket_t *rr; + unsigned cnt=0; + + /* In order to have an equal chance for each record to be selected, we have to count first. */ + for(rr=rrb; rr; rr=rr->next) ++cnt; + + /* We do not use the pdnsd random functions (these might use /dev/urandom if the user is paranoid, + * and we do not need any good PRNG here). */ + if(cnt) for(cnt=random()%cnt; cnt; --cnt) rrb=rrb->next; + + return rrb; +} + +#if IS_CACHED_SRV +#define AR_NUM 6 +#else +#define AR_NUM 5 +#endif +static const int ar_recs[AR_NUM]={T_NS, T_MD, T_MF, T_MB, T_MX +#if IS_CACHED_SRV + ,T_SRV +#endif +}; +/* offsets from record data start to server name */ +static const int ar_offs[AR_NUM]={0,0,0,0,2 +#if IS_CACHED_SRV + ,6 +#endif +}; + +/* This adds an rrset, optionally randomizing the first element it adds. + * if that is done, all rrs after the randomized one appear in order, starting from + * that one and wrapping over if needed. */ +static int add_rrset(dns_msg_t **ans, size_t *sz, size_t *allocsz, + unsigned char *rrn, unsigned tp, time_t queryts, + dns_cent_t *cached, unsigned *udp, dlist *cb, dlist *sva, dlist *ar) +{ + rr_set_t *crrset=getrrset(cached,tp); + + if (crrset && crrset->rrs) { + rr_bucket_t *b; + rr_bucket_t *first=NULL; /* Initialized to inhibit compiler warning */ + int i; + short rnd_recs=global.rnd_recs; + + b=crrset->rrs; + if (rnd_recs) b=first=randrr(crrset->rrs); + + while (b) { + if (!add_rr(ans, sz, allocsz, rrn, tp, ans_ttl(crrset,queryts), + b->rdlen, b->data, S_ANSWER, udp, cb)) + return 0; + if (tp==T_NS || tp==T_A || tp==T_AAAA) { + /* mark it as added */ + if (!sva_add(sva,rrn,tp,b->rdlen,b->data)) + return 0; + } + /* Mark for additional address records. XXX: this should be a more effective algorithm; at least the list is small */ + for (i=0;irdlen-ar_offs[i],((unsigned char *)(b->data))+ar_offs[i], + ucharp "", 0)) + return 0; + break; + } + } + b=b->next; + if (rnd_recs) { + if(!b) b=crrset->rrs; /* wraparound */ + if(b==first) break; + } + } + } + return 1; +} + +/* + * Add the fitting elements of the cached record to the message in ans, where ans + * is grown to fit, sz is the size of the packet and is modified to be the new size. + * The query is in qe. + * cb is the buffer used for message compression. *cb should be NULL if you call add_to_response + * the first time. It gets filled with a pointer to compression information that can be + * reused in subsequent calls to add_to_response. + */ +static int add_to_response(dns_msg_t **ans, size_t *sz, size_t *allocsz, + unsigned char *rrn, unsigned qtype, time_t queryts, + dns_cent_t *cached, unsigned *udp, dlist *cb, dlist *sva, dlist *ar) +{ + /* First of all, unless we have records of qtype, add cnames. + Well, actually, there should be at max one cname. */ + if (qtype!=T_CNAME && qtype!=QT_ALL && !(qtype>=T_MIN && qtype<=T_MAX && have_rr(cached,qtype))) + if (!add_rrset(ans, sz, allocsz, rrn, T_CNAME, queryts, cached, udp, cb, sva, ar)) + return 0; + + /* We need no switch for qclass, since we already have filtered packets we cannot understand */ + if (qtype==QT_AXFR || qtype==QT_IXFR) { + /* I do not know what to do in this case. Since we do not maintain zones (and since we are + no master server, so it is not our task), I just return an error message. If anyone + knows how to do this better, please notify me. + Anyway, this feature is rarely used in client communication, and there is no need for + other name servers to ask pdnsd. Btw: many bind servers reject an ?XFR query for security + reasons. */ + return 0; + } else if (qtype==QT_MAILB) { + if (!add_rrset(ans, sz, allocsz, rrn, T_MB, queryts, cached, udp, cb, sva, ar)) + return 0; + if (!add_rrset(ans, sz, allocsz, rrn, T_MG, queryts, cached, udp, cb, sva, ar)) + return 0; + if (!add_rrset(ans, sz, allocsz, rrn, T_MR, queryts, cached, udp, cb, sva, ar)) + return 0; + } else if (qtype==QT_MAILA) { + if (!add_rrset(ans, sz, allocsz, rrn, T_MD, queryts, cached, udp, cb, sva, ar)) + return 0; + if (!add_rrset(ans, sz, allocsz, rrn, T_MF, queryts, cached, udp, cb, sva, ar)) + return 0; + } else if (qtype==QT_ALL) { + int i, n= NRRITERLIST(cached); + const unsigned short *iterlist= RRITERLIST(cached); + for (i=0; i=T_MIN && qtype<=T_MAX) { + if (!add_rrset(ans, sz, allocsz, rrn, qtype, queryts, cached, udp, cb, sva, ar)) + return 0; + } else /* Shouldn't get here. */ + return 0; +#if 0 + if (!ntohs((*ans)->hdr.ancount)) { + /* Add a SOA if we have one and no other records are present in the answer. + * This is to aid caches so that they have a ttl. */ + if (!add_rrset(ans, sz, allocsz, rrn, T_SOA , queryts, cached, udp, cb, sva, ar)) + return 0; + } +#endif + return 1; +} + +/* + * Add an additional + */ +static int add_additional_rr(dns_msg_t **ans, size_t *rlen, size_t *allocsz, + unsigned char *rhn, unsigned tp, time_t ttl, + unsigned dlen, void *data, int sect, unsigned *udp, dlist *cb, dlist *sva) +{ + sva_t *st; + + /* Check if already added; no double additionals */ + for (st=dlist_first(*sva); st; st=dlist_next(st)) { + if (st->tp==tp && rhnicmp(st->nm,rhn) && st->dlen==dlen && + (memcmp(skiprhn(st->nm),data, dlen)==0)) + { + return 1; + } + } + /* add_rr will do nothing when udp!=NULL and sz>*udp. */ + if(!add_rr(ans, rlen, allocsz, rhn, tp, ttl, dlen, data, sect, udp, cb)) + return 0; + /* mark it as added */ + if (!sva_add(sva,rhn,tp,dlen,data)) + return 0; + + return 1; +} + +/* + * Add one or more additionals from an rr bucket. + */ +static int add_additional_rrs(dns_msg_t **ans, size_t *rlen, size_t *allocsz, + unsigned char *rhn, unsigned tp, time_t ttl, + rr_bucket_t *rrb, int sect, unsigned *udp, dlist *cb, dlist *sva) +{ + rr_bucket_t *rr; + rr_bucket_t *first=NULL; /* Initialized to inhibit compiler warning */ + short rnd_recs=global.rnd_recs; + + rr=rrb; + if (rnd_recs) rr=first=randrr(rrb); + + while(rr) { + if (!add_additional_rr(ans, rlen, allocsz, rhn, tp, ttl, rr->rdlen,rr->data, sect, udp, cb, sva)) + return 0; + rr=rr->next; + if (rnd_recs) { + if(!rr) rr=rrb; /* wraparound */ + if(rr==first) break; + } + } + return 1; +} + +/* + * The code below actually handles A and AAAA additionals. + */ +static int add_additional_a(dns_msg_t **ans, size_t *rlen, size_t *allocsz, + unsigned char *rhn, time_t queryts, + unsigned *udp, dlist *cb, dlist *sva) +{ + dns_cent_t *ae; + int retval = 1; + + if ((ae=lookup_cache(rhn,NULL))) { + rr_set_t *rrset; rr_bucket_t *rr; + rrset=getrrset_A(ae); + if (rrset && (rr=rrset->rrs)) + if (!add_additional_rrs(ans, rlen, allocsz, + rhn, T_A, ans_ttl(rrset,queryts), + rr, S_ADDITIONAL, udp, cb, sva)) + retval = 0; + +#if IS_CACHED_AAAA + if(retval) { + rrset=getrrset_AAAA(ae); + if (rrset && (rr=rrset->rrs)) + if (!add_additional_rrs(ans, rlen, allocsz, + rhn, T_AAAA, ans_ttl(rrset,queryts), + rr, S_ADDITIONAL, udp, cb, sva)) + retval = 0; + } +#endif + free_cent(ae DBG1); + pdnsd_free(ae); + } + return retval; +} + +/* + * Compose an answer message for the decoded query in ql, hdr is the header of the dns request + * rlen is set to be the answer length. + * If udp is not NULL, *udp indicates the max length the dns response may have. + */ +static dns_msg_t *compose_answer(llist *ql, dns_hdr_t *hdr, size_t *rlen, edns_info_t *ednsinfo, unsigned *udp, int *rcodep) +{ + unsigned short rcode=RC_OK, aa=1; + dlist cb=NULL; + dlist sva=NULL; + dlist ar=NULL; + time_t queryts=time(NULL); + dns_queryel_t *qe; + dns_msg_t *ans; + size_t allocsz= ALLOCINITIALSIZE; + dns_cent_t *cached; + + ans=(dns_msg_t *)pdnsd_malloc(allocsz); + if (!ans) + goto return_ans; + ans->hdr.id=hdr->id; + ans->hdr.qr=QR_RESP; + ans->hdr.opcode=OP_QUERY; + ans->hdr.aa=0; + ans->hdr.tc=0; /* If tc is needed, it is set when the response is sent in udp_answer_thread. */ + ans->hdr.rd=hdr->rd; + ans->hdr.ra=1; + ans->hdr.z=0; + ans->hdr.ad=0; + ans->hdr.cd=0; + ans->hdr.rcode=rcode; + ans->hdr.qdcount=0; /* this is first filled in and will be modified */ + ans->hdr.ancount=0; + ans->hdr.nscount=0; + ans->hdr.arcount=0; + + *rlen=sizeof(dns_hdr_t); + /* first, add the query to the response */ + for (qe=llist_first(ql); qe; qe=llist_next(qe)) { + unsigned int qclen; + size_t newsz= dnsmsghdroffset + *rlen + rhnlen(qe->query) + 4; + if(newsz > allocsz) { + /* Need to allocate more space. + To avoid frequent reallocs, we allocate + a multiple of a certain chunk size. */ + size_t newallocsz= (newsz+ALLOCCHUNKSIZEMASK)&(~ALLOCCHUNKSIZEMASK); + dns_msg_t *newans=(dns_msg_t *)pdnsd_realloc(ans,newallocsz); + if (!newans) + goto error_ans; + ans=newans; + allocsz=newallocsz; + } + + { + unsigned char *p = ((unsigned char *)&ans->hdr) + *rlen; + /* the first name occurrence will not be compressed, + but the offset needs to be stored for future compressions */ + if (!(qclen=compress_name(qe->query,p,*rlen,&cb))) + goto error_ans; + p += qclen; + PUTINT16(qe->qtype,p); + PUTINT16(qe->qclass,p); + } + *rlen += qclen+4; + ans->hdr.qdcount=htons(ntohs(ans->hdr.qdcount)+1); + } + + /* Barf if we get a query we cannot answer */ + for (qe=llist_first(ql); qe; qe=llist_next(qe)) { + if ((PDNSD_NOT_CACHED_TYPE(qe->qtype) && + (qe->qtype!=QT_MAILB && qe->qtype!=QT_MAILA && qe->qtype!=QT_ALL)) || + (qe->qclass!=C_IN && qe->qclass!=QC_ALL)) + { + DEBUG_MSG("Unsupported QTYPE or QCLASS.\n"); + ans->hdr.rcode=rcode=RC_NOTSUPP; + goto cleanup_return; + } + } + + /* second, the answer section */ + for (qe=llist_first(ql); qe; qe=llist_next(qe)) { + int hops; + unsigned char qname[DNSNAMEBUFSIZE]; + + rhncpy(qname,qe->query); + /* look if we have a cached copy. otherwise, perform a nameserver query. Same with timeout */ + hops=MAX_HOPS; + do { + int rc; + unsigned char c_soa=cundef; + if ((rc=dns_cached_resolve(qname,qe->qtype, &cached, MAX_HOPS,queryts,&c_soa))!=RC_OK) { + ans->hdr.rcode=rcode=rc; + if(rc==RC_NAMEERR) { + if(c_soa!=cundef) { + /* Try to add a SOA record to the authority section. */ + unsigned scnt=rhnsegcnt(qname); + if(c_soaflags&CF_NEGATIVE)) { + rr_bucket_t *rr; + for(rr=rrset->rrs; rr; rr=rr->next) { + if (!add_rr(&ans,rlen,&allocsz,cached->qname,T_SOA,ans_ttl(rrset,queryts), + rr->rdlen,rr->data,S_AUTHORITY,udp,&cb)) + goto error_cached; + } + } + free_cent(cached DBG1); + pdnsd_free(cached); + } + } + + /* Possibly add an OPT pseudo-RR to the additional section. */ + if(ednsinfo) { + if(!add_opt_pseudo_rr(&ans, rlen, &allocsz, global.udpbufsize, rcode, 0,0)) + goto error_ans; + } + } + goto cleanup_return; + } + if(!(cached->flags&DF_LOCAL)) + aa=0; + + if (!add_to_response(&ans,rlen,&allocsz,qname,qe->qtype,queryts,cached,udp,&cb,&sva,&ar)) + goto error_cached; + if (hdr->rd && qe->qtype!=T_CNAME && qe->qtype!=QT_ALL && + !(qe->qtype>=T_MIN && qe->qtype<=T_MAX && have_rr(cached,qe->qtype)) && + follow_cname_chain(cached,qname)) + /* The rd bit is set and the response does not contain records of the requested type, + * but the response does contain a cname, so repeat the inquiry with the cname. + * add_to_response() has already added the cname to the response. + * Because of follow_cname_chain(), qname now contains the last cname in the chain. */ + ; + else { + /* maintain a list (ar) for authority records: We will add every name server that was + listed as authoritative in a reply we received (and only those) to this list. + This list will be used to fill the authority and additional sections of our own reply. + We only do this for the last record in a cname chain, to prevent answer bloat. */ + rr_set_t *rrset; + int rretp=T_NS; + if((qe->qtype>=T_MIN && qe->qtype<=T_MAX && !have_rr(cached,qe->qtype)) || + (qe->qtype==QT_MAILB && !have_rr_MB(cached) && !have_rr_MG(cached) && !have_rr_MR(cached)) || + (qe->qtype==QT_MAILA && !have_rr_MD(cached) && !have_rr_MF(cached))) + { + /* no record of requested type in the answer section. */ + rretp=T_SOA; + } + rrset=getrrset(cached,rretp); + if(rrset && (rrset->flags&CF_NEGATIVE)) + rrset=NULL; + if(!rrset) { + /* Try to find a name server higher up the hierarchy . + */ + dns_cent_t *prev=cached; + unsigned scnt=rhnsegcnt(prev->qname); + unsigned tcnt=(rretp==T_NS?prev->c_ns:prev->c_soa); + if((cached=lookup_cache((tcnt!=cundef && tcntqname,scnt-tcnt):prev->qname,NULL))) { + rrset=getrrset(cached,rretp); + if(rrset && (rrset->flags&CF_NEGATIVE)) + rrset=NULL; + } + if(!rrset && (prev->flags&DF_LOCAL)) { + unsigned char *nm=getlocalowner(prev->qname,rretp); + if(nm) { + if(cached) { + free_cent(cached DBG1); + pdnsd_free(cached); + } + if((cached=lookup_cache(nm,NULL))) + rrset=getrrset(cached,rretp); + } + } + free_cent(prev DBG1); + pdnsd_free(prev); + } + if (rrset) { + rr_bucket_t *rr; + for (rr=rrset->rrs; rr; rr=rr->next) { + if (!add_ar(&ar, rretp, rr->rdlen,rr->data, cached->qname, + ans_ttl(rrset,queryts))) + goto error_cached; + } + } + hops=0; /* this will break the loop */ + } + if(cached) { + free_cent(cached DBG1); + pdnsd_free(cached); + } + } while (--hops>=0); + } + + { + rr_ext_t *rre; + /* Add the authority section */ + for (rre=dlist_first(ar); rre; rre=dlist_next(rre)) { + if (rre->tp == T_NS || rre->tp == T_SOA) { + unsigned char *nm = rre->tnm + rre->tsz; + if (!add_additional_rr(&ans, rlen, &allocsz, + nm, rre->tp, rre->ttl, rre->tsz, rre->tnm, + S_AUTHORITY, udp, &cb, &sva)) + { + goto error_ans; + } + } + } + + /* Add the additional section, but only if we stay within the UDP buffer limit. */ + /* If a pseudo RR doesn't fit, nothing else will. */ + if(!(udp && *rlen+sizeof_opt_pseudo_rr>*udp)) { + + /* Possibly add an OPT pseudo-RR to the additional section. */ + if(ednsinfo) { + if(!add_opt_pseudo_rr(&ans, rlen, &allocsz, global.udpbufsize, rcode, 0,0)) + goto error_ans; + } + + /* now add the name server addresses */ + for (rre=dlist_first(ar); rre; rre=dlist_next(rre)) { + if (rre->tp == T_NS || rre->tp == RRETP_ADD) { + if (!add_additional_a(&ans, rlen, &allocsz, + rre->tnm, queryts, udp, &cb, &sva)) + goto error_ans; + } + } + } + } + if (aa) + ans->hdr.aa=1; + goto cleanup_return; + + /* You may not like goto's, but here we avoid lots of code duplication. */ +error_cached: + free_cent(cached DBG1); + pdnsd_free(cached); +error_ans: + pdnsd_free(ans); + ans=NULL; +cleanup_return: + dlist_free(ar); + dlist_free(sva); + dlist_free(cb); +return_ans: + if(rcodep) *rcodep=rcode; + return ans; +} + +/* + * Decode the query (the query messgage is in data and rlen bytes long) into a dlist. + * XXX: data needs to be aligned. + * The return value can be RC_OK or RC_TRUNC, in which case the (partially) constructed list is + * returned in qp, or something else (RC_FORMAT or RC_SERVFAIL), in which case no list is returned. + * + * *ptrrem will be assigned the address just after the questions sections in the message, and *lenrem + * the remaining message length after the questions section. These values are only meaningful if the + * return value is RC_OK. + */ +static int decode_query(unsigned char *data, size_t rlen, unsigned char **ptrrem, size_t *lenrem, llist *qp) +{ + int i,res=RC_OK; + dns_hdr_t *hdr=(dns_hdr_t *)data; /* aligned, so no prob. */ + unsigned char *ptr=(unsigned char *)(hdr+1); + size_t sz= rlen - sizeof(dns_hdr_t); + uint16_t qdcount=ntohs(hdr->qdcount); + + llist_init(qp); + for (i=0; iqtype,ptr); + GETINT16(qe->qclass,ptr); + sz-=4; + memcpy(qe->query,qbuf,qlen); + } + + if(ptrrem) *ptrrem=ptr; + if(lenrem) *lenrem=sz; + return res; +} + + +/* Scan the additional section of a query message for an OPT pseudo RR. + data and rlen are as in decode_query(). Note in particular that data needs to be aligned! + ptr should point the beginning of the additional section, sz should contain the + length of this remaining part of the message and numrr the number of resource records in the section. + *numopt is incremented with the number of OPT RRs found (should be at most one). + + Note that a return value of RC_OK means the additional section was parsed without errors, not that + an OPT pseudo RR was found! Check the value of *numopt for the latter. + + The structure pointed to by ep is filled with the information of the first OPT pseudo RR found, + but only if *numopt was set to zero before the call. +*/ +static int decode_query_additional(unsigned char *data, size_t rlen, unsigned char *ptr, size_t sz, int numrr, + int *numopt, edns_info_t *ep) +{ + int i, res; + + for (i=0; i0 + if(nmbuf[0]!=0) { + DEBUG_MSG("decode_query_additional: name in OPT record not empty!\n"); + } +#endif + ep->udpsize= class; + ep->rcode= ((uint16_t)ttlp[0]<<4) | ((dns_hdr_t *)data)->rcode; + ep->version= ttlp[1]; + ep->do_flg= (ttlp[2]>>7)&1; +#if DEBUG>0 + if(debug_p) { + unsigned int Zflags= ((uint16_t)ttlp[2]<<8) | ttlp[3]; + if(Zflags & 0x7fff) { + DEBUG_MSG("decode_query_additional: Z field contains unknown nonzero bits (%04x).\n", + Zflags); + } + if(rdlen) { + DEBUG_MSG("decode_query_additional: RDATA field in OPT record not empty!\n"); + } + } +#endif + } + else { + DEBUG_MSG("decode_query_additional: ingnoring surplus OPT record.\n"); + } + } + else { + DEBUG_MSG("decode_query_additional: ignoring record of type %s (%d).\n", + getrrtpname(type), type); + } + + /* Skip RDATA field. */ + sz -= rdlen; + ptr += rdlen; + } + + return RC_OK; +} + +/* Make a dns error reply message + * Id is the query id and still in network order. + * op is the opcode to fill in, rescode - name says it all. + */ +static void mk_error_reply(unsigned short id, unsigned short opcode,unsigned short rescode,dns_hdr_t *rep) +{ + rep->id=id; + rep->qr=QR_RESP; + rep->opcode=opcode; + rep->aa=0; + rep->tc=0; + rep->rd=0; + rep->ra=1; + rep->z=0; + rep->ad=0; + rep->cd=0; + rep->rcode=rescode; + rep->qdcount=0; + rep->ancount=0; + rep->nscount=0; + rep->arcount=0; +} + +/* + * Analyze and answer the query in data. The answer is returned. rlen is at call the query length and at + * return the length of the answer. You have to free the answer after sending it. + */ +static dns_msg_t *process_query(unsigned char *data, size_t *rlenp, unsigned *udp, int *rcodep) +{ + size_t rlen= *rlenp; + int res; + dns_hdr_t *hdr; + llist ql; + dns_msg_t *ans; + edns_info_t ednsinfo= {0}, *ednsinfop= NULL; + + DEBUG_MSG("Received query (msg len=%u).\n", (unsigned int)rlen); + DEBUG_DUMP_DNS_MSG(data, rlen); + + /* + * We will ignore all records that come with a query, except for the actual query records, + * and possible OPT pseudo RRs in the addtional section. + * We will send back the query in the response. We will reject all non-queries, and + * some not supported thingies. + * If anyone notices behaviour that is not in standard conformance, please notify me! + */ + hdr=(dns_hdr_t *)data; + if (rlen<2) { + DEBUG_MSG("Message too short.\n"); + return NULL; /* message too short: no id provided. */ + } + if (rlenqr!=QR_QUERY) { + DEBUG_MSG("The QR bit indicates this is a response, not a query.\n"); + return NULL; /* RFC says: discard */ + } + if (hdr->opcode!=OP_QUERY) { + DEBUG_MSG("Not a standard query (opcode=%u).\n",hdr->opcode); + res=RC_NOTSUPP; + goto error_reply; + } +#if DEBUG>0 + if(debug_p) { + char flgsbuf[DNSFLAGSMAXSTRSIZE]; + dnsflags2str(hdr, flgsbuf); + if(flgsbuf[0]) { + DEBUG_MSG("Flags:%s\n", flgsbuf); + } + } +#endif + if (hdr->z!=0) { + DEBUG_MSG("Malformed query (nonzero Z bit).\n"); + res=RC_FORMAT; + goto error_reply; + } + if (hdr->rcode!=RC_OK) { + DEBUG_MSG("Bad rcode(%u).\n",hdr->rcode); + return NULL; /* discard (may cause error storms) */ + } + + if (hdr->ancount) { + DEBUG_MSG("Query has a non-empty answer section!\n"); + res=RC_FORMAT; + goto error_reply; + } + + if (hdr->nscount) { + DEBUG_MSG("Query has a non-empty authority section!\n"); + res=RC_FORMAT; + goto error_reply; + } + +#if 0 + /* The following only makes sense if we completely disallow + Extension Mechanisms for DNS (RFC 2671). */ + if (hdr->arcount) { + DEBUG_MSG("Query has a non-empty additional section!\n"); + res=RC_FORMAT; + goto error_reply; + } +#endif + { + unsigned char *ptr; + size_t sz; + uint16_t arcount; + res=decode_query(data,rlen,&ptr,&sz,&ql); + if(res!=RC_OK) { + if(res==RC_TRUNC) { + if(!hdr->tc || llist_isempty(&ql)) { + res=RC_FORMAT; + goto free_ql_error_reply; + } + } + else + goto error_reply; + } + + if ((arcount=ntohs(hdr->arcount))) { + int numoptrr= 0; + DEBUG_MSG("Query has a non-empty additional section: " + "checking for OPT pseudo-RR.\n"); + if(res==RC_TRUNC) { + DEBUG_MSG("Additional section cannot be read due to truncation!\n"); + res=RC_FORMAT; + goto free_ql_error_reply; + } + res=decode_query_additional(data,rlen,ptr,sz,arcount, &numoptrr, &ednsinfo); + if(!(res==RC_OK || (res==RC_TRUNC && hdr->tc))) { + res=RC_FORMAT; + goto free_ql_error_reply; + } + if(numoptrr) { +#if DEBUG>0 + if(numoptrr!=1) { + DEBUG_MSG("Additional section in query contains %d OPT pseudo-RRs!\n", numoptrr); + } +#endif + if(ednsinfo.version!=0) { + DEBUG_MSG("Query contains unsupported EDNS version %d!\n", ednsinfo.version); + res=RC_BADVERS; + goto free_ql_error_reply; + } + if(ednsinfo.rcode!=0) { + DEBUG_MSG("Query contains non-zero EDNS rcode (%d)!\n", ednsinfo.rcode); + res=RC_FORMAT; + goto free_ql_error_reply; + } + DEBUG_MSG("Query contains OPT pseudosection: EDNS udp size = %u, flag DO=%u\n", + ednsinfo.udpsize, ednsinfo.do_flg); + ednsinfop = &ednsinfo; + if(udp && ednsinfo.udpsize>UDP_BUFSIZE) { + unsigned udpbufsize = global.udpbufsize; + if(udpbufsize > ednsinfo.udpsize) + udpbufsize = ednsinfo.udpsize; + *udp = udpbufsize; + } + } + } + } + +#if DEBUG>0 + if (debug_p) { + if(!llist_isempty(&ql)) { + dns_queryel_t *qe; + DEBUG_MSG("Questions are:\n"); + for (qe=llist_first(&ql); qe; qe=llist_next(qe)) { + DEBUG_RHN_MSG("\tqc=%s (%u), qt=%s (%u), query=\"%s\"\n", + get_cname(qe->qclass),qe->qclass,get_tname(qe->qtype),qe->qtype,RHN2STR(qe->query)); + } + } + else { + DEBUG_MSG("Query contains no questions.\n"); + } + } +#endif + + if (llist_isempty(&ql)) { + res=RC_FORMAT; + goto error_reply; + } + if (!(ans=compose_answer(&ql, hdr, rlenp, ednsinfop, udp, rcodep))) { + /* An out of memory condition or similar could cause NULL output. Send failure notification */ + res=RC_SERVFAIL; + goto free_ql_error_reply; + } + llist_free(&ql); + return ans; + + free_ql_error_reply: + llist_free(&ql); + error_reply: + *rlenp=sizeof(dns_hdr_t); + { + size_t allocsz = sizeof(dns_msg_t); + if(res&~0xf) + allocsz += sizeof_opt_pseudo_rr; + ans= (dns_msg_t *)pdnsd_malloc(allocsz); + if (ans) { + mk_error_reply(hdr->id,rlen>=3?hdr->opcode:OP_QUERY,res,&ans->hdr); + if(res&~0xf) + add_opt_pseudo_rr(&ans,rlenp,&allocsz, + global.udpbufsize,res,0,0); + } + else if (++da_mem_errs<=MEM_MAX_ERRS) { + log_error("Out of memory in query processing."); + } + } + if(rcodep) *rcodep= res; + return ans; +} + +/* + * Called by *_answer_thread exit handler to clean up process count. + */ +inline static void decrease_procs() +{ + + pthread_mutex_lock(&proc_lock); + procs--; + qprocs--; + pthread_mutex_unlock(&proc_lock); +} + +static void udp_answer_thread_cleanup(void *data) +{ + pdnsd_free(data); + decrease_procs(); +} + +/* + * A thread opened to answer a query transmitted via udp. Data is a pointer to the structure udp_buf_t that + * contains the received data and various other parameters. + * After the query is answered, the thread terminates + * XXX: data must point to a correctly aligned buffer + */ +static void *udp_answer_thread(void *data) +{ + struct msghdr msg; + struct iovec v; + struct cmsghdr *cmsg; +#if defined(SRC_ADDR_DISC) + char ctrl[CMSG_SPACE(sizeof(pkt_info_t))]; +#endif + size_t rlen=((udp_buf_t *)data)->len; + unsigned udpmaxrespsize = UDP_BUFSIZE; + /* XXX: process_query is assigned to this, this mallocs, so this points to aligned memory */ + dns_msg_t *resp; + int rcode; + unsigned thrid; + pthread_cleanup_push(udp_answer_thread_cleanup, data); + THREAD_SIGINIT; + + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + pdnsd_exit(); + } + } + + for(;;) { + pthread_mutex_lock(&proc_lock); + if (procs0 + if(debug_p) { + int err; + if ((err=pthread_setspecific(thrid_key, &thrid)) != 0) { + if(++da_misc_errs<=MISC_MAX_ERRS) + log_error("pthread_setspecific failed: %s",strerror(err)); + /* pdnsd_exit(); */ + } + } +#endif + + if (!(resp=process_query(((udp_buf_t *)data)->buf,&rlen,&udpmaxrespsize,&rcode))) { + /* + * A return value of NULL is a fatal error that prohibits even the sending of an error message. + * logging is already done. Just exit the thread now. + */ + pthread_exit(NULL); /* data freed by cleanup handler */ + } + pthread_cleanup_push(free, resp); + if (rlen>udpmaxrespsize) { + rlen=udpmaxrespsize; + resp->hdr.tc=1; /*set truncated bit*/ + } + DEBUG_MSG("Outbound msg len %li, tc=%u, rc=\"%s\"\n",(long)rlen,resp->hdr.tc,get_ename(rcode)); + + v.iov_base=(char *)&resp->hdr; + v.iov_len=rlen; + msg.msg_iov=&v; + msg.msg_iovlen=1; +#if (TARGET!=TARGET_CYGWIN) +#if defined(SRC_ADDR_DISC) + msg.msg_control=ctrl; + msg.msg_controllen=sizeof(ctrl); +#else + msg.msg_control=NULL; + msg.msg_controllen=0; +#endif + msg.msg_flags=0; /* to avoid warning message by Valgrind */ +#endif + +#ifdef ENABLE_IPV4 + if (run_ipv4) { + + msg.msg_name=&((udp_buf_t *)data)->addr.sin4; + msg.msg_namelen=sizeof(struct sockaddr_in); +# if defined(SRC_ADDR_DISC) +# if (TARGET==TARGET_LINUX) + ((udp_buf_t *)data)->pi.pi4.ipi_spec_dst=((udp_buf_t *)data)->pi.pi4.ipi_addr; + cmsg=CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len=CMSG_LEN(sizeof(struct in_pktinfo)); + cmsg->cmsg_level=SOL_IP; + cmsg->cmsg_type=IP_PKTINFO; + memcpy(CMSG_DATA(cmsg),&((udp_buf_t *)data)->pi.pi4,sizeof(struct in_pktinfo)); + msg.msg_controllen=CMSG_SPACE(sizeof(struct in_pktinfo)); +# else + cmsg=CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len=CMSG_LEN(sizeof(struct in_addr)); + cmsg->cmsg_level=IPPROTO_IP; + cmsg->cmsg_type=IP_RECVDSTADDR; + memcpy(CMSG_DATA(cmsg),&((udp_buf_t *)data)->pi.ai4,sizeof(struct in_addr)); + msg.msg_controllen=CMSG_SPACE(sizeof(struct in_addr)); +# endif +# endif +# if DEBUG>0 + { + char buf[ADDRSTR_MAXLEN]; + + DEBUG_MSG("Answering to: %s", inet_ntop(AF_INET,&((udp_buf_t *)data)->addr.sin4.sin_addr,buf,ADDRSTR_MAXLEN)); +# if defined(SRC_ADDR_DISC) +# if (TARGET==TARGET_LINUX) + DEBUG_MSGC(", source address: %s\n", inet_ntop(AF_INET,&((udp_buf_t *)data)->pi.pi4.ipi_spec_dst,buf,ADDRSTR_MAXLEN)); +# else + DEBUG_MSGC(", source address: %s\n", inet_ntop(AF_INET,&((udp_buf_t *)data)->pi.ai4,buf,ADDRSTR_MAXLEN)); +# endif +# else + DEBUG_MSGC("\n"); +# endif + } +# endif /* DEBUG */ + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + + msg.msg_name=&((udp_buf_t *)data)->addr.sin6; + msg.msg_namelen=sizeof(struct sockaddr_in6); +# if defined(SRC_ADDR_DISC) + cmsg=CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len=CMSG_LEN(sizeof(struct in6_pktinfo)); + cmsg->cmsg_level=SOL_IPV6; + cmsg->cmsg_type=IPV6_PKTINFO; + memcpy(CMSG_DATA(cmsg),&((udp_buf_t *)data)->pi.pi6,sizeof(struct in6_pktinfo)); + msg.msg_controllen=CMSG_SPACE(sizeof(struct in6_pktinfo)); +# endif +# if DEBUG>0 + { + char buf[ADDRSTR_MAXLEN]; + + DEBUG_MSG("Answering to: %s", inet_ntop(AF_INET6,&((udp_buf_t *)data)->addr.sin6.sin6_addr,buf,ADDRSTR_MAXLEN)); +# if defined(SRC_ADDR_DISC) + DEBUG_MSGC(", source address: %s\n", inet_ntop(AF_INET6,&((udp_buf_t *)data)->pi.pi6.ipi6_addr,buf,ADDRSTR_MAXLEN)); +# else + DEBUG_MSGC("\n"); +# endif + } +# endif /* DEBUG */ + } +#endif + + /* Lock the socket, and clear the error flag before dropping the lock */ +#ifdef SOCKET_LOCKING + pthread_mutex_lock(&s_lock); +#endif + if (sendmsg(((udp_buf_t *)data)->sock,&msg,0)<0) { +#ifdef SOCKET_LOCKING + pthread_mutex_unlock(&s_lock); +#endif + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("Error in udp send: %s",strerror(errno)); + } + } else { + int tmp; + socklen_t sl=sizeof(tmp); + getsockopt(((udp_buf_t *)data)->sock, SOL_SOCKET, SO_ERROR, &tmp, &sl); +#ifdef SOCKET_LOCKING + pthread_mutex_unlock(&s_lock); +#endif + } + + pthread_cleanup_pop(1); /* free(resp) */ + pthread_cleanup_pop(1); /* free(data) */ + return NULL; +} + +int init_udp_socket() +{ + int sock; + int so=1; + union { +#ifdef ENABLE_IPV4 + struct sockaddr_in sin4; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; +#endif + } sin; + socklen_t sinl; + +#ifdef ENABLE_IPV4 + if (run_ipv4) { + if ((sock=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) { + log_error("Could not open udp socket: %s",strerror(errno)); + return -1; + } + memset(&sin.sin4,0,sizeof(struct sockaddr_in)); + sin.sin4.sin_family=AF_INET; + sin.sin4.sin_port=htons(global.port); + sin.sin4.sin_addr=global.a.ipv4; + SET_SOCKA_LEN4(sin.sin4); + sinl=sizeof(struct sockaddr_in); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + if ((sock=socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP))==-1) { + log_error("Could not open udp socket: %s",strerror(errno)); + return -1; + } + memset(&sin.sin6,0,sizeof(struct sockaddr_in6)); + sin.sin6.sin6_family=AF_INET6; + sin.sin6.sin6_port=htons(global.port); + sin.sin6.sin6_flowinfo=IPV6_FLOWINFO; + sin.sin6.sin6_addr=global.a.ipv6; + SET_SOCKA_LEN6(sin.sin6); + sinl=sizeof(struct sockaddr_in6); + } +#endif + +#ifdef SRC_ADDR_DISC +# if (TARGET!=TARGET_LINUX) + if (run_ipv4) { +# endif + /* The following must be set on any case because it also applies for IPv4 packets sent to + * ipv6 addresses. */ +# if (TARGET==TARGET_LINUX ) + if (setsockopt(sock,SOL_IP,IP_PKTINFO,&so,sizeof(so))!=0) { +# else + if (setsockopt(sock,IPPROTO_IP,IP_RECVDSTADDR,&so,sizeof(so))!=0) { +# endif + log_error("Could not set options on udp socket: %s",strerror(errno)); + close(sock); + return -1; + } +# if (TARGET!=TARGET_LINUX) + } +# endif + +# ifdef ENABLE_IPV6 + if (!run_ipv4) { + if (setsockopt(sock,SOL_IPV6,IPV6_RECVPKTINFO,&so,sizeof(so))!=0) { + log_error("Could not set options on udp socket: %s",strerror(errno)); + close(sock); + return -1; + } + } +# endif +#endif + if (bind(sock,(struct sockaddr *)&sin,sinl)!=0) { + log_error("Could not bind to udp socket: %s",strerror(errno)); + close(sock); + return -1; + } + return sock; +} + +/* + * Listen on the specified port for udp packets and answer them (each in a new thread to be nonblocking) + * This was changed to support sending UDP packets with exactly the same source address as they were coming + * to us, as required by rfc2181. Although this is a sensible requirement, it is slightly more difficult + * and may introduce portability issues. + */ +void *udp_server_thread(void *dummy) +{ + int sock; + ssize_t qlen; + pthread_t pt; + udp_buf_t *buf; + struct msghdr msg; + struct iovec v; + struct cmsghdr *cmsg; + char ctrl[512]; +#if defined(ENABLE_IPV6) && (TARGET==TARGET_LINUX) + struct in_pktinfo sip; +#endif + /* (void)dummy; */ /* To inhibit "unused variable" warning */ + + THREAD_SIGINIT; + + + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + pdnsd_exit(); + } + } + + sock=udp_socket; + + while (1) { + int udpbufsize= global.udpbufsize; + if (!(buf=(udp_buf_t *)pdnsd_calloc(1,sizeof(udp_buf_t)+udpbufsize))) { + if (++da_mem_errs<=MEM_MAX_ERRS) { + log_error("Out of memory in request handling."); + } + break; + } + + buf->sock=sock; + + v.iov_base=(char *)buf->buf; + v.iov_len=udpbufsize; + msg.msg_iov=&v; + msg.msg_iovlen=1; +#if (TARGET!=TARGET_CYGWIN) + msg.msg_control=ctrl; + msg.msg_controllen=sizeof(ctrl); +#endif + +#if defined(SRC_ADDR_DISC) +# ifdef ENABLE_IPV4 + if (run_ipv4) { + msg.msg_name=&buf->addr.sin4; + msg.msg_namelen=sizeof(struct sockaddr_in); + if ((qlen=recvmsg(sock,&msg,0))>=0) { + cmsg=CMSG_FIRSTHDR(&msg); + while(cmsg) { +# if (TARGET==TARGET_LINUX) + if (cmsg->cmsg_level==SOL_IP && cmsg->cmsg_type==IP_PKTINFO) { + memcpy(&buf->pi.pi4,CMSG_DATA(cmsg),sizeof(struct in_pktinfo)); + break; + } +# else + if (cmsg->cmsg_level==IPPROTO_IP && cmsg->cmsg_type==IP_RECVDSTADDR) { + memcpy(&buf->pi.ai4,CMSG_DATA(cmsg),sizeof(buf->pi.ai4)); + break; + } +# endif + cmsg=CMSG_NXTHDR(&msg,cmsg); + } + if (!cmsg) { + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("Could not discover udp destination address"); + } + goto free_buf_continue; + } + } else if (errno!=EINTR) { + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("error in UDP recv: %s", strerror(errno)); + } + } + } +# endif +# ifdef ENABLE_IPV6 + ELSE_IPV6 { + msg.msg_name=&buf->addr.sin6; + msg.msg_namelen=sizeof(struct sockaddr_in6); + if ((qlen=recvmsg(sock,&msg,0))>=0) { + cmsg=CMSG_FIRSTHDR(&msg); + while(cmsg) { + if (cmsg->cmsg_level==SOL_IPV6 && cmsg->cmsg_type==IPV6_PKTINFO) { + memcpy(&buf->pi.pi6,CMSG_DATA(cmsg),sizeof(struct in6_pktinfo)); + break; + } + cmsg=CMSG_NXTHDR(&msg,cmsg); + } + if (!cmsg) { + /* We might have an IPv4 Packet incoming on our IPv6 port, so we also have to + * check for IPv4 sender addresses */ + cmsg=CMSG_FIRSTHDR(&msg); + while(cmsg) { +# if (TARGET==TARGET_LINUX) + if (cmsg->cmsg_level==SOL_IP && cmsg->cmsg_type==IP_PKTINFO) { + memcpy(&sip,CMSG_DATA(cmsg),sizeof(sip)); + IPV6_MAPIPV4(&sip.ipi_addr,&buf->pi.pi6.ipi6_addr); + buf->pi.pi6.ipi6_ifindex=sip.ipi_ifindex; + break; + } + /* FIXME: What about BSD? probably ok, but... */ +# endif + cmsg=CMSG_NXTHDR(&msg,cmsg); + } + if (!cmsg) { + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("Could not discover udp destination address"); + } + goto free_buf_continue; + } + } + } else if (errno!=EINTR) { + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("error in UDP recv: %s", strerror(errno)); + } + } + } +# endif +#else /* !SRC_ADDR_DISC */ +# ifdef ENABLE_IPV4 + if (run_ipv4) { + msg.msg_name=&buf->addr.sin4; + msg.msg_namelen=sizeof(struct sockaddr_in); + } +# endif +# ifdef ENABLE_IPV6 + ELSE_IPV6 { + msg.msg_name=&buf->addr.sin6; + msg.msg_namelen=sizeof(struct sockaddr_in6); + } +# endif + qlen=recvmsg(sock,&msg,0); + if (qlen<0 && errno!=EINTR) { + if (++da_udp_errs<=UDP_MAX_ERRS) { + log_error("error in UDP recv: %s", strerror(errno)); + } + } +#endif /* SRC_ADDR_DISC */ + + if (qlen>=0) { + pthread_mutex_lock(&proc_lock); + if (qprocslen=qlen; + err=pthread_create(&pt,&attr_detached,udp_answer_thread,(void *)buf); + if(err==0) + continue; + if(++da_thrd_errs<=THRD_MAX_ERRS) + log_warn("pthread_create failed: %s",strerror(err)); + /* If thread creation failed, free resources associated with it. */ + pthread_mutex_lock(&proc_lock); + --qprocs; --spawned; + } + ++dropped; + pthread_mutex_unlock(&proc_lock); + } + free_buf_continue: + pdnsd_free(buf); + usleep_r(50000); + } + + udp_socket=-1; + close(sock); + udps_thrid=main_thrid; + if (tcp_socket==-1) + pdnsd_exit(); + return NULL; +} + +#ifndef NO_TCP_SERVER + +static void tcp_answer_thread_cleanup(void *csock) +{ + close(*((int *)csock)); + pdnsd_free(csock); + decrease_procs(); +} + +/* + * Process a dns query via tcp. The argument is a pointer to the socket. + */ +static void *tcp_answer_thread(void *csock) +{ + /* XXX: This should be OK, the original must be (and is) aligned */ + int sock=*((int *)csock); + unsigned thrid; + + pthread_cleanup_push(tcp_answer_thread_cleanup, csock); + THREAD_SIGINIT; + + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + pdnsd_exit(); + } + } + + for(;;) { + pthread_mutex_lock(&proc_lock); + if (procs0 + if(debug_p) { + int err; + if ((err=pthread_setspecific(thrid_key, &thrid)) != 0) { + if(++da_misc_errs<=MISC_MAX_ERRS) + log_error("pthread_setspecific failed: %s",strerror(err)); + /* pdnsd_exit(); */ + } + } +#endif +#ifdef TCP_SUBSEQ + + /* rfc1035 says we should process multiple queries in succession, so we are looping until + * the socket is closed by the other side or by tcp timeout. + * This in fact makes DoSing easier. If that is your concern, you should disable pdnsd's + * TCP server.*/ + for(;;) +#endif + { + int rlen,olen; + size_t nlen; + unsigned char *buf; + dns_msg_t *resp; + +#ifdef NO_POLL + fd_set fds; + struct timeval tv; + FD_ZERO(&fds); + PDNSD_ASSERT(sock=2) { /* We need the id to send a valid reply. */ + dns_msg_t err; + mk_error_reply(((dns_hdr_t*)buf)->id, + olen>=3?((dns_hdr_t*)buf)->opcode:OP_QUERY, + RC_FORMAT, + &err.hdr); + err.len=htons(sizeof(dns_hdr_t)); + write_all(sock,&err,sizeof(err)); /* error anyway. */ + } + pthread_exit(NULL); /* buf freed and socket closed by cleanup handlers */ + } + olen += rv; + } + nlen=rlen; + if (!(resp=process_query(buf,&nlen,NULL,NULL))) { + /* + * A return value of NULL is a fatal error that prohibits even the sending of an error message. + * logging is already done. Just exit the thread now. + */ + pthread_exit(NULL); + } + pthread_cleanup_pop(1); /* free(buf) */ + pthread_cleanup_push(free,resp); + { + int err; size_t rsize; + resp->len=htons(nlen); + rsize=dnsmsghdroffset+nlen; + if ((err=write_all(sock,resp,rsize))!=rsize) { + DEBUG_MSG("Error while writing to TCP client: %s\n",err==-1?strerror(errno):"unknown error"); + pthread_exit(NULL); /* resp is freed and socket is closed by cleanup handlers */ + } + } + pthread_cleanup_pop(1); /* free(resp) */ + } + + /* socket is closed by cleanup handler */ + pthread_cleanup_pop(1); + return NULL; +} + +int init_tcp_socket() +{ + int sock; + union { +#ifdef ENABLE_IPV4 + struct sockaddr_in sin4; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; +#endif + } sin; + socklen_t sinl; + +#ifdef ENABLE_IPV4 + if (run_ipv4) { + if ((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) { + log_error("Could not open tcp socket: %s",strerror(errno)); + return -1; + } + memset(&sin.sin4,0,sizeof(struct sockaddr_in)); + sin.sin4.sin_family=AF_INET; + sin.sin4.sin_port=htons(global.port); + sin.sin4.sin_addr=global.a.ipv4; + SET_SOCKA_LEN4(sin.sin4); + sinl=sizeof(struct sockaddr_in); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + if ((sock=socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP))==-1) { + log_error("Could not open tcp socket: %s",strerror(errno)); + return -1; + } + memset(&sin.sin6,0,sizeof(struct sockaddr_in6)); + sin.sin6.sin6_family=AF_INET6; + sin.sin6.sin6_port=htons(global.port); + sin.sin6.sin6_flowinfo=IPV6_FLOWINFO; + sin.sin6.sin6_addr=global.a.ipv6; + SET_SOCKA_LEN6(sin.sin6); + sinl=sizeof(struct sockaddr_in6); + } +#endif + { + int so=1; + /* The SO_REUSEADDR socket option tells the kernel that even if this port + is busy (in the TIME_WAIT state), go ahead and reuse it anyway. If it + is busy, but with another state, we should get an address already in + use error. It is useful if pdnsd is shut down, and then restarted right + away while sockets are still active on its port. There is a slight risk + though. If unexpected data comes in, it may confuse pdnsd, but while + this is possible, it is not likely. + */ + if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&so,sizeof(so))) + log_warn("Could not set options on tcp socket: %s",strerror(errno)); + } + if (bind(sock,(struct sockaddr *)&sin,sinl)) { + log_error("Could not bind tcp socket: %s",strerror(errno)); + close(sock); + return -1; + } + return sock; +} + +/* + * Listen on the specified port for tcp connects and answer them (each in a new thread to be nonblocking) + */ +void *tcp_server_thread(void *p) +{ + int sock; + pthread_t pt; + int *csock; + + /* (void)p; */ /* To inhibit "unused variable" warning */ + + THREAD_SIGINIT; + + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + pdnsd_exit(); + } + } + + sock=tcp_socket; + + if (listen(sock,5)) { + if (++da_tcp_errs<=TCP_MAX_ERRS) { + log_error("Could not listen on tcp socket: %s",strerror(errno)); + } + goto close_sock_return; + } + + while (1) { + if (!(csock=(int *)pdnsd_malloc(sizeof(int)))) { + if (++da_mem_errs<=MEM_MAX_ERRS) { + log_error("Out of memory in request handling."); + } + break; + } + if ((*csock=accept(sock,NULL,0))==-1) { + if (errno!=EINTR && ++da_tcp_errs<=TCP_MAX_ERRS) { + log_error("tcp accept failed: %s",strerror(errno)); + } + } else { + /* + * With creating a new thread, we follow recommendations + * in rfc1035 not to block + */ + pthread_mutex_lock(&proc_lock); + if (qprocs. +*/ + + +#ifndef DNS_ANSWER_H +#define DNS_ANSWER_H + +#include + +/* --- from main.c */ +extern pthread_t main_thrid,servstat_thrid,statsock_thrid,tcps_thrid,udps_thrid; +extern volatile int tcp_socket; +extern volatile int udp_socket; +/* --- */ + +int init_udp_socket(void); +int init_tcp_socket(void); +void start_dns_servers(void); +int report_thread_stat(int f); + +#endif diff --git a/jni/pdnsd/src/dns_query.c b/jni/pdnsd/src/dns_query.c new file mode 100644 index 00000000..0b6c9c04 --- /dev/null +++ b/jni/pdnsd/src/dns_query.c @@ -0,0 +1,3798 @@ +/* dns_query.c - Execute outgoing dns queries and write entries to cache + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#ifdef HAVE_SYS_POLL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include "list.h" +#include "consts.h" +#include "ipvers.h" +#include "dns_query.h" +#include "cache.h" +#include "dns.h" +#include "conff.h" +#include "servers.h" +#include "helpers.h" +#include "netdev.h" +#include "error.h" +#include "debug.h" + + +#if defined(NO_TCP_QUERIES) && M_PRESET!=UDP_ONLY +# error "You may not define NO_TCP_QUERIES when M_PRESET is not set to UDP_ONLY" +#endif +#if defined(NO_UDP_QUERIES) && M_PRESET!=TCP_ONLY +# error "You may not define NO_UDP_QUERIES when M_PRESET is not set to TCP_ONLY" +#endif + +/* data type to hold lists of IP addresses (both v4 and v6) + The allocated size should be: + sizeof(rejectlist_t) + na4*sizeof(addr4maskpair_t) + na6*sizeof(addr6maskpair_t) +*/ +typedef struct rejectlist_s { + struct rejectlist_s *next; + short policy; + short inherit; + int na4; +#if ALLOW_LOCAL_AAAA + int na6; + addr6maskpair_t rdata[0]; /* dummy array for alignment */ +#else + addr4maskpair_t rdata[0]; +#endif +} rejectlist_t; + +/* --- structures and state constants for parallel query */ +typedef struct { + union { +#ifdef ENABLE_IPV4 + struct sockaddr_in sin4; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; +#endif + } a; +#ifdef ENABLE_IPV6 + struct in_addr a4fallback; +#endif + time_t timeout; + unsigned short flags; + short state; + short qm; + char nocache; + char auth_serv; + char lean_query; + char edns_query; + char needs_testing; + char trusted; + char aa; + char tc; + char ra; + char failed; + const unsigned char *nsdomain; + rejectlist_t *rejectlist; + /* internal state for p_exec_query */ + int sock; +#if 0 + dns_cent_t nent; + dns_cent_t servent; +#endif + unsigned short transl; + unsigned short recvl; +#ifndef NO_TCP_QUERIES + int iolen; /* number of bytes written or read up to now */ +#endif + dns_msg_t *msg; + dns_hdr_t *recvbuf; + unsigned short myrid; + int s_errno; +} query_stat_t; +typedef DYNAMIC_ARRAY(query_stat_t) *query_stat_array; + +/* Some macros for handling data in reject lists + Perhaps we should use inline functions instead of macros. +*/ +#define have_rejectlist(st) ((st)->rejectlist!=NULL) +#define inherit_rejectlist(st) ((st)->rejectlist && (st)->rejectlist->inherit) +#define reject_policy(st) ((st)->rejectlist->policy) +#define nreject_a4(st) ((st)->rejectlist->na4) +#if ALLOW_LOCAL_AAAA +#define nreject_a6(st) ((st)->rejectlist->na6) +#define rejectlist_a6(st) ((addr6maskpair_t *)(st)->rejectlist->rdata) +#define rejectlist_a4(st) ((addr4maskpair_t *)(rejectlist_a6(st)+nreject_a6(st))) +#else +#define rejectlist_a4(st) ((addr4maskpair_t *)(st)->rejectlist->rdata) +#endif + +#define QS_INITIAL 0 /* This is the initial state. Set this before starting. */ + +#define QS_TCPINITIAL 1 /* Start a TCP query. */ +#define QS_TCPWRITE 2 /* Waiting to write data. */ +#define QS_TCPREAD 3 /* Waiting to read data. */ + +#define QS_UDPINITIAL 4 /* Start a UDP query */ +#define QS_UDPRECEIVE 5 /* UDP query transmitted, waiting for response. */ + +#define QS_QUERY_CASES case QS_TCPINITIAL: case QS_TCPWRITE: case QS_TCPREAD: case QS_UDPINITIAL: case QS_UDPRECEIVE + +#define QS_CANCELED 7 /* query was started, but canceled before completion */ +#define QS_DONE 8 /* done, resources freed, result is in stat_t */ + + +/* Events to be polled/selected for */ +#define QS_WRITE_CASES case QS_TCPWRITE +#define QS_READ_CASES case QS_TCPREAD: case QS_UDPRECEIVE + +/* + * This is for error handling to prevent spewing the log files. + * Races do not really matter here, so no locks. + */ +#define MAXPOLLERRS 10 +static volatile unsigned long poll_errs=0; + +#define SOCK_ADDR(p) ((struct sockaddr *) &(p)->a) + +#ifdef SIN_LEN +#undef SIN_LEN +#endif + +#define SIN_LEN SEL_IPVER(sizeof(struct sockaddr_in),sizeof(struct sockaddr_in6)) +#define PDNSD_A(p) SEL_IPVER(((pdnsd_a *) &(p)->a.sin4.sin_addr),((pdnsd_a *) &(p)->a.sin6.sin6_addr)) + +#ifndef EWOULDBLOCK +#define EWOULDBLOCK EAGAIN +#endif + +typedef DYNAMIC_ARRAY(dns_cent_t) *dns_cent_array; + + +/* + * Take the data from an RR and add it to an array of cache entries. + * The return value will be RC_OK in case of success, + * RC_SERVFAIL in case there is a problem with inconsistent ttl timestamps + * or RC_FATALERR in case of a memory allocation failure. + */ +static int rr_to_cache(dns_cent_array *centa, unsigned char *oname, int tp, time_t ttl, + unsigned dlen, void *data, unsigned flags, time_t queryts) +{ + int i,n; + dns_cent_t *cent; + + n=DA_NEL(*centa); + for(i=0;iqname,oname)) { + int retval=RC_OK; + /* We already have an entry in the array for this name. add_cent_rr is sufficient. + However, make sure there are no double records. This is done by add_cent_rr */ +#ifdef RFC2181_ME_HARDER + rr_set_t *rrset= getrrset(cent,tp); + if (rrset && rrset->ttl!=ttl) + retval= RC_SERVFAIL; +#endif + return add_cent_rr(cent,tp,ttl,queryts,flags,dlen,data DBG1)? retval: RC_FATALERR; + } + } + + /* Add a new entry to the array for this name. */ + if (!(*centa=DA_GROW1_F(*centa,free_cent0))) + return RC_FATALERR; + cent=&DA_LAST(*centa); + if (!init_cent(cent,oname, 0, 0, 0 DBG1)) { + *centa=DA_RESIZE(*centa,n); + return RC_FATALERR; + } + return add_cent_rr(cent,tp,ttl,queryts,flags,dlen,data DBG1)? RC_OK: RC_FATALERR; +} + +/* + * Takes a pointer (ptr) to a buffer with recnum rrs,decodes them and enters + * them into an array of cache entries. *ptr is modified to point after the last + * rr, and *lcnt is decremented by the size of the rrs. + * + * *numopt is incremented with the number of OPT pseudo RRs found (should be at most one). + * The structure pointed to by ep is filled with the information of the first OPT pseudo RR found, + * but only if *numopt was set to zero before the call. + * + * The return value will be either RC_OK (which indicates success), + * or one of the failure codes RC_FORMAT, RC_TRUNC, RC_SERVFAIL or RC_FATALERR + * (the latter indicates a memory allocation failure). +*/ +static int rrs2cent(unsigned char *msg, size_t msgsz, unsigned char **ptr, size_t *lcnt, int recnum, + unsigned flags, time_t queryts, dns_cent_array *centa, int *numopt, edns_info_t *ep) +{ + int rc, retval=RC_OK; + int i; + uint16_t type,class; uint32_t ttl; uint16_t rdlength; + + for (i=0;i0 + if(oname[0]!=0) { + DEBUG_MSG("rrs2cent: name in OPT record not empty!\n"); + } +#endif + ep->udpsize= class; + ep->rcode= ((uint16_t)ttlp[0]<<4) | ((dns_hdr_t *)msg)->rcode; + ep->version= ttlp[1]; + ep->do_flg= (ttlp[2]>>7)&1; +#if DEBUG>0 + if(debug_p) { + unsigned int Zflags= ((uint16_t)ttlp[2]<<8) | ttlp[3]; + if(Zflags & 0x7fff) { + DEBUG_MSG("rrs2cent: Z field contains unknown nonzero bits (%04x).\n", + Zflags); + } + } + if(rdlength) { + DEBUG_MSG("rrs2cent: RDATA field in OPT record not empty!\n"); + } +#endif + } + else { + DEBUG_MSG("rrs2cent: ingnoring surplus OPT record.\n"); + } + } + else if (!(PDNSD_NOT_CACHED_TYPE(type) || class!=C_IN)) { + /* Some types contain names that may be compressed, so these need to be processed. + * The other records are taken as they are. */ + + size_t blcnt=rdlength; + unsigned char *bptr=*ptr; /* make backup for decompression, because rdlength is the + authoritative record length and pointer and size will be + modified by decompress_name. */ + unsigned char *nptr; + unsigned int slen; + + switch (type) { + case T_A: + /* Validate types we use internally */ + if(rdlength!=4) goto invalid_length; + goto default_case; + + case T_CNAME: + case T_MB: + case T_MD: + case T_MF: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + { + unsigned char db[DNSNAMEBUFSIZE]; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, db, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, len, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; + +#if IS_CACHED_MINFO || IS_CACHED_RP +#if IS_CACHED_MINFO + case T_MINFO: +#endif +#if IS_CACHED_RP + case T_RP: +#endif + { + unsigned char db[DNSNAMEBUFSIZE+DNSNAMEBUFSIZE]; + nptr=db; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_MINFO/T_RP: buffer limit reached"); */ + nptr+=len; + slen=len; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /*nptr+=len;*/ + slen+=len; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif + case T_MX: +#if IS_CACHED_AFSDB + case T_AFSDB: +#endif +#if IS_CACHED_RT + case T_RT: +#endif +#if IS_CACHED_KX + case T_KX: +#endif + { + unsigned char db[2+DNSNAMEBUFSIZE]; + if (blcnt<2) + goto record_too_short; + memcpy(db,bptr,2); /* copy the preference field*/ + blcnt-=2; + bptr+=2; + nptr=db+2; + slen=2; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /*nptr+=len;*/ + slen+=len; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; + + case T_SOA: + { + unsigned char db[DNSNAMEBUFSIZE+DNSNAMEBUFSIZE+20]; + nptr=db; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_SOA: buffer limit reached"); */ + nptr+=len; + slen=len; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + nptr+=len; + slen+=len; + /* PDNSD_ASSERT(slen + 20 <= sizeof(db), "T_SOA: buffer limit reached"); */ + if (blcnt<20) + goto record_too_short; + memcpy(nptr,bptr,20); /*copy the rest of the SOA record*/ + blcnt-=20; + slen+=20; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#if IS_CACHED_AAAA + case T_AAAA: + /* Validate types we use internally */ + if(rdlength!=16) goto invalid_length; + goto default_case; +#endif +#if IS_CACHED_PX + case T_PX: + { + unsigned char db[2+DNSNAMEBUFSIZE+DNSNAMEBUFSIZE]; + if (blcnt<2) + goto record_too_short; + memcpy(db,bptr,2); /* copy the preference field*/ + blcnt-=2; + bptr+=2; + nptr=db+2; + slen=2; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /* PDNSD_ASSERT(len + DNSNAMEBUFSIZE <= sizeof(db), "T_PX: buffer limit reached"); */ + nptr+=len; + slen+=len; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /* nptr+=len; */ + slen+=len; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif +#if IS_CACHED_SRV + case T_SRV: + { + unsigned char db[6+DNSNAMEBUFSIZE]; + if (blcnt<6) + goto record_too_short; + memcpy(db,bptr,6); + blcnt-=6; + bptr+=6; + nptr=db+6; + slen=6; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /*nptr+=len;*/ + slen+=len; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif +#if IS_CACHED_NXT + case T_NXT: + { + unsigned char db[1040]; + nptr=db; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + nptr+=len; + slen=len+blcnt; + if (slen > sizeof(db)) + goto buffer_overflow; + memcpy(nptr,bptr,blcnt); + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif +#if IS_CACHED_NAPTR + case T_NAPTR: + { + int j; + unsigned char db[4 + 3*256 + DNSNAMEBUFSIZE]; + nptr=db; + /* + * After the preference field, three text strings follow, the maximum length being 255 + * characters for each (this is ensured by the type of *bptr), plus one length byte for + * each, so 3 * 256 = 786 in total. In addition, the name below is up to DNSNAMEBUFSIZE characters + * in size, and the preference field is another 4 bytes in size, so the total length + * that can be taken up is 1028 characters. This means that the whole record will always + * fit into db. + */ + len=4; /* also copy the preference field*/ + for (j=0;j<3;j++) { + if (len>=blcnt) + goto record_too_short; + len += ((unsigned)bptr[len])+1; + } + if(len>blcnt) + goto record_too_short; + memcpy(nptr,bptr,len); + blcnt-=len; + bptr+=len; + nptr+=len; + slen=len; + + /* PDNSD_ASSERT(slen+DNSNAMEBUFSIZE <= sizeof(db), "T_NAPTR: buffer limit reached (name)"); */ + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nptr, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + /*nptr+=len;*/ + slen+=len; + if (blcnt!=0) + goto trailing_junk; + if ((rc=rr_to_cache(centa, oname, type, ttl, slen, db, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif +#if IS_CACHED_IPSECKEY + case T_IPSECKEY: + { + unsigned gwtp; + /* An IPSECKEY record can contain a domain name, so we do some sanity checks just to be sure. */ + if(blcnt<3) goto record_too_short; + gwtp= bptr[1]; + blcnt -= 3; + bptr += 3; + switch(gwtp) { + case 0: goto default_case; + case 1: /* There should be enough room for IPv4 address. */ + if(blcnt<4) goto record_too_short; + goto default_case; + case 2: /* There should be enough room for IPv6 address. */ + if(blcnt<16) goto record_too_short; + goto default_case; + case 3: /* Check that domain name is not compressed. */ + if(isnormalencdomname(bptr,blcnt)) goto default_case; + /* It appears the name is compressed even though RFC 4025 + says it shouldn't be. For the sake of flexibility, we + try to decompress it anyway. */ + { + unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE]; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + slen=3+len+blcnt; + rbuf=malloc(slen); + if(!rbuf) return RC_FATALERR; + nptr=mempcpy(rbuf,*ptr,3); + nptr=mempcpy(nptr,nmbuf,len); + memcpy(nptr,bptr,blcnt); + rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts); + free(rbuf); + if(rc!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; + default: + DEBUG_MSG("rrs2cent: %s record contains unsupported gateway type (%u).\n",getrrtpname(type),gwtp); + return RC_FORMAT; + } + } + break; +#endif +#if IS_CACHED_RRSIG + case T_RRSIG: + /* An RRSIG record contains a domain name, so we do some sanity checks just to be sure. */ + if(blcnt<18) goto record_too_short; + blcnt -= 18; + bptr += 18; + if(isnormalencdomname(bptr,blcnt)) goto default_case; + /* It appears the name is compressed even though RFC 4034 + says it shouldn't be. For the sake of flexibility, we + try to decompress it anyway. */ + { + unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE]; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + slen=18+len+blcnt; + rbuf=malloc(slen); + if(!rbuf) return RC_FATALERR; + nptr=mempcpy(rbuf,*ptr,18); + nptr=mempcpy(nptr,nmbuf,len); + memcpy(nptr,bptr,blcnt); + rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts); + free(rbuf); + if(rc!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif +#if IS_CACHED_NSEC + case T_NSEC: + /* An NSEC record contains a domain name, so we do some sanity checks just to be sure. */ + if(isnormalencdomname(bptr,blcnt)) goto default_case; + /* It appears the name is compressed even though RFC 4034 + says it shouldn't be. For the sake of flexibility, we + try to decompress it anyway. */ + { + unsigned char *rbuf, nmbuf[DNSNAMEBUFSIZE]; + if ((rc=decompress_name(msg, msgsz, &bptr, &blcnt, nmbuf, &len))!=RC_OK) + return rc==RC_TRUNC?RC_FORMAT:rc; + slen=len+blcnt; + rbuf=malloc(slen); + if(!rbuf) return RC_FATALERR; + nptr=mempcpy(rbuf,nmbuf,len); + memcpy(nptr,bptr,blcnt); + rc=rr_to_cache(centa, oname, type, ttl, slen, rbuf, flags,queryts); + free(rbuf); + if(rc!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + break; +#endif + default: + default_case: + if ((rc=rr_to_cache(centa, oname, type, ttl, rdlength, *ptr, flags,queryts))!=RC_OK) { + if(rc==RC_FATALERR) + return rc; + retval=rc; + } + } + } + else { + /* skip otherwise */ + DEBUG_MSG("rrs2cent: ignoring record of type %s (%d), class %s (%d).\n", + getrrtpname(type), type, + class==C_IN?"IN":"[unknown]", class); + } + + *lcnt -= rdlength; + *ptr += rdlength; + } + return retval; + + trailing_junk: + DEBUG_MSG("rrs2cent: %s record has trailing junk.\n",getrrtpname(type)); + return RC_FORMAT; + + record_too_short: + DEBUG_MSG("rrs2cent: %s record too short.\n",getrrtpname(type)); + return RC_FORMAT; + + buffer_overflow: + DEBUG_MSG("rrs2cent: buffer too small to process %s record.\n",getrrtpname(type)); + return RC_FORMAT; + + invalid_length: + DEBUG_MSG("rrs2cent: %s record has length %u.\n",getrrtpname(type),rdlength); + return RC_FORMAT; +} + +/* + * Try to bind the socket to a port in the given port range. Returns 1 on success, or 0 on failure. + */ +static int bind_socket(int s) +{ + int query_port_start=global.query_port_start,query_port_end=global.query_port_end; + + /* + * -1, as a special value for query_port_start, denotes that we let the kernel select + * a port when we first use the socket, which used to be the default. + */ + if (query_port_start >= 0) { + union { +#ifdef ENABLE_IPV4 + struct sockaddr_in sin4; +#endif +#ifdef ENABLE_IPV6 + struct sockaddr_in6 sin6; +#endif + } sin; + socklen_t sinl; + int prt, pstart, range = query_port_end-query_port_start+1, m=0xffff; + unsigned try1,try2, maxtry2; + + if (range<=0 || range>0x10000) { + log_warn("Illegal port range in %s line %d, dropping query!\n",__FILE__,__LINE__); + return 0; + } + if(range<=0x8000) { + /* Find the smallest power of 2 >= range. */ + for(m=1; m= range. */ + for(try1=0;;) { + prt= get_rand16()&m; + if(prt=0x10000) { + log_warn("Cannot get random number < range" + " after %d tries in %s line %d," + " bad random number generator?\n", + try1,__FILE__,__LINE__); + return 0; + } + } + prt += query_port_start; + + for(pstart=prt;;) { +#ifdef ENABLE_IPV4 + if (run_ipv4) { + memset(&sin.sin4,0,sizeof(struct sockaddr_in)); + sin.sin4.sin_family=AF_INET; + sin.sin4.sin_port=htons(prt); + sin.sin4.sin_addr=global.out_a.ipv4; + SET_SOCKA_LEN4(sin.sin4); + sinl=sizeof(struct sockaddr_in); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + memset(&sin.sin6,0,sizeof(struct sockaddr_in6)); + sin.sin6.sin6_family=AF_INET6; + sin.sin6.sin6_port=htons(prt); + sin.sin6.sin6_flowinfo=IPV6_FLOWINFO; + sin.sin6.sin6_addr=global.out_a.ipv6; + SET_SOCKA_LEN6(sin.sin6); + sinl=sizeof(struct sockaddr_in6); + } +#endif + if (bind(s,(struct sockaddr *)&sin,sinl)==-1) { + if (errno!=EADDRINUSE && + errno!=EADDRNOTAVAIL) { /* EADDRNOTAVAIL should not happen here... */ + log_warn("Could not bind to socket: %s\n", strerror(errno)); + return 0; + } + /* If the address is in use, we continue. */ + } else + goto done; + + if(++try2>=maxtry2) { + /* It is possible we missed the free ports by chance, + try scanning the whole range. */ + if (++prt>query_port_end) + prt=query_port_start; + if (prt==pstart) { + /* Wrapped around, scanned the whole range. Give up. */ + log_warn("Out of ports in the range" + " %d-%d, dropping query!\n", + query_port_start,query_port_end); + return 0; + } + } + else /* Try new random number */ + break; + } + } + } +done: + return 1; +} + + +inline static void *realloc_or_cleanup(void *ptr,size_t size) +{ + void *retval=pdnsd_realloc(ptr,size); + if(!retval) + pdnsd_free(ptr); + return retval; +} + +#if defined(NO_TCP_QUERIES) +# define USE_UDP(st) 1 +#elif defined(NO_UDP_QUERIES) +# define USE_UDP(st) 0 +#else /* !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) */ +# define USE_UDP(st) ((st)->qm==UDP_ONLY || (st)->qm==UDP_TCP) + +/* These functions will be used in case a TCP query might fail and we want to try again using UDP. */ + +# define tentative_tcp_query(st) ((st)->qm==TCP_UDP && ((st)->state==QS_TCPWRITE || ((st)->state==QS_TCPREAD && (st)->iolen==0))) + +inline static void switch_to_udp(query_stat_t *st) +{ + st->qm=UDP_ONLY; + st->myrid=get_rand16(); + st->msg->hdr.id=htons(st->myrid); + st->state=QS_UDPINITIAL; + /* st->failed=0; */ +} + +/* This function will be used in case a UDP reply was truncated and we want to try again using TCP. */ + +inline static void switch_to_tcp(query_stat_t *st) +{ + /* PDNSD_ASSERT(st->state==QS_INITIAL || st->state==QS_DONE || st->state==QS_CANCELED, + "Attempt to switch to TCP while a query is in progress."); */ + st->qm=TCP_ONLY; + st->state=QS_INITIAL; + st->failed=0; +} +#endif + + +/* ------ following is the parallel query code. + * It has been observed that a whole lot of name servers are just damn lame, with response time + * of about 1 min. If that slow one is by chance the first server we try, serializing the tries is quite + * sub-optimal. Also when doing serial queries, the timeout values given in the config will add up, which + * is not the Right Thing. Now that serial queries are in place, this is still true for CNAME recursion, + * and for recursion in quest for the holy AA, but not totally for querying multiple servers. + * The impact on network bandwith should be only marginal (given todays bandwith). + * + * The actual strategy is to do (max) PAR_QUERIES parallel queries, and, if these time out or fail, do again + * that number of queries, until we are successful or there are no more servers to query. + * Since the memory footprint of a thread is considerably large on some systems, and because we have better + * control, we will do the parallel queries multiplexed in one thread. + */ + +/* The query state machine that is called from p_exec_query. This is called once for initialization (state + * QS_TCPINITIAL or QS_UDPINITIAL is preset), and the state that it gives back may either be state QS_DONE, + * in which case it must return a return code other than -1 and is called no more for this server + * (except perhaps in UDP mode if TCP failed). If p_query_sm returns -1, then the state machine is in a read + * or write state, and a function higher up the calling chain can setup a poll() or select() together with st->sock. + * If that poll/select is succesful for that socket, p_exec_query is called again and will hand over to p_query_sm. + * So, you can assume that read(), write() and recvfrom() will not block at the start of a state handling when you + * have returned -1 (which means "call again") as last step of the last state handling. */ +static int p_query_sm(query_stat_t *st) +{ + int retval=RC_SERVFAIL,rv; + +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + tryagain: +#endif + switch (st->state){ + /* TCP query code */ +#ifndef NO_TCP_QUERIES + case QS_TCPINITIAL: + if ((st->sock=socket(PDNSD_PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) { + DEBUG_MSG("Could not open socket: %s\n", strerror(errno)); + break; + } + /* sin4 or sin6 is intialized, hopefully. */ + + /* maybe bind */ + if (!bind_socket(st->sock)) { + close(st->sock); + break; + } + + /* transmit query by tcp*/ + /* make the socket non-blocking */ + { + int oldflags = fcntl(st->sock, F_GETFL, 0); + if (oldflags == -1 || fcntl(st->sock,F_SETFL,oldflags|O_NONBLOCK)==-1) { + DEBUG_PDNSDA_MSG("fcntl error while trying to make socket to %s non-blocking: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno)); + close(st->sock); + break; + } + } + st->iolen=0; +#ifdef ENABLE_IPV6 + retry_tcp_connect: +#endif + if (connect(st->sock,SOCK_ADDR(st),SIN_LEN)==-1) { + if (errno==EINPROGRESS || errno==EPIPE) { + st->state=QS_TCPWRITE; + /* st->event=QEV_WRITE; */ /* wait for writability; the connect is then done */ + return -1; + } else if (errno==ECONNREFUSED) { + st->s_errno=errno; + DEBUG_PDNSDA_MSG("TCP connection refused by %s\n", PDNSDA2STR(PDNSD_A(st))); + close(st->sock); + goto tcp_failed; /* We may want to try again using UDP */ + } else { + /* Since immediate connect() errors do not cost any time, we do not try to switch the + * server status to offline */ +#ifdef ENABLE_IPV6 + /* if IPv6 connectivity is for some reason unavailable, perhaps the + IPv4 fallback address can still be reached. */ + if(!run_ipv4 && (errno==ENETUNREACH || errno==ENETDOWN) + && st->a4fallback.s_addr!=INADDR_ANY) + { +#if DEBUG>0 + char abuf[ADDRSTR_MAXLEN]; + DEBUG_PDNSDA_MSG("Connecting to %s failed: %s, retrying with IPv4 address %s\n", + PDNSDA2STR(PDNSD_A(st)),strerror(errno), + inet_ntop(AF_INET,&st->a4fallback,abuf,sizeof(abuf))); +#endif + IPV6_MAPIPV4(&st->a4fallback,&st->a.sin6.sin6_addr); + st->a4fallback.s_addr=INADDR_ANY; + goto retry_tcp_connect; + } +#endif + DEBUG_PDNSDA_MSG("Error while connecting to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno)); + close(st->sock); + break; + } + } + st->state=QS_TCPWRITE; + /* st->event=QEV_WRITE; */ + /* fall through in case of not EINPROGRESS */ + case QS_TCPWRITE: + { + int rem= dnsmsghdroffset + st->transl - st->iolen; + if(rem>0) { + rv=write(st->sock,((unsigned char*)st->msg)+st->iolen,rem); + if(rv==-1) { + if(errno==EWOULDBLOCK) + return -1; + st->s_errno=errno; + close(st->sock); + if (st->iolen==0 && + (st->s_errno==ECONNREFUSED || st->s_errno==ECONNRESET || + st->s_errno==EPIPE)) + { + /* This error may be delayed from connect() */ + DEBUG_PDNSDA_MSG("TCP connection to %s failed: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(st->s_errno)); + goto tcp_failed; /* We may want to try again using UDP */ + } + DEBUG_PDNSDA_MSG("Error while sending data to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(st->s_errno)); + break; + } + st->iolen += rv; + if(rvstate=QS_TCPREAD; + st->iolen=0; + /* st->event=QEV_READ; */ + /* fall through */ + case QS_TCPREAD: + if(st->iolen==0) { + uint16_t recvl_net; + rv=read(st->sock,&recvl_net,sizeof(recvl_net)); + if(rv==-1 && errno==EWOULDBLOCK) + return -1; + if(rv!=sizeof(recvl_net)) + goto error_receiv_data; + st->iolen=rv; + st->recvl=ntohs(recvl_net); + if(!(st->recvbuf=(dns_hdr_t *)realloc_or_cleanup(st->recvbuf,st->recvl))) { + close(st->sock); + DEBUG_MSG("Out of memory in query.\n"); + retval=RC_FATALERR; + break; + } + } + { + int offset=st->iolen-sizeof(uint16_t); + int rem=st->recvl-offset; + if(rem>0) { + rv=read(st->sock,((unsigned char*)st->recvbuf)+offset,rem); + if(rv==-1) { + if(errno==EWOULDBLOCK) + return -1; + goto error_receiv_data; + } + if(rv==0) + goto error_receiv_data; /* unexpected EOF */ + st->iolen += rv; + if(rvsock); + st->state=QS_DONE; + return RC_OK; + error_receiv_data: + if(rv==-1) st->s_errno=errno; + DEBUG_PDNSDA_MSG("Error while receiving data from %s: %s\n", PDNSDA2STR(PDNSD_A(st)), + rv==-1?strerror(errno):(rv==0 && st->iolen==0)?"no data":"incomplete data"); + close(st->sock); + tcp_failed: +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + if(st->qm==TCP_UDP) { + switch_to_udp(st); + DEBUG_PDNSDA_MSG("TCP query to %s failed. Trying to use UDP.\n", PDNSDA2STR(PDNSD_A(st))); + goto tryagain; + } +#endif + break; +#endif + +#ifndef NO_UDP_QUERIES + /* UDP query code */ + case QS_UDPINITIAL: + if ((st->sock=socket(PDNSD_PF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) { + DEBUG_MSG("Could not open socket: %s\n", strerror(errno)); + break; + } + + /* maybe bind */ + if (!bind_socket(st->sock)) { + close(st->sock); + break; + } + + /* connect */ +#ifdef ENABLE_IPV6 + retry_udp_connect: +#endif + if (connect(st->sock,SOCK_ADDR(st),SIN_LEN)==-1) { + if (errno==ECONNREFUSED) st->s_errno=errno; +#ifdef ENABLE_IPV6 + /* if IPv6 connectivity is for some reason unavailable, perhaps the + IPv4 fallback address can still be reached. */ + else if(!run_ipv4 && (errno==ENETUNREACH || errno==ENETDOWN) + && st->a4fallback.s_addr!=INADDR_ANY) + { +#if DEBUG>0 + char abuf[ADDRSTR_MAXLEN]; + DEBUG_PDNSDA_MSG("Connecting to %s failed: %s, retrying with IPv4 address %s\n", + PDNSDA2STR(PDNSD_A(st)),strerror(errno), + inet_ntop(AF_INET,&st->a4fallback,abuf,sizeof(abuf))); +#endif + IPV6_MAPIPV4(&st->a4fallback,&st->a.sin6.sin6_addr); + st->a4fallback.s_addr=INADDR_ANY; + goto retry_udp_connect; + } +#endif + DEBUG_PDNSDA_MSG("Error while connecting to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno)); + close(st->sock); + break; + } + + /* transmit query by udp*/ + /* send will hopefully not block on a freshly opened socket (the buffer + * must be empty) */ + if (send(st->sock,&st->msg->hdr,st->transl,0)==-1) { + st->s_errno=errno; + DEBUG_PDNSDA_MSG("Error while sending data to %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno)); + close(st->sock); + break; + } + st->state=QS_UDPRECEIVE; + /* st->event=QEV_READ; */ + return -1; + case QS_UDPRECEIVE: + { + int udpbufsize= (st->edns_query?global.udpbufsize:UDP_BUFSIZE); + if(!(st->recvbuf=(dns_hdr_t *)realloc_or_cleanup(st->recvbuf,udpbufsize))) { + close(st->sock); + DEBUG_MSG("Out of memory in query.\n"); + retval=RC_FATALERR; + break; + } + if ((rv=recv(st->sock,st->recvbuf,udpbufsize,0))==-1) { + st->s_errno=errno; + DEBUG_PDNSDA_MSG("Error while receiving data from %s: %s\n", PDNSDA2STR(PDNSD_A(st)),strerror(errno)); + close(st->sock); + break; + } + st->recvl=rv; + if (st->recvlrecvbuf->id)!=st->myrid) { + DEBUG_MSG("Bad answer received. Ignoring it.\n"); + /* no need to care about timeouts here. That is done at an upper layer. */ + st->state=QS_UDPRECEIVE; + /* st->event=QEV_READ; */ + return -1; + } + close(st->sock); + st->state=QS_DONE; + return RC_OK; + } +#endif + } + + /* If we get here, something has gone wrong. */ + st->state=QS_DONE; + return retval; /* should be either RC_SERVFAIL or RC_FATALERR */ +} + +static dns_cent_t *lookup_cent_array(dns_cent_array ca, const unsigned char *nm) +{ + int i,n=DA_NEL(ca); + for(i=0;iqname,nm)) + return ce; + } + return NULL; +} + +/* Extract the minimum ttl field from the SOA record stored in an rr bucket. */ +static time_t soa_minimum(rr_bucket_t *rrs) +{ + uint32_t minimum; + unsigned char *p=(unsigned char *)(rrs->data); + + /* Skip owner and maintainer. Lengths are validated in cache. */ + p=skiprhn(skiprhn(p)); + /* Skip serial, refresh, retry, expire fields. */ + p += 4*sizeof(uint32_t); + GETINT32(minimum,p); + return minimum; +} + +/* + * The function that will actually execute a query. It takes a state structure in st. + * st->state must be set to QS_INITIAL before calling. + * This may return one of the RC_* codes, where RC_OK indicates success, the other + * RC codes indicate the appropriate errors. -1 is the return value that indicates that + * you should call p_exec_query again with the same state for the result until you get + * a return value >0. Alternatively, call p_cancel_query to cancel it. + * Timeouts are already handled by this function. + * Any records that the query has yielded and that are not a direct answer to the query + * (i.e. are records for other domains) are added to the cache, while the direct answers + * are returned in ent. + * All ns records, to whomever they might belong, are additionally returned in the ns list. + * Free it when done. + * This function calls another query state machine function that supports TCP and UDP. + * + * If you want to tell me that this function has a truly ugly coding style, ah, well... + * You are right, somehow, but I feel it is conceptually elegant ;-) + */ +static int p_exec_query(dns_cent_t **entp, const unsigned char *name, int thint, + query_stat_t *st, dlist *ns, unsigned char *c_soa) +{ + int rv,rcode; + unsigned short rd; + + switch (st->state){ + case QS_INITIAL: { + size_t transl,allocsz; + unsigned int rrnlen=0; + + allocsz= sizeof(dns_msg_t); + if(name) { + rrnlen=rhnlen(name); + allocsz += rrnlen+4; + if(st->edns_query) + allocsz += sizeof_opt_pseudo_rr; + } + st->msg=(dns_msg_t *)pdnsd_malloc(allocsz); + if (!st->msg) { + st->state=QS_DONE; + return RC_FATALERR; /* unrecoverable error */ + } + st->myrid=get_rand16(); + st->msg->hdr.id=htons(st->myrid); + st->msg->hdr.qr=QR_QUERY; + st->msg->hdr.opcode=OP_QUERY; + st->msg->hdr.aa=0; + st->msg->hdr.tc=0; + st->msg->hdr.rd=(name && st->trusted); + st->msg->hdr.ra=0; + st->msg->hdr.z=0; + st->msg->hdr.ad=0; + st->msg->hdr.cd=0; + st->msg->hdr.rcode=RC_OK; + st->msg->hdr.qdcount=htons(name!=NULL); + st->msg->hdr.ancount=0; + st->msg->hdr.nscount=0; + st->msg->hdr.arcount=0; + + transl= sizeof(dns_hdr_t); + if(name) { + unsigned char *p = mempcpy((unsigned char *)(&st->msg->hdr+1),name,rrnlen); + unsigned short qtype=(st->lean_query?thint:QT_ALL); + PUTINT16(qtype,p); + PUTINT16(C_IN,p); + transl += rrnlen+4; + if(st->edns_query) + add_opt_pseudo_rr(&st->msg,&transl,&allocsz, + global.udpbufsize,RC_OK,0,0); + } + st->transl=transl; +#ifndef NO_TCP_QUERIES + st->msg->len=htons(st->transl); +#endif + st->recvbuf=NULL; + st->state=(USE_UDP(st)?QS_UDPINITIAL:QS_TCPINITIAL); + /* fall through */ + } + QS_QUERY_CASES: + tryagain: + rv=p_query_sm(st); + if (rv==-1) { + return -1; + } + if (rv!=RC_OK) { + pdnsd_free(st->msg); + pdnsd_free(st->recvbuf); + st->state=QS_DONE; + if(st->needs_testing) { + switch(st->s_errno) { + case ENETUNREACH: /* network unreachable */ + case EHOSTUNREACH: /* host unreachable */ + case ENOPROTOOPT: /* protocol unreachable */ + case ECONNREFUSED: /* port unreachable */ + case ENETDOWN: /* network down */ + case EHOSTDOWN: /* host down */ +#ifdef ENONET + case ENONET: /* machine not on the network */ +#endif + /* Mark this server as down for a period of time */ + sched_server_test(PDNSD_A(st),1,0); + st->needs_testing=0; + } + } + return rv; + } + /* rv==RC_OK */ + DEBUG_PDNSDA_MSG("Received reply from %s (msg len=%u).\n", PDNSDA2STR(PDNSD_A(st)), st->recvl); + DEBUG_DUMP_DNS_MSG(st->recvbuf, st->recvl); + + /* Basic sanity checks */ + if (st->recvlrecvbuf->id); + if (recvid!=st->myrid) { + DEBUG_MSG("ID mismatch: expected %04x, got %04x!\n", st->myrid, recvid); + goto discard_reply; + } + } + if (st->recvbuf->qr!=QR_RESP) { + DEBUG_MSG("The QR bit indicates this is a query, not a response!\n"); + goto discard_reply; + } + if (st->recvbuf->opcode!=OP_QUERY) { + DEBUG_MSG("Not a reply to a standard query (opcode=%u).\n",st->recvbuf->opcode); + goto discard_reply; + } + + rcode=st->recvbuf->rcode; +#if DEBUG>0 + { + char flgsbuf[DNSFLAGSMAXSTRSIZE]; + DEBUG_MSG("rcode=%u (%s), flags:%s\n", rcode, get_ename(rcode), dnsflags2str(st->recvbuf, flgsbuf)); + } +#endif + if (st->recvbuf->z!=0) { + DEBUG_MSG("Malformed response (nonzero Z bit).\n"); + goto discard_reply; + } + + if(st->needs_testing) { + /* We got an answer from this server, so don't bother with up tests for a while. */ + sched_server_test(PDNSD_A(st),1,1); + st->needs_testing=0; + } + + rv=rcode; + if(rcode==RC_OK || rcode==RC_NAMEERR) { + /* success or at least no requery is needed */ + st->state=QS_DONE; + break; + } + else if (entp) { + if(rcode==RC_SERVFAIL || rcode==RC_NOTSUPP || rcode==RC_REFUSED) { + if (st->msg->hdr.rd && !st->recvbuf->ra) { + /* seems as if we have got no recursion available. + We will have to do it by ourselves (sigh...) */ + DEBUG_PDNSDA_MSG("Server %s returned error code: %s." + " Maybe does not support recursive query?" + " Querying non-recursively.\n", + PDNSDA2STR(PDNSD_A(st)),get_ename(rcode)); + st->msg->hdr.rd=0; + goto resetstate_tryagain; + } + else if(rcode!=RC_SERVFAIL && st->edns_query && st->msg->hdr.arcount) + goto try_withoutedns; + else if (st->recvbuf->ancount && st->auth_serv==2) { + /* The name server returned a failure code, + but the answer section is not empty, + and the answer is from a server lower down the call chain. + Use this answer tentatively (it may be the + best we can get), but remember the failure. */ + DEBUG_PDNSDA_MSG("Server %s returned error code: %s," + " but the answer section is not empty." + " Using the answer tentatively.\n", + PDNSDA2STR(PDNSD_A(st)),get_ename(rcode)); + st->failed=3; + st->state=QS_DONE; + break; + } + } + else if(rcode==RC_FORMAT && st->edns_query && st->msg->hdr.arcount) + try_withoutedns: { + size_t transl; + /* Perhaps the remote server barfs when the query + contains an OPT RR in the additional section. + Try again with an empty addtional section. */ + DEBUG_PDNSDA_MSG("Server %s returned error code: %s." + " Maybe cannot handle EDNS?" + " Querying with empty additional section.\n", + PDNSDA2STR(PDNSD_A(st)),get_ename(rcode)); + transl=remove_opt_pseudo_rr(st->msg,st->transl); + if(transl!=0 && st->msg->hdr.arcount==0) { + st->transl=transl; +#ifndef NO_TCP_QUERIES + st->msg->len=htons(st->transl); +#endif + st->edns_query=0; + resetstate_tryagain: + st->myrid=get_rand16(); + st->msg->hdr.id=htons(st->myrid); + st->state=(USE_UDP(st)?QS_UDPINITIAL:QS_TCPINITIAL); + goto tryagain; + } + else { + DEBUG_PDNSDA_MSG("Internal error: could not remove additional section from query" + " to server %s\n", PDNSDA2STR(PDNSD_A(st))); + } + } + } + + discard_reply: + /* report failure */ + pdnsd_free(st->msg); + pdnsd_free(st->recvbuf); + /*close(st->sock);*/ + st->state=QS_DONE; +#if DEBUG>0 + if(entp) { + DEBUG_PDNSDA_MSG("Discarding reply from server %s\n", PDNSDA2STR(PDNSD_A(st))); + } +#endif + if (rv!=RC_OK) + return rv; + + return RC_SERVFAIL; /* mock error code */ + + default: /* we shouldn't get here */ + st->state=QS_DONE; + return RC_SERVFAIL; /* mock error code */ + } + + /* If we reach this code, we have successfully received an answer, + * because we have returned error codes on errors or -1 on AGAIN conditions. + * So we *should* have a usable dns record in recvbuf by now. + */ + rd= st->msg->hdr.rd; /* Save the 'Recursion Desired' bit of the query. */ + pdnsd_free(st->msg); + if(entp) { + time_t queryts=time(NULL); + size_t lcnt= ((size_t)st->recvl) - sizeof(dns_hdr_t); + unsigned char *rrp=(unsigned char *)(st->recvbuf+1); + dns_cent_array secs[3]={NULL,NULL,NULL}; +# define ans_sec secs[0] +# define auth_sec secs[1] +# define add_sec secs[2] + unsigned short qtype,flags,aa,neg_ans=0,reject_ans=0,num_ns=0; + int numoptrr; + edns_info_t ednsinfo= {0}; + + if (ntohs(st->recvbuf->qdcount)!=1) { + DEBUG_PDNSDA_MSG("Bad number of query records in answer from %s\n", + PDNSDA2STR(PDNSD_A(st))); + rv=RC_SERVFAIL; + goto free_recvbuf_return; + } + /* check & skip the query record. */ + { + unsigned char nbuf[DNSNAMEBUFSIZE]; + if ((rv=decompress_name((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, nbuf, NULL))!=RC_OK) { + DEBUG_PDNSDA_MSG("Cannot decompress QNAME in answer from %s\n", + PDNSDA2STR(PDNSD_A(st))); + rv=RC_SERVFAIL; + goto free_recvbuf_return; + } + if(!rhnicmp(nbuf,name)) { + DEBUG_PDNSDA_MSG("Answer from %s does not match query.\n", + PDNSDA2STR(PDNSD_A(st))); + rv=RC_SERVFAIL; + goto free_recvbuf_return; + } + } + + qtype=(st->lean_query?thint:QT_ALL); + if (lcnt<4) { + DEBUG_PDNSDA_MSG("Format error in reply from %s (message truncated in qtype or qclass).\n", + PDNSDA2STR(PDNSD_A(st))); + rv=RC_SERVFAIL; /* mock error code */ + goto free_recvbuf_return; + } + { + unsigned short qt,qc; + GETINT16(qt,rrp); + GETINT16(qc,rrp); + if(qt!=qtype) { + DEBUG_PDNSDA_MSG("qtype in answer (%u) from %s does not match expected qtype (%u).\n", + qt,PDNSDA2STR(PDNSD_A(st)),qtype); + rv=RC_SERVFAIL; + goto free_recvbuf_return; + } + } + lcnt-=4; + + st->aa= (st->recvbuf->aa && !st->failed); + st->tc= st->recvbuf->tc; + st->ra= (rd && st->recvbuf->ra); + + /* Don't flag cache entries from a truncated reply as authoritative. */ + aa= (st->aa && !st->tc); + flags=st->flags; + if (aa) flags|=CF_AUTH; + + + /* Initialize a dns_cent_t in the array for the answer section */ + if (!(ans_sec=DA_GROW1(ans_sec))) { + rv=RC_FATALERR; /* unrecoverable error */ + goto free_recvbuf_return; + } + /* By marking DF_AUTH, we mean authoritative AND complete. */ + if (!init_cent(&DA_INDEX(ans_sec,0), name, 0, 0, (aa && qtype==QT_ALL)?DF_AUTH:0 DBG1)) { + rv=RC_FATALERR; /* unrecoverable error */ + goto free_centarrays_recvbuf_return; + } + + /* Now read the answer, authority and additional sections, + storing the results in the arrays ans_sec,auth_sec and add_sec. + */ + numoptrr=0; + rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, ntohs(st->recvbuf->ancount), + flags, queryts, &ans_sec, &numoptrr, &ednsinfo); +#if DEBUG>0 + if(numoptrr!=0) { + DEBUG_MSG("Answer section in reply contains %d OPT pseudo-RRs!\n", numoptrr); + } +#endif + numoptrr=0; + if(rv==RC_OK) { + uint16_t nscount=ntohs(st->recvbuf->nscount); + if (nscount) { + rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, nscount, + flags|CF_ADDITIONAL, queryts, &auth_sec, &numoptrr, &ednsinfo); +#if DEBUG>0 + if(numoptrr!=0) { + DEBUG_MSG("Authority section in reply contains %d OPT pseudo-RRs!\n", numoptrr); + } +#endif + } + } + + numoptrr=0; + if(rv==RC_OK) { + uint16_t arcount=ntohs(st->recvbuf->arcount); + if (arcount) { + rv=rrs2cent((unsigned char *)st->recvbuf, st->recvl, &rrp, &lcnt, arcount, + flags|CF_ADDITIONAL, queryts, &add_sec, &numoptrr, &ednsinfo); + if(numoptrr!=0) { +#if DEBUG>0 + if(numoptrr!=1) { + DEBUG_MSG("Additional section in reply contains %d OPT pseudo-RRs!\n", numoptrr); + } + DEBUG_PDNSDA_MSG("Reply from %s contains OPT pseudosection: EDNS version = %u, udp size = %u, flag DO=%u\n", + PDNSDA2STR(PDNSD_A(st)), ednsinfo.version, ednsinfo.udpsize, ednsinfo.do_flg); +#endif + if(rcode!=ednsinfo.rcode) { + DEBUG_PDNSDA_MSG("Reply from %s contains unexpected EDNS rcode %u (%s)!\n", + PDNSDA2STR(PDNSD_A(st)), ednsinfo.rcode, get_ename(ednsinfo.rcode)); + rcode=ednsinfo.rcode; + /* Mark as failed, but use answer tentatively. */ + if(!st->failed) st->failed=1; + } + } + } + } + + if(!(rv==RC_OK || (rv==RC_TRUNC && st->recvbuf->tc))) { + DEBUG_PDNSDA_MSG(rv==RC_FORMAT?"Format error in reply from %s.\n": + rv==RC_TRUNC?"Format error in reply from %s (message unexpectedly truncated).\n": + rv==RC_SERVFAIL?"Inconsistent timestamps in reply from %s.\n": + "Out of memory while processing reply from %s.\n", + PDNSDA2STR(PDNSD_A(st))); + if(rv==RC_SERVFAIL) { + /* Inconsistent ttl timestamps and we are + enforcing strict RFC 2181 compliance. + Mark as failed, but use answer tentatively. */ + if(!st->failed) st->failed=1; + } + else { + if(rv!=RC_FATALERR) rv=RC_SERVFAIL; + goto free_ent_centarrays_recvbuf_return; + } + } + + { + /* Remember references to NS and SOA records in the answer or authority section + so that we can add this information to our own reply. */ + int i,n=DA_NEL(ans_sec); + for(i=0;iqname); + + if(getrrset_NS(cent)) + cent->c_ns=scnt; + if(getrrset_SOA(cent)) + cent->c_soa=scnt; + + if((qtype>=QT_MIN && qtype<=QT_MAX) || + (/* (qtype>=T_MIN && qtype<=T_MAX) && */ getrrset(cent,qtype)) || + (n==1 && cent->num_rrs==0)) + { + /* Match this name with names in the authority section */ + int j,m=DA_NEL(auth_sec); + for(j=0;jqname,cent->qname, &rem, NULL); + if(rem==0 && + /* Don't accept records for the root domain from name servers + that were not listed in the configuration file. */ + (ml || st->auth_serv!=2)) { + if(getrrset_NS(ce)) { + if(cent->c_ns==cundef || cent->c_nsc_ns=ml; + } + if(getrrset_SOA(ce)) { + if(cent->c_soa==cundef || cent->c_soac_soa=ml; + } + } + } + } + } + } + + /* Check whether the answer contains an IP address that should be rejected. */ + if(have_rejectlist(st)) { + int i; + int na4=nreject_a4(st); + addr4maskpair_t *a4arr=rejectlist_a4(st); +#if ALLOW_LOCAL_AAAA + int na6=nreject_a6(st); + addr6maskpair_t *a6arr=rejectlist_a6(st); +#endif + /* Check addresses in the answer, authority and additional sections. */ + for(i=0;i<3;++i) { + dns_cent_array sec=secs[i]; + int j,nce=DA_NEL(sec); + for(j=0;jrrs; rr; rr=rr->next) { + struct in_addr *a=(struct in_addr *)(rr->data); + int k; + for(k=0;ka,&am->mask)) { +#if DEBUG>0 + unsigned char nmbuf[DNSNAMEBUFSIZE]; char abuf[ADDRSTR_MAXLEN]; + DEBUG_PDNSDA_MSG("Rejecting answer from server %s because it contains an A record" + " for \"%s\" with an address in the reject list: %s\n", + PDNSDA2STR(PDNSD_A(st)), + rhn2str(cent->qname,nmbuf,sizeof(nmbuf)), + inet_ntop(AF_INET,a,abuf,sizeof(abuf))); +#endif + reject_ans=1; goto rejectlist_scan_done; + } + } + } + } +#if ALLOW_LOCAL_AAAA + rrset=getrrset_AAAA(cent); + if(rrset && na6) { + rr_bucket_t *rr; + for(rr=rrset->rrs; rr; rr=rr->next) { + struct in6_addr *a=(struct in6_addr *)(rr->data); + int k; + for(k=0;ka,&am->mask)) { +#if DEBUG>0 + unsigned char nmbuf[DNSNAMEBUFSIZE]; char abuf[INET6_ADDRSTRLEN]; + DEBUG_PDNSDA_MSG("Rejecting answer from server %s because it contains an AAAA record" + " for \"%s\" with an address in the reject list: %s\n", + PDNSDA2STR(PDNSD_A(st)), + rhn2str(cent->qname,nmbuf,sizeof(nmbuf)), + inet_ntop(AF_INET6,a,abuf,sizeof(abuf))); +#endif + reject_ans=1; goto rejectlist_scan_done; + } + } + } + } +#endif + } + } + rejectlist_scan_done:; + } + + /* negative caching for domains */ + if (rcode==RC_NAMEERR) { + DEBUG_PDNSDA_MSG("Server %s returned error code: %s\n", PDNSDA2STR(PDNSD_A(st)),get_ename(rcode)); + name_error: + neg_ans=1; + { + /* We did not get what we wanted. Cache according to policy */ + dns_cent_t *ent=&DA_INDEX(ans_sec,0); + int neg_domain_pol=global.neg_domain_pol; + if (neg_domain_pol==C_ON || (neg_domain_pol==C_AUTH && st->aa)) { + time_t ttl=global.neg_ttl; + + /* Try to find a SOA record that came with the reply. + */ + if(ent->c_soa!=cundef) { + unsigned scnt=rhnsegcnt(name); + dns_cent_t *cent; + if(ent->c_soac_soa)))) { + rr_set_t *rrset=getrrset_SOA(cent); + if (rrset && rrset->rrs) { + time_t min=soa_minimum(rrset->rrs); + ttl=rrset->ttl; + if(ttl>min) + ttl=min; + } + } + } + DEBUG_RHN_MSG("Caching domain %s negative with ttl %li\n",RHN2STR(name),(long)ttl); + negate_cent(ent,ttl,queryts); + if(st->nocache) ent->flags |= DF_NOCACHE; + goto cleanup_return_OK; + } else { + if(c_soa) *c_soa=ent->c_soa; + free_cent(ent DBG1); + rv=RC_NAMEERR; + goto add_additional; + } + } + } + + if(reject_ans) { + if(reject_policy(st)==C_NEGATE && st->failed<=1) + goto name_error; + else { + rv=RC_SERVFAIL; + goto free_ent_centarrays_recvbuf_return; + } + } + + if(global.deleg_only_zones && st->auth_serv<3) { /* st->auth_serv==3 means this server is a root-server. */ + int missingdelegation,authcnt; + /* The deleg_only_zones data may change due to runtime reconfiguration, + therefore use locks. */ + lock_server_data(); + missingdelegation=0; authcnt=0; + { + int i,n=DA_NEL(global.deleg_only_zones); unsigned rem,zrem; + for(i=0;iqname,DA_INDEX(global.deleg_only_zones,l),&rem,&zrem) && zrem==0) { + if(rem) break; + else goto try_next_auth; + } + } + goto delegation_OK; + } + try_next_auth:; + } + } +#if DEBUG>0 + { + unsigned char nmbuf[DNSNAMEBUFSIZE],zbuf[DNSNAMEBUFSIZE]; + DEBUG_PDNSDA_MSG(authcnt?"%s is in %s zone, but no delegation found in answer returned by server %s\n" + :"%s is in %s zone, but no authority information provided by server %s\n", + rhn2str(name,nmbuf,sizeof(nmbuf)), rhn2str(DA_INDEX(global.deleg_only_zones,i),zbuf,sizeof(zbuf)), + PDNSDA2STR(PDNSD_A(st))); + } +#endif + missingdelegation=1; + } + delegation_OK:; + } + unlock_server_data(); + + if(missingdelegation) { + if(authcnt && st->failed<=1) { + /* Treat this as a nonexistant name. */ + goto name_error; + } + else if(st->auth_serv<2) { + /* If this is one of the servers obtained from the list + pdnsd was configured with, treat this as a failure. + Hopefully one of the other servers in the list will + return a non-empty authority section. + */ + rv=RC_SERVFAIL; + goto free_ent_centarrays_recvbuf_return; + } + } + } + + { + /* Negative caching of rr sets */ + dns_cent_t *ent=&DA_INDEX(ans_sec,0); + + if(!ent->num_rrs) neg_ans=1; + + if (thint>=T_MIN && thint<=T_MAX && !getrrset(ent,thint) && !st->tc && st->failed<=1) { + /* We did not get what we wanted. Cache according to policy */ + int neg_rrs_pol=global.neg_rrs_pol; + if (neg_rrs_pol==C_ON || (neg_rrs_pol==C_AUTH && aa) || + (neg_rrs_pol==C_DEFAULT && (aa || st->ra))) + { + time_t ttl=global.neg_ttl; + rr_set_t *rrset=getrrset_SOA(ent); + dns_cent_t *cent; + unsigned scnt; + /* If we received a SOA, we should take the ttl of that record. */ + if ((rrset && rrset->rrs) || + /* Try to find a SOA record higher up the hierarchy that came with the reply. */ + ((cent=lookup_cent_array(auth_sec, + (ent->c_soa!=cundef && ent->c_soa<(scnt=rhnsegcnt(name)))? + skipsegs(name,scnt-ent->c_soa): + name)) && + (rrset=getrrset_SOA(cent)) && rrset->rrs)) + { + time_t min=soa_minimum(rrset->rrs); + ttl=rrset->ttl; + if(ttl>min) + ttl=min; + } + DEBUG_RHN_MSG("Caching type %s for domain %s negative with ttl %li\n",getrrtpname(thint),RHN2STR(name),(long)ttl); + if (!add_cent_rrset_by_type(ent, thint, ttl, queryts, CF_NEGATIVE|flags DBG1)) { + rv=RC_FATALERR; + goto free_ent_centarrays_recvbuf_return; + } + } + } + } + + if (st->failed<=1) { + /* The domain names of all name servers found in the answer and authority sections are placed in *ns, + which is automatically grown. */ + /* dns_cent_array secs[2]={ans_sec,auth_sec}; */ + int i; + for(i=0;i<2;++i) { + dns_cent_array sec=secs[i]; + int j,n=DA_NEL(sec); + for(j=0;jqname) || st->auth_serv!=2) && + /* Don't accept possibly poisoning nameserver entries in paranoid mode */ + (st->trusted || !st->nsdomain || (domain_match(st->nsdomain, cent->qname, &rem,NULL),rem==0)) && + /* The following test is actually redundant and should never fail. */ + *(cent->qname)!=0xff) + { + /* Some nameservers obviously choose to send SOA records instead of NS ones. + * Although I think that this is poor behaviour, we'll have to work around that. */ + static const unsigned short nstypes[2]={T_NS,T_SOA}; + int k; + for(k=0;k<2;++k) { + rr_set_t *rrset=getrrset(cent,nstypes[k]); + if(rrset) { + rr_bucket_t *rr; + unsigned short first=1; + for(rr=rrset->rrs; rr; rr=rr->next) { + size_t sz1,sz2; + unsigned char *p; + /* Skip duplicate records */ + for(p=dlist_first(*ns); p; p=dlist_next(p)) { + if(rhnicmp(*p==0xff?p+1:skiprhn(p),(unsigned char *)(rr->data))) + goto next_nsr; + } + /* add to the nameserver list. + Here we use a little compression trick: if + the first byte of a name is 0xff, this means + repeat the previous name. + */ + sz1= (first?rhnlen(cent->qname):1); + sz2=rhnlen((unsigned char *)(rr->data)); + if (!(*ns=dlist_grow(*ns,sz1+sz2))) { + rv=RC_FATALERR; + goto free_ent_centarrays_recvbuf_return; + } + p=dlist_last(*ns); + if(first) { + first=0; + p=mempcpy(p,cent->qname,sz1); + } + else + *p++ = 0xff; /* 0xff means 'idem' */ + /* This will only copy the first name, which is the NS */ + memcpy(p,(unsigned char *)(rr->data),sz2); + ++num_ns; + next_nsr:; + } + } + } + } + } + } + } + cleanup_return_OK: + if(st->failed && neg_ans && num_ns==0) { + DEBUG_PDNSDA_MSG("Answer from server %s does not contain usable records.\n", + PDNSDA2STR(PDNSD_A(st))); + rv=RC_SERVFAIL; + goto free_ns_ent_centarrays_recvbuf_return; + } + if(!(*entp=malloc(sizeof(dns_cent_t)))) { + rv=RC_FATALERR; + goto free_ns_ent_centarrays_recvbuf_return; + } + **entp=DA_INDEX(ans_sec,0); + rv=RC_OK; + add_additional: + if (!st->failed && !reject_ans) { + /* Add the additional RRs to the cache. */ + /* dns_cent_array secs[3]={ans_sec,auth_sec,add_sec}; */ + int i; +#if DEBUG>0 + if(debug_p && neg_ans) { + int j,n=DA_NEL(ans_sec); + for(j=1; jqname) || st->auth_serv!=2) { + unsigned int rem; + if(st->trusted || !st->nsdomain || (domain_match(st->nsdomain, cent->qname, &rem, NULL),rem==0)) + add_cache(cent); + else { +#if DEBUG>0 + unsigned char nmbuf[DNSNAMEBUFSIZE],nsbuf[DNSNAMEBUFSIZE]; + DEBUG_MSG("Record for %s not in nsdomain %s; dropped.\n", + rhn2str(cent->qname,nmbuf,sizeof(nmbuf)),rhn2str(st->nsdomain,nsbuf,sizeof(nsbuf))); +#endif + } + } + else { +#if DEBUG>0 + static const char *const secname[3]={"answer","authority","additional"}; + DEBUG_PDNSDA_MSG("Record(s) for root domain in %s section from %s dropped.\n", secname[i],PDNSDA2STR(PDNSD_A(st))); +#endif + } + } + } + } + goto free_centarrays_recvbuf_return; + + free_ns_ent_centarrays_recvbuf_return: + dlist_free(*ns); *ns=NULL; + free_ent_centarrays_recvbuf_return: + if(DA_NEL(ans_sec)>=1) free_cent(&DA_INDEX(ans_sec,0) DBG1); + free_centarrays_recvbuf_return: + { + /* dns_cent_array secs[3]={ans_sec,auth_sec,add_sec}; */ + int i; + for(i=0;i<3;++i) { + dns_cent_array sec=secs[i]; + int j,n=DA_NEL(sec); + /* The first entry in the answer section is treated separately, so skip that one. */ + for(j= !i; jrecvbuf); + return rv; +} + +/* + * Cancel a query, freeing all resources. Any query state is valid as input (this may even be called + * if a call to p_exec_query already returned error or success) + */ +static void p_cancel_query(query_stat_t *st) +{ + switch (st->state) { + QS_WRITE_CASES: + QS_READ_CASES: + close(st->sock); + /* fall through */ + case QS_TCPINITIAL: + case QS_UDPINITIAL: + pdnsd_free(st->recvbuf); + pdnsd_free(st->msg); + } + if(st->state!=QS_INITIAL && st->state!=QS_DONE) + st->state=QS_CANCELED; +} + +#if 0 +/* + * Initialize a query_serv_t (server list for parallel query) + * This is there for historical reasons only. + */ +inline static void init_qserv(query_stat_array *q) +{ + *q=NULL; +} +#endif + +/* + * Add a server entry to a query_serv_t + * Note: only a reference to nsdomain is copied, not the name itself. + * Be sure to free the q-list before freeing the name. + */ +static int add_qserv(query_stat_array *q, pdnsd_a2 *a, int port, time_t timeout, unsigned flags, + char nocache, char lean_query, char edns_query, char auth_s, char needs_testing, char trusted, + const unsigned char *nsdomain, rejectlist_t *rejectlist) +{ + query_stat_t *qs; + + if ((*q=DA_GROW1(*q))==NULL) { + DEBUG_MSG("Out of memory in add_qserv()\n"); + return 0; + } + + qs=&DA_LAST(*q); +#ifdef ENABLE_IPV4 + if (run_ipv4) { + memset(&qs->a.sin4,0,sizeof(qs->a.sin4)); + qs->a.sin4.sin_family=AF_INET; + qs->a.sin4.sin_port=htons(port); + qs->a.sin4.sin_addr=a->ipv4; + SET_SOCKA_LEN4(qs->a.sin4); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + memset(&qs->a.sin6,0,sizeof(qs->a.sin6)); + qs->a.sin6.sin6_family=AF_INET6; + qs->a.sin6.sin6_port=htons(port); + qs->a.sin6.sin6_flowinfo=IPV6_FLOWINFO; + qs->a.sin6.sin6_addr=a->ipv6; + SET_SOCKA_LEN6(qs->a.sin6); + + qs->a4fallback=a->ipv4; + } +#endif + qs->timeout=timeout; + qs->flags=flags; + qs->nocache=nocache; + qs->auth_serv=auth_s; + qs->lean_query=lean_query; + qs->edns_query=edns_query; + qs->needs_testing=needs_testing; + qs->trusted=trusted; + qs->aa=0; + qs->tc=0; + qs->ra=0; + qs->failed=0; + qs->nsdomain=nsdomain; /* Note: only a reference is copied, not the name itself! */ + qs->rejectlist=rejectlist; + + qs->state=QS_INITIAL; + qs->qm=global.query_method; + qs->s_errno=0; + return 1; +} + +/* Test whether two pdnsd_a2 addresses are the same. */ +inline __attribute__((always_inline)) +static int same_inaddr2_2(pdnsd_a2 *a, pdnsd_a2 *b) +{ + return SEL_IPVER( a->ipv4.s_addr==b->ipv4.s_addr, + IN6_ARE_ADDR_EQUAL(&a->ipv6,&b->ipv6) && + a->ipv4.s_addr==b->ipv4.s_addr ); +} + +/* This can be used to check whether a server address was already used in a + previous query_stat_t entry. */ +inline static int query_stat_same_inaddr2(query_stat_t *qs, pdnsd_a2 *b) +{ + return SEL_IPVER( qs->a.sin4.sin_addr.s_addr==b->ipv4.s_addr, + IN6_ARE_ADDR_EQUAL(&qs->a.sin6.sin6_addr,&b->ipv6) && + qs->a4fallback.s_addr==b->ipv4.s_addr ); +} + + +/* + * Free resources used by a query_serv_t + * There for historical reasons only. + */ +inline static void del_qserv(query_stat_array q) +{ + da_free(q); +} + +struct qstatnode_s { + query_stat_array qa; + struct qstatnode_s *next; +}; +typedef struct qstatnode_s qstatnode_t; + +struct qhintnode_s { + const unsigned char *nm; + int tp; + struct qhintnode_s *next; +}; +/* typedef struct qhintnode_s qhintnode_t; */ /* Already defined in dns_query.h */ + +static int auth_ok(query_stat_array q, const unsigned char *name, int thint, dns_cent_t *ent, + int hops, qstatnode_t *qslist, qhintnode_t *qhlist, + query_stat_t *qse, dlist ns, query_stat_array *serv); +static int p_dns_cached_resolve(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **cachedp, + int hops, qstatnode_t *qslist, qhintnode_t *qhlist, time_t queryts, + unsigned char *c_soa); +static int simple_dns_cached_resolve(atup_array atup_a, int port, char edns_query, time_t timeout, + const unsigned char *name, int thint, dns_cent_t **cachedp); + + +/* + * Performs a semi-parallel query on the servers in q. PAR_QUERIES are executed parallel at a time. + * name is the query name in dns protocol format (number.string etc), + * ent is the dns_cent_t that will be filled. + * hops is the number of recursions left. + * qslist should refer to a list of server arrays used higher up in the calling chain. This way we can + * avoid name servers that have already been tried for this name. + * qhlist should refer to a list of names that we are trying to resolve higher up in the calling chain. + * These names should be avoided further down the chain, or we risk getting caught in a wasteful cycle. + * thint is a hint on the requested query type used to decide whether an aa record must be fetched + * or a non-authoritative answer will be enough. + * + * nocache is needed because we add AA records to the cache. If the nocache flag is set, we do not + * take the original values for the record, but flags=0 and ttl=0 (but only if we do not already have + * a cached record for that set). These settings cause the record be purged on the next cache addition. + * It will also not be used again. + * + * The return value of p_recursive_query() has the same meaning as that of p_dns_cached_resolve() + * (see below). + */ +static int p_recursive_query(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **entp, + int *nocache, int hops, qstatnode_t *qslist, qhintnode_t *qhlist, + unsigned char *c_soa) +{ + dns_cent_t *ent,*entsave=NULL; + int i,j,k; + int rv=RC_SERVFAIL; + int qualval=0; + query_stat_t *qse=NULL; /* Initialized to inhibit compiler warning */ + dlist ns=NULL,nssave=NULL; + query_stat_array serv=NULL,servsave=NULL; + +# define W_AUTHOK 8 +# define W_NOTFAILED 2 +# define W_NOTTRUNC 1 +# define NOTFAILMASK 6 +# define GOODQUAL (W_AUTHOK+3*W_NOTFAILED) +# define save_query_result(ent,qs,ns,serv,authok) \ + { \ + int qval = authok*W_AUTHOK + (3-qs->failed)*W_NOTFAILED + (!qs->tc)*W_NOTTRUNC; \ + if(entsave && qval>qualval) { \ + /* Free the old copy, because the new result is better. */ \ + free_cent(entsave DBG1); \ + pdnsd_free(entsave); \ + entsave=NULL; \ + del_qserv(servsave); \ + dlist_free(nssave); \ + } \ + if(!entsave) { \ + entsave=ent; \ + servsave=serv; \ + /* The serv array contains references to data within the ns list, \ + so we need to save a copy of the ns list as well! */ \ + if(DA_NEL(serv)>0) nssave=ns; else {nssave=NULL;dlist_free(ns);} \ + qualval=qval; \ + qse=qs; \ + } \ + else { \ + /* We already have a copy, free the present one. */ \ + free_cent(ent DBG1); \ + pdnsd_free(ent); \ + del_qserv(serv); \ + dlist_free(ns); \ + } \ + serv=NULL; \ + ns=NULL; \ + } + + { + time_t ts0=time(NULL),global_timeout=global.timeout; + int dc=0,mc=0,nq=DA_NEL(q),parqueries=global.par_queries; + + for (j=0; jnq) mc=nq; + + /* First, call p_exec_query once for each parallel set to initialize. + * Then, as long as not all have the state QS_DONE or we have a timeout, + * build a poll/select set for all active queries and call them accordingly. */ + for (i=dc;i=j) { + /* The below should not happen any more, but may once again + * (immediate success) */ + DEBUG_PDNSDA_MSG("Sending query to %s\n", PDNSDA2STR(PDNSD_A(qs))); + retryquery: + rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa); + if (rv==RC_OK) { + int authok; + DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs))); + if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) { + if(authok>=0) { + if(!qs->failed +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + && !(qs->qm==UDP_TCP && qs->tc) +#endif + ) + { + qse=qs; + mc=i; /* No need to cancel queries beyond i */ + goto done; + } + } + else { + mc=i; /* No need to cancel queries beyond i */ + goto free_ent_return_failed; + } + } + /* We do not have a satisfactory answer. + However, we will save a copy in case none of the other + servers in the q list give a satisfactory answer either. + */ + save_query_result(ent,qs,ns,serv,authok); +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + if(qs->qm==UDP_TCP && qs->tc) { + switch_to_tcp(qs); + DEBUG_PDNSDA_MSG("Reply from %s was truncated. Trying again using TCP.\n", + PDNSDA2STR(PDNSD_A(qs))); + goto retryquery; + } +#endif + } + else if (rv==RC_NAMEERR || rv==RC_FATALERR) { + mc=i; /* No need to cancel queries beyond i */ + goto done; + } + } + if (qs->state==QS_DONE && i==dc) + dc++; + } + if (dcstate!=QS_DONE) { + if (i>=j && qs->timeout>maxto) + maxto=qs->timeout; +#ifdef NO_POLL + if (qs->sock>maxfd) { + maxfd=qs->sock; + PDNSD_ASSERT(maxfdstate) { + QS_READ_CASES: + FD_SET(qs->sock,&reads); + break; + QS_WRITE_CASES: + FD_SET(qs->sock,&writes); + break; + } +#else + polls[pc].fd=qs->sock; + switch (qs->state) { + QS_READ_CASES: + polls[pc].events=POLLIN; + break; + QS_WRITE_CASES: + polls[pc].events=POLLOUT; + break; + default: + polls[pc].events=0; + } +#endif + pc++; + } + } + if (pc==0) { + /* In this case, ALL are done and we do not need to cancel any + * query. */ + dc=mc; + break; + } + now=time(NULL); + maxto -= now-ts; + if (mc==nq) { +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + /* Don't use the global timeout if there are TCP queries + we might want to retry using UDP. */ + for (i=j;imaxto) maxto=globto; + } +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + skip_globto:; +#endif + } +#ifdef NO_POLL + tv.tv_sec=(maxto>0)?maxto:0; + tv.tv_usec=0; + nevents=select(maxfd+1,&reads,&writes,NULL,&tv); +#else + nevents=poll(polls,pc,(maxto>0)?(maxto*1000):0); +#endif + if (nevents<0) { + /* if(errno==EINTR) + continue; */ + log_warn("poll/select failed: %s",strerror(errno)); + goto done; + } + if (nevents==0) { + /* We have timed out. Mark the unresponsive servers so that we can consider + them for retesting later on. We will continue to listen for replies from + these servers as long as we have additional servers to try. */ + for (i=j;istate!=QS_DONE && qs->needs_testing) + qs->needs_testing=2; +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + if (tentative_tcp_query(qs)) { + /* We timed out while waiting for a TCP connection. + Try again using UDP. + */ + close(qs->sock); + switch_to_udp(qs); + DEBUG_PDNSDA_MSG("TCP connection to %s timed out. Trying to use UDP.\n", + PDNSDA2STR(PDNSD_A(qs))); + + rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa); + /* In the unlikely case of immediate success */ + if (rv==RC_OK) { + int authok; + DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs))); + if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) { + if(authok>=0) { + if(!qs->failed) { + qse=qs; + goto done; + } + } + else + goto free_ent_return_failed; + } + save_query_result(ent,qs,ns,serv,authok); + } + else if (rv==RC_NAMEERR || rv==RC_FATALERR) { + goto done; + } + ++nevents; + } +#endif + } +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + if (mc==nq) { + /* We will not try additional servers, but we might want to try again + using UDP instead of TCP + */ + if(nevents && (time(NULL)-ts0)state!=QS_DONE) { + int srv_event=0; + /* This detection may seem suboptimal, but normally, we have at most 2-3 parallel + * queries, and anything else would be higher overhead, */ +#ifdef NO_POLL + switch (qs->state) { + QS_READ_CASES: + srv_event=FD_ISSET(qs->sock,&reads); + break; + QS_WRITE_CASES: + srv_event=FD_ISSET(qs->sock,&writes); + break; + } +#else + do { + PDNSD_ASSERT(icsock); + /* + * In case of an error, reenter the state machine + * to catch it. + */ + switch (qs->state) { + QS_READ_CASES: + srv_event=polls[k].revents&(POLLIN|POLLERR|POLLHUP|POLLNVAL); + break; + QS_WRITE_CASES: + srv_event=polls[k].revents&(POLLOUT|POLLERR|POLLHUP|POLLNVAL); + break; + } +#endif + if (srv_event) { + --nevents; + retryquery2: + rv=p_exec_query(&ent, name, thint, qs,&ns,c_soa); + if (rv==RC_OK) { + int authok; + DEBUG_PDNSDA_MSG("Query to %s succeeded.\n", PDNSDA2STR(PDNSD_A(qs))); + if((authok=auth_ok(q, name, thint, ent, hops, qslist, qhlist, qs, ns, &serv))) { + if(authok>=0) { + if(!qs->failed +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + && !(qs->qm==UDP_TCP && qs->tc) +#endif + ) + { + qse=qs; + goto done; + } + } + else + goto free_ent_return_failed; + } + save_query_result(ent,qs,ns,serv,authok); +#if !defined(NO_TCP_QUERIES) && !defined(NO_UDP_QUERIES) + if(qs->qm==UDP_TCP && qs->tc) { + switch_to_tcp(qs); + DEBUG_PDNSDA_MSG("Reply from %s was truncated. Trying again using TCP.\n", + PDNSDA2STR(PDNSD_A(qs))); + goto retryquery2; + } +#endif + } + else if (rv==RC_NAMEERR || rv==RC_FATALERR) { + goto done; + } + } + } + /* recheck, this might have changed after the last p_exec_query */ + if (qs->state==QS_DONE && i==dc) + dc++; + } + if(nevents>0) { + /* We have not managed to handle all the events reported by poll/select. + Better call it quits, or we risk getting caught in a wasteful cycle. + */ + if(++poll_errs<=MAXPOLLERRS) + log_error("%d unhandled poll/select event(s) in p_recursive_query() at %s, line %d.",nevents,__FILE__,__LINE__); + rv=RC_SERVFAIL; + goto done; + } + } while (dc 1) + ++n; + if(n>0) { + pdnsd_a addrs[n]; /* variable length array */ + k=0; + for (i=0;ineeds_testing > 1) + addrs[k++]= *PDNSD_A(qs); + } + sched_server_test(addrs,n,-1); + } + } + } + + if(entsave) { + /* + * If we didn't get rrs from any of the authoritative servers, or the answers were + * unsatisfactory for another reason, take the one we had. + * However, raise the CF_NOCACHE flag, so that it won't be used again (outside the + * cache latency period). + */ + DEBUG_PDNSDA_MSG("Using %s reply from %s.\n", + !(qualval&NOTFAILMASK)? "reportedly failed": + !(qualval&W_NOTFAILED)? "inconsistent": + !(qualval&W_NOTTRUNC)? "truncated": + !(qualval&W_AUTHOK)? "non-authoritative": "good", + PDNSDA2STR(PDNSD_A(qse))); + ent=entsave; + serv=servsave; + ns=nssave; + if(qualvalflags&DF_NEGATIVE)) { + int jlim= RRARR_LEN(ent); + for (j=0; jflags |= CF_NOCACHE; + } + } + else /* Very unlikely, but not impossible. */ + ent->flags |= DF_NOCACHE; + } + rv=RC_OK; + } + else if (rv!=RC_OK) { + if(rv==RC_FATALERR) { + DEBUG_MSG("Unrecoverable error encountered while processing query.\n"); + rv=RC_SERVFAIL; + } + DEBUG_MSG("%sReturning error code \"%s\"\n", + rv!=RC_NAMEERR? "No query succeeded. ": "", + get_ename(rv)); + goto clean_up_return; + } + + if(nocache) *nocache=qse->nocache; + + if (DA_NEL(serv)>0) { + /* Authority records present. Ask them, because the answer was non-authoritative. */ + qstatnode_t qsn={q,qslist}; + unsigned char save_ns=ent->c_ns,save_soa=ent->c_soa; + + if(qse->aa || qse->ra) { + /* The server claimed to be authoritative or have recursion available, + yet we did not completely trust the answer for some reason. + We will try to ask the servers in the authority records, + but in case we fail, we will save a copy of the answer. */ + entsave=ent; + } + else { + free_cent(ent DBG1); + pdnsd_free(ent); + entsave=NULL; + } + rv=p_dns_cached_resolve(serv, name, thint,&ent,hops-1,&qsn,qhlist,time(NULL),c_soa); + if(rv==RC_OK || rv==RC_CACHED || (rv==RC_STALE && !entsave)) { + if(save_ns!=cundef && (ent->c_ns==cundef || ent->c_nsc_ns=save_ns; + if(save_soa!=cundef && (ent->c_soa==cundef || ent->c_soac_soa=save_soa; + goto free_entsave; + } + else if(rv==RC_NAMEERR) { + if(c_soa && save_soa!=cundef && (*c_soa==cundef || *c_soaaa? "be authoritative": "have recursion available"); + ent=entsave; + rv=RC_OK; + } + } + + clean_up_return: + /* Always free the serv array before freeing the ns list, + because the serv array contains references to data within the ns list! */ + del_qserv(serv); + dlist_free(ns); + + if(rv==RC_OK || rv==RC_CACHED || rv==RC_STALE) *entp=ent; + return rv; +# undef save_query_result +} + +/* auth_ok returns 1 if we don't need an authoritative answer or + if we can find servers to ask for an authoritative answer. + In the latter case these servers will be added to the *serv list. + A return value of 0 means the answer is not satisfactory in the + previous sense. + A return value of -1 indicates an error. +*/ +static int auth_ok(query_stat_array q, const unsigned char *name, int thint, dns_cent_t *ent, + int hops, qstatnode_t *qslist, qhintnode_t *qhlist, + query_stat_t *qse, dlist ns, query_stat_array *serv) +{ + int retval=0; + + /* If the answer was obtained from a name server which returned a failure code, + the answer is never satisfactory. */ + if(qse->failed > 1) return 0; + + /* + Look into the query type hint. If it is a wildcard (QT_*), we need an authoritative answer. + Same if there is no record that answers the query. + This test will also succeed if we have a negative cached record. This is done purposely. + */ +#define aa_needed ((thint>=QT_MIN && thint<=QT_MAX) || \ + ((thint>=T_MIN && thint<=T_MAX) && \ + (!have_rr(ent,thint) && !have_rr_CNAME(ent)))) + + /* We will want to query authoritative servers if all of the following conditions apply: + + 1) The server from which we got the answer was not configured as "proxy only". + 2) The answer is not a negatively cached domain (i.e. the server did not reply with NXDOMAIN). + 3) The query type is a wild card (QT_*), or no record answers the query. + 4) The answer that we have is non-authoritative. + */ + if(!(qse->auth_serv && !(ent->flags&DF_NEGATIVE) && aa_needed)) + return 1; + + if(qse->aa) { + /* The reply we have claims to be authoritative. + However, I have seen cases where name servers raise the authority flag incorrectly (groan...), + so as a work-around, we will check whether the domains for which the servers in the ns + list are responsible, match the queried name better than the domain for which the + last server was responsible. */ + unsigned char *nsdomain; + + if(!qse->nsdomain) + return 1; + + nsdomain=dlist_first(ns); + if(!nsdomain) + return 1; + for(;;) { + unsigned int rem,crem; + domain_match(nsdomain,qse->nsdomain,&rem,&crem); + if(!(rem>0 && crem==0)) + return 1; + domain_match(nsdomain,name,&rem,NULL); + if(rem!=0) + return 1; + do { + nsdomain=dlist_next(nsdomain); + if(!nsdomain) + goto done_checkauth; + } while(*nsdomain==0xff); /* Skip repeats. */ + } + done_checkauth:; + + /* The name servers in the ns list are a better match for the queried name than + the server from which we got the last reply, so ignore the aa flag. + */ +#if DEBUG>0 + if(debug_p) { + unsigned char dbuf[DNSNAMEBUFSIZE],sdbuf[DNSNAMEBUFSIZE]; + nsdomain=dlist_first(ns); + DEBUG_PDNSDA_MSG("The name server %s which is responsible for the %s domain, raised the aa flag, but appears to delegate to the sub-domain %s\n", + PDNSDA2STR(PDNSD_A(qse)), + rhn2str(qse->nsdomain,dbuf,sizeof(dbuf)), + rhn2str(nsdomain,sdbuf,sizeof(sdbuf))); + } +#endif + } + + /* The answer was non-authoritative. Try to build a list of addresses of authoritative servers. */ + if (hops>0) { + unsigned char *nsdomp, *nsdomain=NULL; + rr_set_t *localrrset=NULL; + rr_bucket_t *localrr=NULL; + for (nsdomp=dlist_first(ns);;) { + unsigned char *nsname=NULL; /* Initialize to inhibit compiler warning. */ + int nserva, ia, n; + pdnsd_a2 serva[MAXNAMESERVIPS]; + + /* Get next name server. */ + if(localrr) { + /* Use next locally defined NS record. */ + nsname=(unsigned char *)(localrr->data); + localrr= localrr->next; + } + else { + if(localrrset) { + /* clean up rrset */ + del_rrset(localrrset DBG1); + localrrset=NULL; + } + if(!nsdomp) + break; + else if(*nsdomp!=0xff) { + /* New domain. */ + nsdomain=nsdomp; + if (global.paranoid) { + unsigned int rem; + /* paranoia mode: don't query name servers that are not responsible */ + domain_match(nsdomain,name,&rem,NULL); + if (rem!=0) { +#if DEBUG>0 + unsigned char nmbuf[DNSNAMEBUFSIZE],dbuf[DNSNAMEBUFSIZE],nsbuf[DNSNAMEBUFSIZE]; + DEBUG_MSG("The name server %s is responsible for the %s domain, which does not match %s\n", + rhn2str(nsname,nsbuf,sizeof(nsbuf)), + rhn2str(nsdomain,dbuf,sizeof(dbuf)), + rhn2str(name,nmbuf,sizeof(nmbuf))); +#endif + /* Skip records in ns list for the same domain. */ + do { + nsdomp=dlist_next(nsdomp); + } while (nsdomp && *nsdomp==0xff); + continue; + } + } + /* Check if we have locally defined NS records, because + they will override the ones provided by remote servers. + */ + localrrset=lookup_cache_local_rrset(nsdomain,T_NS); + if(localrrset) { + /* Skip records in ns list for the same domain. */ + do { + nsdomp=dlist_next(nsdomp); + } while (nsdomp && *nsdomp==0xff); + localrr=localrrset->rrs; + if(!localrr) continue; + nsname=(unsigned char *)(localrr->data); + localrr= localrr->next; + } + else { + nsname=skiprhn(nsdomp); + nsdomp=dlist_next(nsdomp); + } + } + else { + /* domain repeated. */ + nsname= nsdomp+1; + nsdomp=dlist_next(nsdomp); + } + } + /* look it up in the cache or resolve it if needed. + The records received should be in the cache now, so it's ok. + */ + nserva=0; + + { + const unsigned char *nm=name; + int tp=thint; + qhintnode_t *ql=qhlist; + + for(;;) { + if(rhnicmp(nm,nsname) && tp==T_A) { + DEBUG_RHN_MSG("Not looking up address for name server \"%s\": " + "risk of infinite recursion.\n",RHN2STR(nsname)); + goto skip_server; + } + if(!ql) break; + nm=ql->nm; + tp=ql->tp; + ql=ql->next; + } + { + qhintnode_t qhn={name,thint,qhlist}; + dns_cent_t *servent; + if (r_dns_cached_resolve(nsname,T_A, &servent, hops-1, &qhn,time(NULL),NULL)==RC_OK) { +#ifdef ENABLE_IPV4 + if (run_ipv4) { + rr_set_t *rrset=getrrset_A(servent); + rr_bucket_t *rrs; + if (rrset) + for(rrs=rrset->rrs; rrs && nservanext) + serva[nserva++].ipv4 = *((struct in_addr *)rrs->data); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + rr_set_t *rrset6=getrrset_AAAA(servent); + rr_bucket_t *rrs6= (rrset6? rrset6->rrs: NULL); + rr_set_t *rrset4=getrrset_A(servent); + rr_bucket_t *rrs4= (rrset4? rrset4->rrs: NULL); + while(nservadata); + rrs6=rrs6->next; + if (rrs4) { + /* Store IPv4 address as fallback. */ + serva[nserva].ipv4 = *((struct in_addr *)rrs4->data); + rrs4=rrs4->next; + } + else + serva[nserva].ipv4.s_addr=INADDR_ANY; + } + else if (rrs4) { + struct in_addr *ina = (struct in_addr *)rrs4->data; + struct in6_addr *in6a = &serva[nserva].ipv6; + IPV6_MAPIPV4(ina,in6a); + serva[nserva].ipv4.s_addr=INADDR_ANY; + rrs4=rrs4->next; + } + else + break; + ++nserva; + } + } +#endif + free_cent(servent DBG1); + pdnsd_free(servent); + } + } + } + +#if DEBUG>0 + if(nserva==0) { + DEBUG_RHN_MSG("Looking up address for name server \"%s\" failed.\n",RHN2STR(nsname)); + } +#endif + n=DA_NEL(*serv); + for(ia=0; iastate==QS_DONE && equiv_inaddr2(PDNSD_A(qs),pserva)) { + DEBUG_PDNSDA_MSG("Not trying name server %s, already queried.\n", PDNSDA2STR(PDNSD_A2_TO_A(pserva))); + goto skip_server_addr; + } + } + if(!ql) break; + qa=ql->qa; + ql=ql->next; + } + } + + /* lean query mode is inherited. CF_AUTH and CF_ADDITIONAL are not (as specified + * in CFF_NOINHERIT). */ + if (!add_qserv(serv, pserva, 53, qse->timeout, qse->flags&~CFF_NOINHERIT, 0, + qse->lean_query,qse->edns_query,2,0,!global.paranoid,nsdomain, + inherit_rejectlist(qse)?qse->rejectlist:NULL)) + { + return -1; + } + retval=1; + skip_server_addr:; + } + skip_server:; + } +#if DEBUG>0 + if(!retval) { + DEBUG_PDNSDA_MSG("No remaining authoritative name servers to try in authority section from %s.\n", PDNSDA2STR(PDNSD_A(qse))); + } +#endif + } + else { + DEBUG_MSG("Maximum hops count reached; not trying any more name servers.\n"); + } + + return retval; + +#undef aa_needed +} + +/* + * This checks the given name to resolve against the access list given for the server using the + * include=, exclude= and policy= parameters. + */ +static int use_server(servparm_t *s, const unsigned char *name) +{ + int i,n=DA_NEL(s->alist); + + for (i=0;ialist,i); + unsigned int nrem,lrem; + domain_match(name,sl->domain,&nrem,&lrem); + if(!lrem && (!sl->exact || !nrem)) + return sl->rule==C_INCLUDED; + } + + if (s->policy==C_SIMPLE_ONLY || s->policy==C_FQDN_ONLY) { + if(rhnsegcnt(name)<=1) + return s->policy==C_SIMPLE_ONLY; + else + return s->policy==C_FQDN_ONLY; + } + + return s->policy==C_INCLUDED; +} + +#if ALLOW_LOCAL_AAAA +#define serv_has_rejectlist(s) ((s)->reject_a4!=NULL || (s)->reject_a6!=NULL) +#else +#define serv_has_rejectlist(s) ((s)->reject_a4!=NULL) +#endif + +/* Take the lists of IP addresses from a server section sp and + convert them into a form that can be used by p_exec_query(). + If successful, add_rejectlist returns a new list which is added to the old list rl, + otherwise the return value is NULL. +*/ +static rejectlist_t *add_rejectlist(rejectlist_t *rl, servparm_t *sp) +{ + int i,na4=DA_NEL(sp->reject_a4); + addr4maskpair_t *a4p; +#if ALLOW_LOCAL_AAAA + int na6=DA_NEL(sp->reject_a6); + addr6maskpair_t *a6p; +#endif + rejectlist_t *rlist = malloc(sizeof(rejectlist_t) + na4*sizeof(addr4maskpair_t) +#if ALLOW_LOCAL_AAAA + + na6*sizeof(addr6maskpair_t) +#endif + ); + + if(rlist) { +#if ALLOW_LOCAL_AAAA + /* Store the larger IPv6 addresses first to avoid possible alignment problems. */ + rlist->na6 = na6; + a6p = (addr6maskpair_t *)rlist->rdata; + for(i=0;ireject_a6,i); +#endif + rlist->na4 = na4; +#if ALLOW_LOCAL_AAAA + a4p = (addr4maskpair_t *)a6p; +#else + a4p = (addr4maskpair_t *)rlist->rdata; +#endif + for(i=0;ireject_a4,i); + + rlist->policy = sp->rejectpolicy; + rlist->inherit = sp->rejectrecursively; + rlist->next = rl; + } + else { + DEBUG_MSG("Out of memory in add_rejectlist()\n"); + } + + return rlist; +} + +inline static void free_rejectlist(rejectlist_t *rl) +{ + while(rl) { + rejectlist_t *next = rl->next; + free(rl); + rl=next; + } +} + +/* Lookup addresses of nameservers provided by root servers for a given domain in the cache. + Returns NULL if unsuccessful (or the cache entries have timed out). +*/ +static addr2_array lookup_ns(const unsigned char *domain) +{ + addr2_array res=NULL; + + dns_cent_t *cent=lookup_cache(domain,NULL); + if(cent) { + rr_set_t *rrset=getrrset_NS(cent); + if(rrset && (rrset->flags&CF_ROOTSERV) && !timedout(rrset)) { + rr_bucket_t *rr; + for(rr=rrset->rrs; rr; rr=rr->next) { + dns_cent_t *servent=lookup_cache((unsigned char*)(rr->data),NULL); + int nserva=0; + pdnsd_a2 serva[MAXNAMESERVIPS]; + if(servent) { +#ifdef ENABLE_IPV4 + if (run_ipv4) { + rr_set_t *rrset=getrrset_A(servent); + rr_bucket_t *rrs; + if (rrset && !timedout(rrset)) + for(rrs=rrset->rrs; rrs && nservanext) + serva[nserva++].ipv4 = *((struct in_addr *)rrs->data); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + rr_set_t *rrset6=getrrset_AAAA(servent); + rr_set_t *rrset4=getrrset_A(servent); + rr_bucket_t *rrs6=NULL, *rrs4=NULL; + if (rrset6 && !(rrset6->flags&CF_NEGATIVE)) { + if(!timedout(rrset6)) { + rrs6= rrset6->rrs; + if (rrs6 && rrset4 && !(rrset4->flags&CF_NEGATIVE)) { + if(timedout(rrset4) || !(rrs4=rrset4->rrs)) + /* Treat this as a failure. */ + rrs6=NULL; + } + } + } + else if (rrset4 && !timedout(rrset4)) + rrs4= rrset4->rrs; + + while(nservadata); + rrs6=rrs6->next; + if (rrs4) { + /* Store IPv4 address as fallback. */ + serva[nserva].ipv4 = *((struct in_addr *)rrs4->data); + rrs4=rrs4->next; + } + else + serva[nserva].ipv4.s_addr=INADDR_ANY; + } + else if (rrs4) { + struct in_addr *ina = (struct in_addr *)rrs4->data; + struct in6_addr *in6a = &serva[nserva].ipv6; + IPV6_MAPIPV4(ina,in6a); + serva[nserva].ipv4.s_addr=INADDR_ANY; + rrs4=rrs4->next; + } + else + break; + ++nserva; + } + } +#endif + free_cent(servent DBG1); + pdnsd_free(servent); + } + if(nserva==0) { + /* Address lookup failed. */ + da_free(res); res=NULL; + break; + } + else { + int i, j, n=DA_NEL(res); + for(i=0; irrs; rr; rr=rr->next) { + dns_cent_t *servent; + int nserva=0; + pdnsd_a2 serva[MAXNAMESERVIPS]; + + rc=simple_dns_cached_resolve(atup_a,port,edns_query,timeout, + (const unsigned char *)(rr->data),T_A,&servent); + if(rc==RC_OK) { +#ifdef ENABLE_IPV4 + if (run_ipv4) { + rr_set_t *rrset=getrrset_A(servent); + rr_bucket_t *rrs; + if (rrset) + for(rrs=rrset->rrs; rrs && nservanext) + serva[nserva++].ipv4 = *((struct in_addr *)rrs->data); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + rr_set_t *rrset6=getrrset_AAAA(servent); + rr_bucket_t *rrs6= (rrset6? rrset6->rrs: NULL); + rr_set_t *rrset4=getrrset_A(servent); + rr_bucket_t *rrs4= (rrset4? rrset4->rrs: NULL); + while(nservadata); + rrs6=rrs6->next; + if (rrs4) { + /* Store IPv4 address as fallback. */ + serva[nserva].ipv4 = *((struct in_addr *)rrs4->data); + rrs4=rrs4->next; + } + else + serva[nserva].ipv4.s_addr=INADDR_ANY; + } + else if (rrs4) { + struct in_addr *ina = (struct in_addr *)rrs4->data; + struct in6_addr *in6a = &serva[nserva].ipv6; + IPV6_MAPIPV4(ina,in6a); + serva[nserva].ipv4.s_addr=INADDR_ANY; + rrs4=rrs4->next; + } + else + break; + ++nserva; + } + } +#endif + free_cent(servent DBG1); + pdnsd_free(servent); + } + else { + DEBUG_RHN_MSG("Simple query for %s type A failed (rc: %s)\n", + RHN2STR((const unsigned char *)(rr->data)),get_ename(rc)); + } + + if(nserva==0) { + /* Address lookup failed. */ + DEBUG_RHN_MSG("Failed to obtain address of root server %s in dns_rootserver_resolv()\n", + RHN2STR((const unsigned char *)(rr->data))); + ++nfail; + } + else { + int i, j, n=DA_NEL(res); + for(i=0; iDA_NEL(res)) { + DEBUG_MSG("Too many root-server resolve failures (%u succeeded, %u failed)," + " rejecting the result.\n", DA_NEL(res),nfail); + da_free(res); res=NULL; + } + } + free_cent_return: + free_cent(cent DBG1); + pdnsd_free(cent); + } + else { + DEBUG_MSG("Simple query for root domain type NS failed (rc: %s)\n",get_ename(rc)); + } + + return res; +} + + +static int p_dns_resolve(const unsigned char *name, int thint, dns_cent_t **cachedp, int hops, qhintnode_t *qhlist, + unsigned char *c_soa) +{ + int i,n,rc; + int one_up=0,seenrootserv=0; + query_stat_array serv=NULL; + rejectlist_t *rejectlist=NULL; + + /* try the servers in the order of their definition */ + lock_server_data(); + n=DA_NEL(servers); + for (i=0;irootserver<=1 && use_server(sp,name)) { + int m=DA_NEL(sp->atup_a); + if(m>0) { + rejectlist_t *rjl=NULL; + int j=0, jstart=0; + if(sp->rand_servers) j=jstart=random()%m; + do { + atup_t *at=&DA_INDEX(sp->atup_a,j); + if (at->is_up) { + if(sp->rootserver) { + if(!seenrootserv) { + int nseg,mseg=1,l=0; + const unsigned char *topdomain=NULL; + addr2_array adrs=NULL; + seenrootserv=1; + nseg=rhnsegcnt(name); + if(nseg>=2) { + static const unsigned char rhn_arpa[6]= {4,'a','r','p','a',0}; + unsigned int rem; + /* Check if the queried name ends in "arpa" */ + domain_match(rhn_arpa, name, &rem,NULL); + if(rem==0) mseg=3; + } + if(nseg<=mseg) { + if(nseg>0) mseg=nseg-1; else mseg=0; + } + for(;mseg>=1; --mseg) { + topdomain=skipsegs(name,nseg-mseg); + adrs=lookup_ns(topdomain); + l=DA_NEL(adrs); + if(l>0) break; + if(adrs) da_free(adrs); + } + if(l>0) { + /* The name servers for this top level domain have been found in the cache. + Instead of asking the root server, we will use this cached information. + */ + int k=0, kstart=0; + if(sp->rand_servers) k=kstart=random()%l; + if(serv_has_rejectlist(sp) && sp->rejectrecursively && !rjl) { + rjl=add_rejectlist(rejectlist,sp); + if(!rjl) {one_up=0; da_free(adrs); goto done;} + rejectlist=rjl; + } + do { + one_up=add_qserv(&serv, &DA_INDEX(adrs,k), 53, sp->timeout, + mk_flag_val(sp)&~CFF_NOINHERIT, sp->nocache, + sp->lean_query, sp->edns_query, 2, 0, + !global.paranoid, topdomain, rjl); + if(!one_up) { + da_free(adrs); + goto done; + } + if(++k==l) k=0; + } while(k!=kstart); + da_free(adrs); + DEBUG_PDNSDA_MSG("Not querying root-server %s, using cached information instead.\n", + PDNSDA2STR(PDNSD_A2_TO_A(&at->a))); + seenrootserv=2; + break; + } + } + else if(seenrootserv==2) + break; + } + if(serv_has_rejectlist(sp) && !rjl) { + rjl=add_rejectlist(rejectlist,sp); + if(!rjl) {one_up=0; goto done;} + rejectlist=rjl; + } + one_up=add_qserv(&serv, &at->a, sp->port, sp->timeout, + mk_flag_val(sp), sp->nocache, sp->lean_query, sp->edns_query, + sp->rootserver?3:(!sp->is_proxy), + needs_testing(sp), 1, NULL, rjl); + if(!one_up) + goto done; + } + if(++j==m) j=0; + } while(j!=jstart); + } + } + } + done: + unlock_server_data(); + if (one_up) { + dns_cent_t *cached; + int nocache; + rc=p_recursive_query(serv, name, thint, &cached, &nocache, hops, NULL, qhlist, c_soa); + if (rc==RC_OK) { + if (!nocache) { + dns_cent_t *tc; + add_cache(cached); + if ((tc=lookup_cache(name,NULL))) { + /* The cache may hold more information than the recent query yielded. + * try to get the merged record. If that fails, revert to the new one. */ + free_cent(cached DBG1); + pdnsd_free(cached); + cached=tc; + /* rc=RC_CACHED; */ + } else + DEBUG_MSG("p_dns_resolve: merging answer with cache failed, using local cent copy.\n"); + } else + DEBUG_MSG("p_dns_resolve: nocache.\n"); + + *cachedp=cached; + } + else if(rc==RC_CACHED || rc==RC_STALE) + *cachedp=cached; + } + else { + DEBUG_MSG("No server is marked up and allowed for this domain.\n"); + rc=RC_SERVFAIL; /* No server up */ + } + del_qserv(serv); + free_rejectlist(rejectlist); + return rc; +} + +static int set_flags_ttl(unsigned short *flags, time_t *ttl, dns_cent_t *cached, int tp) +{ + rr_set_t *rrset=getrrset(cached,tp); + if (rrset) { + time_t t; + *flags|=rrset->flags; + t=rrset->ts+CLAT_ADJ(rrset->ttl); + if (!*ttl || *ttl>t) + *ttl=t; + return 1; + } + return 0; +} + +static void set_all_flags_ttl(unsigned short *flags, time_t *ttl, dns_cent_t *cached) +{ + int i, ilim= RRARR_LEN(cached); + + for(i=0; iflags; + t=rrset->ts+CLAT_ADJ(rrset->ttl); + if (!*ttl || *ttl>t) + *ttl=t; + } + } +} + +/* + Lookup name in the cache, and if records of type thint are found, check whether a requery is needed. + Possible returns values are: + RC_OK: the name is locally defined. + RC_NAMEERR: the name is locally negatively cached. + RC_CACHED: name was found in the cache, requery not needed. + RC_STALE: name was found in the cache, but requery is needed. + RC_NOTCACHED: name was not found in the cache. +*/ +static int lookup_cache_status(const unsigned char *name, int thint, dns_cent_t **cachedp, unsigned short *flagsp, + time_t queryts, unsigned char *c_soa) +{ + dns_cent_t *cached; + int rc=RC_NOTCACHED; + int wild=0; + unsigned short flags=0; + + if ((cached=lookup_cache(name,&wild))) { + short int neg=0,timed=0,need_req=0; + time_t ttl=0; + + if (cached->flags&DF_LOCAL) { +#if DEBUG>0 + { + char dflagstr[DFLAGSTRLEN]; + DEBUG_RHN_MSG("Entry found in cache for '%s' with dflags=%s.\n", + RHN2STR(cached->qname),dflags2str(cached->flags,dflagstr)); + } +#endif + if((cached->flags&DF_NEGATIVE) || wild==w_locnerr) { + if(c_soa) { + if(cached->c_soa!=cundef) + *c_soa=cached->c_soa; + else if(have_rr_SOA(cached)) + *c_soa=rhnsegcnt(cached->qname); + else { + unsigned char *owner=getlocalowner(cached->qname,T_SOA); + if(owner) + *c_soa=rhnsegcnt(owner); + } + } + free_cent(cached DBG1); + pdnsd_free(cached); + rc= RC_NAMEERR; + goto return_rc; + } + else { + rc= RC_OK; + goto return_rc_cent; + } + } + DEBUG_RHN_MSG("Record found in cache for %s\n",RHN2STR(cached->qname)); + if (cached->flags&DF_NEGATIVE) { + if ((ttl=cached->neg.ts+CLAT_ADJ(cached->neg.ttl))>=queryts) + neg=1; + else + timed=1; + } else { + if (thint==QT_ALL) { + set_all_flags_ttl(&flags, &ttl, cached); + } + else if (!set_flags_ttl(&flags, &ttl, cached, T_CNAME) || (getrrset_CNAME(cached)->flags&CF_NEGATIVE)) { + flags=0; ttl=0; + if (thint>=T_MIN && thint<=T_MAX) { + if (set_flags_ttl(&flags, &ttl, cached, thint)) + neg=getrrset(cached,thint)->flags&CF_NEGATIVE && ttl>=queryts; + } + else if (thint==QT_MAILB) { + set_flags_ttl(&flags, &ttl, cached, T_MB); + set_flags_ttl(&flags, &ttl, cached, T_MG); + set_flags_ttl(&flags, &ttl, cached, T_MR); + } + else if (thint==QT_MAILA) { + set_flags_ttl(&flags, &ttl, cached, T_MD); + set_flags_ttl(&flags, &ttl, cached, T_MF); + } + } + if(!(flags&CF_LOCAL)) { + if (thint==QT_ALL) { + if(!(cached->flags&DF_AUTH)) + need_req=1; + } + else if (thint>=QT_MIN && thint<=QT_MAX) { + if(!(flags&CF_AUTH && !(flags&CF_ADDITIONAL))) + need_req=1; + } + if (ttl0 + { + char dflagstr[DFLAGSTRLEN],cflagstr[CFLAGSTRLEN]; + DEBUG_MSG("Requery decision: dflags=%s, cflags=%s, req=%i, neg=%i, timed=%i, %s=%li\n", + dflags2str(cached->flags,dflagstr),cflags2str(flags,cflagstr),need_req,neg,timed, + ttl?"ttl":"timestamp",(long)(ttl?(ttl-queryts):ttl)); + } +#endif + rc = (!neg && (need_req || timed))? RC_STALE: RC_CACHED; + return_rc_cent: + *cachedp=cached; + } + +return_rc: + if(flagsp) *flagsp=flags; + return rc; +} + + +/* + * Resolve records for name into dns_cent_t, type thint. + * q is the set of servers to query from. Set q to NULL if you want to ask the servers registered with pdnsd. + * qslist should refer to a list of server arrays already used higher up the calling chain (may be NULL). + * p_dns_cached_resolve() returns one of the following values: + * RC_OK means that the name was successfully resolved by querying other servers. + * RC_CACHED or RC_STALE means that the name was found in the cache. + * RC_NAMEERR or RC_SERVFAIL indicates a resolve error. + */ +static int p_dns_cached_resolve(query_stat_array q, const unsigned char *name, int thint, dns_cent_t **cachedp, + int hops, qstatnode_t *qslist, qhintnode_t *qhlist, time_t queryts, + unsigned char *c_soa) +{ + dns_cent_t *cached=NULL; + int rc; + unsigned short flags=0; + + DEBUG_RHN_MSG("Starting cached resolve for: %s, query %s\n",RHN2STR(name),get_tname(thint)); + rc= lookup_cache_status(name, thint, &cached, &flags,queryts,c_soa); + if(rc==RC_OK) { + /* Locally defined record. */ + *cachedp=cached; + return RC_CACHED; + } + else if(rc==RC_NAMEERR) /* Locally negated name. */ + return RC_NAMEERR; + + /* update server records set onquery */ + if(global.onquery) test_onquery(); + if (global.lndown_kluge && !(flags&CF_LOCAL)) { + int i,n,linkdown=1; + lock_server_data(); + n=DA_NEL(servers); + for(i=0;irootserver<=1) { + int j,m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j).is_up) { + linkdown=0; + goto done; + } + } + } + } + done: + unlock_server_data(); + if (linkdown) { + DEBUG_MSG("Link is down.\n"); + rc=RC_SERVFAIL; + goto cleanup_return; + } + } + if (rc!=RC_CACHED) { + dns_cent_t *ent; + DEBUG_MSG("Trying name servers.\n"); + if (q) + rc=p_recursive_query(q,name,thint, &ent,NULL,hops,qslist,qhlist,c_soa); + else + rc=p_dns_resolve(name,thint, &ent,hops,qhlist,c_soa); + + if(rc==RC_OK || rc==RC_CACHED || rc==RC_STALE) { + if (cached) { + free_cent(cached DBG1); + pdnsd_free(cached); + } + cached=ent; + } + else if (rc==RC_SERVFAIL && cached && (flags&CF_NOPURGE)) { + /* We could not get a new record, but we have a timed-out cached one + with the nopurge flag set. This means that we shall use it even + if timed out when no new one is available*/ + DEBUG_MSG("Falling back to cached record.\n"); + rc=RC_STALE; + } + else + goto cleanup_return; + } else { + DEBUG_MSG("Using cached record.\n"); + } + *cachedp=cached; + return rc; + + cleanup_return: + if(cached) { + free_cent(cached DBG1); + pdnsd_free(cached); + } + return rc; +} + + +/* r_dns_cached_resolve() is like p_dns_cached_resolve(), except that r_dns_cached_resolve() + will not return negatively cached entries, but returns RC_NAMEERR instead. + It also does not return RC_CACHED or RC_STALE, but RC_OK instead. +*/ +int r_dns_cached_resolve(unsigned char *name, int thint, dns_cent_t **cachedp, + int hops, qhintnode_t *qhlist, time_t queryts, + unsigned char *c_soa) +{ + dns_cent_t *cached; + int rc=p_dns_cached_resolve(NULL,name,thint,&cached,hops,NULL,qhlist,queryts,c_soa); + if(rc==RC_OK || rc==RC_CACHED || rc==RC_STALE) { + if(cached->flags&DF_NEGATIVE) { + if(c_soa) + *c_soa=cached->c_soa; + free_cent(cached DBG1); + pdnsd_free(cached); + return RC_NAMEERR; + } + else { + *cachedp=cached; + return RC_OK; + } + } + return rc; +} + + +static int simple_dns_cached_resolve(atup_array atup_a, int port, char edns_query, time_t timeout, + const unsigned char *name, int thint, dns_cent_t **cachedp) +{ + dns_cent_t *cached=NULL; + int rc; + + DEBUG_RHN_MSG("Starting simple cached resolve for: %s, query %s\n",RHN2STR(name),get_tname(thint)); + rc= lookup_cache_status(name, thint, &cached, NULL, time(NULL), NULL); + if(rc==RC_OK) { + /* Locally defined record. */ + *cachedp=cached; + return RC_OK; + } + else if(rc==RC_NAMEERR) /* Locally negated name. */ + return RC_NAMEERR; + + if (rc!=RC_CACHED) { + query_stat_array qserv; + int j,m; + if (cached) { + free_cent(cached DBG1); + pdnsd_free(cached); + cached=NULL; + } + DEBUG_MSG("Trying name servers.\n"); + qserv=NULL; + m=DA_NEL(atup_a); + for(j=0; jflags&DF_NEGATIVE) { + free_cent(cached DBG1); + pdnsd_free(cached); + return RC_NAMEERR; + } + + *cachedp=cached; + return RC_OK; +} + + +/* Check whether a server is responsive by sending it an (empty) query. + rep is the number of times this is tried in case of no reply. + */ +int query_uptest(pdnsd_a *addr, int port, const unsigned char *name, time_t timeout, int rep) +{ + query_stat_t qs; + int iter=0,rv; + +#ifdef ENABLE_IPV4 + if (run_ipv4) { + memset(&qs.a.sin4,0,sizeof(qs.a.sin4)); + qs.a.sin4.sin_family=AF_INET; + qs.a.sin4.sin_port=htons(port); + qs.a.sin4.sin_addr=addr->ipv4; + SET_SOCKA_LEN4(qs.a.sin4); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + memset(&qs.a.sin6,0,sizeof(qs.a.sin6)); + qs.a.sin6.sin6_family=AF_INET6; + qs.a.sin6.sin6_port=htons(port); + qs.a.sin6.sin6_flowinfo=IPV6_FLOWINFO; + qs.a.sin6.sin6_addr=addr->ipv6; + SET_SOCKA_LEN6(qs.a.sin6); + + qs.a4fallback.s_addr=INADDR_ANY; + } +#endif + qs.timeout=timeout; + qs.flags=0; + qs.nocache=0; + qs.auth_serv=0; + qs.lean_query=1; + qs.edns_query=0; + qs.needs_testing=0; + qs.trusted=1; + qs.aa=0; + qs.tc=0; + qs.ra=0; + qs.failed=0; + qs.nsdomain=NULL; + qs.rejectlist=NULL; + + try_again: + qs.state=QS_INITIAL; + qs.qm=global.query_method; + qs.s_errno=0; + rv=p_exec_query(NULL, name, T_A, &qs, NULL, NULL); + if(rv==-1) { + time_t ts, tpassed; + for(ts=time(NULL), tpassed=0;; tpassed=time(NULL)-ts) { + int event; +#ifdef NO_POLL + fd_set reads; + fd_set writes; + struct timeval tv; + FD_ZERO(&reads); + FD_ZERO(&writes); + PDNSD_ASSERT(qs.socktpassed?timeout-tpassed:0; + tv.tv_usec=0; + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that doing + this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + p_cancel_query(&qs); + return 0; + } + event=select(qs.sock+1,&reads,&writes,NULL,&tv); +#else + struct pollfd pfd; + pfd.fd=qs.sock; + switch (qs.state) { + QS_READ_CASES: + pfd.events=POLLIN; + break; + QS_WRITE_CASES: + pfd.events=POLLOUT; + break; + default: + pfd.events=0; + } + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that doing + this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + p_cancel_query(&qs); + return 0; + } + event=poll(&pfd,1,timeout>tpassed?(timeout-tpassed)*1000:0); +#endif + if (event<0) { + if(errno==EINTR && is_interrupted_servstat_thread()) { + DEBUG_MSG("poll/select interrupted in server status thread.\n"); + } + else + log_warn("poll/select failed: %s",strerror(errno)); + p_cancel_query(&qs); + return 0; + } + if(event==0) { + /* timed out */ + p_cancel_query(&qs); + if(++iter. +*/ + + +#ifndef DNS_QUERY_H +#define DNS_QUERY_H + +#include "cache.h" + +/* Default UDP buffer size (when EDNS is not used). */ +#define UDP_BUFSIZE 512 + + +typedef struct qhintnode_s qhintnode_t; + +/* --- parallel query */ +int r_dns_cached_resolve(unsigned char *name, int thint, dns_cent_t **cachedp, + int hops, qhintnode_t *qhlist, time_t queryts, + unsigned char *c_soa); +#define dns_cached_resolve(name,thint,cachedp,hops,queryts,c_soa) \ + r_dns_cached_resolve(name,thint,cachedp,hops,NULL,queryts,c_soa) + +addr2_array dns_rootserver_resolv(atup_array atup_a, int port, char edns_query, time_t timeout); +int query_uptest(pdnsd_a *addr, int port, const unsigned char *name, time_t timeout, int rep); + +/* --- from dns_answer.c */ +int add_opt_pseudo_rr(dns_msg_t **ans, size_t *sz, size_t *allocsz, + unsigned short udpsize, unsigned short rcode, + unsigned short ednsver, unsigned short Zflags); +size_t remove_opt_pseudo_rr(dns_msg_t *ans, size_t sz); + +#endif diff --git a/jni/pdnsd/src/error.c b/jni/pdnsd/src/error.c new file mode 100644 index 00000000..45848660 --- /dev/null +++ b/jni/pdnsd/src/error.c @@ -0,0 +1,142 @@ +/* error.c - Error handling + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2004, 2005, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "error.h" +#include "helpers.h" +#include "conff.h" + + +pthread_mutex_t loglock = PTHREAD_MUTEX_INITIALIZER; +volatile short int use_log_lock=0; + +/* + * Initialize a mutex for io-locking in order not to produce gibberish on + * multiple simultaneous errors. + */ +/* This is now defined as an inline function in error.h */ +#if 0 +void init_log_lock(void) +{ + use_log_lock=1; +} +#endif + +/* We crashed? Ooops... */ +void crash_msg(char *msg) +{ + log_error("%s", msg); + log_error("pdnsd probably crashed due to a bug. Please consider sending a bug"); + log_error("report to p.a.rombouts@home.nl or tmoestl@gmx.net"); +} + +/* Log a warning, error or info message. + * If we are a daemon, use the syslog. s is a format string like in printf, + * the optional following arguments are the arguments like in printf */ +void log_message(int prior, const char *s, ...) +{ + int gotlock=0; + va_list va; + FILE *f; + + if (use_log_lock) { + gotlock=softlock_mutex(&loglock); + /* If we failed to get the lock and the type of the + message is "info" or less important, then don't bother. */ + if(!gotlock && prior>=LOG_INFO) + return; + } + if (global.daemon) { + openlog("pdnsd",LOG_PID,LOG_DAEMON); + va_start(va,s); + vsyslog(prior,s,va); + va_end(va); + closelog(); + } + else { + f=stderr; +#if DEBUG > 0 + goto printtofile; + } + if(debug_p) { + f=dbg_file; + printtofile: +#endif + { + char ts[sizeof "* 12/31 23:59:59| "]; + time_t tt = time(NULL); + struct tm tm; + + if(!localtime_r(&tt, &tm) || strftime(ts, sizeof(ts), "* %m/%d %T| ", &tm) <=0) + ts[0]=0; + fprintf(f,"%spdnsd: %s: ", ts, + prior<=LOG_CRIT?"critical": + prior==LOG_ERR?"error": + prior==LOG_WARNING?"warning": + "info"); + } + va_start(va,s); + vfprintf(f,s,va); + va_end(va); + { + const char *p=strchr(s,0); + if(!p || p==s || *(p-1)!='\n') + fputc('\n',f); + } + } + if (gotlock) + pthread_mutex_unlock(&loglock); +} + + +#if DEBUG > 0 +/* XXX: The timestamp generation makes this a little heavy-weight */ +void debug_msg(int c, const char *fmt, ...) +{ + va_list va; + + if (!c) { + char ts[sizeof "12/31 23:59:59"]; + time_t tt = time(NULL); + struct tm tm; + unsigned *id; + + if(localtime_r(&tt, &tm) && strftime(ts, sizeof(ts), "%m/%d %T", &tm) > 0) { + if((id = (unsigned *)pthread_getspecific(thrid_key))) + fprintf(dbg_file,"%u %s| ", *id, ts); + else + fprintf(dbg_file,"- %s| ", ts); + } + } + va_start(va,fmt); + vfprintf(dbg_file,fmt,va); + va_end(va); + fflush(dbg_file); +} +#endif /* DEBUG */ diff --git a/jni/pdnsd/src/error.h b/jni/pdnsd/src/error.h new file mode 100644 index 00000000..1678744e --- /dev/null +++ b/jni/pdnsd/src/error.h @@ -0,0 +1,115 @@ +/* error.h - Error handling + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2004, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef ERROR_H +#define ERROR_H + +#include +#include +#include +#include +#include +#include + +#include "thread.h" +#include "helpers.h" +#include "pdnsd_assert.h" + +/* --- from error.c */ +extern volatile short int use_log_lock; +/* --- */ + +void crash_msg(char *msg); + +inline static void init_log_lock(void) __attribute__((always_inline)); +inline static void init_log_lock(void) +{ + use_log_lock=1; +} + +void log_message(int prior,const char *s, ...) printfunc(2, 3); +#if !defined(CPP_C99_VARIADIC_MACROS) +/* GNU C Macro Varargs style. */ +#define log_error(args...) log_message(LOG_ERR,args) +#define log_warn(args...) log_message(LOG_WARNING,args) +#define log_info(level,args...) {if((level)<=global.verbosity) log_message(LOG_INFO,args);} +#else +/* ANSI C99 style. */ +#define log_error(...) log_message(LOG_ERR,__VA_ARGS__) +#define log_warn(...) log_message(LOG_WARNING,__VA_ARGS__) +#define log_info(level,...) {if((level)<=global.verbosity) log_message(LOG_INFO,__VA_ARGS__);} +#endif + +/* Following are some ugly macros for debug messages that + * should inhibit any code generation when DEBUG is not defined. + * Of course, those messages could be done in a function, but I + * want to save the overhead when DEBUG is not defined. + * debug_p needs to be defined (by including conff.h), or you + * will get strange errors. + * A macro call expands to a complete statement, so a semicolon after + * the macro call is redundant. + * The arguments are normal printfs, so you know how to use the args + */ +#if DEBUG>0 +void debug_msg(int c, const char *fmt, ...) printfunc(2, 3); +/* from main.c */ +extern FILE *dbg_file; +#endif + +#if !defined(CPP_C99_VARIADIC_MACROS) +/* GNU C Macro Varargs style. */ +# if DEBUG > 0 +# define DEBUG_MSG(args...) {if (debug_p) debug_msg(0,args);} +# define DEBUG_MSGC(args...) {if (debug_p) debug_msg(1,args);} +# define DEBUG_PDNSDA_MSG(args...) {char _debugsockabuf[ADDRSTR_MAXLEN]; DEBUG_MSG(args);} +# define PDNSDA2STR(a) pdnsd_a2str(a,_debugsockabuf,sizeof(_debugsockabuf)) +# define DEBUG_RHN_MSG(args...) {unsigned char _debugstrbuf[DNSNAMEBUFSIZE]; DEBUG_MSG(args);} +# define RHN2STR(a) rhn2str(a,_debugstrbuf,sizeof(_debugstrbuf)) +# else +# define DEBUG_MSG(args...) +# define DEBUG_MSGC(args...) +# define DEBUG_PDNSDA_MSG(args...) +# define DEBUG_RHN_MSG(args...) +# endif /* DEBUG > 0 */ +#else +/* ANSI C99 style. */ +# if DEBUG > 0 +/* + * XXX: The ANSI and GCC variadic macros should be merged as far as possible, but that + * might make things even more messy... + */ +# define DEBUG_MSG(...) {if (debug_p) debug_msg(0,__VA_ARGS__);} +# define DEBUG_MSGC(...) {if (debug_p) debug_msg(1,__VA_ARGS__);} +# define DEBUG_PDNSDA_MSG(...) {char _debugsockabuf[ADDRSTR_MAXLEN]; DEBUG_MSG(__VA_ARGS__);} +# define PDNSDA2STR(a) pdnsd_a2str(a,_debugsockabuf,ADDRSTR_MAXLEN) +# define DEBUG_RHN_MSG(...) {unsigned char _debugstrbuf[DNSNAMEBUFSIZE]; DEBUG_MSG(__VA_ARGS__);} +# define RHN2STR(a) rhn2str(a,_debugstrbuf,sizeof(_debugstrbuf)) +# else +# define DEBUG_MSG(...) +# define DEBUG_MSGC(...) +# define DEBUG_PDNSDA_MSG(...) +# define DEBUG_RHN_MSG(...) +# endif /* DEBUG > 0 */ +#endif + +#endif diff --git a/jni/pdnsd/src/freebsd_netinet_ip_icmp.h b/jni/pdnsd/src/freebsd_netinet_ip_icmp.h new file mode 100644 index 00000000..e4577cea --- /dev/null +++ b/jni/pdnsd/src/freebsd_netinet_ip_icmp.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/netinet/ip_icmp.h,v 1.20 2003/03/21 15:28:10 mdodd Exp $ + */ + +#ifndef _NETINET_IP_ICMP_H_ +#define _NETINET_IP_ICMP_H_ + +/* + * Interface Control Message Protocol Definitions. + * Per RFC 792, September 1981. + */ + +/* + * Internal of an ICMP Router Advertisement + */ +struct icmp_ra_addr { + u_int32_t ira_addr; + u_int32_t ira_preference; +}; + +/* + * Structure of an icmp header. + */ +struct icmp { + u_char icmp_type; /* type of message, see below */ + u_char icmp_code; /* type sub code */ + u_short icmp_cksum; /* ones complement cksum of struct */ + union { + u_char ih_pptr; /* ICMP_PARAMPROB */ + struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + struct ih_idseq { + n_short icd_id; + n_short icd_seq; + } ih_idseq; + int ih_void; + + /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ + struct ih_pmtu { + n_short ipm_void; + n_short ipm_nextmtu; + } ih_pmtu; + + struct ih_rtradv { + u_char irt_num_addrs; + u_char irt_wpa; + u_int16_t irt_lifetime; + } ih_rtradv; + } icmp_hun; +#define icmp_pptr icmp_hun.ih_pptr +#define icmp_gwaddr icmp_hun.ih_gwaddr +#define icmp_id icmp_hun.ih_idseq.icd_id +#define icmp_seq icmp_hun.ih_idseq.icd_seq +#define icmp_void icmp_hun.ih_void +#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void +#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu +#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs +#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa +#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime + union { + struct id_ts { /* ICMP Timestamp */ + n_time its_otime; /* Originate */ + n_time its_rtime; /* Receive */ + n_time its_ttime; /* Transmit */ + } id_ts; + struct id_ip { + struct ip idi_ip; + /* options and then 64 bits of data */ + } id_ip; + struct icmp_ra_addr id_radv; + u_int32_t id_mask; + char id_data[1]; + } icmp_dun; +#define icmp_otime icmp_dun.id_ts.its_otime +#define icmp_rtime icmp_dun.id_ts.its_rtime +#define icmp_ttime icmp_dun.id_ts.its_ttime +#define icmp_ip icmp_dun.id_ip.idi_ip +#define icmp_radv icmp_dun.id_radv +#define icmp_mask icmp_dun.id_mask +#define icmp_data icmp_dun.id_data +}; + +/* + * Lower bounds on packet lengths for various types. + * For the error advice packets must first insure that the + * packet is large enough to contain the returned ip header. + * Only then can we do the check to see if 64 bits of packet + * data have been returned, since we need to check the returned + * ip header length. + */ +#define ICMP_MINLEN 8 /* abs minimum */ +#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ +#define ICMP_MASKLEN 12 /* address mask */ +#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ +#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) + /* N.B.: must separately check that ip_hl >= 5 */ + +/* + * Definition of type and code field values. + */ +#define ICMP_ECHOREPLY 0 /* echo reply */ +#define ICMP_UNREACH 3 /* dest unreachable, codes: */ +#define ICMP_UNREACH_NET 0 /* bad net */ +#define ICMP_UNREACH_HOST 1 /* bad host */ +#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ +#define ICMP_UNREACH_PORT 3 /* bad port */ +#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ +#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ +#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ +#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ +#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ +#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ +#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ +#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ +#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */ +#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */ +#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */ +#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ +#define ICMP_REDIRECT 5 /* shorter route, codes: */ +#define ICMP_REDIRECT_NET 0 /* for network */ +#define ICMP_REDIRECT_HOST 1 /* for host */ +#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ +#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ +#define ICMP_ECHO 8 /* echo service */ +#define ICMP_ROUTERADVERT 9 /* router advertisement */ +#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ +#define ICMP_TIMXCEED 11 /* time exceeded, code: */ +#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ +#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ +#define ICMP_PARAMPROB 12 /* ip header bad */ +#define ICMP_PARAMPROB_ERRATPTR 0 /* error at param ptr */ +#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ +#define ICMP_PARAMPROB_LENGTH 2 /* bad length */ +#define ICMP_TSTAMP 13 /* timestamp request */ +#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ +#define ICMP_IREQ 15 /* information request */ +#define ICMP_IREQREPLY 16 /* information reply */ +#define ICMP_MASKREQ 17 /* address mask request */ +#define ICMP_MASKREPLY 18 /* address mask reply */ + +#define ICMP_MAXTYPE 18 + +#define ICMP_INFOTYPE(type) \ + ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ + (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ + (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ + (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ + (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) + +#ifdef _KERNEL +void icmp_error(struct mbuf *, int, int, n_long, struct ifnet *); +void icmp_input(struct mbuf *, int); +#endif + +#endif diff --git a/jni/pdnsd/src/hash.c b/jni/pdnsd/src/hash.c new file mode 100644 index 00000000..12e20740 --- /dev/null +++ b/jni/pdnsd/src/hash.c @@ -0,0 +1,322 @@ +/* hash.c - Manage hashes for cached dns records + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2005 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include "hash.h" +#include "cache.h" +#include "error.h" +#include "helpers.h" +#include "consts.h" + + +/* This is not a perfect hash, but I hope it holds. It is designed for 1024 hash + * buckets, and hashes strings with case-insensitivity. + * It is position-aware in a limited way. + * It is exactly seen a two-way hash: because I do not want to exaggerate + * the hash buckets (i do have 1024), but I hash strings and string-comparisons + * are expensive, I save another 32 bit hash in each hash element that is checked + * before the string. The 32 bit hash is also used to order the entries in a hash chain. + * I hope not to have all too much collision concentration. + * + * The ip hash was removed. I don't think it concentrated the collisions too much. + * If it does, the hash algorithm needs to be changed, rather than using another + * hash. + * Some measurements seem to indicate that the hash algorithm is doing reasonable well. + */ + +dns_hash_ent_t *hash_buckets[HASH_NUM_BUCKETS]; + + +/* + * Hash a dns name (length-byte string format) to HASH_SZ bit. + * *rhash is set to a long int hash. + */ +static unsigned dns_hash(const unsigned char *str, unsigned long *rhash) +{ + unsigned s,i,lb,c; + unsigned long r; + s=0; r=0; + i=0; + while((lb=str[i])) { + s+=lb<<(i%(HASH_SZ-5)); + r+=((unsigned long)lb)<<(i%(8*sizeof(unsigned long)-7)); + ++i; + do { + c=toupper(str[i]); + s+=c<<(i%(HASH_SZ-5)); + r+=((unsigned long)c)<<(i%(8*sizeof(unsigned long)-7)); + ++i; + } while(--lb); + } + s=(s&HASH_BITMASK)+((s&(~HASH_BITMASK))>>HASH_SZ); + s=(s&HASH_BITMASK)+((s&(~HASH_BITMASK))>>HASH_SZ); + s &= HASH_BITMASK; +#ifdef DEBUG_HASH + { + unsigned char buf[DNSNAMEBUFSIZE]; + printf("Diagnostic: hashes for %s: %03x,%04lx\n",rhn2str(str,buf,sizeof(buf)),s,r); + } +#endif + if(rhash) *rhash=r; + return s; +} + +/* + * Initialize hash to hold a dns hash table + */ +/* This is now defined as an inline function in hash.h */ +#if 0 +void mk_dns_hash() +{ + int i; + for(i=0;irhash<=rh) { + if (he->rhash==rh && rhnicmp(key,he->data->qname)) { + retval = he->data; + break; + } + hep = &he->next; + } + if(loc) { + loc->pos = hep; + loc->rhash = rh; + } + return retval; +} + +/* + Add a cache entry to the hash table. + + loc must contain the location where the the new entry should be inserted + (this location can be obtained with dns_lookup). + + add_dns_hash returns 1 on success, or 0 if out of memory. +*/ +int add_dns_hash(dns_cent_t *data, dns_hash_loc_t *loc) +{ + dns_hash_ent_t *he = malloc(sizeof(dns_hash_ent_t)); + + if(!he) + return 0; + + he->next = *(loc->pos); + he->rhash = loc->rhash; + he->data = data; + *(loc->pos) = he; + + return 1; +} + +/* + Delete the hash entry indentified by the location returned by dns_lookup(). +*/ +dns_cent_t *del_dns_hash_ent(dns_hash_loc_t *loc) +{ + dns_hash_ent_t *he = *(loc->pos); + dns_cent_t *data; + + *(loc->pos) = he->next; + data = he->data; + free(he); + return data; +} + +/* + * Delete the first entry indexed by key from the hash. Returns the data field or NULL. + * Since two cents are not allowed to be for the same host name, there will be only one. + */ +dns_cent_t *del_dns_hash(const unsigned char *key) +{ + unsigned idx; + unsigned long rh; + dns_hash_ent_t **hep,*he; + dns_cent_t *data; + + idx = dns_hash(key,&rh); + hep = &hash_buckets[idx]; + while ((he= *hep) && he->rhash<=rh) { + if (he->rhash==rh && rhnicmp(key,he->data->qname)) { + *hep = he->next; + data = he->data; + free(he); + return data; + } + hep = &he->next; + } + return NULL; /* not found */ +} + + +/* + * Delete all entries in a hash bucket. + */ +void free_dns_hash_bucket(int i) +{ + dns_hash_ent_t *he,*hen; + + he=hash_buckets[i]; + hash_buckets[i]=NULL; + while (he) { + hen=he->next; + del_cent(he->data); + free(he); + he=hen; + } +} + +/* + * Delete all entries in a hash bucket whose names match those in + * an include/exclude list. + */ +void free_dns_hash_selected(int i, slist_array sla) +{ + dns_hash_ent_t **hep,*he,*hen; + int j,m=DA_NEL(sla); + + hep= &hash_buckets[i]; + he= *hep; + + while (he) { + unsigned char *name=he->data->qname; + for(j=0;jdomain,&nrem,&lrem); + if(!lrem && (!sl->exact || !nrem)) { + if(sl->rule==C_INCLUDED) + goto delete_entry; + else + break; + } + } + /* default policy is not to delete */ + hep= &he->next; + he= *hep; + continue; + + delete_entry: + *hep=hen=he->next;; + del_cent(he->data); + free(he); + he=hen; + } +} + +/* + * Delete the whole hash table, freeing all memory + */ +void free_dns_hash() +{ + int i; + dns_hash_ent_t *he,*hen; + for (i=0;inext; + del_cent(he->data); + free(he); + he=hen; + } + } +} + +/* + * The following functions are for iterating over the hash. + * fetch_first returns the data field of the first element (or NULL if there is none), and fills pos + * for subsequent calls of fetch_next. + * fetch_next returns the data field of the element after the element that was returned by the last + * call with the same position argument (or NULL if there is none) + * + * Note that these are designed so that you may actually delete the elements you retrieved from the hash. + */ +dns_cent_t *fetch_first(dns_hash_pos_t *pos) +{ + int i; + for (i=0;ibucket=i; + pos->ent=he->next; + return he->data; + } + } + return NULL; +} + +dns_cent_t *fetch_next(dns_hash_pos_t *pos) +{ + dns_hash_ent_t *he=pos->ent; + int i; + if (he) { + pos->ent=he->next; + return he->data; + } + + for (i=pos->bucket+1;ibucket=i; + pos->ent=he->next; + return he->data; + } + } + return NULL; +} + +#ifdef DEBUG_HASH +void dumphash() +{ + if(debug_p) { + int i, j; + dns_hash_ent_t *he; + + for (i=0; inext, j++) ; + DEBUG_MSG("bucket %d: %d entries\n", i, j); + } + } +} +#endif diff --git a/jni/pdnsd/src/hash.h b/jni/pdnsd/src/hash.h new file mode 100644 index 00000000..db25a34f --- /dev/null +++ b/jni/pdnsd/src/hash.h @@ -0,0 +1,83 @@ +/* hash.h - Manage hashes for cached dns records + + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2003, 2005 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _HASH_H_ +#define _HASH_H_ +#include +#include "cache.h" + +typedef struct dns_hash_ent_s { + struct dns_hash_ent_s *next; + unsigned long rhash; /* this is a better hash */ + dns_cent_t *data; +} dns_hash_ent_t; + +/* Redefine this if you want another hash size. Should work ;-). + * The number of hash buckets is computed as power of two; + * so, e.g. HASH_SZ set to 10 yields 1024 hash rows (2^10 or 1<<10). + * Only powers of two are possible conveniently. + * HASH_SZ may not be bigger than 32 (if you set it even close to that value, + * you are nuts.) */ +/* #define HASH_SZ 10 */ /* Now defined in config.h */ +#define HASH_NUM_BUCKETS (1<. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipvers.h" +#include "thread.h" +#include "error.h" +#include "helpers.h" +#include "cache.h" +#include "conff.h" + + +/* + * This is to exit pdnsd from any thread. + */ +void pdnsd_exit() +{ + pthread_kill(main_thrid,SIGTERM); + pthread_exit(NULL); +} + +/* + * Try to grab a mutex. If we can't, fail. This will loop until we get the + * mutex or fail. This is only used in debugging code or at exit, otherwise + * we might run into lock contention problems. + */ +int softlock_mutex(pthread_mutex_t *mutex) +{ + unsigned int tr=0; + while(pthread_mutex_trylock(mutex)) { + if (++tr>=SOFTLOCK_MAXTRIES) + return 0; + usleep_r(10000); + } + return 1; +} + +/* + * setuid() and setgid() for a specified user. + */ +int run_as(const char *user) +{ + if (user[0]) { +#ifdef HAVE_GETPWNAM_R + struct passwd pwdbuf, *pwd; + size_t buflen; + int err; + + for(buflen=128;; buflen*=2) { + char buf[buflen]; /* variable length array */ + + /* Note that we use getpwnam_r() instead of getpwnam(), + which returns its result in a statically allocated buffer and + cannot be considered thread safe. + Doesn't use NSS! */ + err=getpwnam_r(user, &pwdbuf, buf, buflen, &pwd); + if(err==0 && pwd) { + /* setgid first, because we may not be allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid)!=0) { + log_error("Could not change group id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + + /* initgroups uses NSS, so we can disable it, + i.e. we might need DNS for LDAP lookups, which times out */ + if (global.use_nss && (initgroups(user, pwd->pw_gid)!=0)) { + log_error("Could not initialize the group access list of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + if (setuid(pwd->pw_uid)!=0) { + log_error("Could not change user id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + break; + } + else if(err!=ERANGE) { + if(err) + log_error("run_as user '%s' could not be found: %s",user,strerror(err)); + else + log_error("run_as user '%s' could not be found.",user); + return 0; + } + else if(buflen>=16*1024) { + /* If getpwnam_r() seems defective, call it quits rather than + keep on allocating ever larger buffers until we crash. */ + log_error("getpwnam_r() requires more than %u bytes of buffer space.",(unsigned)buflen); + return 0; + } + /* Else try again with larger buffer. */ + } +#else + /* No getpwnam_r() :-( We'll use getpwnam() and hope for the best. */ + struct passwd *pwd; + + if (!(pwd=getpwnam(user))) { + log_error("run_as user %s could not be found.",user); + return 0; + } + /* setgid first, because we may not allowed to do it anymore after setuid */ + if (setgid(pwd->pw_gid)!=0) { + log_error("Could not change group id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + /* initgroups uses NSS, so we can disable it, + i.e. we might need DNS for LDAP lookups, which times out */ + if (global.use_nss && (initgroups(user, pwd->pw_gid)!=0)) { + log_error("Could not initialize the group access list of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } + if (setuid(pwd->pw_uid)!=0) { + log_error("Could not change user id to that of run_as user '%s': %s", + user,strerror(errno)); + return 0; + } +#endif + } + + return 1; +} + +/* + * returns whether c is allowed in IN domain names + */ +#if 0 +int isdchar (unsigned char c) +{ + if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='-' +#ifdef UNDERSCORE + || c=='_' +#endif + ) + return 1; + return 0; +} +#endif + +/* + * Convert a string given in dotted notation to the transport format (length byte prepended + * domain name parts, ended by a null length sequence) + * The memory areas referenced by str and rhn may not overlap. + * The buffer rhn points to is assumed to be at least DNSNAMEBUFSIZE bytes in size. + * + * Returns 1 if successful, otherwise 0. + */ +int str2rhn(const unsigned char *str, unsigned char *rhn) +{ + unsigned int i,j; + + if(*str=='.' && !*(str+1)) { + /* Special case: root domain */ + rhn[0]=0; + return 1; + } + + for(i=0;;) { + unsigned int jlim= i+63; + if(jlim>DNSNAMEBUFSIZE-2) jlim=DNSNAMEBUFSIZE-2; /* DNSNAMEBUFSIZE-2 because the termination 0 has to follow */ + for(j=i; str[j] && str[j]!='.'; ++j) { + if(j>=jlim) return 0; + rhn[j+1]=str[j]; + } + if(!str[j]) + break; + if(j<=i) + return 0; + rhn[i]=(unsigned char)(j-i); + i = j+1; + } + + rhn[i]=0; + if (j>i || i==0) + return 0; + return 1; +} + +/* + parsestr2rhn is essentially the same as str2rhn, except that it doesn't look beyond + the first len chars in the input string. It also tolerates strings + not ending in a dot and returns a message in case of an error. + */ +const char *parsestr2rhn(const unsigned char *str, unsigned int len, unsigned char *rhn) +{ + unsigned int i,j; + + if(len>0 && *str=='.' && (len==1 || !*(str+1))) { + /* Special case: root domain */ + rhn[0]=0; + return NULL; + } + + i=0; + do { + unsigned int jlim= i+63; + if(jlim>DNSNAMEBUFSIZE-2) jlim=DNSNAMEBUFSIZE-2; + for(j=i; j=jlim) + return "Domain name element too long"; + rhn[j+1]=str[j]; + } + + if(j<=i) { + if(j=2) + str[j++]='.'; + } + else { + do { + for (;lb;--lb) { + unsigned char c; + if(j+2>=size) + goto overflow; + c=rhn[i++]; + if(isgraph(c)) { + if(c=='.' || c=='\\' || c=='"') { + str[j++]='\\'; + if(j+2>=size) + goto overflow; + } + str[j++]=c; + } + else { + unsigned int rem=size-1-j; + int n=snprintf(charp &str[j],rem,"\\%03o",c); + if(n<0 || n>=rem) { + str[j++]='.'; + goto overflow; + } + j+=n; + } + } + str[j++]='.'; + lb=rhn[i++]; + } while(lb); + } + str[j]=0; + return str; + + overflow: + j=size; + str[--j]=0; + if(j>0) { + str[--j]='.'; + if(j>0) { + str[--j]='.'; + if(j>0) + str[--j]='.'; + } + } + return str; +} + +/* Return the length of a domain name in transport format. + The definition has in fact been moved to helpers.h as an inline function. + Note added by Paul Rombouts: + Compared to the definition used by Thomas Moestl (strlen(rhn)+1), the following definition of rhnlen + may yield a different result in certain error situations (when a domain name segment contains null byte). +*/ +#if 0 +unsigned int rhnlen(const unsigned char *rhn) +{ + unsigned int i=0,lb; + + while((lb=rhn[i++])) + i+=lb; + return i; +} +#endif + +/* + * Non-validating rhn copy (use with checked or generated data only). + * Returns number of characters copied. The buffer dst points to is assumed to be DNSNAMEBUFSIZE (or + * at any rate large enough) bytes in size. + * The answer assembly code uses this; it is guaranteed to not clobber anything + * after the name. + */ +unsigned int rhncpy(unsigned char *dst, const unsigned char *src) +{ + unsigned int len = rhnlen(src); + + PDNSD_ASSERT(len<=DNSNAMEBUFSIZE,"rhncpy: src too long!"); + memcpy(dst,src,len>DNSNAMEBUFSIZE?DNSNAMEBUFSIZE:len); + return len; +} + + +/* Check whether a name is a normal wire-encoded domain name, + i.e. is not compressed, doesn't use extended labels and is not + too long. +*/ +int isnormalencdomname(const unsigned char *rhn, unsigned maxlen) +{ + unsigned int i,lb; + + if(maxlen>DNSNAMEBUFSIZE) + maxlen=DNSNAMEBUFSIZE; + for(i=0;;) { + if(i>=maxlen) return 0; + lb=rhn[i++]; + if(lb==0) break; + if(lb>0x3f) return 0; + i += lb; + } + + return 1; +} + +int str2pdnsd_a(const char *addr, pdnsd_a *a) +{ +#ifdef ENABLE_IPV4 + if (run_ipv4) { + return inet_aton(addr,&a->ipv4); + } +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + /* Try to map an IPv4 address to IPv6 */ + struct in_addr a4; + if(inet_aton(addr,&a4)) { + a->ipv6=global.ipv4_6_prefix; + ((uint32_t *)(&a->ipv6))[3]=a4.s_addr; + return 1; + } + return inet_pton(AF_INET6,addr,&a->ipv6)>0; + } +#endif + /* return 0; */ +} + +/* definition moved to helpers.h */ +#if 0 +int is_inaddr_any(pdnsd_a *a) +{ + return SEL_IPVER( a->ipv4.s_addr==INADDR_ANY, + IN6_IS_ADDR_UNSPECIFIED(&a->ipv6) ); +} +#endif + +/* + * This is used for user output only, so it does not matter when an error occurs. + */ +const char *pdnsd_a2str(pdnsd_a *a, char *buf, int maxlen) +{ + const char *res= SEL_IPVER( inet_ntop(AF_INET,&a->ipv4,buf,maxlen), + inet_ntop(AF_INET6,&a->ipv6,buf,maxlen) ); + if (!res) { + log_error("inet_ntop: %s", strerror(errno)); + return "?.?.?.?"; + } + + return res; +} + + +/* Appropriately set our random device */ +#ifdef R_DEFAULT +# if (TARGET == TARGET_BSD) && !defined(__NetBSD__) +# define R_ARC4RANDOM 1 +# else +# define R_RANDOM 1 +# endif +#endif + +#ifdef RANDOM_DEVICE +FILE *rand_file; +#endif + +#ifdef R_RANDOM +void init_crandom() +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + srandom(tv.tv_sec^tv.tv_usec); /* not as guessable as time() */ +} +#endif + +/* initialize the PRNG */ +int init_rng() +{ +#ifdef RANDOM_DEVICE + if (!(rand_file=fopen(RANDOM_DEVICE,"r"))) { + log_error("Could not open %s.",RANDOM_DEVICE); + return 0; + } +#endif +#ifdef R_RANDOM + init_crandom(); +#endif + return 1; +} + +/* The following function is now actually defined as a macro in helpers.h */ +#if 0 +void free_rng() +{ +#ifdef RANDOM_DEVICE + if (rand_file) + fclose(rand_file); +#endif +} +#endif + +/* generate a (more or less) random number 16 bits long. */ +unsigned short get_rand16() +{ +#ifdef RANDOM_DEVICE + unsigned short rv; + + if (rand_file) { + if (fread(&rv,sizeof(rv),1, rand_file)!=1) { + log_error("Error while reading from random device: %s", strerror(errno)); + pdnsd_exit(); + } + return rv&0xffff; + } else + return random()&0xffff; +#endif +#ifdef R_RANDOM + return random()&0xffff; +#endif +#ifdef R_ARC4RANDOM + return arc4random()&0xffff; +#endif +} + +/* fsprintf does formatted output to a file descriptor. + The functionality is similar to fprintf, but note that fd + is of type int instead of FILE*. + This function has been rewritten by Paul Rombouts */ +int fsprintf(int fd, const char *format, ...) +{ + int n; + va_list va; + + { + char buf[256]; + + va_start(va,format); + n=vsnprintf(buf,sizeof(buf),format,va); + va_end(va); + + if(n<(int)sizeof(buf)) { + if(n>0) n=write_all(fd,buf,n); + return n; + } + } + /* retry with a right sized buffer, needs glibc 2.1 or higher to work */ + { + unsigned bufsize=n+1; + char buf[bufsize]; + + va_start(va,format); + n=vsnprintf(buf,bufsize,format,va); + va_end(va); + + if(n>0) n=write_all(fd,buf,n); + } + return n; +} + +/* Convert data into a hexadecimal representation (for debugging purposes).. + The result is stored in the character array buf. + If buf is not large enough to hold the result, the + truncation is indicated by trailing dots. +*/ +void hexdump(const void *data, int dlen, char *buf, int buflen) +{ + const unsigned char *p=data; + int i,j=0; + for(i=0;i=rem) goto truncated; + j += n; + } + goto done; + + truncated: + if(j>=6) { + j -= 3; + if(j+4>=buflen) + j -= 3; + buf[j++]=' '; + buf[j++]='.'; + buf[j++]='.'; + buf[j++]='.'; + } + else { + int ndots=buflen-1; + if(ndots>3) ndots=3; + j=0; + while(j=size) + return -1; + c=in[i]; + if(!isprint(c)) { + int rem=size-j; + int n=snprintf(&str[j],rem,"\\%03o",c); + if(n<0 || n>=rem) { + return -1; + } + j+=n; + } + else { + if(c=='\\' || c=='"') { + str[j++]='\\'; + if(j+1>=size) + return -1; + } + str[j++]=c; + } + } + str[j]=0; + return j; +} + +/* + * This is not like strcmp, but will return 1 on match or 0 if the + * strings are different. + */ +/* definition moved to helpers.h as an inline function. */ +#if 0 +int stricomp(char *a, char *b) +{ + int i; + if (strlen(a) != strlen(b)) + return 0; + for (i=0;i= dstsz-1 && o!='\0') + return 0; + return 1; +} +#endif + +#ifndef HAVE_GETLINE +/* Note by Paul Rombouts: I know that getline is a GNU extension and is not really portable, + but the alternative standard functions have some real problems. + The following substitute does not have exactly the same semantics as the GNU getline, + but it should be good enough, as long as the stream doesn't contain any null chars. + This version is actually based on fgets_realloc() that I found in the WWWOFFLE source. +*/ + +#define BUFSIZE 256 +int getline(char **lineptr, size_t *n, FILE *stream) +{ + char *line=*lineptr; + size_t sz=*n,i; + + if(!line || sz=sz) { + /* retry with a right sized buffer, needs glibc 2.1 or higher to work */ + sz=n+1; + { + char *tmp=realloc(line,sz); + if(tmp) { + line=tmp; + n=vsnprintf(line,sz,format,vasave); + } + else + n= -1; + } + } + va_end(vasave); + + if(n>=0) + *lineptr=line; + else + free(line); + return n; +} +#endif + +#ifndef HAVE_ASPRINTF +int asprintf (char **lineptr, const char *format, ...) +{ + int n; + va_list va; + + va_start(va,format); + n=vasprintf(lineptr,format,va); + va_end(va); + + return n; +} +#endif + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size) +{ + const char *rc = NULL; + + if (src != NULL && dst != NULL && size > 0) { + switch (af) { + case AF_INET: + { + const unsigned char *p=src; + int n = snprintf(dst, size, "%u.%u.%u.%u", + p[0],p[1],p[2],p[3]); + if (n >= 0 && n < size) rc = dst; + } + break; + +#ifdef AF_INET6 + case AF_INET6: + { + const unsigned char *p=src; + unsigned int i,offs=0; + for (i=0;i<16;i+=2) { + int n=snprintf(dst+offs, size-offs,i==0?"%x":":%x", ((unsigned)p[i]<<8)|p[i+1]); + if(n<0) return NULL; + offs+=n; + if(offs>=size) return NULL; + } + rc = dst; + } + break; +#endif + } + } + + return rc; +} +#endif diff --git a/jni/pdnsd/src/helpers.h b/jni/pdnsd/src/helpers.h new file mode 100644 index 00000000..e45c56ee --- /dev/null +++ b/jni/pdnsd/src/helpers.h @@ -0,0 +1,319 @@ +/* helpers.h - Various helper functions + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2007, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef HELPERS_H +#define HELPERS_H + +#include +#include +#include +#include +#include +#include "cache.h" +#include "pdnsd_assert.h" + +#define SOFTLOCK_MAXTRIES 1000 + +int run_as(const char *user); +void pdnsd_exit(void); +int softlock_mutex(pthread_mutex_t *mutex); + +#if 0 +inline static int isdchar (unsigned char c) +{ + return ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='-' +#ifdef UNDERSCORE + || c=='_' +#endif + ); +} +#endif + +const unsigned char *rhn2str(const unsigned char *rhn, unsigned char *str, unsigned int size); +int str2rhn(const unsigned char *str, unsigned char *rhn); +const char *parsestr2rhn(const unsigned char *str, unsigned int len, unsigned char *rhn); + +/* Note added by Paul Rombouts: + Compared to the definition used by Thomas Moestl (strlen(rhn)+1), the following definition of rhnlen + may yield a different result in certain error situations (when a domain name segment contains a null byte). +*/ +inline static unsigned int rhnlen(const unsigned char *rhn) + __attribute__((always_inline)); +inline static unsigned int rhnlen(const unsigned char *rhn) +{ + unsigned int i=0,lb; + + while((lb=rhn[i++])) + i+=lb; + return i; +} + +/* Skip k segments in a name in length-byte string notation. */ +inline static const unsigned char *skipsegs(const unsigned char *nm, unsigned k) + __attribute__((always_inline)); +inline static const unsigned char *skipsegs(const unsigned char *nm, unsigned k) +{ + unsigned lb; + for(;k && (lb= *nm); --k) { + nm += lb+1; + } + return nm; +} + +/* Skip a name in length-byte string notation and return a pointer to the + position right after the terminating null byte. +*/ +inline static unsigned char *skiprhn(unsigned char *rhn) + __attribute__((always_inline)); +inline static unsigned char *skiprhn(unsigned char *rhn) +{ + unsigned lb; + + while((lb= *rhn++)) + rhn += lb; + return rhn; +} + +/* count the number of name segments of a name in length-byte string notation. */ +inline static unsigned int rhnsegcnt(const unsigned char *rhn) + __attribute__((always_inline)); +inline static unsigned int rhnsegcnt(const unsigned char *rhn) +{ + unsigned int res=0,lb; + + while((lb= *rhn)) { + ++res; + rhn += lb+1; + } + return res; +} + +unsigned int rhncpy(unsigned char *dst, const unsigned char *src); +int isnormalencdomname(const unsigned char *rhn, unsigned maxlen); + +inline static int is_inaddr_any(pdnsd_a *a) __attribute__((always_inline)); +inline static int is_inaddr_any(pdnsd_a *a) +{ + return SEL_IPVER( a->ipv4.s_addr==INADDR_ANY, + IN6_IS_ADDR_UNSPECIFIED(&a->ipv6) ); +} + + +inline static int same_inaddr(pdnsd_a *a, pdnsd_a *b) + __attribute__((always_inline)); +inline static int same_inaddr(pdnsd_a *a, pdnsd_a *b) +{ + return SEL_IPVER( a->ipv4.s_addr==b->ipv4.s_addr, + IN6_ARE_ADDR_EQUAL(&a->ipv6,&b->ipv6) ); +} + +/* Compare a pdnsd_a* with a pdnsd_a2*. */ +inline static int same_inaddr2(pdnsd_a *a, pdnsd_a2 *b) + __attribute__((always_inline)); +inline static int same_inaddr2(pdnsd_a *a, pdnsd_a2 *b) +{ + return SEL_IPVER( a->ipv4.s_addr==b->ipv4.s_addr, + IN6_ARE_ADDR_EQUAL(&a->ipv6,&b->ipv6) && b->ipv4.s_addr==INADDR_ANY ); +} + +inline static int equiv_inaddr2(pdnsd_a *a, pdnsd_a2 *b) + __attribute__((always_inline)); +inline static int equiv_inaddr2(pdnsd_a *a, pdnsd_a2 *b) +{ + return SEL_IPVER( a->ipv4.s_addr==b->ipv4.s_addr, + IN6_ARE_ADDR_EQUAL(&a->ipv6,&b->ipv6) || + (b->ipv4.s_addr!=INADDR_ANY && ADDR_EQUIV6_4(&a->ipv6,&b->ipv4)) ); +} + +int str2pdnsd_a(const char *addr, pdnsd_a *a); +const char *pdnsd_a2str(pdnsd_a *a, char *buf, int maxlen); + +int init_rng(void); +#ifdef RANDOM_DEVICE +extern FILE *rand_file; +/* Because this is usually empty, it is now defined as a macro to save overhead.*/ +#define free_rng() {if (rand_file) fclose(rand_file);} +#else +#define free_rng() +#endif + +unsigned short get_rand16(void); + +int fsprintf(int fd, const char *format, ...) printfunc(2, 3); +#if !defined(CPP_C99_VARIADIC_MACROS) +/* GNU C Macro Varargs style. */ +# define fsprintf_or_return(args...) {int _retval; if((_retval=fsprintf(args))<0) return _retval;} +#else +/* ANSI C99 style variadic macro. */ +# define fsprintf_or_return(...) {int _retval; if((_retval=fsprintf(__VA_ARGS__))<0) return _retval;} +#endif + +/* Added by Paul Rombouts */ +inline static ssize_t write_all(int fd,const void *data,size_t n) + __attribute__((always_inline)); +inline static ssize_t write_all(int fd,const void *data,size_t n) +{ + ssize_t written=0; + + while(written +int vasprintf (char **lineptr, const char *format, va_list va); +#endif + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#define strlitlen(strlit) (sizeof(strlit)-1) + +#endif /* HELPERS_H */ diff --git a/jni/pdnsd/src/icmp.c b/jni/pdnsd/src/icmp.c new file mode 100644 index 00000000..6e3e46fe --- /dev/null +++ b/jni/pdnsd/src/icmp.c @@ -0,0 +1,544 @@ +/* icmp.c - Server response tests using ICMP echo requests + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2005, 2007, 2012 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +/* + * This should now work on both Linux and FreeBSD (and CYGWIN?). If anyone + * with experience in other Unix flavors wants to contribute platform-specific + * code, he is very welcome. + */ + +#include +#ifdef HAVE_SYS_POLL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "ipvers.h" +#if (TARGET==TARGET_LINUX) +# include +# include +# include +#elif (TARGET==TARGET_BSD) +# include +# include +# include +#elif (TARGET==TARGET_CYGWIN) +# include +# include +# include +# include "freebsd_netinet_ip_icmp.h" +#else +# error Unsupported platform! +#endif +#ifdef ENABLE_IPV6 +# include +# include +#endif +#include +#include "icmp.h" +#include "error.h" +#include "helpers.h" +#include "servers.h" + + +#define ICMP_MAX_ERRS 10 +static volatile unsigned long icmp_errs=0; /* This is only here to minimize log output. + Since the consequences of a race is only + one log message more/less (out of + ICMP_MAX_ERRS), no lock is required. */ + +volatile int ping_isocket=-1; +#ifdef ENABLE_IPV6 +volatile int ping6_isocket=-1; +#endif + +/* different names, same thing... be careful, as these are macros... */ +#if (TARGET==TARGET_LINUX) +# define ip_saddr saddr +# define ip_daddr daddr +# define ip_hl ihl +# define ip_p protocol +#else +# define icmphdr icmp +# define iphdr ip +# define ip_saddr ip_src.s_addr +# define ip_daddr ip_dst.s_addr +#endif + +#if (TARGET==TARGET_LINUX) +# define icmp_type type +# define icmp_code code +# define icmp_cksum checksum +# define icmp_id un.echo.id +# define icmp_seq un.echo.sequence +#else +# define ICMP_DEST_UNREACH ICMP_UNREACH +# define ICMP_TIME_EXCEEDED ICMP_TIMXCEED +#endif + +#define ICMP_BASEHDR_LEN 8 +#define ICMP4_ECHO_LEN ICMP_BASEHDR_LEN + +#if (TARGET==TARGET_LINUX) || (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN) +/* + * These are the ping implementations for Linux/FreeBSD in their IPv4/ICMPv4 and IPv6/ICMPv6 versions. + * I know they share some code, but I'd rather keep them separated in some parts, as some + * things might go in different directions there. + */ + +/* Initialize the sockets for pinging */ +void init_ping_socket() +{ + if ((ping_isocket=socket(PF_INET, SOCK_RAW, IPPROTO_ICMP))==-1) { + log_warn("icmp ping: socket() failed: %s",strerror(errno)); + } +#ifdef ENABLE_IPV6 + if (!run_ipv4) { + /* Failure to initialize the IPv4 ping socket is not + necessarily a problem, as long as the IPv6 version works. */ + if ((ping6_isocket=socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6))==-1) { + log_warn("icmpv6 ping: socket() failed: %s",strerror(errno)); + } + } +#endif +} + +/* Takes a packet as send out and a received ICMP packet and looks whether the ICMP packet is + * an error reply on the sent-out one. packet is only the packet (without IP header). + * errmsg includes an IP header. + * to is the destination address of the original packet (the only thing that is actually + * compared of the IP header). The RFC says that we get at least 8 bytes of the offending packet. + * We do not compare more, as this is all we need.*/ +static int icmp4_errcmp(char *packet, int plen, struct in_addr *to, char *errmsg, int elen, int errtype) +{ + struct iphdr iph; + struct icmphdr icmph; + struct iphdr eiph; + char *data; + + /* XXX: lots of memcpy to avoid unaligned accesses on alpha */ + if (elen= ICMP_BASEHDR_LEN, "icmp4_errcmp: ICMP_BASEHDR_LEN botched"); + memcpy(&icmph,errmsg+iph.ip_hl*4,ICMP_BASEHDR_LEN); + memcpy(&eiph,errmsg+iph.ip_hl*4+ICMP_BASEHDR_LEN,sizeof(eiph)); + if (elens_addr, &eiph.ip_daddr, sizeof(to->s_addr))==0 && + memcmp(data, packet, plen<8?plen:8)==0; +} + +/* IPv4/ICMPv4 ping. Called from ping (see below) */ +static int ping4(struct in_addr addr, int timeout, int rep) +{ + int i; + int isock; +#if (TARGET==TARGET_LINUX) + struct icmp_filter f; +#endif + unsigned short id=(unsigned short)get_rand16(); /* randomize a ping id */ + + isock=ping_isocket; + +#if (TARGET==TARGET_LINUX) + /* Fancy ICMP filering -- only on Linux (as far is I know) */ + + /* In fact, there should be macros for treating icmp_filter, but I haven't found them in Linux 2.2.15. + * So, set it manually and unportable ;-) */ + /* This filter lets ECHO_REPLY (0), DEST_UNREACH(3) and TIME_EXCEEDED(11) pass. */ + /* !(0000 1000 0000 1001) = 0xff ff f7 f6 */ + f.data=0xfffff7f6; + if (setsockopt(isock,SOL_RAW,ICMP_FILTER,&f,sizeof(f))==-1) { + if (++icmp_errs<=ICMP_MAX_ERRS) { + log_warn("icmp ping: setsockopt() failed: %s", strerror(errno)); + } + return -1; + } +#endif + + for (i=0;i> 16) + (sum & 0xffff); + sum += (sum >> 16); + icmpd.icmp_cksum=~sum; + + memset(&to,0,sizeof(to)); + to.sin_family=AF_INET; + to.sin_port=0; + to.sin_addr=addr; + SET_SOCKA_LEN4(to); + if (sendto(isock,&icmpd,ICMP4_ECHO_LEN,0,(struct sockaddr *)&to,sizeof(to))==-1) { + if (++icmp_errs<=ICMP_MAX_ERRS) { + log_warn("icmp ping: sendto() failed: %s.",strerror(errno)); + } + return -1; + } + /* listen for reply. */ + tm=time(NULL); tpassed=0; + do { + int psres; +#ifdef NO_POLL + fd_set fds,fdse; + struct timeval tv; + FD_ZERO(&fds); + PDNSD_ASSERT(isocktpassed?timeout-tpassed:0; + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that the effort + to do this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + return -1; + } + psres=select(isock+1,&fds,NULL,&fdse,&tv); +#else + struct pollfd pfd; + pfd.fd=isock; + pfd.events=POLLIN; + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that the effort + to do this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + return -1; + } + psres=poll(&pfd,1,timeout>tpassed?(timeout-tpassed)*1000:0); +#endif + + if (psres<0) { + if(errno==EINTR && is_interrupted_servstat_thread()) { + DEBUG_MSG("poll/select interrupted in server status thread.\n"); + } + else if (++icmp_errs<=ICMP_MAX_ERRS) { + log_warn("poll/select failed: %s",strerror(errno)); + } + return -1; + } + if (psres==0) /* timed out */ + break; + +#ifdef NO_POLL + if (FD_ISSET(isock,&fds) || FD_ISSET(isock,&fdse)) +#else + if (pfd.revents&(POLLIN|POLLERR)) +#endif + { + char buf[1024]; + socklen_t sl=sizeof(from); + int len; + + if ((len=recvfrom(isock,&buf,sizeof(buf),0,(struct sockaddr *)&from,&sl))!=-1) { + if (len>sizeof(struct iphdr)) { + struct iphdr iph; + + memcpy(&iph, buf, sizeof(iph)); + if (len-iph.ip_hl*4>=ICMP_BASEHDR_LEN) { + struct icmphdr icmpp; + + memcpy(&icmpp, ((uint32_t *)buf)+iph.ip_hl, sizeof(icmpp)); + if (iph.ip_saddr==addr.s_addr && icmpp.icmp_type==ICMP_ECHOREPLY && + ntohs(icmpp.icmp_id)==id && ntohs(icmpp.icmp_seq)<=i) { + return (i-ntohs(icmpp.icmp_seq))*timeout+(time(NULL)-tm); /* return the number of ticks */ + } else { + /* No regular echo reply. Maybe an error? */ + if (icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN, &to.sin_addr, buf, len, ICMP_DEST_UNREACH) || + icmp4_errcmp((char *)&icmpd, ICMP4_ECHO_LEN, &to.sin_addr, buf, len, ICMP_TIME_EXCEEDED)) { + return -1; + } + } + } + } + } else { + return -1; /* error */ + } + } + else { + if (++icmp_errs<=ICMP_MAX_ERRS) { + log_error("Unhandled poll/select event in ping4() at %s, line %d.",__FILE__,__LINE__); + } + return -1; + } + tpassed=time(NULL)-tm; + } while (tpassedtpassed?timeout-tpassed:0; + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that the effort + to do this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + return -1; + } + psres=select(isock+1,&fds,NULL,&fdse,&tv); +#else + struct pollfd pfd; + pfd.fd=isock; + pfd.events=POLLIN; + /* There is a possible race condition with the arrival of a signal here, + but it is so unlikely to be a problem in practice that the effort + to do this properly is not worth the trouble. + */ + if(is_interrupted_servstat_thread()) { + DEBUG_MSG("server status thread interrupted.\n"); + return -1; + } + psres=poll(&pfd,1,timeout>tpassed?(timeout-tpassed)*1000:0); +#endif + + if (psres<0) { + if(errno==EINTR && is_interrupted_servstat_thread()) { + DEBUG_MSG("poll/select interrupted in server status thread.\n"); + } + else if (++icmp_errs<=ICMP_MAX_ERRS) { + log_warn("poll/select failed: %s",strerror(errno)); + } + return -1; + } + if (psres==0) /* timed out */ + break; + +#ifdef NO_POLL + if (FD_ISSET(isock,&fds) || FD_ISSET(isock,&fdse)) +#else + if (pfd.revents&(POLLIN|POLLERR)) +#endif + { + char buf[1024]; + socklen_t sl=sizeof(from); + int len; + if ((len=recvfrom(isock,&buf,sizeof(buf),0,(struct sockaddr *)&from,&sl))!=-1) { + if (len>=sizeof(struct icmp6_hdr)) { + /* we get packets without IPv6 header, luckily */ + struct icmp6_hdr icmpp; + + memcpy(&icmpp, buf, sizeof(icmpp)); + if (IN6_ARE_ADDR_EQUAL(&from.sin6_addr,&a) && + ntohs(icmpp.icmp6_id)==id && ntohs(icmpp.icmp6_seq)<=i) { + return (i-ntohs(icmpp.icmp6_seq))*timeout+(time(NULL)-tm); /* return the number of ticks */ + } else { + /* No regular echo reply. Maybe an error? */ + if (icmp6_errcmp((char *)&icmpd, sizeof(icmpd), &from.sin6_addr, buf, len, ICMP6_DST_UNREACH) || + icmp6_errcmp((char *)&icmpd, sizeof(icmpd), &from.sin6_addr, buf, len, ICMP6_TIME_EXCEEDED)) { + return -1; + } + } + } + } else { + return -1; /* error */ + } + } + else { + if (++icmp_errs<=ICMP_MAX_ERRS) { + log_error("Unhandled poll/select event in ping6() at %s, line %d.",__FILE__,__LINE__); + } + return -1; + } + tpassed=time(NULL)-tm; + } while (tpassedipv4,timeout,rep); +#endif +#ifdef ENABLE_IPV6 + ELSE_IPV6 { + /* If it is a IPv4 mapped IPv6 address, we prefer ICMPv4. */ + if (ping_isocket!=-1 && IN6_IS_ADDR_V4MAPPED(&addr->ipv6)) { + struct in_addr v4; + v4.s_addr=((uint32_t *)&addr->ipv6)[3]; + return ping4(v4,timeout,rep); + } else + return ping6(addr->ipv6,timeout,rep); + } +#endif + return -1; +} + +#else +# error "Huh! No OS macro defined!" +#endif /*(TARGET==TARGET_LINUX) || (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN)*/ diff --git a/jni/pdnsd/src/icmp.h b/jni/pdnsd/src/icmp.h new file mode 100644 index 00000000..3fa6778c --- /dev/null +++ b/jni/pdnsd/src/icmp.h @@ -0,0 +1,43 @@ +/* icmp.h - Server response tests using ICMP echo requests + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2007 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef ICMP_H +#define ICMP_H + + +#include +#include "ipvers.h" + +volatile extern int ping_isocket; +volatile extern int ping6_isocket; + +/* initialize a socket for pinging */ +void init_ping_socket(void); + +/* + * This is a classical ping routine. + * timeout in 10ths of seconds, rep is the repetition count. + */ + +int ping(pdnsd_a *addr, int timeout, int rep); + +#endif diff --git a/jni/pdnsd/src/ipvers.h b/jni/pdnsd/src/ipvers.h new file mode 100644 index 00000000..b1d7a2cd --- /dev/null +++ b/jni/pdnsd/src/ipvers.h @@ -0,0 +1,297 @@ +/* ipvers.h - definitions for IPv4 and IPv6 + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2007, 2009 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef IPVERS_H +#define IPVERS_H + +#include +#include +#include +#include +#include +#include "rr_types.h" + +#if defined(ENABLE_IPV4) && !defined(ENABLE_IPV6) +# ifdef DEFAULT_IPV4 +# undef DEFAULT_IPV4 +# endif +# define DEFAULT_IPV4 1 +#endif + +#if !defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +# ifdef DEFAULT_IPV4 +# undef DEFAULT_IPV4 +# endif +# define DEFAULT_IPV4 0 +#endif + +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +# define ELSE_IPV6 else +#else +# define ELSE_IPV6 +#endif + +/* From main.c */ +#ifdef ENABLE_IPV4 +# ifdef ENABLE_IPV6 +extern short int run_ipv4; +extern short int cmdlineipv; +# define SEL_IPVER(a4,a6) (run_ipv4? a4: a6) +# else +# define run_ipv4 1 +# define SEL_IPVER(a4,a6) (a4) +# endif +#else +# define run_ipv4 0 +# define SEL_IPVER(a4,a6) (a6) +#endif +#ifdef ENABLE_IPV6 +#define DEFAULT_IPV4_6_PREFIX "::ffff:0.0.0.0" +/* extern short int cmdlineprefix; */ +#endif + +#if (TARGET==TARGET_LINUX) && !defined(HAVE_STRUCT_IN_PKTINFO) +struct in_pktinfo +{ + int ipi_ifindex; + struct in_addr ipi_spec_dst; + struct in_addr ipi_addr; +}; +#endif + +#if (TARGET==TARGET_LINUX) +/* some older glibc versions seem to lack this. */ +# ifndef IP_PKTINFO +# define IP_PKTINFO 8 +# endif +# ifndef CMSG_LEN +/* ---- from glibc 2.1.2 */ + +/* Ancillary data object manipulation macros. */ +# if !defined __STRICT_ANSI__ && defined __GNUC__ && __GNUC__ >= 2 +# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data) +# else +# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1)) +# endif +# define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg) +# define CMSG_FIRSTHDR(mhdr) \ + ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \ + ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) NULL) +# define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ + & ~(sizeof (size_t) - 1)) +# define CMSG_SPACE(len) (CMSG_ALIGN (len) \ + + CMSG_ALIGN (sizeof (struct cmsghdr))) +# define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) +extern struct cmsghdr *__cmsg_nxthdr __P ((struct msghdr *__mhdr, + struct cmsghdr *__cmsg)); +# ifdef __USE_EXTERN_INLINES +# ifndef _EXTERN_INLINE +# define _EXTERN_INLINE extern __inline +# endif +_EXTERN_INLINE struct cmsghdr * +__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW +{ + if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) + /* The kernel header does this so there may be a reason. */ + return 0; + + __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + + CMSG_ALIGN (__cmsg->cmsg_len)); + if ((unsigned char *) (__cmsg + 1) >= ((unsigned char *) __mhdr->msg_control + + __mhdr->msg_controllen) + || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) + >= ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) + /* No more entries. */ + return 0; + return __cmsg; +} +# endif /* Use `extern inline'. */ +/* ---- */ +# endif +#endif + +#if defined(ENABLE_IPV4) && !defined(SIN_LEN) && (TARGET==TARGET_BSD) +# define SIN_LEN +#endif + +#if defined(ENABLE_IPV6) && (TARGET==TARGET_LINUX) + +/* Some glibc versions (I know of 2.1.2) get this wrong, so we define our own. To be exact, this is fixed + * glibc code. */ +#ifdef IN6_ARE_ADDR_EQUAL +# undef IN6_ARE_ADDR_EQUAL +#endif +#define IN6_ARE_ADDR_EQUAL(a,b) \ + ((((uint32_t *) (a))[0] == ((uint32_t *) (b))[0]) && \ + (((uint32_t *) (a))[1] == ((uint32_t *) (b))[1]) && \ + (((uint32_t *) (a))[2] == ((uint32_t *) (b))[2]) && \ + (((uint32_t *) (a))[3] == ((uint32_t *) (b))[3])) + +#endif + +/* This is the IPv6 flowid that we pass on to the IPv6 protocol stack. This value was not currently defined + * at the time of writing. Should this change, define a appropriate flowinfo here. */ +#ifndef IPV6_FLOWINFO +#define IPV6_FLOWINFO 0 +#endif + +/* There does not seem to be a function/macro to generate IPv6-mapped IPv4-Adresses. So here comes mine. + * Pass an in_addr* and an in6_addr* */ +#define IPV6_MAPIPV4(a,b) {((uint32_t *)(b))[3]=(a)->s_addr; \ + ((uint32_t *)(b))[2]=htonl(0xffff); \ + ((uint32_t *)(b))[1]=((uint32_t *)(b))[0]=0; } + +/* A macro to extract the pointer to the address of a struct sockaddr (_in or _in6) */ + +#define SOCKA_A4(a) ((pdnsd_a *)&((struct sockaddr_in *)(a))->sin_addr) +#define SOCKA_A6(a) ((pdnsd_a *)&((struct sockaddr_in6 *)(a))->sin6_addr) + +#define SOCKA_A(a) SEL_IPVER(SOCKA_A4(a),SOCKA_A6(a)) +#define PDNSD_PF_INET SEL_IPVER(PF_INET,PF_INET6) +#define PDNSD_AF_INET SEL_IPVER(AF_INET,AF_INET6) + +/* This is to compare two addresses. This is a macro because it may change due to the more complex IPv6 adressing architecture + * (there are, for example, two equivalent addresses of the loopback device) + * Pass this two addresses as in_addr or in6_addr. pdnsd_a is ok (it is a union) */ + +#define ADDR_EQUIV4(a,b) (((struct in_addr *)(a))->s_addr==((struct in_addr *)(b))->s_addr) +#define ADDR_EQUIV6(a,b) IN6_ARE_ADDR_EQUAL(((struct in6_addr *)(a)),((struct in6_addr *)(b))) + +#define ADDR_EQUIV(a,b) SEL_IPVER(ADDR_EQUIV4(a,b), ADDR_EQUIV6(a,b)) + +/* Compare an IPv6 adress with an IPv4 one. b should have type struct in_addr*. + Note the similarity with the IPV6_MAPIPV4 macro. */ +#define ADDR_EQUIV6_4(a,b) (((uint32_t *)(a))[3]==(b)->s_addr && \ + ((uint32_t *)(a))[2]==htonl(0xffff) && \ + ((uint32_t *)(a))[1]==0 && \ + ((uint32_t *)(a))[0]==0) + +/* Compare two address a and b in combination with a netmask m. + Only the bits coresponding to those set in the netmask are matched, the rest are ignored. + Pass in_addr* or in6_addr* arguments, respectively. */ +#define ADDR4MASK_EQUIV(a,b,m) ((((a)->s_addr^(b)->s_addr)&(m)->s_addr)==0) +#define ADDR6MASK_EQUIV(a,b,m) (((((uint32_t *)(a))[0]^((uint32_t *)(b))[0])&((uint32_t *)(m))[0])==0 && \ + ((((uint32_t *)(a))[1]^((uint32_t *)(b))[1])&((uint32_t *)(m))[1])==0 && \ + ((((uint32_t *)(a))[2]^((uint32_t *)(b))[2])&((uint32_t *)(m))[2])==0 && \ + ((((uint32_t *)(a))[3]^((uint32_t *)(b))[3])&((uint32_t *)(m))[3])==0) + +/* See if we need 4.4BSD style sockaddr_* structures and define some macros that set the length field. + * The non-4.4BSD behaviour is the only one that is POSIX-conformant.*/ +#if defined(SIN6_LEN) || defined(SIN_LEN) +# define BSD44_SOCKA +# define SET_SOCKA_LEN4(socka) (socka.sin_len=sizeof(struct sockaddr_in)) +# define SET_SOCKA_LEN6(socka) (socka.sin6_len=sizeof(struct sockaddr_in6)) +#else +# define SET_SOCKA_LEN4(socka) +# define SET_SOCKA_LEN6(socka) +#endif + +#ifdef ENABLE_IPV6 +# define ADDRSTR_MAXLEN INET6_ADDRSTRLEN +#else +# ifdef INET_ADDRSTRLEN +# define ADDRSTR_MAXLEN INET_ADDRSTRLEN +# else +# define ADDRSTR_MAXLEN 16 +# endif +#endif + +#if (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN) +# define SOL_IPV6 IPPROTO_IPV6 +#endif + +#ifdef ENABLE_IPV6 +# ifndef IPV6_RECVPKTINFO +/* This appears to be needed e.g. on Darwin (Mac OS X). */ +# define IPV6_RECVPKTINFO IPV6_PKTINFO +# endif +#endif + +typedef union { +#ifdef ENABLE_IPV4 + struct in_addr ipv4; +#endif +#ifdef ENABLE_IPV6 + struct in6_addr ipv6; +#endif +} pdnsd_a; + +#ifdef ENABLE_IPV4 +#define PDNSD_A_INITIALIZER {{INADDR_ANY}} +#else +#define PDNSD_A_INITIALIZER {IN6ADDR_ANY_INIT} +#endif + + +/* The pdnsd_a2 type is very similar to pdnsd_a, but can hold + both an IPv4 and an IPv6 address at the same time, + i.e. a struct instead of a union. +*/ +typedef struct { +#ifdef ENABLE_IPV6 + struct in6_addr ipv6; +#endif + struct in_addr ipv4; +} pdnsd_a2; + +/* Macros/functions for assigning/converting a pdnsd_a* to a pdnsd_a2* type, + and vice versa. +*/ +#ifdef ENABLE_IPV6 +inline static void SET_PDNSD_A2(pdnsd_a2 *a2, pdnsd_a *a) __attribute__((always_inline)); +inline static void SET_PDNSD_A2(pdnsd_a2 *a2, pdnsd_a *a) +{ +#ifdef ENABLE_IPV4 + if(run_ipv4) + a2->ipv4=a->ipv4; + else +#endif + { + a2->ipv6=a->ipv6; + a2->ipv4.s_addr=INADDR_ANY; + } +} +#else +# define SET_PDNSD_A2(a2,a) ((a2)->ipv4=(a)->ipv4) +#endif + +#define PDNSD_A2_TO_A(a2) SEL_IPVER(((pdnsd_a *)&(a2)->ipv4),((pdnsd_a *)&(a2)->ipv6)) + +/* Do we have sufficient support in the C libraries to allow local AAAA records + to be defined? */ +#if defined(HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_PTON) +# define ALLOW_LOCAL_AAAA IS_CACHED_AAAA +#else +# define ALLOW_LOCAL_AAAA 0 +#endif + +/* Used to enter local records */ +typedef union { + struct in_addr ipv4; +#if ALLOW_LOCAL_AAAA + struct in6_addr ipv6; +#endif +} pdnsd_ca; + + +#endif diff --git a/jni/pdnsd/src/list.c b/jni/pdnsd/src/list.c new file mode 100644 index 00000000..03701860 --- /dev/null +++ b/jni/pdnsd/src/list.c @@ -0,0 +1,171 @@ +/* list.c - Dynamic array and list handling + + Copyright (C) 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2007, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include "helpers.h" +#include "error.h" +#include "list.h" + + +/* Grow a dynamic array to hold one extra element. + This could be done using da_resize(), but this is such a common operation + it is has been given its own optimized implementation. + da_grow1() returns a pointer to the new (possibly reallocated) array if + successful, otherwise it frees the old array (after freeing all the array + elements if a clean-up routine is supplied) and returns NULL. +*/ +darray da_grow1(darray a, size_t headsz, size_t elemsz, void (*cleanuproutine) (void *)) +{ + size_t k = (a?a->nel:0); + if(!a || (k!=0 && (k&7)==0)) { + darray tmp=(darray)realloc(a, headsz+elemsz*(k+8)); + if (!tmp && a) { + if(cleanuproutine) { + size_t i; + for(i=0;inel=k+1; + return a; +} + +inline static size_t alloc_nel(size_t n) +{ + return n==0 ? 8 : (n+7)&(~7); +} + +/* da_resize() allows you to grow (or shrink) a dynamic array to an arbitrary length n, + but is otherwise similar to da_grow1(). +*/ +darray da_resize(darray a, size_t headsz, size_t elemsz, size_t n, void (*cleanuproutine) (void *)) +{ + size_t ael = (a?alloc_nel(a->nel):0); + size_t new_ael = alloc_nel(n); + if(new_ael != ael) { + /* adjust alloced space. */ + darray tmp=(darray)realloc(a, headsz+elemsz*new_ael); + if (!tmp && a) { + if(cleanuproutine) { + size_t i,k=a->nel; + for(i=0;inel=n; + return a; +} + +#ifdef ALLOC_DEBUG +void DBGda_free(darray a, size_t headsz, size_t elemsz, char *file, int line) +{ + if (a==NULL) + {DEBUG_MSG("- da_free, %s:%d, not initialized\n", file, line);} + else + {DEBUG_MSG("- da_free, %s:%d, %lu bytes\n", file, line, + (unsigned long)(headsz+elemsz*alloc_nel(a->nel)));} + free(a); +} +#endif + + +#define DLISTALIGN(len) (((len) + (sizeof(size_t)-1)) & ~(sizeof(size_t)-1)) +/* This mask corresponds to a chunk size of 1024. */ +#define DLISTCHUNKSIZEMASK ((size_t)0x3ff) + +/* Add space for a new item of size len to the list a. + dlist_grow() returns a pointer to the new (possibly reallocated) list structure if + successful, otherwise it frees the old list and returns NULL. +*/ +dlist dlist_grow(dlist a, size_t len) +{ + size_t sz=0, allocsz=0, szincr, newsz; + if(a) { + sz=a->last+a->lastsz; + allocsz = (sz+DLISTCHUNKSIZEMASK)&(~DLISTCHUNKSIZEMASK); + *((size_t *)&a->data[a->last])=a->lastsz; + } + szincr=DLISTALIGN(len+sizeof(size_t)); + newsz=sz+szincr; + if(newsz>allocsz) { + dlist tmp; + allocsz = (newsz+DLISTCHUNKSIZEMASK)&(~DLISTCHUNKSIZEMASK); + tmp=realloc(a, sizeof(struct _dynamic_list_head)+allocsz); + if (!tmp) + free(a); + a=tmp; + } + if(a) { + a->last=sz; + a->lastsz=szincr; + *((size_t *)&a->data[sz])=0; + } + return a; +} + + +/* Add a new node, capable of holding data of size len, at the end of a linked list. + llist_grow() returns 1 if successful, otherwise it frees the entire linked list + and returns 0. + */ +int llist_grow(llist *a, size_t len) +{ + struct llistnode_s *new= (struct llistnode_s *)malloc(sizeof(struct llistnode_s)+len); + + if(!new) { + llist_free(a); + return 0; + } + + new->next=NULL; + + if(!a->first) + a->first=new; + else + a->last->next=new; + + a->last=new; + + return 1; +} + +void llist_free(llist *a) +{ + struct llistnode_s *p= a->first; + + while(p) { + struct llistnode_s *next= p->next; + free(p); + p=next; + } + + a->first=NULL; + a->last= NULL; +} diff --git a/jni/pdnsd/src/list.h b/jni/pdnsd/src/list.h new file mode 100644 index 00000000..c63534e7 --- /dev/null +++ b/jni/pdnsd/src/list.h @@ -0,0 +1,170 @@ +/* list.h - Dynamic array and list handling + + Copyright (C) 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2007, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef LIST_H +#define LIST_H + +#include +#include +#include "pdnsd_assert.h" + + +typedef struct {size_t nel;} *darray; + +/* used in type declarations */ +#define DYNAMIC_ARRAY(typ) struct {size_t nel; typ elem[0];} +#define DA_TYP_OFFSET(atyp) ((size_t)((atyp)0)->elem) +#define DA_OFFSET(a) DA_TYP_OFFSET(typeof (a)) + +#define DA_CREATE(atyp,n) ((atyp)da_resize(NULL,DA_TYP_OFFSET(atyp),sizeof(((atyp)0)->elem[0]),n,NULL)) +#define DA_INDEX(a,i) ((a)->elem[i]) +/* Used often, so make special-case macro here */ +#define DA_LAST(a) ((a)->elem[(a)->nel-1]) + +#define DA_GROW1(a) ((typeof (a))da_grow1((darray)(a),DA_OFFSET(a),sizeof((a)->elem[0]),NULL)) +#define DA_GROW1_F(a,cleanup) ((typeof (a))da_grow1((darray)(a),DA_OFFSET(a),sizeof((a)->elem[0]),cleanup)) +#define DA_RESIZE(a,n) ((typeof (a))da_resize((darray)(a),DA_OFFSET(a),sizeof((a)->elem[0]),n,NULL)) +#define DA_NEL(a) da_nel((darray)(a)) + +/* + * Some or all of these should be inline. + * They aren't macros for type safety. + */ + +darray da_grow1(darray a, size_t headsz, size_t elemsz, void (*cleanuproutine) (void *)); +darray da_resize(darray a, size_t headsz, size_t elemsz, size_t n, void (*cleanuproutine) (void *)); + +inline static unsigned int da_nel(darray a) + __attribute__((always_inline)); +inline static unsigned int da_nel(darray a) +{ + if (a==NULL) + return 0; + return a->nel; +} + +/* alloc/free debug code.*/ +#ifdef ALLOC_DEBUG +void DBGda_free(darray a, size_t headsz, size_t elemsz, char *file, int line); +#define da_free(a) DBGda_free((darray)(a),DA_OFFSET(a),sizeof((a)->elem[0]), __FILE__, __LINE__) +#else +#define da_free free +#endif + + +/* This dynamic "list" structure is useful if the items are not all the same size. + The elements can only be read back in sequential order, not indexed as with the dynamic arrays. +*/ +struct _dynamic_list_head { + size_t last,lastsz; + char data[0]; +}; + +typedef struct _dynamic_list_head *dlist; + +inline static void *dlist_first(dlist a) + __attribute__((always_inline)); +inline static void *dlist_first(dlist a) +{ + return a?&a->data[sizeof(size_t)]:NULL; +} + +/* dlist_next() returns a reference to the next item in the list, or NULL is there is no next item. + ref should be properly aligned. + If the dlist was grown with dlist_grow(), this should be OK. +*/ +inline static void *dlist_next(void *ref) + __attribute__((always_inline)); +inline static void *dlist_next(void *ref) +{ + size_t incr= *(((size_t *)ref)-1); + return incr?((char *)ref)+incr:NULL; +} + +/* dlist_last() returns a reference to the last item. */ +inline static void *dlist_last(dlist a) + __attribute__((always_inline)); +inline static void *dlist_last(dlist a) +{ + return a?&a->data[a->last+sizeof(size_t)]:NULL; +} + +dlist dlist_grow(dlist a, size_t len); + +#define dlist_free free + + +/* linked list data type. */ +struct llistnode_s { + struct llistnode_s *next; + char *data[0]; +}; + +typedef struct { + struct llistnode_s *first, *last; +} + llist; + +inline static void llist_init(llist *a) + __attribute__((always_inline)); +inline static void llist_init(llist *a) +{ + a->first=NULL; + a->last= NULL; +} + +inline static int llist_isempty(llist *a) + __attribute__((always_inline)); +inline static int llist_isempty(llist *a) +{ + return a->first==NULL; +} + +inline static void *llist_first(llist *a) + __attribute__((always_inline)); +inline static void *llist_first(llist *a) +{ + struct llistnode_s *p= a->first; + return p?p->data:NULL; +} + +inline static void *llist_next(void *ref) + __attribute__((always_inline)); +inline static void *llist_next(void *ref) +{ + struct llistnode_s *next= *(((struct llistnode_s **)ref)-1); + return next?next->data:NULL; +} + +inline static void *llist_last(llist *a) + __attribute__((always_inline)); +inline static void *llist_last(llist *a) +{ + struct llistnode_s *p= a->last; + return p?p->data:NULL; +} + +int llist_grow(llist *a, size_t len); +void llist_free(llist *a); + +#endif /* def LIST_H */ diff --git a/jni/pdnsd/src/main.c b/jni/pdnsd/src/main.c new file mode 100644 index 00000000..1190b77c --- /dev/null +++ b/jni/pdnsd/src/main.c @@ -0,0 +1,710 @@ +/* main.c - Command line parsing, intialisation and server start + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +/* in order to use O_NOFOLLOW on Linux: */ +/* #define _GNU_SOURCE */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "consts.h" +#include "cache.h" +#include "status.h" +#include "servers.h" +#include "dns_answer.h" +#include "dns_query.h" +#include "error.h" +#include "helpers.h" +#include "icmp.h" +#include "hash.h" + + +#if DEBUG>0 +short int debug_p=0; +#endif +short int stat_pipe=0; + +/* int sigr=0; */ +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +short int run_ipv4=DEFAULT_IPV4; +short int cmdlineipv=0; +#endif +cmdlineflags_t cmdline={0}; +pthread_t main_thrid,servstat_thrid,statsock_thrid,tcps_thrid,udps_thrid; +uid_t init_uid; +#if DEBUG>0 +FILE *dbg_file=NULL; +#endif +volatile int tcp_socket=-1; +volatile int udp_socket=-1; +sigset_t sigs_msk; +char *conf_file=CONFDIR"/pdnsd.conf"; + + +/* version and licensing information */ +static const char info_message[] = + + "pdnsd - dns proxy daemon, version " VERSION "\n\n" + "Copyright (C) 2000, 2001 Thomas Moestl\n" + "Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 Paul A. Rombouts\n\n" + "pdnsd is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 3 of the License, or\n" + "(at your option) any later version.\n\n" + "pdnsd is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n" + "You should have received a copy of the GNU General Public License\n" + "along with pdsnd; see the file COPYING. If not, see\n" + ".\n"; + + +/* the help page */ +static const char help_message[] = + + "\n\nUsage: pdnsd [-h] [-V] [-s] [-d] [-g] [-t] [-p file] [-vn] [-mxx] [-c file]" +#ifdef ENABLE_IPV4 + " [-4]" +#endif +#ifdef ENABLE_IPV6 + " [-6] [-i prefix]" +#endif +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + " [-a]" +#endif + "\n\n" + "Options:\n" + "-h\t\t--or--\n" + "--help\t\tprint this help page and exit.\n" + "-V\t\t--or--\n" + "--version\tprint version and license information and exit.\n" + "--pdnsd-user\tprint the user pdnsd will run as and exit.\n" + "-s\t\t--or--\n" + "--status\tEnable status control socket in the cache directory.\n" + "-d\t\t--or--\n" + "--daemon\tStart pdnsd in daemon mode (as background process.)\n" + "-g\t\t--or--\n" + "--debug\t\tPrint some debug messages on the console or to the\n" + "\t\tfile pdnsd.debug in your cache directory (in daemon mode).\n" + "-t\t\t--or--\n" + "--tcp\t\tEnables the TCP server thread. pdnsd will then serve\n" + "\t\tTCP and UDP queries.\n" + "-p\t\tWrites the pid the server runs as to a specified filename.\n" + "\t\tWorks only in daemon mode.\n" + "-vn\t\tsets the verbosity of pdnsd. n is a numeric argument from 0\n" + "\t\t(normal operation) to 9 (many messages for debugging).\n" + "\t\tUse like -v2\n" + "-mxx\t\tsets the query method pdnsd uses. Possible values for xx are:\n" + "\t\tuo (UDP only), to (TCP only), tu (TCP or, if the server\n" + "\t\tdoes not support this, UDP) and ut (UDP and, if the reply was\n" + "\t\ttruncated, TCP). Use like -muo. Preset: " +#if M_PRESET==UDP_ONLY + "-muo" +#elif M_PRESET==TCP_ONLY + "-mto" +#elif M_PRESET==TCP_UDP + "-mtu" +#else + "-mut" +#endif + "\n" + "-c\t\t--or--\n" + "--config-file\tspecifies the file the configuration is read from.\n" + "\t\tDefault is " CONFDIR "/pdnsd.conf\n" +#ifdef ENABLE_IPV4 + "-4\t\tswitches to IPv4 mode.\n" + "\t\t" +# if DEFAULT_IPV4 + "On" +# else + "Off" +# endif + " by default.\n" +#endif +#ifdef ENABLE_IPV6 + "-6\t\tswitches to IPv6 mode.\n" + "\t\t" +# if DEFAULT_IPV4 + "Off" +# else + "On" +# endif + " by default.\n" + "-i\t\t--or--\n" + "--ipv4_6_prefix\tspecifies the prefix pdnsd uses to map IPv4 to IPv6\n" + "\t\taddresses. Must be a valid IPv6 address.\n" + "\t\tDefault is " DEFAULT_IPV4_6_PREFIX "\n" +#endif +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) + "-a\t\tWith this option, pdnsd will try to detect automatically if\n" + "\t\tthe system supports IPv6, and revert to IPv4 otherwise.\n" +#endif + "\n\n\"no\" can be prepended to the --status, --daemon, --debug and --tcp\n" + "options (e.g. --notcp) to reverse their effect.\n"; + + +/* These are some init steps we have to call before we get daemon on linux, but need + * to call after daemonizing on other OSes. + * Theay are also the last steps before we drop privileges. */ +int final_init() +{ +#ifndef NO_TCP_SERVER + if (!global.notcp) + tcp_socket=init_tcp_socket(); +#endif + udp_socket=init_udp_socket(); + if (tcp_socket==-1 && udp_socket==-1) { + log_error("tcp and udp initialization failed. Exiting."); + return 0; + } + if (global.strict_suid) { + if (!run_as(global.run_as)) { + return 0; + } + } + return 1; +} + +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +/* Check if IPv6 is available. + * With thanks to Juliusz Chroboczek. + */ +static int check_ipv6() +{ + int fd; + fd = socket(PF_INET6, SOCK_STREAM, 0); + if(fd < 0) { + if(errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || errno == EINVAL) + return 0; + return -1; + } + close(fd); + return 1; +} +#endif + + +/* + * Argument parsing, init, server startup + */ +int main(int argc,char *argv[]) +{ + int i,sig,pfd=-1; /* Initialized to inhibit compiler warning */ + + main_thrid=pthread_self(); + servstat_thrid=main_thrid; + statsock_thrid=main_thrid; + tcps_thrid=main_thrid; + udps_thrid=main_thrid; + init_uid=getuid(); +#ifdef ENABLE_IPV6 + { + int err; + if((err=inet_pton(AF_INET6,DEFAULT_IPV4_6_PREFIX,&global.ipv4_6_prefix))<=0) { + fprintf(stderr,"Error: inet_pton() wont accept default prefix %s in %s, line %d\n", + DEFAULT_IPV4_6_PREFIX,__FILE__,__LINE__); + if(err) + perror("inet_pton"); + exit(1); + } + } +#endif + + /* Parse the command line. + Remember which options were specified here, because the command-line options + shall override the ones given in the config file */ + for (i=1;ipw_name); + else + printf("%i\n",uid); + } + exit(0); + } + + if(!global.cache_dir) global.cache_dir = CACHEDIR; + if(!global.scheme_file) global.scheme_file = "/var/lib/pcmcia/scheme"; + stat_pipe=global.stat_pipe; + + if (!(global.run_as[0] && global.strict_suid)) { + for (i=0; iuptest==C_EXEC && sp->uptest_usr[0]=='\0') { + uid_t uid=getuid(); + struct passwd *pws=getpwuid(uid); + + /* No explicit uptest user given. If we run_as and strict_suid, we assume that + * this is safe. If not - warn. */ + fprintf(stderr,"Warning: uptest command \"%s\" will implicitly be executed as user ", sp->uptest_cmd); + if (pws) + fprintf(stderr,"%s\n",pws->pw_name); + else + fprintf(stderr,"%i\n",uid); + + } + } + } + + if (global.daemon && global.pidfile) { + if (unlink(global.pidfile)!=0 && errno!=ENOENT) { + log_error("Error: could not unlink pid file %s: %s",global.pidfile, strerror(errno)); + exit(1); + } + if ((pfd=open(global.pidfile,O_WRONLY|O_CREAT|O_EXCL +#ifdef O_NOFOLLOW + |O_NOFOLLOW +#else + /* + * No O_NOFOLLOW. Nevertheless, this not a hole, since the + * directory for pidfiles should not be world writeable. + * OS's that do not support O_NOFOLLOW are currently not + * supported, this is just-in-case code. + */ +#endif + , 0600))==-1) + { + log_error("Error: could not open pid file %s: %s",global.pidfile, strerror(errno)); + exit(1); + } + } + for (i=0;i0 + if (global.debug) { + char dbgpath[strlen(global.cache_dir)+sizeof("/pdnsd.debug")]; + stpcpy(stpcpy(dbgpath,global.cache_dir),"/pdnsd.debug"); + if (!(dbg_file=fopen(dbgpath,"w"))) + log_warn("Warning: could not open debug file %s: %s",dbgpath, strerror(errno)); + } +#endif + } else { +#if DEBUG>0 + dbg_file=stdout; +#endif + } + +#if DEBUG>0 + debug_p= (global.debug && dbg_file); +#endif + log_info(0,"pdnsd-%s starting.\n",VERSION); + DEBUG_MSG("Debug messages activated\n"); + +#if (TARGET!=TARGET_LINUX) + if (!final_init()) + _exit(1); +#endif + DEBUG_MSG(SEL_IPVER("Using IPv4.\n", "Using IPv6.\n")); + + /* initialize attribute for creating detached threads */ + pthread_attr_init(&attr_detached); + pthread_attr_setdetachstate(&attr_detached,PTHREAD_CREATE_DETACHED); + + read_disk_cache(); + + /* This must be done before any other thread is started to avoid races. */ + if (stat_pipe) + init_stat_sock(); + + + /* Before this point, logging and cache accesses are not locked because we are single-threaded. */ + init_log_lock(); + init_cache_lock(); + + sigemptyset(&sigs_msk); + sigaddset(&sigs_msk,SIGHUP); + sigaddset(&sigs_msk,SIGINT); +#ifndef THREADLIB_NPTL + sigaddset(&sigs_msk,SIGILL); +#endif + sigaddset(&sigs_msk,SIGABRT); + sigaddset(&sigs_msk,SIGFPE); +#ifndef THREADLIB_NPTL + sigaddset(&sigs_msk,SIGSEGV); +#endif + sigaddset(&sigs_msk,SIGTERM); + /* if (!daemon_p) { + sigaddset(&sigs_msk,SIGQUIT); + } */ +#if (TARGET==TARGET_LINUX) + pthread_sigmask(SIG_BLOCK,&sigs_msk,NULL); +#endif + +#if DEBUG>0 + { + int err; + /* Generate a key for storing our thread id's */ + if ((err=pthread_key_create(&thrid_key, NULL)) != 0) { + log_error("pthread_key_create failed: %s",strerror(err)); + _exit(1); + } + } +#endif + + { +#if DEBUG>0 + int thrdsucc=1; +# define thrdfail (thrdsucc=0) +#else +# define thrdfail +#endif + + if(start_servstat_thread()) thrdfail; + +#if (TARGET==TARGET_LINUX) + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + _exit(1); + } + } +#endif + + if (stat_pipe) + if(start_stat_sock()) thrdfail; + + start_dns_servers(); + +#if DEBUG>0 + if(thrdsucc) { + DEBUG_MSG("All threads started successfully.\n"); + } +#endif +#undef thrdfail + } + +#if (TARGET==TARGET_LINUX) && !defined(THREADLIB_NPTL) + pthread_sigmask(SIG_BLOCK,&sigs_msk,NULL); + waiting=1; +#endif + { + int err; + while ((err=sigwait(&sigs_msk,&sig))) { + if (err!=EINTR) { + log_error("sigwait failed: %s",strerror(err)); + sig=0; + break; + } + } + } + if(sig) DEBUG_MSG("Signal %i caught.\n",sig); + write_disk_cache(); + destroy_cache(); + if(sig) log_warn("Caught signal %i. Exiting.",sig); + if (sig==SIGSEGV || sig==SIGILL || sig==SIGBUS) + crash_msg("This is a fatal signal probably triggered by a bug."); + if (ping_isocket!=-1) + close(ping_isocket); +#ifdef ENABLE_IPV6 + if (ping6_isocket!=-1) + close(ping6_isocket); +#endif + /* Close and delete the status socket */ + if(stat_pipe) close(stat_sock); + if (sock_path && unlink(sock_path)) + log_warn("Failed to unlink %s: %s",sock_path, strerror(errno)); + + free_rng(); +#if DEBUG>0 + if (debug_p && global.daemon) + if(fclose(dbg_file)<0) { + log_warn("Could not close debug file: %s", strerror(errno)); + } +#endif + _exit(0); +} diff --git a/jni/pdnsd/src/make_rr_types_h.pl b/jni/pdnsd/src/make_rr_types_h.pl new file mode 100644 index 00000000..c8c0f9fb --- /dev/null +++ b/jni/pdnsd/src/make_rr_types_h.pl @@ -0,0 +1,309 @@ +#!/usr/bin/perl -w + +# This Perl script is used to generate rr_types.h, using rr_types.in as input. +# +# Copyright (C) 2010, 2011 Paul A. Rombouts +# +# This file is part of the pdnsd package. +# + +use strict; +use integer; + +print << "END-OF-TEXT"; +/* This file was generated by running '$0 @ARGV'. + Modifications to this file may be lost the next time it is automatically + regenerated. +*/ + +END-OF-TEXT + +my %valdic; +my %namedic; +my %classdic; +my %muset; +my $nrr=0; +my $nmu=0; +my $minval; +my $maxval; +#my $maxmuval; + +while(<>) { + if(/\S/ && !/^\s*\#/) { + if(/^\s*(?:([*+-])\s*)?([\w-]+)\s+(\d+)\s+(?:\((\w+)\))?/) { + my $mu = $1; my $name=$2; my $val=$3+0; my $class=$4; + $name =~ s/-/_/g; + if(defined($valdic{$name})) {warn "The name \"$name\" does not have a unique value.\n"} + if(defined($namedic{$val})) {warn "The value \"$val\" does not have a unique name.\n"} + $valdic{$name}=$val; $namedic{$val}=$name; $classdic{$val}=$class if defined($class); + if(defined($mu)) { + if($mu eq '-') {next} + $muset{$val}= 1; + ++$nmu; + #if(!defined($maxmuval) || $val>$maxmuval) {$maxmuval=$val} + } + else {$muset{$val}= 0} + ++$nrr; + if(!defined($minval) || $val<$minval) {$minval=$val} + if(!defined($maxval) || $val>$maxval) {$maxval=$val} + } + else {die "Can't find name-value pair in following line:\n$_\n"} + } +} + +defined($minval) or die "No values defined.\n"; +if($nrr>255) {warn "Warning: total number of cache-able RR types is greater than 255.\n"} + +print << 'END-OF-TEXT'; +/* rr_types.h - A header file with names & descriptions of + all rr types known to pdnsd + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2007, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#ifndef _RR_TYPES_H_ +#define _RR_TYPES_H_ + +#include + +END-OF-TEXT + +print "#define T_MIN $minval\n"; +foreach my $name (sort {$valdic{$a} <=> $valdic{$b} } (keys %valdic)) { + printf("#define %-12s %2d\n", "T_$name", $valdic{$name}); +} +print "#define T_MAX $maxval\n"; +print("\n/* T_MAX - T_MIN + 1 */\n","#define T_NUM ",$maxval+1-$minval,"\n"); +#print("\n/* Largest most frequently used type value. */\n","#define T_MAXMU $maxmuval\n"); +print("\n/* Number of most frequently used rr types. */\n","#define NRRMU $nmu\n"); +print("\n/* Number of remaining rr types. */\n","#define NRREXT ",$nrr-$nmu,"\n"); +print("\n/* NRRMU + NRREXT */\n","#define NRRTOT $nrr\n"); + +print << 'END-OF-TEXT'; + +/* Lookup table for converting rr type values to internally used indices. */ +extern const unsigned short int rrlkuptab[T_NUM]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const unsigned short int rrlkuptab[T_NUM] = { +END-OF-TEXT +my @rrtpval=(); +for(my $val=$minval, my $i=0, my $j=$nmu, my $k=$nrr; $val<=$maxval; ++$val) { + my $idx; + if(defined($muset{$val})) { + if($muset{$val}) { + $idx = $i++; + } + else { + $idx = $j++; + } + $rrtpval[$idx]=$val; + } + else { + $idx = $k++; + } + + printf('%4d', $idx); + if(defined($namedic{$val})) { + print " /* $namedic{$val} */"; + } + print ',' if $val<$maxval; + print "\n"; +} +#print << 'END-OF-TEXT'; +#}; +##endif +# +#/* Table for converting internally used indices to rr type values. +# This is more or less the inverse of the rrlkuptab[] mapping. */ +#extern const unsigned short int rrtpval[NRRTOT]; +##if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +#const unsigned short int rrtpval[NRRTOT] = { +#END-OF-TEXT +#for(my $i=0; $i<$nrr; ++$i) { +# if($i ==0) { +# print " /* Most frequently used types. */\n"; +# } +# else { +# print ",\n"; +# } +# print " /* Remaining (less frequently used) types. */\n" +# if $i == $nmu; +# my $val= $rrtpval[$i]; +# print(" ",defined($namedic{$val})? "T_$namedic{$val}": $val); +#} +print << 'END-OF-TEXT'; +}; +#endif + +/* List of most frequently used RR types in ascending order. */ +extern const unsigned short int rrmuiterlist[NRRMU]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const unsigned short int rrmuiterlist[NRRMU] = { +END-OF-TEXT +for(my $val=$minval, my $i=0; $val<=$maxval; ++$val) { + if(defined($muset{$val}) && $muset{$val}) { + print ",\n" if $i++; + print(" ",defined($namedic{$val})? "T_$namedic{$val}": $val); + } +} +print << 'END-OF-TEXT'; + +}; +#endif + +/* List of the cache-able RR types in ascending order. */ +extern const unsigned short int rrcachiterlist[NRRTOT]; +#if DEFINE_RR_TYPE_ARRAYS +const unsigned short int rrcachiterlist[NRRTOT] = { +END-OF-TEXT +for(my $val=$minval, my $i=0; $val<=$maxval; ++$val) { + if(defined($muset{$val})) { + print ",\n" if $i++; + print(" ",defined($namedic{$val})? "T_$namedic{$val}": $val); + } +} +print << 'END-OF-TEXT'; + +}; +#endif + +/* Optimized getrrset macros for fixed rr types. */ +END-OF-TEXT +for(my $val=$minval, my $i=0, my $j=0; $val<=$maxval; ++$val) { + if(defined($muset{$val})) { + my $name = $namedic{$val}; + my $mdef; + if($muset{$val}) { + $mdef= "GET_RRSMU(cent,$i)"; + ++$i; + } + else { + $mdef= "GET_RRSEXT(cent,$j)"; + ++$j; + } + printf("#define %-25s %s\n", "getrrset_$name(cent)", $mdef) + if defined($name); + } +} +print << 'END-OF-TEXT'; + +/* have_rr macros for fixed rr types. */ +END-OF-TEXT +for(my $val=$minval, my $i=0, my $j=0; $val<=$maxval; ++$val) { + my $name = $namedic{$val}; + my $mdef = '0'; + if(defined($muset{$val})) { + if($muset{$val}) { + $mdef= "HAVE_RRMU(cent,$i)"; + ++$i; + } + else { + $mdef= "HAVE_RREXT(cent,$j)"; + ++$j; + } + } + printf("#define %-25s %s\n", "have_rr_$name(cent)", $mdef) + if defined($name); +} +print << 'END-OF-TEXT'; + +/* These macros specify which RR types are cached by pdnsd. */ +END-OF-TEXT +for(my $val=$minval; $val<=$maxval; ++$val) { + if(defined($muset{$val})) { + my $name = $namedic{$val}; + printf("#define IS_CACHED_%-10s 1\n", defined($name)? $name: "TYPE$val") + } +} +print << 'END-OF-TEXT'; + +/* Array indices for most frequently used rr types. */ +END-OF-TEXT +for(my $val=$minval, my $i=0; $val<=$maxval; ++$val) { + if(defined($muset{$val}) && $muset{$val}) { + printf("#define %-18s %2d\n", "RRMUINDEX_$namedic{$val}", $i) + if defined($namedic{$val}); + ++$i; + } +} +print << 'END-OF-TEXT'; + +/* Table of rr names. */ +extern const char *const rrnames[T_NUM]; +#if DEFINE_RR_TYPE_ARRAYS +const char *const rrnames[T_NUM] = { +END-OF-TEXT +for(my $val=$minval; $val<=$maxval; ++$val) { + my $name = $namedic{$val}; + print(' "', defined($name)? $name: "TYPE$val", '"'); + print ',' if $val<$maxval; + print "\n"; +} +print << 'END-OF-TEXT'; +}; +#endif + +/* Structure for rr information */ +struct rr_infos { + unsigned short class; /* class (values see below) */ + unsigned short excludes; /* relations to other classes. + Mutual exclusion is marked by or'ing the + respective RRCL value in this field. + Exclusions should be symmetric. */ +}; + +/* Class values */ +#define RRCL_ALIAS 1 /* for CNAMES, conflicts with RRCL_RECORD */ +#define RRCL_RECORD 2 /* normal direct record */ +#define RRCL_IDEM 4 /* types that conflict with no others (MX, CNAME, ...) */ +#define RRCL_PTR 8 /* PTR */ + +/* Standard excludes for the classes */ +#define RRX_ALIAS (RRCL_RECORD|RRCL_PTR) +#define RRX_RECORD (RRCL_ALIAS|RRCL_PTR) +#define RRX_IDEM 0 +#define RRX_PTR (RRCL_ALIAS|RRCL_RECORD) + +/* There could be a separate table detailing the relationship of types, but this + * is slightly more flexible, as it allows a finer granularity of exclusion. Also, + * Membership in multiple classes could be added. + * Index by internally used RR-set indices, not RR type values! + */ +extern const struct rr_infos rr_info[NRRTOT]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const struct rr_infos rr_info[NRRTOT] = { +END-OF-TEXT +for(my $i=0; $i<$nrr; ++$i) { + print ",\n" if $i; + my $val=$rrtpval[$i]; + my $class = (defined($classdic{$val})? $classdic{$val}: 'IDEM'); + printf(' %-16s %-15s %s',"{RRCL_$class,", "RRX_$class}", defined($namedic{$val})?"/* $namedic{$val} */":""); +} +print << 'END-OF-TEXT'; + +}; +#endif + +int rr_tp_byname(char *name); +const char *loc2str(const void *binary, char *ascii, size_t asclen); + +#endif +END-OF-TEXT + +exit diff --git a/jni/pdnsd/src/netdev.c b/jni/pdnsd/src/netdev.c new file mode 100644 index 00000000..bd5f8c45 --- /dev/null +++ b/jni/pdnsd/src/netdev.c @@ -0,0 +1,363 @@ +/* netdev.c - Test network devices for existence and status + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +/* + * Portions are under the following copyright and taken from FreeBSD + * (clause 3 deleted as it no longer applies): + * + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)if.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/net/if.h,v 1.58.2.1 2000/05/05 13:37:04 jlemon Exp $ + */ + +#include +#include "ipvers.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "helpers.h" +#include "netdev.h" +#include "error.h" + + +#if (TARGET==TARGET_BSD) +/* Taken from FreeBSD net/if.h rev. 1.58.2.1 */ +#define SIZEOF_ADDR_IFREQ(ifr) \ + ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ + (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ + (ifr).ifr_addr.sa_len) : sizeof(struct ifreq)) +#elif (TARGET==TARGET_CYGWIN) +#define SIZEOF_ADDR_IFREQ(ifr) (sizeof(struct sockaddr)) +#endif + +#define MAX_SOCKETOPEN_ERRS 10 +static volatile unsigned long socketopen_errs=0; + +/* + * Portions of the following code are Linux/FreeBSD specific. + * Please write interface-detection routines for other flavours of Unix if you can and want. + */ + +#if (TARGET==TARGET_LINUX) || (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN) +# if (TARGET==TARGET_LINUX) + +static volatile unsigned long isdn_errs=0; + +# ifdef ISDN_SUPPORT + +/* + * Test the status of an ippp interface. Taken from the isdn4k-utils (thanks!) and adapted + * by me (I love free software!) + * This will not work with older kernels. + * If your kernel is too old or too new, just try to get the status as uptest=exec command + * This will work, although slower. + */ + +# include + +int statusif(char *name) +{ + isdn_net_ioctl_phone phone; + int isdninfo,rc=0; + + if ((isdninfo = open("/dev/isdninfo", O_RDONLY))<0) { + if (++isdn_errs<=2) { + log_warn("Could not open /dev/isdninfo for uptest: %s",strerror(errno)); + } + return 0; + } + + strncp(phone.name, name, sizeof(phone.name)); + if (ioctl(isdninfo, IIOCNETGPN, &phone)==0) + rc=1; + close(isdninfo); + return rc; +} +# endif + +/* + * Test whether the network interface specified in ifname and its + * associated device specified in devname have locks owned by the + * same process. + */ +int dev_up(char *ifname, char *devname) +{ + FILE *fd; + int pidi, pidd, rv; + + { + char path[sizeof("/var/run/.pid")+strlen(ifname)]; + stpcpy(stpcpy(stpcpy(path,"/var/run/"),ifname),".pid"); + if ((fd=fopen(path, "r")) == NULL ) + return 0; + + if (fscanf(fd, "%d", &pidi) != 1 ) { + fclose(fd) ; + return 0; + } + fclose(fd); + } + + { + char path[sizeof("/var/lock/LCK..")+strlen(devname)]; + stpcpy(stpcpy(path,"/var/lock/LCK.."),devname); + if ((fd=fopen(path, "r")) == NULL) + return 0; + + if (fscanf(fd, "%d", &pidd) != 1) { + fclose(fd); + return 0; + } + fclose(fd); + } + + if (pidi != pidd) + return 0; + /* Test whether pppd is still alive */ + rv=kill(pidi,0); + return (rv==0 || (rv==-1 && errno!=ESRCH)); +} + + +# endif /*(TARGET==TARGET_LINUX)*/ + +/* + * Test whether the network device specified in devname is up and + * running (returns -1) or non-existent, down or not-running (returns 0) + * + * Note on IPv6-Comptability: rfc2133 requires all IPv6 implementation + * to be backwards-compatible to IPv4 in means of permitting socket(PF_INET,...) + * and similar. So, I don't put code here for both IPv4 and IPv6, since + * I use that socket only for ioctls. If somebody notices incompatabilities, + * please notify me. + */ +int if_up(char *devname) +{ + int sock; + struct ifreq ifr; +# if (TARGET==TARGET_LINUX) + unsigned int devnamelen=strlen(devname); + if (devnamelen>4 && devnamelen<=6 && strncmp(devname,"ippp",4)==0) { + /* This function didn't manage the interface uptest correctly. Thanks to + * Joachim Dorner for pointing out. + * The new code (statusif()) was shamelessly stolen from isdnctrl.c of the + * isdn4k-utils. */ +# ifdef ISDN_SUPPORT + return statusif(devname); +# else + if (isdn_errs++==0) { + log_warn("An ippp? device was specified for uptest, but pdnsd was compiled without ISDN support."); + log_warn("The uptest result will be wrong."); + } +# endif + /* If it doesn't match our rules for isdn devices, treat as normal if */ + } +# endif + if ((sock=socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP))==-1) { + if(++socketopen_errs<=MAX_SOCKETOPEN_ERRS) { + log_warn("Could not open socket in if_up(): %s",strerror(errno)); + } + return 0; + } + strncp(ifr.ifr_name,devname,IFNAMSIZ); + if (ioctl(sock,SIOCGIFFLAGS,&ifr)==-1) { + close(sock); + return 0; + } + close(sock); + return (ifr.ifr_flags&IFF_UP) && (ifr.ifr_flags&IFF_RUNNING); +} + +# if (TARGET==TARGET_LINUX) +# ifdef ENABLE_IPV6 +#define MAX_IF_INET6_OPEN_ERRS 10 +static volatile unsigned long if_inet6_open_errs=0; +# endif + +int is_local_addr(pdnsd_a *a) +{ + int res=0; + +# ifdef ENABLE_IPV4 + if (run_ipv4) { + int i,sock; + struct ifreq ifr; + if ((sock=socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP))==-1) { + if(++socketopen_errs<=MAX_SOCKETOPEN_ERRS) { + log_warn("Could not open socket in is_local_addr(): %s",strerror(errno)); + } + return 0; + } + for (i=1;i<255;i++) { + ifr.ifr_ifindex=i; + if (ioctl(sock,SIOCGIFNAME,&ifr)==-1) { + /* There may be gaps in the interface enumeration, so just continue */ + continue; + } + if (ioctl(sock,SIOCGIFADDR, &ifr)==-1) { + continue; + } + if (((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr.s_addr==a->ipv4.s_addr) { + res=1; + break; + } + } + close(sock); + } + +# endif +# ifdef ENABLE_IPV6 + ELSE_IPV6 { + char buf[40]; + FILE *f; + struct in6_addr b; + /* the interface configuration and information retrieval is obiously currently done via + * rt-netlink sockets. I think it is relatively likely to change in an incompatible way the + * Linux kernel (there seem to be some major changes for 2.4). + * Right now, I just analyze the /proc/net/if_inet6 entry. This may not be the fastest, but + * should work and is easy to adapt should the format change. */ + if (!(f=fopen("/proc/net/if_inet6","r"))) { + if(++if_inet6_open_errs<=MAX_IF_INET6_OPEN_ERRS) { + log_warn("Could not open /proc/net/if_inet6 in is_local_addr(): %s",strerror(errno)); + } + return 0; + } + /* The address is at the start of the line. We just read 32 characters and insert a ':' 7 + * times. Such, we can use inet_pton conveniently. More portable, that. */ + for(;;) { + int i,ch; char *p=buf; + for (i=0;i<32;i++) { + if(i && i%4==0) *p++ = ':'; + if ((ch=fgetc(f))==EOF) + goto fclose_return; /* we are at the end of the file and haven't found anything.*/ + if(ch=='\n') goto nextline; + *p++ = ch; + } + *p=0; + if (inet_pton(AF_INET6,buf,&b) >0) { + if (IN6_ARE_ADDR_EQUAL(&b,&a->ipv6)) { + res=1; + goto fclose_return; + } + } + do { + if ((ch=fgetc(f))==EOF) goto fclose_return; + } while(ch!='\n'); + nextline:; + } + fclose_return: + fclose(f); + } +# endif + return res; +} + +# else /*(TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN)*/ + + +#define MAX_SIOCGIFCONF_ERRS 4 +static volatile unsigned long siocgifconf_errs=0; + +int is_local_addr(pdnsd_a *a) +{ + int retval=0, sock, cnt; + struct ifconf ifc; + char buf[2048]; + + + if ((sock=socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP))==-1) { + if(++socketopen_errs<=MAX_SOCKETOPEN_ERRS) { + log_warn("Could not open socket in is_local_addr(): %s",strerror(errno)); + } + return 0; + } + + ifc.ifc_len=sizeof(buf); + ifc.ifc_buf=buf; + if (ioctl(sock,SIOCGIFCONF,&ifc)==-1) { + if(++siocgifconf_errs<=MAX_SIOCGIFCONF_ERRS) { + log_warn("ioctl() call with request SIOCGIFCONF failed in is_local_addr(): %s",strerror(errno)); + } + goto close_sock_return; + } + + cnt=0; + while(cnt+sizeof(struct ifreq)<=ifc.ifc_len) { + struct ifreq *ir= (struct ifreq *)(buf+cnt); + cnt += SIZEOF_ADDR_IFREQ(*ir); + if (cnt>ifc.ifc_len) + break; + if (SEL_IPVER(ir->ifr_addr.sa_family==AF_INET && + ((struct sockaddr_in *)&ir->ifr_addr)->sin_addr.s_addr==a->ipv4.s_addr, + ir->ifr_addr.sa_family==AF_INET6 && + IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)&ir->ifr_addr)->sin6_addr, + &a->ipv6))) + { + retval=1; + break; + } + } + + close_sock_return: + close(sock); + + return retval; +} + +# endif + +#else +# error "Huh. No OS macro defined." +#endif diff --git a/jni/pdnsd/src/netdev.h b/jni/pdnsd/src/netdev.h new file mode 100644 index 00000000..529b8a88 --- /dev/null +++ b/jni/pdnsd/src/netdev.h @@ -0,0 +1,32 @@ +/* netdev.h - Test network devices for existence and status + Copyright (C) 2000 Thomas Moestl + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _NETDEV_H_ +#define _NETDEV_H_ + +#include +#include "ipvers.h" + +int if_up(char *devname); +int dev_up(char *ifname, char *devname); +int is_local_addr(pdnsd_a *a); + +#endif diff --git a/jni/pdnsd/src/pdnsd-ctl/Makefile.am b/jni/pdnsd/src/pdnsd-ctl/Makefile.am new file mode 100644 index 00000000..bcb73274 --- /dev/null +++ b/jni/pdnsd/src/pdnsd-ctl/Makefile.am @@ -0,0 +1,18 @@ + +sbin_PROGRAMS = pdnsd-ctl + +pdnsd_ctl_SOURCES = pdnsd-ctl.c +pdnsd_ctl_LDADD = rr_types.o +pdnsd_ctl_DEPENDENCIES = rr_types.o + +# These are Symlinks we want to have in the package +#EXTRA_DIST = rr_types.h + +pdnsd-ctl.o rr_types.o: ../rr_types.h + +../rr_types.h: ../make_rr_types_h.pl ../rr_types.in + perl ../make_rr_types_h.pl ../rr_types.in > ../rr_types.h + +rr_types.o: %.o: ../%.c + $(COMPILE) -DCLIENT_ONLY -c $< + diff --git a/jni/pdnsd/src/pdnsd-ctl/Makefile.in b/jni/pdnsd/src/pdnsd-ctl/Makefile.in new file mode 100644 index 00000000..80f39872 --- /dev/null +++ b/jni/pdnsd/src/pdnsd-ctl/Makefile.in @@ -0,0 +1,470 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +sbin_PROGRAMS = pdnsd-ctl$(EXEEXT) +subdir = src/pdnsd-ctl +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" +PROGRAMS = $(sbin_PROGRAMS) +am_pdnsd_ctl_OBJECTS = pdnsd-ctl.$(OBJEXT) +pdnsd_ctl_OBJECTS = $(am_pdnsd_ctl_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(pdnsd_ctl_SOURCES) +DIST_SOURCES = $(pdnsd_ctl_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pdnsd_ctl_SOURCES = pdnsd-ctl.c +pdnsd_ctl_LDADD = rr_types.o +pdnsd_ctl_DEPENDENCIES = rr_types.o +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/pdnsd-ctl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/pdnsd-ctl/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) +pdnsd-ctl$(EXEEXT): $(pdnsd_ctl_OBJECTS) $(pdnsd_ctl_DEPENDENCIES) + @rm -f pdnsd-ctl$(EXEEXT) + $(LINK) $(pdnsd_ctl_OBJECTS) $(pdnsd_ctl_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdnsd-ctl.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-sbinPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-sbinPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-sbinPROGRAMS + + +# These are Symlinks we want to have in the package +#EXTRA_DIST = rr_types.h + +pdnsd-ctl.o rr_types.o: ../rr_types.h + +../rr_types.h: ../make_rr_types_h.pl ../rr_types.in + perl ../make_rr_types_h.pl ../rr_types.in > ../rr_types.h + +rr_types.o: %.o: ../%.c + $(COMPILE) -DCLIENT_ONLY -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/pdnsd-ctl/pdnsd-ctl.c b/jni/pdnsd/src/pdnsd-ctl/pdnsd-ctl.c new file mode 100644 index 00000000..33a21cec --- /dev/null +++ b/jni/pdnsd/src/pdnsd-ctl/pdnsd-ctl.c @@ -0,0 +1,799 @@ +/* pdnsd-ctl.c - Control pdnsd through a pipe + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#ifdef HAVE_ALLOCA_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include /* for offsetof */ +#include "../helpers.h" +#include "../status.h" +#include "../conff.h" +#include "../list.h" +#include "../dns.h" +#include "../rr_types.h" +#include "../cache.h" + +#if !defined(HAVE_ALLOCA) && !defined(alloca) +#define alloca malloc +#endif + + +#if defined(HAVE_STRUCT_IN6_ADDR) && defined(HAVE_INET_PTON) +# define ALLOW_AAAA IS_CACHED_AAAA +#else +# define ALLOW_AAAA 0 +#endif + +static short int verbose=1; + +typedef struct { + char *name; + int val; +} cmd_s; + +#define CMD_LIST_RRTYPES (CTL_MAX+1) +#define CMD_HELP (CTL_MAX+2) +#define CMD_VERSION (CTL_MAX+3) + +static const cmd_s top_cmds[]={ + {"help",CMD_HELP},{"version",CMD_VERSION},{"list-rrtypes",CMD_LIST_RRTYPES}, + {"status",CTL_STATS},{"server",CTL_SERVER},{"record",CTL_RECORD}, + {"source",CTL_SOURCE},{"add",CTL_ADD},{"neg",CTL_NEG}, + {"config",CTL_CONFIG},{"include",CTL_INCLUDE},{"eval",CTL_EVAL}, + {"empty-cache",CTL_EMPTY}, {"dump",CTL_DUMP}, + {NULL,0} +}; +static const cmd_s server_cmds[]= {{"up",CTL_S_UP},{"down",CTL_S_DOWN},{"retest",CTL_S_RETEST},{NULL,0}}; +static const cmd_s record_cmds[]= {{"delete",CTL_R_DELETE},{"invalidate",CTL_R_INVAL},{NULL,0}}; +static const cmd_s onoff_cmds[]= {{"off",0},{"on",1},{NULL,0}}; +static const cmd_s rectype_cmds[]= {{"a",T_A}, +#if ALLOW_AAAA + {"aaaa",T_AAAA}, +#endif + {"ptr",T_PTR},{"cname",T_CNAME},{"mx",T_MX},{"ns",T_NS},{NULL,0}}; + +static const char version_message[] = + "pdnsd-ctl, version pdnsd-" VERSION "\n\n"; + +static const char license_statement[] = + "Copyright (C) 2000, 2001 Thomas Moestl\n" + "Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 Paul A. Rombouts\n\n" + "This program is part of the pdnsd package.\n\n" + "pdnsd is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 3 of the License, or\n" + "(at your option) any later version.\n\n" + "pdnsd is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n" + "You should have received a copy of the GNU General Public License\n" + "along with pdsnd; see the file COPYING. If not, see\n" + ".\n"; + +static const char *const help_messages[] = +{ + "Usage: pdnsd-ctl [-c cachedir] [-q] [arguments]\n\n" + + "Command-line options:\n" + + "-c\tcachedir\n\tSet the cache directory to cachedir (must match pdnsd setting).\n" + "\tThe default is '" CACHEDIR "'.\n" + "-q\n\tBe quiet unless output is specified by command or something goes wrong.\n\n" + + "Commands and needed arguments are:\n" + + "help\t[no arguments]\n\tPrint this help.\n" + "version\t[no arguments]\n\tPrint version and license info.\n", + + "status\t[no arguments]\n\tPrint pdnsd's status.\n", + + "server\t(index|label)\t(up|down|retest)\t[dns1[,dns2[,...]]]\n" + "\tSet the status of the server with the given index to up or down, or\n" + "\tforce a retest. The index is assigned in the order of definition in\n" + "\tpdnsd.conf starting with 0. Use the status command to see the indexes.\n" + "\tYou can specify the label of a server (that matches the label option)\n" + "\tinstead of an index to make this easier.\n" + + "\tYou can specify all instead of an index to perform the action for all\n" + "\tservers registered with pdnsd.\n" + + "\tAn optional third argument can be given consisting of a list of IP\n" + "\taddresses separated by commas or spaces. This list will replace the\n" + "\taddresses of name servers used by pdnsd for the given server section.\n" + "\tThis feature is useful for run-time configuration of pdnsd with dynamic\n" + "\tDNS data in scripts called by ppp or DHCP clients. The last argument\n" + "\tmay also be an empty string, which causes existing IP addresses to be\n" + "\tremoved and the corresponding server section to become inactive.\n", + + "record\tname\t(delete|invalidate)\n" + "\tDelete or invalidate the record of the given domain if it is in the\n" + "\tcache.\n", + + "source\tfn\towner\t[ttl]\t[(on|off)]\t[noauth]\n" + "\tLoad a hosts-style file. Works like using the pdnsd source\n" + "\tconfiguration section.\n" + "\tOwner and ttl are used as in the source section. ttl has a default\n" + "\tof 900 (it does not need to be specified). The next to last argument\n" + "\tcorresponds to the serve_aliases option, and is off by default.\n" + "\tnoauth is used to make the domains non-authoritative (please\n" + "\tconsult the pdnsd manual for what that means).\n" + "\tfn is the name of the file, which must be readable by pdnsd.\n", + + "add\ta\taddr\tname\t[ttl]\t[noauth]\n" +#if ALLOW_AAAA + "add\taaaa\taddr\tname\t[ttl]\t[noauth]\n" +#endif + "add\tptr\thost\tname\t[ttl]\t[noauth]\n" + "add\tcname\thost\tname\t[ttl]\t[noauth]\n" + "add\tmx\thost\tname\tpref\t[ttl]\t[noauth]\n" + "add\tns\thost\tname\t[ttl]\t[noauth]\n" + "\tAdd a record of the given type to the pdnsd cache, replacing existing\n" + "\trecords for the same name and type. The 2nd argument corresponds\n" + "\tto the value of the option in the rr section that is named like\n" + "\tthe first argument. The addr argument may be a list of IP addresses,\n" + "\tseparated by commas or white space. The ttl is optional, the default is\n" + "\t900 seconds. noauth is used to make the domains non-authoritative.\n" + "\tIf you want no other record than the newly added in the cache, do\n" + "\tpdnsdctl record delete\n" + "\tbefore adding records.\n", + + "neg\tname\t[type]\t[ttl]\n" + "\tAdd a negatively cached record to pdnsd's cache, replacing existing\n" + "\trecords for the same name and type. If no type is given, the whole\n" + "\tdomain is cached negatively. For negatively cached records, errors are\n" + "\timmediately returned on a query, without querying other servers first.\n" + "\tThe ttl is optional, the default is 900 seconds.\n", + + "config\t[filename]\n" + "\tReload pdnsd's configuration file.\n" + "\tThe config file must be owned by the uid that pdnsd had when it was\n" + "\tstarted, and be readable by pdnsd's run_as uid. If no file name is\n" + "\tspecified, the config file used at start up is reloaded.\n", + + "include\tfilename\n" + "\tParse the given file as an include file, which may contain the same\n" + "\ttype of sections as a config file, expect for global and server\n" + "\tsections, which are not allowed. This command can be used to add data\n" + "\tto the cache without reconfiguring pdnsd.\n", + + "eval\tstring\n" + "\tParse string as if it were part of pdnsd's configuration file.\n" + "\tThe string should hold one or more complete configuration sections,\n" + "\tbut no global and server sections, which are not allowed.\n" + "\tIf multiple strings are given, they will be joined using newline chars\n" + "\tand parsed together.\n", + + "empty-cache\t[[+|-]name ...]\n" + "\tDelete all entries in the cache matching include/exclude rules.\n" + "\tIf no arguments are provided, the cache is completely emptied,\n" + "\tfreeing all existing entries. This also removes \"local\" records,\n" + "\tas defined by the config file. To restore local records, run\n" + "\t\"pdnsd-ctl config\" or \"pdnsd-ctl include filename\" immediately\n" + "\tafterwards.\n" + "\tIf one or more arguments are provided, these are interpreted as \n" + "\tinclude/exclude names. If an argument starts with a '+' the name is to\n" + "\tbe included. If an argument starts with a '-' it is to be excluded.\n" + "\tIf an argument does not begin with '+' or '-', a '+' is assumed.\n" + "\tIf the domain name of a cache entry ends in one of the names in the\n" + "\tlist, the first match will determine what happens. If the matching name\n" + "\tis to be included, the cache entry is deleted, otherwise it remains.\n" + "\tIf there are no matches, the default action is not to delete.\n", + + "dump\t[name]\n" + "\tPrint information stored in the cache about name.\n" + "\tIf name begins with a dot and is not the root domain, information\n" + "\tabout the names in the cache ending in name (including name without\n" + "\tthe leading dot) will be printed. If name is missing, information about\n" + "\tall the names in the cache will be printed.\n", + + "list-rrtypes\t[no arguments]\n" + "\tList available rr types for the neg command. Note that those are only\n" + "\tused for the neg command, not for add!\n" +}; + +#define NUM_HELP_MESSAGES (sizeof(help_messages)/sizeof(char*)) + + +/* Open connection to control socket and send command code. + If successful, open_sock returns a file descriptor for the new socket, + otherwise the program is aborted. +*/ +static int open_sock(const char *cache_dir, uint16_t cmd) +{ + struct sockaddr_un *sa; + unsigned int sa_len; + int sock; + uint16_t nc; + + if ((sock=socket(PF_UNIX,SOCK_STREAM,0))==-1) { + perror("Error: could not open socket"); + exit(2); + } + + sa_len = (offsetof(struct sockaddr_un, sun_path) + strlitlen("/pdnsd.status") + strlen(cache_dir)); + sa=(struct sockaddr_un *)alloca(sa_len+1); + sa->sun_family=AF_UNIX; + stpcpy(stpcpy(sa->sun_path,cache_dir),"/pdnsd.status"); + + if (connect(sock,(struct sockaddr *)sa,sa_len)==-1) { + fprintf(stderr,"Error: could not open socket %s: %s\n",sa->sun_path,strerror(errno)); + close(sock); + exit(2); + } + if(verbose) printf("Opening socket %s\n",sa->sun_path); + + /* Send command code */ + + nc=htons(cmd|CTL_CMDVERNR); /* Add magic number, convert to network byte order. */ + + if (write(sock,&nc,sizeof(nc))!=sizeof(nc)) { + perror("Error: could not write command code"); + close(sock); + exit(2); + } + + return sock; +} + +static void send_long(int fd,uint32_t cmd) +{ + uint32_t nc=htonl(cmd); + + if (write(fd,&nc,sizeof(nc))!=sizeof(nc)) { + perror("Error: could not write long"); + close(fd); + exit(2); + } +} + +static void send_short(int fd,uint16_t cmd) +{ + uint16_t nc=htons(cmd); + + if (write(fd,&nc,sizeof(nc))!=sizeof(nc)) { + perror("Error: could not write short"); + close(fd); + exit(2); + } +} + +#define MAXSENDSTRLEN 0xfffe + +static void send_string(int fd, const char *s) +{ + if(s) { + size_t len=strlen(s); + if(len>MAXSENDSTRLEN) { + fprintf(stderr,"Error: send_string: string length (%lu) exceeds maximum (%u).\n", + (unsigned long)len, MAXSENDSTRLEN); + close(fd); + exit(2); + } + send_short(fd,len); + if (write_all(fd,s,len)!=len) { + perror("Error: could not write string"); + close(fd); + exit(2); + } + } + else + send_short(fd, ~0); +} + +static uint16_t read_short(int fd) +{ + ssize_t err; + uint16_t nc; + + if ((err=read(fd,&nc,sizeof(nc)))!=sizeof(nc)) { + fprintf(stderr,"Error: could not read short: %s\n",err<0?strerror(errno):"unexpected EOF"); + close(fd); + exit(2); + } + return ntohs(nc); +} + +/* copy data from file descriptor fd to file stream out until EOF + or error is encountered. +*/ +static ssize_t copymsgtofile(int fd, FILE* out) +{ + ssize_t n,ntot=0; + char buf[1024]; + + while ((n=read(fd,buf,sizeof(buf)))>0) + ntot+=fwrite(buf,1,n,out); + + if(n<0) + return n; + + return ntot; +} + +static int match_cmd(const char *cmd, const cmd_s cmds[]) +{ + int i; + for(i=0; cmds[i].name; ++i) { + if (strcasecmp(cmd,cmds[i].name)==0) + return cmds[i].val; + } + return -1; +} + +int main(int argc, char *argv[]) +{ + char *cache_dir= CACHEDIR; + int rv=0; + { + int i; + char *arg; + for(i=1; i4) + goto wrong_args; + acnt=2; + server_cmd=match_cmd(argv[2],server_cmds); + if(server_cmd==-1) goto bad_arg; + pf=open_sock(cache_dir, cmd); + send_string(pf,argv[1]); + send_short(pf,server_cmd); + send_string(pf,argc<4?NULL:argv[3]); + } + goto read_retval; + + case CTL_RECORD: { + int record_cmd; + if (argc!=3) + goto wrong_args; + acnt=2; + record_cmd=match_cmd(argv[2],record_cmds); + if(record_cmd==-1) goto bad_arg; + pf=open_sock(cache_dir, cmd); + send_short(pf,record_cmd); + send_string(pf,argv[1]); + } + goto read_retval; + + case CTL_SOURCE: { + long ttl; + int servaliases,flags; + if (argc<3 || argc>6) + goto wrong_args; + ttl=900; + flags=DF_LOCAL; + acnt=3; + if (argc==6 || (argc>=4 && isdigit(argv[3][0]))) { + char *endptr; + ttl=strtol(argv[3],&endptr,0); + if (*endptr) + goto bad_arg; + acnt++; + } + servaliases=0; + if (acntacnt+2) + goto wrong_args; + + ttl=900; + flags=DF_LOCAL; + pref=0; + if(tp==T_MX) { + char *endptr; + pref=strtol(argv[4],&endptr,0); + if (*endptr) { + acnt=4; + goto bad_arg; + } + } + + if (acnt4) + goto wrong_args; + tp=255; + ttl=900; + acnt=2; + if (argc==3) { + if (isdigit(argv[2][0])) { + char *endptr; + ttl=strtol(argv[2],&endptr,0); + if (*endptr) + goto bad_arg; + } else if ((tp=rr_tp_byname(argv[2]))==-1) { + goto bad_type; + } + } else if (argc==4) { + char *endptr; + if ((tp=rr_tp_byname(argv[2]))==-1) + goto bad_type; + ttl=strtol(argv[3],&endptr,0); + if (*endptr) { + acnt=3; + goto bad_arg; + } + } + pf=open_sock(cache_dir, cmd); + send_string(pf,argv[1]); + send_short(pf,tp); + send_long(pf,ttl); + } + goto read_retval; + + case CTL_CONFIG: + if (argc>2) + goto wrong_args; + pf=open_sock(cache_dir, cmd); + send_string(pf,argc<2?NULL:argv[1]); + goto read_retval; + + case CTL_INCLUDE: + if (argc!=2) + goto wrong_args; + pf=open_sock(cache_dir, cmd); + send_string(pf,argv[1]); + goto read_retval; + + case CTL_EVAL: { + int i; size_t bufsz; + + if (argc<2) + goto wrong_args; + bufsz=0; + for(i=1; iMAXSENDSTRLEN) { + fprintf(stderr,"Cannot send 'eval' command: " + "string length (%lu) exceeds maximum (%u).\n", + (unsigned long)bufsz, MAXSENDSTRLEN); + exit(2); + } + pf=open_sock(cache_dir, cmd); + send_short(pf,bufsz); + { + /* Variable-size array for storing the joined strings. */ + char buf[bufsz]; + char *p=buf; + for(i=1; iMAXSENDSTRLEN) { + fprintf(stderr,"Cannot send 'empty' command: " + "string length (%lu) exceeds maximum (%u).\n", + (unsigned long)totsz, MAXSENDSTRLEN); + exit(2); + } + pf=open_sock(cache_dir, cmd); + if(argc>1) { + send_short(pf,totsz); + for(i=1; i2) + goto wrong_args; + pf=open_sock(cache_dir, cmd); + send_string(pf,argc<2?NULL:argv[1]); + copy_pf: + if((rv=read_short(pf))) + goto retval_failed; + if(copymsgtofile(pf,stdout)<0) { + perror("Error while reading from socket"); + close(pf); + exit(2); + } + goto close_pf; + + read_retval: + if((rv=read_short(pf))) { + retval_failed: + fprintf(stderr,"Failed: "); + if(copymsgtofile(pf,stderr)<0) + fprintf(stderr,"(could not read error message from socket: %s)",strerror(errno)); + + fputc('\n',stderr); + } + close_pf: + if(close(pf)==-1) + perror("Couldn't close socket"); + else if (rv==0 && verbose) + printf("Succeeded\n"); + break; + wrong_args: + fprintf(stderr,"Wrong number of arguments for '%s' command.\n",argv[0]); + goto print_cmd_usage; + bad_arg: + fprintf(stderr,"Bad argument for '%s' command: %s\n",argv[0],argv[acnt]); + print_cmd_usage: + fprintf(stderr,"Usage:\n\n%s\n" + "Try 'pdnsd-ctl help' for a description of all available commands and options.\n", + help_messages[cmd]); + exit(2); + bad_type: + fprintf(stderr,"Bad (type) argument for '%s' command: %s\n" + "Run 'pdnsd-ctl list-rrtypes' for a list of available rr types.\n", + argv[0],argv[acnt]); + exit(2); + } + } + + return rv; +} + diff --git a/jni/pdnsd/src/pdnsd_assert.h b/jni/pdnsd/src/pdnsd_assert.h new file mode 100644 index 00000000..0acdfc24 --- /dev/null +++ b/jni/pdnsd/src/pdnsd_assert.h @@ -0,0 +1,51 @@ +/* This include file was added by Paul A. Rombouts. + I had terrible difficulties with cyclic dependencies of the include files + written by Thomas Moestl. The only way I knew how to break the cycle was to + put some declarations in a seperate file. + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#ifndef PDNSD_ASSERT_H +#define PDNSD_ASSERT_H + +/* Originally in helpers.h */ + +/* format string checking for printf-like functions */ +#ifdef __GNUC__ +#define printfunc(fmt, firstva) __attribute__((__format__(__printf__, fmt, firstva))) +#else +#define printfunc(fmt, firstva) +#endif + +void pdnsd_exit(void); + + +/* + * Assert macro, used in some places. For now, it should be always defined, not + * only in the DEBUG case, to be on the safe side security-wise. + */ +#define PDNSD_ASSERT(cond, msg) \ + { if (!(cond)) { \ + log_error("%s:%d: %s", __FILE__, __LINE__, msg); \ + pdnsd_exit(); \ + } } + +#endif diff --git a/jni/pdnsd/src/rc/ArchLinux/Makefile.am b/jni/pdnsd/src/rc/ArchLinux/Makefile.am new file mode 100644 index 00000000..2a7b4204 --- /dev/null +++ b/jni/pdnsd/src/rc/ArchLinux/Makefile.am @@ -0,0 +1,7 @@ + +install-exec-local: + if [ "$(distribution)" = "ArchLinux" ] ; then \ + $(mkinstalldirs) "$(DESTDIR)/etc/rc.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/rc.d/pdnsd";\ + fi + diff --git a/jni/pdnsd/src/rc/ArchLinux/Makefile.in b/jni/pdnsd/src/rc/ArchLinux/Makefile.in new file mode 100644 index 00000000..6af6f9e4 --- /dev/null +++ b/jni/pdnsd/src/rc/ArchLinux/Makefile.in @@ -0,0 +1,332 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc/ArchLinux +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/pdnsd.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pdnsd +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/ArchLinux/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/ArchLinux/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pdnsd: $(top_builddir)/config.status $(srcdir)/pdnsd.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am + + +install-exec-local: + if [ "$(distribution)" = "ArchLinux" ] ; then \ + $(mkinstalldirs) "$(DESTDIR)/etc/rc.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/rc.d/pdnsd";\ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/ArchLinux/pdnsd.in b/jni/pdnsd/src/rc/ArchLinux/pdnsd.in new file mode 100644 index 00000000..c3927506 --- /dev/null +++ b/jni/pdnsd/src/rc/ArchLinux/pdnsd.in @@ -0,0 +1,45 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions + +PID=`pidof -o %PPID @prefix@/sbin/pdnsd` + +start() { + stat_busy "Starting PDNSD" + [ -z "$PID" ] && @prefix@/sbin/pdnsd -d -c /etc/pdnsd.conf + if [ $? -gt 0 ]; then + stat_fail + else + add_daemon pdnsd + stat_done + fi +} + +stop() { + stat_busy "Stopping PDNSD" + [ ! -z "$PID" ] && kill $PID &> /dev/null + if [ $? -gt 0 ]; then + stat_fail + else + rm_daemon pdnsd + stat_done + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + $0 stop + sleep 2 + $0 start + ;; + *) + echo "usage: $0 {start|stop|restart}" +esac +exit 0 diff --git a/jni/pdnsd/src/rc/Debian/Makefile.am b/jni/pdnsd/src/rc/Debian/Makefile.am new file mode 100644 index 00000000..61d3eb3b --- /dev/null +++ b/jni/pdnsd/src/rc/Debian/Makefile.am @@ -0,0 +1,8 @@ + +install-exec-local: + if [ "$(distribution)" = "Debian" ] ; then \ + CURDIR=`pwd`; \ + $(mkinstalldirs) "$(DESTDIR)/etc/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/init.d"; \ + update-rc.d pdnsd defaults 19 ;\ + fi diff --git a/jni/pdnsd/src/rc/Debian/Makefile.in b/jni/pdnsd/src/rc/Debian/Makefile.in new file mode 100644 index 00000000..992a0597 --- /dev/null +++ b/jni/pdnsd/src/rc/Debian/Makefile.in @@ -0,0 +1,334 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc/Debian +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/pdnsd.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pdnsd +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/Debian/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/Debian/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pdnsd: $(top_builddir)/config.status $(srcdir)/pdnsd.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am + + +install-exec-local: + if [ "$(distribution)" = "Debian" ] ; then \ + CURDIR=`pwd`; \ + $(mkinstalldirs) "$(DESTDIR)/etc/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/init.d"; \ + update-rc.d pdnsd defaults 19 ;\ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/Debian/pdnsd.in b/jni/pdnsd/src/rc/Debian/pdnsd.in new file mode 100644 index 00000000..068606ee --- /dev/null +++ b/jni/pdnsd/src/rc/Debian/pdnsd.in @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# This script was written and contributed by Markus Mohr, and +# slightly modified by me for version 1.0.6 (which obviously +# broke it some way). I then applied a set of corrections +# by Markus Mohr. +# +# Carsten Block has patched this with some magic so that +# the actual script is generated by configure, and that +# the pdnsd user is determined from pdnsd.conf +# I changed this a little to use the --pdnsd-user option +# of pdnsd to determine the run_as user. +# + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +test -x @prefix@/sbin/pdnsd || exit 0 + +case "$1" in + start) + # Check if cache dir exists and recreate if neccessary + test -d @cachedir@ || mkdir @cachedir@ + RUNAS=`@prefix@/sbin/pdnsd --pdnsd-user` || echo -n " failed" + [ -z "$RUNAS" ] && RUNAS=nobody + chown $RUNAS @cachedir@ + echo -n "Starting domain name service: pdnsd" + start-stop-daemon --start --quiet --pidfile /var/run/pdnsd.pid --name pdnsd \ + --exec @prefix@/sbin/pdnsd -- --daemon -p /var/run/pdnsd.pid \ + || echo -n " failed" + echo "." + ;; + + stop) + echo -n "Stopping domain name service: pdnsd" + start-stop-daemon --stop --quiet --pidfile /var/run/pdnsd.pid --name pdnsd --exec @prefix@/sbin/pdnsd \ + || echo -n " failed" + echo "." + ;; + + restart) + $0 stop + $0 start + ;; + + *) + echo "Usage: /etc/init.d/pdnsd {start|stop|restart}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/jni/pdnsd/src/rc/Makefile.am b/jni/pdnsd/src/rc/Makefile.am new file mode 100644 index 00000000..abf2e6dc --- /dev/null +++ b/jni/pdnsd/src/rc/Makefile.am @@ -0,0 +1,5 @@ + +SUBDIRS = RedHat SuSE Debian Slackware ArchLinux + +EXTRA_DIST = README + diff --git a/jni/pdnsd/src/rc/Makefile.in b/jni/pdnsd/src/rc/Makefile.in new file mode 100644 index 00000000..38ee297c --- /dev/null +++ b/jni/pdnsd/src/rc/Makefile.in @@ -0,0 +1,526 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = RedHat SuSE Debian Slackware ArchLinux +EXTRA_DIST = README +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic ctags \ + ctags-recursive distclean distclean-generic distclean-tags \ + distdir dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ + tags-recursive uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/README b/jni/pdnsd/src/rc/README new file mode 100644 index 00000000..4e007640 --- /dev/null +++ b/jni/pdnsd/src/rc/README @@ -0,0 +1,104 @@ +rc/ +=== + +These are start scripts for different Linux distros and other things that +do not directly belong to pdnsd. +If you do start scripts for the distro you use, please GPL them and send +them in, so that they can be included in this package for other users. +Note that there is NO WARRANTY OF ANY KIND on anything in this directory; +read the COPYING that comes with pdnsd for details. +So far there are files in the following directories: + +SuSE +---- +pdnsd - Start script for SuSE Linux. Tested for 6.? but should run on some + versions below. You can do 'make install' as root in the SuSE + directory to install it, or you can install manually: + --manual installation------------------------------------------------- + For manual installation, copy it into /sbin/init.d/, go to + /sbin/init.d/rc2.d/ and create there the following two symlinks: + S11pdnsd -> ../pdnsd (do "ln -s ../pdnsd S11pdnsd" in that dir) + K34pdnsd -> ../pdnsd (do "ln -s ../pdnsd K34pdnsd" in that dir) + The numbers dictate the order different services are started and + might need to be modified. Then edit your /etc/rc.config file and + add the line "START_PDNSD=yes" to start pdnsd at boot time. + ---------------------------------------------------------------------- + If you used the 'make install' command, "START_PDNSD=yes" has been + appended to your /etc/rc.config file, causing pdnsd to be started + at boot time. If you don't want that, change the "yes" into "no". + This start script was created from /sbin/init.d/skeleton by me, so the + most is copyrighted by SuSE. They put it under the GPL, however, so + the licence stated in COPYING also applies to this script. + This is no official SuSE script, and SuSE naturally does NO support + for it. + +Redhat +------ +The contents of the Redhat directory and the following documentation were +contributed by Torben Janssen. Thanks a lot! + +pdnsd - Start script for Redhat Linux. Tested for 6.1 but should run on 5.0+. + You can do 'make install' as root in the Redhat directory to + install it, or you can install manually: + + --manual installation------------------------------------------------- + For manual installation, copy pdnsd into /etc/rc.d/init.d/ + + Then go to /etc/rc.d/rc3.d and create there the following symlink: + S78pdnsd -> ../init.d/pdnsd + (do "ln -f -s ../init.d/pdnsd S78pdnsd" in that dir) + + Then go to /etc/rc.d/rc0.d and create there the following symlink: + K78pdnsd -> ../init.d/pdnsd + (do "ln -f -s ../init.d/pdnsd K78pdnsd" in that dir) + + Then go to /etc/rc.d/rc6.d and create there the following symlink: + K78pdnsd -> ../init.d/pdnsd + (do "ln -f -s ../init.d/pdnsd K78pdnsd" in that dir) + + WHY + --- + the rc[0-6].d dirs includes the scripts which starts/stops the + services on entering runlevel [0-6] + the interesting runlevels on Redhat are: + 0 - halt + 3 - multi user system + 6 - reboot + The links have an 'S' or 'K' and a number at the beginnig. All links + with 'S' starts the script on entering the runlevel and 'K' stops + them. + So, there's an 'S' link in rc3 and 'K' links in rc0 and rc6. + I choose 78 as number, because there was no script with this number on + my system. You can choose every number you want, AFAIK . + + This is no offical Redhat script, and Redhat naturally does NO support + for it. + +Debian +------ +The contents of the Debian directory were contributed by Markus Mohr. +His installation instructions are (translated): +Install the pdnsd script to /etc/init and run +update-rc.d pdnsd defaults 19 +as root. + +Slackware +--------- +A Slackware start-up script rc.pdnsd was contributed by Nikola Kotur . +His comments were: + +Slackware uses traditional BSD style init script layout instead of SystemV +style startup scripts. So I adjusted the start-up script for pdnsd, and +now it can be used with Slackware 9.1 distribution, and probably with all the +others. + +Additional info: +1) put these lines in the /etc/rc.d/rc.M: + if [ -x /etc/rc.d/rc.pdnsd ]; then + /etc/rc.d/rc.pdnsd start + fi + +2) put these lines in the /etc/rc.d/rc.6 and /etc/rc.d/rc.K: + if [ -x /etc/rc.d/rc.pdnsd ]; then + /etc/rc.d/rc.pdnsd stop + fi diff --git a/jni/pdnsd/src/rc/RedHat/Makefile.am b/jni/pdnsd/src/rc/RedHat/Makefile.am new file mode 100644 index 00000000..cb8de885 --- /dev/null +++ b/jni/pdnsd/src/rc/RedHat/Makefile.am @@ -0,0 +1,12 @@ + +# no need to create links. 'chkconfig' will take care of this. +# In the spec case, chkconfig is called during rpm install +install-exec-local: + if [ "$(distribution)" = "RedHat" ] ; then \ + $(mkinstalldirs) "$(DESTDIR)/etc/rc.d/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/rc.d/init.d/pdnsd"; \ + if [ "$(specbuild)" = "no" ] ; then \ + /sbin/chkconfig --add pdnsd; \ + fi \ + fi + diff --git a/jni/pdnsd/src/rc/RedHat/Makefile.in b/jni/pdnsd/src/rc/RedHat/Makefile.in new file mode 100644 index 00000000..a88a037c --- /dev/null +++ b/jni/pdnsd/src/rc/RedHat/Makefile.in @@ -0,0 +1,337 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc/RedHat +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/pdnsd.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pdnsd +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/RedHat/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/RedHat/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pdnsd: $(top_builddir)/config.status $(srcdir)/pdnsd.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am + + +# no need to create links. 'chkconfig' will take care of this. +# In the spec case, chkconfig is called during rpm install +install-exec-local: + if [ "$(distribution)" = "RedHat" ] ; then \ + $(mkinstalldirs) "$(DESTDIR)/etc/rc.d/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/etc/rc.d/init.d/pdnsd"; \ + if [ "$(specbuild)" = "no" ] ; then \ + /sbin/chkconfig --add pdnsd; \ + fi \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/RedHat/pdnsd.in b/jni/pdnsd/src/rc/RedHat/pdnsd.in new file mode 100644 index 00000000..b6d9081d --- /dev/null +++ b/jni/pdnsd/src/rc/RedHat/pdnsd.in @@ -0,0 +1,88 @@ +#!/bin/bash +# +# /etc/rc.d/init.d/pdnsd +# +# Script for starting the Proxy DNS Daemon +# Modified by Paul Rombouts, 2003 +# +# chkconfig: 2345 11 89 +# description: Proxy DNS Daemon +# processname: pdnsd +# config: /etc/pdnsd.conf + +PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin + +# Source function library. +. /etc/rc.d/init.d/functions + +# Source networking configuration. +. /etc/sysconfig/network + +# Check that networking is up. +if [[ $NETWORKING == [Nn][Oo] ]]; then exit 0; fi + +# Source sysconfig settings, if any. +if [ -f /etc/sysconfig/pdnsd ]; then . /etc/sysconfig/pdnsd; fi + +start() { + echo -n 'Starting pdnsd: ' + daemon @prefix@/sbin/pdnsd -d -s -p /var/run/pdnsd.pid "$EXTRAOPTIONS" + local RETVAL=$? + echo + if [ $RETVAL -eq 0 ]; then touch /var/lock/subsys/pdnsd; fi + return $RETVAL +} + +stop() { + echo -n 'Shutting down pdnsd: ' + killproc pdnsd + local RETVAL=$? + case @threadlib@ in + [Ll]inux[Tt]hreads*|lt*) + # Wait until all threads have terminated. + local -i count=20 + while [[ count -gt 0 ]] && pidof pdnsd > /dev/null + do + usleep 200000 + let --count + done + ;; + esac + echo + if [ $RETVAL -eq 0 ]; then rm -f /var/lock/subsys/pdnsd; fi + return $RETVAL +} + +restart() { + stop + start +} + +# +# See how we were called. +# +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status pdnsd + ;; + reload) + @prefix@/sbin/pdnsd-ctl config + ;; + restart) + restart + ;; + condrestart) + if [ -f /var/lock/subsys/pdnsd ]; then restart; fi + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}" + exit 1 +esac + +exit diff --git a/jni/pdnsd/src/rc/Slackware/Makefile.am b/jni/pdnsd/src/rc/Slackware/Makefile.am new file mode 100644 index 00000000..e44b50f8 --- /dev/null +++ b/jni/pdnsd/src/rc/Slackware/Makefile.am @@ -0,0 +1,3 @@ +# TODO: write an install rule for the Slackware start-up script. + +install-exec-local: diff --git a/jni/pdnsd/src/rc/Slackware/Makefile.in b/jni/pdnsd/src/rc/Slackware/Makefile.in new file mode 100644 index 00000000..14ebd33b --- /dev/null +++ b/jni/pdnsd/src/rc/Slackware/Makefile.in @@ -0,0 +1,330 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# TODO: write an install rule for the Slackware start-up script. +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc/Slackware +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/rc.pdnsd.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = rc.pdnsd +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/Slackware/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/Slackware/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +rc.pdnsd: $(top_builddir)/config.status $(srcdir)/rc.pdnsd.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am + + +install-exec-local: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/Slackware/rc.pdnsd.in b/jni/pdnsd/src/rc/Slackware/rc.pdnsd.in new file mode 100644 index 00000000..6e969713 --- /dev/null +++ b/jni/pdnsd/src/rc/Slackware/rc.pdnsd.in @@ -0,0 +1,74 @@ +#!/bin/bash +# +# /etc/rc.d/rc.pdnsd +# +# Starts the Proxy DNS Daemon +# +# description: Proxy DNS Daemon +# processname: pdnsd +# config: /etc/pdnsd.conf +# distribution: Slackware +# author: Nikola Kotur +# +# Additional info: +# 1) put these lines in the /etc/rc.d/rc.M: +# if [ -x /etc/rc.d/rc.pdnsd ]; then +# /etc/rc.d/rc.pdnsd start +# fi +# +# 2) put these lines in the /etc/rc.d/rc.6 and /etc/rc.d/rc.K: +# if [ -x /etc/rc.d/rc.pdnsd ]; then +# /etc/rc.d/rc.pdnsd stop +# fi + + +test -x @prefix@/sbin/pdnsd || exit 0 +[ -f @sysconfdir@/pdnsd.conf ] || exit 1 + +RETVAL=0 + +start() { + echo -n "Starting pdnsd... " + RETVAL=$? + @prefix@/sbin/pdnsd -d + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/pdnsd + echo ' OK' +} + +stop() { + echo -n "Shutting down pdnsd... " + killall pdnsd + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/pdnsd + echo ' OK' +} + +restart() { + stop + start +} + +condrestart() { + [ -e /var/lock/subsys/pdnsd ] && restart + return 0 +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + reload|restart) + restart + ;; + condrestart) + condrestart + ;; + *) + echo $"Usage: $0 {start|stop|restart|condrestart|reload}" + RETVAL=1 +esac + +exit $RETVAL diff --git a/jni/pdnsd/src/rc/SuSE/Makefile.am b/jni/pdnsd/src/rc/SuSE/Makefile.am new file mode 100644 index 00000000..dc5f485b --- /dev/null +++ b/jni/pdnsd/src/rc/SuSE/Makefile.am @@ -0,0 +1,22 @@ + +install-exec-local: + if [ "$(distribution)" = "SuSE" ] ; then \ + CURDIR=`pwd`; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/sbin/init.d/pdnsd"; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d/rc2.d"; \ + cd "$(DESTDIR)/sbin/init.d/rc2.d"; \ + ln -fs ../pdnsd K34pdnsd; ln -s ../pdnsd S11pdnsd; \ + cd $$CURDIR ; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d/rc3.d"; \ + cd "$(DESTDIR)/sbin/init.d/rc3.d"; \ + ln -fs ../pdnsd K34pdnsd; ln -s ../pdnsd S11pdnsd; \ + cd $$CURDIR ; \ + grep "START_PDNSD" "$(DESTDIR)/etc/rc.config" > /dev/null ; \ + if [ $$? -eq 1 ] ; then \ + echo -e "\n\n#\n# Set to yes to start pdnsd at boot time\n#\nSTART_PDNSD=yes" >> /etc/rc.config ; \ + fi \ + fi + + + diff --git a/jni/pdnsd/src/rc/SuSE/Makefile.in b/jni/pdnsd/src/rc/SuSE/Makefile.in new file mode 100644 index 00000000..df1660fd --- /dev/null +++ b/jni/pdnsd/src/rc/SuSE/Makefile.in @@ -0,0 +1,345 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = src/rc/SuSE +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/pdnsd.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pdnsd +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/rc/SuSE/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/rc/SuSE/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pdnsd: $(top_builddir)/config.status $(srcdir)/pdnsd.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-exec-local + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-exec-local \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ + uninstall-am + + +install-exec-local: + if [ "$(distribution)" = "SuSE" ] ; then \ + CURDIR=`pwd`; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d"; \ + $(INSTALL_SCRIPT) $(srcdir)/pdnsd "$(DESTDIR)/sbin/init.d/pdnsd"; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d/rc2.d"; \ + cd "$(DESTDIR)/sbin/init.d/rc2.d"; \ + ln -fs ../pdnsd K34pdnsd; ln -s ../pdnsd S11pdnsd; \ + cd $$CURDIR ; \ + $(mkinstalldirs) "$(DESTDIR)/sbin/init.d/rc3.d"; \ + cd "$(DESTDIR)/sbin/init.d/rc3.d"; \ + ln -fs ../pdnsd K34pdnsd; ln -s ../pdnsd S11pdnsd; \ + cd $$CURDIR ; \ + grep "START_PDNSD" "$(DESTDIR)/etc/rc.config" > /dev/null ; \ + if [ $$? -eq 1 ] ; then \ + echo -e "\n\n#\n# Set to yes to start pdnsd at boot time\n#\nSTART_PDNSD=yes" >> /etc/rc.config ; \ + fi \ + fi + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/rc/SuSE/pdnsd.in b/jni/pdnsd/src/rc/SuSE/pdnsd.in new file mode 100644 index 00000000..9711ecad --- /dev/null +++ b/jni/pdnsd/src/rc/SuSE/pdnsd.in @@ -0,0 +1,68 @@ +#! /bin/sh +# Copyright (c) 1995-1998 SuSE GmbH Nuernberg, Germany. +# +# Modified 2000 from SuSE Linux 6.3 /sbin/init.d/skeleton by Thomas Moestl +# +# /sbin/init.d/pdnsd +# +# and symbolic its link +# +# /sbin/rc?/pdnsd +# + +. /etc/rc.config + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test $link = $base && START_PDNSD=yes +test "$START_PDNSD" = yes || exit 0 + +# The echo return value for success (defined in /etc/rc.config). +return=$rc_done +case "$1" in + start) + echo -n "Starting pdnsd" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc @prefix@/sbin/pdnsd -d || return=$rc_failed + + echo -e "$return" + ;; + stop) + echo -n "Shutting down pdnsd" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -TERM @prefix@/sbin/pdnsd || return=$rc_failed + + echo -e "$return" + ;; + restart) + ## If first returns OK call the second, if first or + ## second command fails, set echo return value. + $0 stop && $0 start || return=$rc_failed + ;; + reload) + $0 stop && $0 start || return=$rc_failed + ;; + status) + echo -n "Checking for pdnsd: " + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + checkproc @prefix@/sbin/pdnsd && echo OK || echo No process + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload}" + exit 1 + ;; +esac + +# Inform the caller not only verbosely and set an exit status. +test "$return" = "$rc_done" || exit 1 +exit 0 + diff --git a/jni/pdnsd/src/rr_types.c b/jni/pdnsd/src/rr_types.c new file mode 100644 index 00000000..275a90a4 --- /dev/null +++ b/jni/pdnsd/src/rr_types.c @@ -0,0 +1,172 @@ +/* rr_types.c - Tables with information for handling + all rr types known to pdnsd, plus + some helper functions useful for turning + binary RR data into text or vice versa. + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2003, 2004, 2007, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#define DEFINE_RR_TYPE_ARRAYS 1 +#include "helpers.h" +#include "dns.h" +#include "rr_types.h" + + +/* + * OK, this is inefficient. But it is used _really_ seldom (only in some cases while parsing the + * config file or by pdnsd-ctl), so it is much more effective to sort by id. + */ +int rr_tp_byname(char *name) +{ + int i; + + for (i=0;i> 4); + exponent = (prec & 0x0f); + + if(mantissa>=10 || exponent>=10) + return NULL; + if (exponent>= 2) + sprintf(retbuf, "%u", mantissa * poweroften[exponent-2]); + else + sprintf(retbuf, "0.%.2u", mantissa * poweroften[exponent]); + return (retbuf); +} + +/* takes an on-the-wire LOC RR and formats it in a human readable format. + This is an adapted version of the loc_ntoa function that + can be found in the BIND 9 source. + */ +const char *loc2str(const void *binary, char *ascii, size_t asclen) +{ + const unsigned char *cp = binary; + + int latdeg, latmin, latsec, latsecfrac; + int longdeg, longmin, longsec, longsecfrac; + char northsouth, eastwest; + const char *altsign; + int altmeters, altfrac; + + const uint32_t referencealt = 100000 * 100; + + int32_t latval, longval, altval; + uint32_t templ; + uint8_t sizeval, hpval, vpval, versionval; + + char sizestr[NPRECSIZE],hpstr[NPRECSIZE],vpstr[NPRECSIZE]; + + versionval = *cp++; + + if (versionval) { + /* unknown LOC RR version */ + return NULL; + } + + sizeval = *cp++; + + hpval = *cp++; + vpval = *cp++; + + GETINT32(templ, cp); + latval = (templ - ((unsigned)1<<31)); + + GETINT32(templ, cp); + longval = (templ - ((unsigned)1<<31)); + + GETINT32(templ, cp); + if (templ < referencealt) { /* below WGS 84 spheroid */ + altval = referencealt - templ; + altsign = "-"; + } else { + altval = templ - referencealt; + altsign = ""; + } + + if (latval < 0) { + northsouth = 'S'; + latval = -latval; + } else + northsouth = 'N'; + + latsecfrac = latval % 1000; + latval /= 1000; + latsec = latval % 60; + latval /= 60; + latmin = latval % 60; + latval /= 60; + latdeg = latval; + + if (longval < 0) { + eastwest = 'W'; + longval = -longval; + } else + eastwest = 'E'; + + longsecfrac = longval % 1000; + longval /= 1000; + longsec = longval % 60; + longval /= 60; + longmin = longval % 60; + longval /= 60; + longdeg = longval; + + altfrac = altval % 100; + altmeters = (altval / 100); + + if(!precsize_ntoa(sizeval,sizestr) || !precsize_ntoa(hpval,hpstr) || !precsize_ntoa(vpval,vpstr)) + return NULL; + { + int n=snprintf(ascii,asclen, + "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm", + latdeg, latmin, latsec, latsecfrac, northsouth, + longdeg, longmin, longsec, longsecfrac, eastwest, + altsign, altmeters, altfrac, + sizestr, hpstr, vpstr); + if(n<0 || n>=asclen) + return NULL; + } + + return (ascii); +} + +#endif diff --git a/jni/pdnsd/src/rr_types.h b/jni/pdnsd/src/rr_types.h new file mode 100644 index 00000000..6025fae5 --- /dev/null +++ b/jni/pdnsd/src/rr_types.h @@ -0,0 +1,536 @@ +/* This file was generated by running 'make_rr_types_h.pl rr_types.in'. + Modifications to this file may be lost the next time it is automatically + regenerated. +*/ + +/* rr_types.h - A header file with names & descriptions of + all rr types known to pdnsd + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2007, 2010, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#ifndef _RR_TYPES_H_ +#define _RR_TYPES_H_ + +#include + +#define T_MIN 1 +#define T_A 1 +#define T_NS 2 +#define T_MD 3 +#define T_MF 4 +#define T_CNAME 5 +#define T_SOA 6 +#define T_MB 7 +#define T_MG 8 +#define T_MR 9 +#define T_NULL 10 +#define T_WKS 11 +#define T_PTR 12 +#define T_HINFO 13 +#define T_MINFO 14 +#define T_MX 15 +#define T_TXT 16 +#define T_RP 17 +#define T_AFSDB 18 +#define T_X25 19 +#define T_ISDN 20 +#define T_RT 21 +#define T_NSAP 22 +#define T_NSAP_PTR 23 +#define T_SIG 24 +#define T_KEY 25 +#define T_PX 26 +#define T_GPOS 27 +#define T_AAAA 28 +#define T_LOC 29 +#define T_NXT 30 +#define T_EID 31 +#define T_NIMLOC 32 +#define T_SRV 33 +#define T_ATMA 34 +#define T_NAPTR 35 +#define T_KX 36 +#define T_CERT 37 +#define T_A6 38 +#define T_DNAME 39 +#define T_SINK 40 +#define T_OPT 41 +#define T_APL 42 +#define T_DS 43 +#define T_SSHFP 44 +#define T_IPSECKEY 45 +#define T_RRSIG 46 +#define T_NSEC 47 +#define T_DNSKEY 48 +#define T_DHCID 49 +#define T_NSEC3 50 +#define T_NSEC3PARAM 51 +#define T_HIP 55 +#define T_NINFO 56 +#define T_RKEY 57 +#define T_TALINK 58 +#define T_SPF 99 +#define T_UINFO 100 +#define T_UID 101 +#define T_GID 102 +#define T_UNSPEC 103 +#define T_MAX 51 + +/* T_MAX - T_MIN + 1 */ +#define T_NUM 51 + +/* Number of most frequently used rr types. */ +#define NRRMU 8 + +/* Number of remaining rr types. */ +#define NRREXT 39 + +/* NRRMU + NRREXT */ +#define NRRTOT 47 + +/* Lookup table for converting rr type values to internally used indices. */ +extern const unsigned short int rrlkuptab[T_NUM]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const unsigned short int rrlkuptab[T_NUM] = { + 0 /* A */, + 1 /* NS */, + 8 /* MD */, + 9 /* MF */, + 2 /* CNAME */, + 3 /* SOA */, + 10 /* MB */, + 11 /* MG */, + 12 /* MR */, + 13 /* NULL */, + 14 /* WKS */, + 4 /* PTR */, + 15 /* HINFO */, + 16 /* MINFO */, + 5 /* MX */, + 6 /* TXT */, + 17 /* RP */, + 18 /* AFSDB */, + 19 /* X25 */, + 20 /* ISDN */, + 21 /* RT */, + 22 /* NSAP */, + 23 /* NSAP_PTR */, + 24 /* SIG */, + 25 /* KEY */, + 26 /* PX */, + 27 /* GPOS */, + 7 /* AAAA */, + 28 /* LOC */, + 29 /* NXT */, + 30 /* EID */, + 31 /* NIMLOC */, + 32 /* SRV */, + 33 /* ATMA */, + 34 /* NAPTR */, + 35 /* KX */, + 36 /* CERT */, + 47 /* A6 */, + 48 /* DNAME */, + 49 /* SINK */, + 50 /* OPT */, + 37 /* APL */, + 38 /* DS */, + 39 /* SSHFP */, + 40 /* IPSECKEY */, + 41 /* RRSIG */, + 42 /* NSEC */, + 43 /* DNSKEY */, + 44 /* DHCID */, + 45 /* NSEC3 */, + 46 /* NSEC3PARAM */ +}; +#endif + +/* List of most frequently used RR types in ascending order. */ +extern const unsigned short int rrmuiterlist[NRRMU]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const unsigned short int rrmuiterlist[NRRMU] = { + T_A, + T_NS, + T_CNAME, + T_SOA, + T_PTR, + T_MX, + T_TXT, + T_AAAA +}; +#endif + +/* List of the cache-able RR types in ascending order. */ +extern const unsigned short int rrcachiterlist[NRRTOT]; +#if DEFINE_RR_TYPE_ARRAYS +const unsigned short int rrcachiterlist[NRRTOT] = { + T_A, + T_NS, + T_MD, + T_MF, + T_CNAME, + T_SOA, + T_MB, + T_MG, + T_MR, + T_NULL, + T_WKS, + T_PTR, + T_HINFO, + T_MINFO, + T_MX, + T_TXT, + T_RP, + T_AFSDB, + T_X25, + T_ISDN, + T_RT, + T_NSAP, + T_NSAP_PTR, + T_SIG, + T_KEY, + T_PX, + T_GPOS, + T_AAAA, + T_LOC, + T_NXT, + T_EID, + T_NIMLOC, + T_SRV, + T_ATMA, + T_NAPTR, + T_KX, + T_CERT, + T_APL, + T_DS, + T_SSHFP, + T_IPSECKEY, + T_RRSIG, + T_NSEC, + T_DNSKEY, + T_DHCID, + T_NSEC3, + T_NSEC3PARAM +}; +#endif + +/* Optimized getrrset macros for fixed rr types. */ +#define getrrset_A(cent) GET_RRSMU(cent,0) +#define getrrset_NS(cent) GET_RRSMU(cent,1) +#define getrrset_MD(cent) GET_RRSEXT(cent,0) +#define getrrset_MF(cent) GET_RRSEXT(cent,1) +#define getrrset_CNAME(cent) GET_RRSMU(cent,2) +#define getrrset_SOA(cent) GET_RRSMU(cent,3) +#define getrrset_MB(cent) GET_RRSEXT(cent,2) +#define getrrset_MG(cent) GET_RRSEXT(cent,3) +#define getrrset_MR(cent) GET_RRSEXT(cent,4) +#define getrrset_NULL(cent) GET_RRSEXT(cent,5) +#define getrrset_WKS(cent) GET_RRSEXT(cent,6) +#define getrrset_PTR(cent) GET_RRSMU(cent,4) +#define getrrset_HINFO(cent) GET_RRSEXT(cent,7) +#define getrrset_MINFO(cent) GET_RRSEXT(cent,8) +#define getrrset_MX(cent) GET_RRSMU(cent,5) +#define getrrset_TXT(cent) GET_RRSMU(cent,6) +#define getrrset_RP(cent) GET_RRSEXT(cent,9) +#define getrrset_AFSDB(cent) GET_RRSEXT(cent,10) +#define getrrset_X25(cent) GET_RRSEXT(cent,11) +#define getrrset_ISDN(cent) GET_RRSEXT(cent,12) +#define getrrset_RT(cent) GET_RRSEXT(cent,13) +#define getrrset_NSAP(cent) GET_RRSEXT(cent,14) +#define getrrset_NSAP_PTR(cent) GET_RRSEXT(cent,15) +#define getrrset_SIG(cent) GET_RRSEXT(cent,16) +#define getrrset_KEY(cent) GET_RRSEXT(cent,17) +#define getrrset_PX(cent) GET_RRSEXT(cent,18) +#define getrrset_GPOS(cent) GET_RRSEXT(cent,19) +#define getrrset_AAAA(cent) GET_RRSMU(cent,7) +#define getrrset_LOC(cent) GET_RRSEXT(cent,20) +#define getrrset_NXT(cent) GET_RRSEXT(cent,21) +#define getrrset_EID(cent) GET_RRSEXT(cent,22) +#define getrrset_NIMLOC(cent) GET_RRSEXT(cent,23) +#define getrrset_SRV(cent) GET_RRSEXT(cent,24) +#define getrrset_ATMA(cent) GET_RRSEXT(cent,25) +#define getrrset_NAPTR(cent) GET_RRSEXT(cent,26) +#define getrrset_KX(cent) GET_RRSEXT(cent,27) +#define getrrset_CERT(cent) GET_RRSEXT(cent,28) +#define getrrset_APL(cent) GET_RRSEXT(cent,29) +#define getrrset_DS(cent) GET_RRSEXT(cent,30) +#define getrrset_SSHFP(cent) GET_RRSEXT(cent,31) +#define getrrset_IPSECKEY(cent) GET_RRSEXT(cent,32) +#define getrrset_RRSIG(cent) GET_RRSEXT(cent,33) +#define getrrset_NSEC(cent) GET_RRSEXT(cent,34) +#define getrrset_DNSKEY(cent) GET_RRSEXT(cent,35) +#define getrrset_DHCID(cent) GET_RRSEXT(cent,36) +#define getrrset_NSEC3(cent) GET_RRSEXT(cent,37) +#define getrrset_NSEC3PARAM(cent) GET_RRSEXT(cent,38) + +/* have_rr macros for fixed rr types. */ +#define have_rr_A(cent) HAVE_RRMU(cent,0) +#define have_rr_NS(cent) HAVE_RRMU(cent,1) +#define have_rr_MD(cent) HAVE_RREXT(cent,0) +#define have_rr_MF(cent) HAVE_RREXT(cent,1) +#define have_rr_CNAME(cent) HAVE_RRMU(cent,2) +#define have_rr_SOA(cent) HAVE_RRMU(cent,3) +#define have_rr_MB(cent) HAVE_RREXT(cent,2) +#define have_rr_MG(cent) HAVE_RREXT(cent,3) +#define have_rr_MR(cent) HAVE_RREXT(cent,4) +#define have_rr_NULL(cent) HAVE_RREXT(cent,5) +#define have_rr_WKS(cent) HAVE_RREXT(cent,6) +#define have_rr_PTR(cent) HAVE_RRMU(cent,4) +#define have_rr_HINFO(cent) HAVE_RREXT(cent,7) +#define have_rr_MINFO(cent) HAVE_RREXT(cent,8) +#define have_rr_MX(cent) HAVE_RRMU(cent,5) +#define have_rr_TXT(cent) HAVE_RRMU(cent,6) +#define have_rr_RP(cent) HAVE_RREXT(cent,9) +#define have_rr_AFSDB(cent) HAVE_RREXT(cent,10) +#define have_rr_X25(cent) HAVE_RREXT(cent,11) +#define have_rr_ISDN(cent) HAVE_RREXT(cent,12) +#define have_rr_RT(cent) HAVE_RREXT(cent,13) +#define have_rr_NSAP(cent) HAVE_RREXT(cent,14) +#define have_rr_NSAP_PTR(cent) HAVE_RREXT(cent,15) +#define have_rr_SIG(cent) HAVE_RREXT(cent,16) +#define have_rr_KEY(cent) HAVE_RREXT(cent,17) +#define have_rr_PX(cent) HAVE_RREXT(cent,18) +#define have_rr_GPOS(cent) HAVE_RREXT(cent,19) +#define have_rr_AAAA(cent) HAVE_RRMU(cent,7) +#define have_rr_LOC(cent) HAVE_RREXT(cent,20) +#define have_rr_NXT(cent) HAVE_RREXT(cent,21) +#define have_rr_EID(cent) HAVE_RREXT(cent,22) +#define have_rr_NIMLOC(cent) HAVE_RREXT(cent,23) +#define have_rr_SRV(cent) HAVE_RREXT(cent,24) +#define have_rr_ATMA(cent) HAVE_RREXT(cent,25) +#define have_rr_NAPTR(cent) HAVE_RREXT(cent,26) +#define have_rr_KX(cent) HAVE_RREXT(cent,27) +#define have_rr_CERT(cent) HAVE_RREXT(cent,28) +#define have_rr_A6(cent) 0 +#define have_rr_DNAME(cent) 0 +#define have_rr_SINK(cent) 0 +#define have_rr_OPT(cent) 0 +#define have_rr_APL(cent) HAVE_RREXT(cent,29) +#define have_rr_DS(cent) HAVE_RREXT(cent,30) +#define have_rr_SSHFP(cent) HAVE_RREXT(cent,31) +#define have_rr_IPSECKEY(cent) HAVE_RREXT(cent,32) +#define have_rr_RRSIG(cent) HAVE_RREXT(cent,33) +#define have_rr_NSEC(cent) HAVE_RREXT(cent,34) +#define have_rr_DNSKEY(cent) HAVE_RREXT(cent,35) +#define have_rr_DHCID(cent) HAVE_RREXT(cent,36) +#define have_rr_NSEC3(cent) HAVE_RREXT(cent,37) +#define have_rr_NSEC3PARAM(cent) HAVE_RREXT(cent,38) + +/* These macros specify which RR types are cached by pdnsd. */ +#define IS_CACHED_A 1 +#define IS_CACHED_NS 1 +#define IS_CACHED_MD 1 +#define IS_CACHED_MF 1 +#define IS_CACHED_CNAME 1 +#define IS_CACHED_SOA 1 +#define IS_CACHED_MB 1 +#define IS_CACHED_MG 1 +#define IS_CACHED_MR 1 +#define IS_CACHED_NULL 1 +#define IS_CACHED_WKS 1 +#define IS_CACHED_PTR 1 +#define IS_CACHED_HINFO 1 +#define IS_CACHED_MINFO 1 +#define IS_CACHED_MX 1 +#define IS_CACHED_TXT 1 +#define IS_CACHED_RP 1 +#define IS_CACHED_AFSDB 1 +#define IS_CACHED_X25 1 +#define IS_CACHED_ISDN 1 +#define IS_CACHED_RT 1 +#define IS_CACHED_NSAP 1 +#define IS_CACHED_NSAP_PTR 1 +#define IS_CACHED_SIG 1 +#define IS_CACHED_KEY 1 +#define IS_CACHED_PX 1 +#define IS_CACHED_GPOS 1 +#define IS_CACHED_AAAA 1 +#define IS_CACHED_LOC 1 +#define IS_CACHED_NXT 1 +#define IS_CACHED_EID 1 +#define IS_CACHED_NIMLOC 1 +#define IS_CACHED_SRV 1 +#define IS_CACHED_ATMA 1 +#define IS_CACHED_NAPTR 1 +#define IS_CACHED_KX 1 +#define IS_CACHED_CERT 1 +#define IS_CACHED_APL 1 +#define IS_CACHED_DS 1 +#define IS_CACHED_SSHFP 1 +#define IS_CACHED_IPSECKEY 1 +#define IS_CACHED_RRSIG 1 +#define IS_CACHED_NSEC 1 +#define IS_CACHED_DNSKEY 1 +#define IS_CACHED_DHCID 1 +#define IS_CACHED_NSEC3 1 +#define IS_CACHED_NSEC3PARAM 1 + +/* Array indices for most frequently used rr types. */ +#define RRMUINDEX_A 0 +#define RRMUINDEX_NS 1 +#define RRMUINDEX_CNAME 2 +#define RRMUINDEX_SOA 3 +#define RRMUINDEX_PTR 4 +#define RRMUINDEX_MX 5 +#define RRMUINDEX_TXT 6 +#define RRMUINDEX_AAAA 7 + +/* Table of rr names. */ +extern const char *const rrnames[T_NUM]; +#if DEFINE_RR_TYPE_ARRAYS +const char *const rrnames[T_NUM] = { + "A", + "NS", + "MD", + "MF", + "CNAME", + "SOA", + "MB", + "MG", + "MR", + "NULL", + "WKS", + "PTR", + "HINFO", + "MINFO", + "MX", + "TXT", + "RP", + "AFSDB", + "X25", + "ISDN", + "RT", + "NSAP", + "NSAP_PTR", + "SIG", + "KEY", + "PX", + "GPOS", + "AAAA", + "LOC", + "NXT", + "EID", + "NIMLOC", + "SRV", + "ATMA", + "NAPTR", + "KX", + "CERT", + "A6", + "DNAME", + "SINK", + "OPT", + "APL", + "DS", + "SSHFP", + "IPSECKEY", + "RRSIG", + "NSEC", + "DNSKEY", + "DHCID", + "NSEC3", + "NSEC3PARAM" +}; +#endif + +/* Structure for rr information */ +struct rr_infos { + unsigned short class; /* class (values see below) */ + unsigned short excludes; /* relations to other classes. + Mutual exclusion is marked by or'ing the + respective RRCL value in this field. + Exclusions should be symmetric. */ +}; + +/* Class values */ +#define RRCL_ALIAS 1 /* for CNAMES, conflicts with RRCL_RECORD */ +#define RRCL_RECORD 2 /* normal direct record */ +#define RRCL_IDEM 4 /* types that conflict with no others (MX, CNAME, ...) */ +#define RRCL_PTR 8 /* PTR */ + +/* Standard excludes for the classes */ +#define RRX_ALIAS (RRCL_RECORD|RRCL_PTR) +#define RRX_RECORD (RRCL_ALIAS|RRCL_PTR) +#define RRX_IDEM 0 +#define RRX_PTR (RRCL_ALIAS|RRCL_RECORD) + +/* There could be a separate table detailing the relationship of types, but this + * is slightly more flexible, as it allows a finer granularity of exclusion. Also, + * Membership in multiple classes could be added. + * Index by internally used RR-set indices, not RR type values! + */ +extern const struct rr_infos rr_info[NRRTOT]; +#if DEFINE_RR_TYPE_ARRAYS && !defined(CLIENT_ONLY) +const struct rr_infos rr_info[NRRTOT] = { + {RRCL_RECORD, RRX_RECORD} /* A */, + {RRCL_IDEM, RRX_IDEM} /* NS */, + {RRCL_ALIAS, RRX_ALIAS} /* CNAME */, + {RRCL_IDEM, RRX_IDEM} /* SOA */, + {RRCL_PTR, RRX_PTR} /* PTR */, + {RRCL_IDEM, RRX_IDEM} /* MX */, + {RRCL_IDEM, RRX_IDEM} /* TXT */, + {RRCL_RECORD, RRX_RECORD} /* AAAA */, + {RRCL_IDEM, RRX_IDEM} /* MD */, + {RRCL_IDEM, RRX_IDEM} /* MF */, + {RRCL_IDEM, RRX_IDEM} /* MB */, + {RRCL_IDEM, RRX_IDEM} /* MG */, + {RRCL_IDEM, RRX_IDEM} /* MR */, + {RRCL_IDEM, RRX_IDEM} /* NULL */, + {RRCL_RECORD, RRX_RECORD} /* WKS */, + {RRCL_RECORD, RRX_RECORD} /* HINFO */, + {RRCL_IDEM, RRX_IDEM} /* MINFO */, + {RRCL_RECORD, RRX_RECORD} /* RP */, + {RRCL_RECORD, RRX_RECORD} /* AFSDB */, + {RRCL_RECORD, RRX_RECORD} /* X25 */, + {RRCL_RECORD, RRX_RECORD} /* ISDN */, + {RRCL_RECORD, RRX_RECORD} /* RT */, + {RRCL_RECORD, RRX_RECORD} /* NSAP */, + {RRCL_PTR, RRX_PTR} /* NSAP_PTR */, + {RRCL_IDEM, RRX_IDEM} /* SIG */, + {RRCL_IDEM, RRX_IDEM} /* KEY */, + {RRCL_IDEM, RRX_IDEM} /* PX */, + {RRCL_RECORD, RRX_RECORD} /* GPOS */, + {RRCL_RECORD, RRX_RECORD} /* LOC */, + {RRCL_IDEM, RRX_IDEM} /* NXT */, + {RRCL_RECORD, RRX_RECORD} /* EID */, + {RRCL_RECORD, RRX_RECORD} /* NIMLOC */, + {RRCL_RECORD, RRX_RECORD} /* SRV */, + {RRCL_RECORD, RRX_RECORD} /* ATMA */, + {RRCL_RECORD, RRX_RECORD} /* NAPTR */, + {RRCL_RECORD, RRX_RECORD} /* KX */, + {RRCL_RECORD, RRX_RECORD} /* CERT */, + {RRCL_IDEM, RRX_IDEM} /* APL */, + {RRCL_IDEM, RRX_IDEM} /* DS */, + {RRCL_IDEM, RRX_IDEM} /* SSHFP */, + {RRCL_IDEM, RRX_IDEM} /* IPSECKEY */, + {RRCL_IDEM, RRX_IDEM} /* RRSIG */, + {RRCL_IDEM, RRX_IDEM} /* NSEC */, + {RRCL_IDEM, RRX_IDEM} /* DNSKEY */, + {RRCL_IDEM, RRX_IDEM} /* DHCID */, + {RRCL_IDEM, RRX_IDEM} /* NSEC3 */, + {RRCL_IDEM, RRX_IDEM} /* NSEC3PARAM */ +}; +#endif + +int rr_tp_byname(char *name); +const char *loc2str(const void *binary, char *ascii, size_t asclen); + +#endif diff --git a/jni/pdnsd/src/rr_types.in b/jni/pdnsd/src/rr_types.in new file mode 100644 index 00000000..5ebd2f37 --- /dev/null +++ b/jni/pdnsd/src/rr_types.in @@ -0,0 +1,99 @@ +# This file is part of the pdnsd package. + +# This file contains information about the RR types implemented in pdnsd +# and is used for generating rr_types.h. +# It was derived from the following source: http://www.bind9.net/dns-parameters +# +# After making modifications to this file the file rr_types.h should be regenerated! +# +# Info about the format of this file: +# Blank lines and lines starting with '#' are ignored, all other lines +# are assumed to define an RR type. Lines starting with '+' define most +# frequently used types. An RR type preceded by a '-' will not be cached +# by pdnsd. The next two fields are interpreted as the name and the value +# of the RR type, resp. A subsequent word in parenthesis will be interpreted a +# class name (used for conflict resolution). Remaining fields are ignored. +# +# Adding or removing an initial '+' can be done safely without requiring +# changes to the source code (other than regenerating rr_types.h). +# +# If you are sure that you will never use certain RR types you can disable +# caching for them and make pdnsd slightly more efficient by placing a +# '-' sign in front of the lines that define those types. +# For a list of obsolete RR types see e.g. +# http://en.wikipedia.org/wiki/List_of_DNS_record_types . +# Note that some RR types are essential for pdnsd; these are currently: +# A, NS, CNAME, SOA, PTR, MX and (if you want IPv6 support) AAAA. +# Disabling caching for these types will cause pdnsd to fail to compile +# or cause a fatal run-time error. +# +# Removing a '-' sign to enable caching can be risky if the support in +# the pdnsd code is missing or inadequate, so only do this if you really know +# what you are doing. SPF records are supported, however, so it should be safe +# to enable caching for them. + +# RR TYPE Value (class) and meaning Reference +# ----------- --------------------------------------------- --------- ++ A 1 (RECORD) a host address [RFC 1035] ++ NS 2 an authoritative name server [RFC 1035] + MD 3 a mail destination (Obsolete - use MX) [RFC 1035] + MF 4 a mail forwarder (Obsolete - use MX) [RFC 1035] ++ CNAME 5 (ALIAS) the canonical name for an alias [RFC 1035] ++ SOA 6 marks the start of a zone of authority [RFC 1035] + MB 7 a mailbox domain name (EXPERIMENTAL) [RFC 1035] + MG 8 a mail group member (EXPERIMENTAL) [RFC 1035] + MR 9 a mail rename domain name (EXPERIMENTAL) [RFC 1035] + NULL 10 a null RR (EXPERIMENTAL) [RFC 1035] + WKS 11 (RECORD) a well known service description [RFC 1035] ++ PTR 12 (PTR) a domain name pointer [RFC 1035] + HINFO 13 (RECORD) host information [RFC 1035] + MINFO 14 mailbox or mail list information [RFC 1035] ++ MX 15 mail exchange [RFC 1035] ++ TXT 16 text strings [RFC 1035] + RP 17 (RECORD) for Responsible Person [RFC 1183] + AFSDB 18 (RECORD) for AFS Data Base location [RFC 1183][RFC 5864] + X25 19 (RECORD) for X.25 PSDN address [RFC 1183] + ISDN 20 (RECORD) for ISDN address [RFC 1183] + RT 21 (RECORD) for Route Through [RFC 1183] + NSAP 22 (RECORD) for NSAP address, NSAP style A record [RFC 1706] + NSAP-PTR 23 (PTR) for domain name pointer, NSAP style [RFC 1348] + SIG 24 for security signature [RFC 4034][RFC 3755][RFC 2535] + KEY 25 for security key [RFC 4034][RFC 3755][RFC 2535] + PX 26 X.400 mail mapping information [RFC 2163] + GPOS 27 (RECORD) Geographical Position [RFC 1712] ++ AAAA 28 (RECORD) IP6 Address [RFC 3596] + LOC 29 (RECORD) Location Information [RFC 1876] + NXT 30 Next Domain - OBSOLETE [RFC 3755][RFC 2535] + EID 31 (RECORD) Endpoint Identifier [Patton] + NIMLOC 32 (RECORD) Nimrod Locator [Patton] + SRV 33 (RECORD) Server Selection [RFC 2782] + ATMA 34 (RECORD) ATM Address [ATMDOC] + NAPTR 35 (RECORD) Naming Authority Pointer [RFC 2915][RFC 2168][RFC 3403] + KX 36 (RECORD) Key Exchanger [RFC 2230] + CERT 37 (RECORD) CERT [RFC 4398] +- A6 38 A6 (Experimental) [RFC 3226][RFC 2874] +- DNAME 39 (ALIAS) DNAME [RFC 2672] +- SINK 40 SINK [Eastlake] +- OPT 41 OPT [RFC 2671] + APL 42 APL [RFC 3123] + DS 43 Delegation Signer [RFC 4034][RFC 3658] + SSHFP 44 SSH Key Fingerprint [RFC 4255] + IPSECKEY 45 IPSECKEY [RFC 4025] + RRSIG 46 RRSIG [RFC 4034][RFC 3755] + NSEC 47 NSEC [RFC 4034][RFC 3755] + DNSKEY 48 DNSKEY [RFC 4034][RFC 3755] + DHCID 49 DHCID [RFC 4701] + NSEC3 50 NSEC3 [RFC 5155] + NSEC3PARAM 51 NSEC3PARAM [RFC 5155] +# Unassigned 52-54 +- HIP 55 Host Identity Protocol [RFC 5205] +- NINFO 56 NINFO [Reid] +- RKEY 57 RKEY [Reid] +- TALINK 58 Trust Anchor LINK [Wijngaards] +# Unassigned 59-98 +- SPF 99 Sender Policy Framework [RFC 4408] +- UINFO 100 [IANA-Reserved] +- UID 101 [IANA-Reserved] +- GID 102 [IANA-Reserved] +- UNSPEC 103 [IANA-Reserved] +# Unassigned 104-248 diff --git a/jni/pdnsd/src/servers.c b/jni/pdnsd/src/servers.c new file mode 100644 index 00000000..8549865a --- /dev/null +++ b/jni/pdnsd/src/servers.c @@ -0,0 +1,856 @@ +/* servers.c - manage a set of dns servers + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2005, 2007, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" +#include "error.h" +#include "servers.h" +#include "conff.h" +#include "consts.h" +#include "icmp.h" +#include "netdev.h" +#include "helpers.h" +#include "dns_query.h" + + +/* + * We may be a little over-strict with locks here. Never mind... + * Also, there may be some code-redundancy regarding uptests. It saves some locks, though. + */ + +static pthread_mutex_t servers_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t server_data_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t server_test_cond = PTHREAD_COND_INITIALIZER; +static int server_data_users = 0, server_status_ping = 0; +/* Used to notify the server status thread that it should discontinue uptests. */ +volatile int signal_interrupt=0; +#define statusintsig SIGHUP + +static short retest_flag=0; + +static char schm[32]; + +static void sigint_handler(int signum); + +/* + * Execute an individual uptest. Call with locks applied + */ +static int uptest (servparm_t *serv, int j) +{ + int ret=0, count_running_ping=0; + pdnsd_a *s_addr= PDNSD_A2_TO_A(&DA_INDEX(serv->atup_a,j).a); + + DEBUG_PDNSDA_MSG("performing uptest (type=%s) for %s\n",const_name(serv->uptest),PDNSDA2STR(s_addr)); + + /* Unlock the mutex because some of the tests may take a while. */ + ++server_data_users; + if((serv->uptest==C_PING || serv->uptest==C_QUERY) && pthread_equal(pthread_self(),servstat_thrid)) { + /* Inform other threads that a ping is in progress. */ + count_running_ping=1; + ++server_status_ping; + } + pthread_mutex_unlock(&servers_lock); + + switch (serv->uptest) { + case C_NONE: + /* Don't change */ + ret=DA_INDEX(serv->atup_a,j).is_up; + break; + case C_PING: + ret=ping(is_inaddr_any(&serv->ping_a) ? s_addr : &serv->ping_a, serv->ping_timeout,PINGREPEAT)!=-1; + break; + case C_IF: + case C_DEV: + case C_DIALD: + ret=if_up(serv->interface); +#if (TARGET==TARGET_LINUX) + if (ret!=0) { + if(serv->uptest==C_DEV) + ret=dev_up(serv->interface,serv->device); + else if (serv->uptest==C_DIALD) + ret=dev_up("diald",serv->device); + } +#endif + break; + case C_EXEC: { + pid_t pid; + + if ((pid=fork())==-1) { + DEBUG_MSG("Could not fork to perform exec uptest: %s\n",strerror(errno)); + break; + } else if (pid==0) { /* child */ + /* + * If we ran as setuid or setgid, do not inherit this to the + * command. This is just a last guard. Running pdnsd as setuid() + * or setgid() is a no-no. + */ + if (setgid(getgid()) == -1 || setuid(getuid()) == -1) { + log_error("Could not reset uid or gid: %s",strerror(errno)); + _exit(1); + } + /* Try to setuid() to a different user as specified. Good when you + don't want the test command to run as root */ + if (!run_as(serv->uptest_usr)) { + _exit(1); + } + { + struct rlimit rl; int i; + /* + * Mark all open fd's FD_CLOEXEC for paranoia reasons. + */ + if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { + log_error("getrlimit() failed: %s",strerror(errno)); + _exit(1); + } + for (i = 0; i < rl.rlim_max; i++) { + if (fcntl(i, F_SETFD, FD_CLOEXEC) == -1 && errno != EBADF) { + log_error("fcntl(F_SETFD) failed: %s",strerror(errno)); + _exit(1); + } + } + } + execl("/bin/sh", "uptest_sh","-c",serv->uptest_cmd,(char *)NULL); + _exit(1); /* failed execl */ + } else { /* parent */ + int status; + pid_t wpid = waitpid(pid,&status,0); + if (wpid==pid) { + if(WIFEXITED(status)) { + int exitstatus=WEXITSTATUS(status); + DEBUG_MSG("uptest command \"%s\" exited with status %d\n", + serv->uptest_cmd, exitstatus); + ret=(exitstatus==0); + } +#if DEBUG>0 + else if(WIFSIGNALED(status)) { + DEBUG_MSG("uptest command \"%s\" was terminated by signal %d\n", + serv->uptest_cmd, WTERMSIG(status)); + } + else { + DEBUG_MSG("status of uptest command \"%s\" is of unkown type (0x%x)\n", + serv->uptest_cmd, status); + } +#endif + } +#if DEBUG>0 + else if (wpid==-1) { + DEBUG_MSG("Error while waiting for uptest command \"%s\" to terminate: " + "waitpid for pid %d failed: %s\n", + serv->uptest_cmd, pid, strerror(errno)); + } + else { + DEBUG_MSG("Error while waiting for uptest command \"%s\" to terminate: " + "waitpid returned %d, expected pid %d\n", + serv->uptest_cmd, wpid, pid); + } +#endif + } + } + break; + case C_QUERY: + ret=query_uptest(s_addr, serv->port, serv->query_test_name, + serv->timeout>=global.timeout?serv->timeout:global.timeout, + PINGREPEAT); + } /* end of switch */ + + pthread_mutex_lock(&servers_lock); + if(count_running_ping) + --server_status_ping; + PDNSD_ASSERT(server_data_users>0, "server_data_users non-positive before attempt to decrement it"); + if (--server_data_users==0) pthread_cond_broadcast(&server_data_cond); + + DEBUG_PDNSDA_MSG("result of uptest for %s: %s\n", + PDNSDA2STR(s_addr), + ret?"OK":"failed"); + return ret; +} + +static int scheme_ok(servparm_t *serv) +{ + if (serv->scheme[0]) { + if (!schm[0]) { + ssize_t nschm; + int sc = open(global.scheme_file, O_RDONLY); + char *s; + if (sc<0) + return 0; + nschm = read(sc, schm, sizeof(schm)-1); + close(sc); + if (nschm < 0) + return 0; + schm[nschm] = '\0'; + s = strchr(schm, '\n'); + if (s) + *s='\0'; + } + if (fnmatch(serv->scheme, schm, 0)) + return 0; + } + return 1; +} + +/* Internal server test. Call with locks applied. + May test a single server ip or several collectively. + */ +static void retest(int i, int j) +{ + time_t s_ts; + servparm_t *srv=&DA_INDEX(servers,i); + int nsrvs=DA_NEL(srv->atup_a); + + if(!nsrvs) return; + if(j>=0) { + if(jatup_a,j); + at->is_up=0; + at->i_ts=s_ts; + } + } + else if(srv->uptest==C_NONE) { + s_ts=time(NULL); + + for(;jatup_a,j).i_ts=s_ts; + } + } + else if(srv->uptest==C_QUERY || (srv->uptest==C_PING && is_inaddr_any(&srv->ping_a))) { /* test each ip address separately */ + for(;jatup_a,j); + s_ts=time(NULL); + at->is_up=uptest(srv,j); + if(signal_interrupt) + break; + at->i_ts=s_ts; + } + } + else { /* test ip addresses collectively */ + int res; + + s_ts=time(NULL); + res=uptest(srv,j); + for(;jatup_a,j); + at->is_up=res; + if(signal_interrupt && srv->uptest==C_PING) + continue; + at->i_ts=s_ts; + } + } +} + + +/* This is called by the server status thread to discover the addresses of root servers. + Call with server_lock applied. +*/ +static addr2_array resolv_rootserver_addrs(atup_array a, int port, char edns_query, time_t timeout) +{ + addr2_array retval=NULL; + + /* Unlock the mutex because this may take a while. */ + ++server_data_users; + pthread_mutex_unlock(&servers_lock); + + retval= dns_rootserver_resolv(a,port,edns_query,timeout); + + pthread_mutex_lock(&servers_lock); + PDNSD_ASSERT(server_data_users>0, "server_data_users non-positive before attempt to decrement it"); + if (--server_data_users==0) pthread_cond_broadcast(&server_data_cond); + + return retval; +} + +/* + * Refresh the server status by pinging or testing the interface in the given interval. + * Note that you may get inaccuracies in the dimension of the ping timeout or the runtime + * of your uptest command if you have uptest=ping or uptest=exec for at least one server. + * This happens when all the uptests for the first n servers take more time than the inteval + * of n+1 (or 0 when n+1>servnum). I do not think that these delays are critical, so I did + * not to anything about that (because that may also be costly). + */ +void *servstat_thread(void *p) +{ + struct sigaction action; + int keep_testing; + + /* (void)p; */ /* To inhibit "unused variable" warning */ + + THREAD_SIGINIT; + + pthread_mutex_lock(&servers_lock); + /* servstat_thrid=pthread_self(); */ + + signal_interrupt=0; + action.sa_handler = sigint_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + if(sigaction(statusintsig, &action, NULL) == 0) { + sigset_t smask; + sigemptyset(&smask); + sigaddset(&smask, statusintsig); + pthread_sigmask(SIG_UNBLOCK,&smask,NULL); + } + else { + log_warn("Cannot install signal handler for server status thread: %s\n",strerror(errno)); + } + + for(;;) { + do { + int i,n; + keep_testing=0; + retest_flag=0; + schm[0] = '\0'; + n=DA_NEL(servers); + for (i=0;irootserver==2) { + /* First get addresses of root servers. */ + addr2_array adrs; + int l, one_up=0; + + if(!scheme_ok(sp)) { + time_t now=time(NULL); + m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j).i_ts=now; + } else if(sp->uptest==C_PING || sp->uptest==C_QUERY) { + /* Skip ping or query tests until after discovery. */ + if(sp->interval>0) + one_up= DA_NEL(sp->atup_a); + else { + time_t now=time(NULL); + m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j); + if(at->is_up || at->i_ts==0) + one_up=1; + at->i_ts=now; + } + } + } + else { + retest(i,-1); + + m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j).is_up) { + one_up=1; + break; + } + } + } + + if(!one_up) { + if (needs_intermittent_testing(sp)) keep_testing=1; + continue; + } + + DEBUG_MSG("Attempting to discover root servers for server section #%d.\n",i); + adrs=resolv_rootserver_addrs(sp->atup_a,sp->port,sp->edns_query,sp->timeout); + l= DA_NEL(adrs); + if(l>0) { + struct timeval now; + struct timespec timeout; + atup_array ata; + DEBUG_MSG("Filling server section #%d with %d root server addresses.\n",i,l); + gettimeofday(&now,NULL); + timeout.tv_sec = now.tv_sec + 60; /* time out after 60 seconds */ + timeout.tv_nsec = now.tv_usec * 1000; + while (server_data_users>0) { + if(pthread_cond_timedwait(&server_data_cond, &servers_lock, &timeout) == ETIMEDOUT) { + DEBUG_MSG("Timed out while waiting for exclusive access to server data" + " to set root server addresses of server section #%d\n",i); + da_free(adrs); + keep_testing=1; + continue; + } + } + ata = DA_CREATE(atup_array, l); + if(!ata) { + log_warn("Out of memory in servstat_thread() while discovering root servers."); + da_free(adrs); + keep_testing=1; + continue; + } + for(j=0; ja = DA_INDEX(adrs,j); + at->is_up=sp->preset; + at->i_ts= sp->interval<0 ? time(NULL): 0; + } + da_free(sp->atup_a); + sp->atup_a=ata; + da_free(adrs); + /* Successfully set IP addresses for this server section. */ + sp->rootserver=1; + } + else { + DEBUG_MSG("Failed to discover root servers in servstat_thread() (server section #%d).\n",i); + if(adrs) da_free(adrs); + if(DA_NEL(sp->atup_a)) keep_testing=1; + continue; + } + } + + if (needs_testing(sp)) keep_testing=1; + m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j).i_ts) + goto individual_tests; + /* Test collectively */ + if(!signal_interrupt) retest(i,-1); + continue; + + individual_tests: + for(j=0; !signal_interrupt && jatup_a,j).i_ts, now; + + if (ts==0 /* Always test servers with timestamp 0 */ || + (needs_intermittent_testing(sp) && + ((now=time(NULL))-ts>sp->interval || + ts>now /* kluge for clock skew */))) + { + retest(i,j); + } + } + } + } while(!signal_interrupt && retest_flag); + + signal_interrupt=0; + + /* Break the loop and exit the thread if it is no longer needed. */ + if(!keep_testing) break; + + { + struct timeval now; + struct timespec timeout; + time_t minwait; + int i,n,retval; + + gettimeofday(&now,NULL); + minwait=3600; /* Check at least once every hour. */ + n=DA_NEL(servers); + for (i=0;iatup_a); + for(j=0;jatup_a,j).i_ts; + if(ts==0) { + /* Test servers with timestamp 0 without delay */ + if(minwait > 0) minwait=0; + } + else if(needs_intermittent_testing(sp)) { + time_t wait= ts + sp->interval - now.tv_sec; + if(wait < minwait) minwait=wait; + } + } + } + timeout.tv_sec = now.tv_sec; + if(minwait>0) + timeout.tv_sec += minwait; + timeout.tv_nsec = now.tv_usec * 1000 + 500000000; /* wait at least half a second. */ + if(timeout.tv_nsec>=1000000000) { + timeout.tv_nsec -= 1000000000; + ++timeout.tv_sec; + } + /* While we wait for a server_test_cond condition or a timeout + the servers_lock mutex is unlocked, so other threads can access + server data + */ + retval=pthread_cond_timedwait(&server_test_cond, &servers_lock, &timeout); + DEBUG_MSG("Server status thread woke up (%s signal).\n", + retval==0?"test condition":retval==ETIMEDOUT?"timer":retval==EINTR?"interrupt":"error"); + } + } + + /* server status thread no longer needed. */ + servstat_thrid=main_thrid; + pthread_mutex_unlock(&servers_lock); + DEBUG_MSG("Server status thread exiting.\n"); + return NULL; +} + +/* + * Start the server status thread. + */ +int start_servstat_thread() +{ + pthread_t stt; + + int rv=pthread_create(&stt,&attr_detached,servstat_thread,NULL); + if (rv) + log_warn("Failed to start server status thread: %s",strerror(rv)); + else { + servstat_thrid=stt; + log_info(2,"Server status thread started."); + } + return rv; +} + +/* + * This can be used to mark a server (or a list of nadr servers) up (up=1) or down (up=0), + * or to schedule an immediate retest (up=-1). + * We can't always use indices to identify a server, because we allow run-time + * configuration of server addresses, so the servers are identified by their IP addresses. + */ +void sched_server_test(pdnsd_a *sa, int nadr, int up) +{ + int k,signal_test; + + pthread_mutex_lock(&servers_lock); + + signal_test=0; + /* This obviously isn't very efficient, but nadr should be small + and anything else would introduce considerable overhead */ + for(k=0;katup_a); + for(j=0;jatup_a,j); + if(equiv_inaddr2(sak,&at->a)) { + if(up>=0) { + at->is_up=up; + at->i_ts=time(NULL); + DEBUG_PDNSDA_MSG("Marked server %s %s.\n",PDNSDA2STR(sak),up?"up":"down"); + } + else if(at->i_ts) { + /* A test may take a while, and we don't want to hold + up the calling thread. + Instead we set the timestamp to zero and signal + a condition which should wake up the server test thread. + */ + at->i_ts=0; + signal_test=1; + } + } + } + } + } + if(signal_test) pthread_cond_signal(&server_test_cond); + + pthread_mutex_unlock(&servers_lock); +} + +/* Mark a set of servers up or down or schedule uptests. + * If i>=0 only the server section with index i is scanned, + * if i<0 all sections are scanned. + * Only sections matching label are actually set. A NULL label matches + * any section. + * up=1 or up=0 means mark server up or down, up=-1 means retest. + * + * A non-zero return value indicates an error. + */ +int mark_servers(int i, char *label, int up) +{ + int retval=0,n,signal_test; + + pthread_mutex_lock(&servers_lock); + + signal_test=0; + n=DA_NEL(servers); + if(i>=0) { + /* just one section */ + if(ilabel && !strcmp(sp->label,label))) { + int j,m=DA_NEL(sp->atup_a); + + /* If a section with undiscovered root servers is marked up, signal a test. */ + if(m && sp->rootserver>1 && up>0) signal_test=1; + + for(j=0;jatup_a,j); + if(up>=0) { + at->is_up=up; + at->i_ts=time(NULL); + } + else if(at->i_ts) { + /* A test may take a while, and we don't want to hold + up the calling thread. + Instead we set the timestamp to zero and signal + a condition which should wake up the server test thread. + */ + at->i_ts=0; + signal_test=1; + } + } + } + } + if(signal_test) { + if(pthread_equal(servstat_thrid,main_thrid)) + retval=start_servstat_thread(); + else { + retest_flag=1; + retval=pthread_cond_signal(&server_test_cond); + } + } + + pthread_mutex_unlock(&servers_lock); + return retval; +} + +/* + * Test called by the dns query handlers to handle interval=onquery cases. + */ +void test_onquery() +{ + int i,n,signal_test; + + pthread_mutex_lock(&servers_lock); + schm[0] = '\0'; + signal_test=0; + n=DA_NEL(servers); + for (i=0;iinterval==-1) { + if(sp->rootserver<=1) + retest(i,-1); + else { + /* We leave root-server discovery to the server status thread */ + int j,m=DA_NEL(sp->atup_a); + for(j=0;jatup_a,j).i_ts=0; + signal_test=1; + } + } + } + + if(signal_test) { + int rv; + if(pthread_equal(servstat_thrid,main_thrid)) + start_servstat_thread(); + else { + retest_flag=1; + if((rv=pthread_cond_signal(&server_test_cond))) { + DEBUG_MSG("test_onquery(): couldn't signal server status thread: %s\n",strerror(rv)); + } + } + } + + pthread_mutex_unlock(&servers_lock); +} + +/* non-exclusive lock, for read only access to server data. */ +void lock_server_data() +{ + pthread_mutex_lock(&servers_lock); + ++server_data_users; + pthread_mutex_unlock(&servers_lock); +} + +void unlock_server_data() +{ + pthread_mutex_lock(&servers_lock); + PDNSD_ASSERT(server_data_users>0, "server_data_users non-positive before attempt to decrement it"); + if (--server_data_users==0) pthread_cond_broadcast(&server_data_cond); + pthread_mutex_unlock(&servers_lock); +} + +/* Try to obtain an exclusive lock, needed for modifying server data. + Return 1 on success, 0 on failure (time out after tm seconds). +*/ +int exclusive_lock_server_data(int tm) +{ + struct timeval now; + struct timespec timeout; + + pthread_mutex_lock(&servers_lock); + if(server_status_ping>0 && !pthread_equal(servstat_thrid,main_thrid)) { + int err; + /* Try to interrupt server status thread to prevent delays. */ + DEBUG_MSG("Sending server status thread an interrupt signal.\n"); + if((err=pthread_kill(servstat_thrid,statusintsig))) { + DEBUG_MSG("pthread_kill failed: %s\n",strerror(err)); + } + } + gettimeofday(&now,NULL); + timeout.tv_sec = now.tv_sec + tm; /* time out after tm seconds */ + timeout.tv_nsec = now.tv_usec * 1000; + while (server_data_users>0) { + if(pthread_cond_timedwait(&server_data_cond, &servers_lock, &timeout) == ETIMEDOUT) { + pthread_mutex_unlock(&servers_lock); + return 0; + } + } + return 1; +} +/* Call this to free the lock obtained with exclusive_lock_server_data(). + If retest is nonzero, the server-status thread is reactivated to check + which servers are up. This is useful in case the configuration has changed. +*/ +void exclusive_unlock_server_data(int retest) +{ + if(retest) { + if(pthread_equal(servstat_thrid,main_thrid)) + start_servstat_thread(); + else + pthread_cond_signal(&server_test_cond); + } + pthread_mutex_unlock(&servers_lock); +} + +/* + Change addresses of servers during runtime. + i is the number of the server section to change. + ar should point to an array of IP addresses (may be NULL). + up=1 or up=0 means mark server up or down afterwards, + up=-1 means retest. + + A non-zero return value indicates an error. +*/ +int change_servers(int i, addr_array ar, int up) +{ + int retval=0,j,change,signal_test; + int n; + servparm_t *sp; + + pthread_mutex_lock(&servers_lock); + + signal_test=0; + change=0; + n=DA_NEL(ar); + sp=&DA_INDEX(servers,i); + if(n != DA_NEL(sp->atup_a) || sp->rootserver>1) + change=1; + else { + int j; + for(j=0;jatup_a,j).a)) { + change=1; + break; + } + } + if(change) { + /* we need exclusive access to the server data to make the changes */ + struct timeval now; + struct timespec timeout; + atup_array ata; + + if(server_status_ping>0 && !pthread_equal(servstat_thrid,main_thrid)) { + int err; + /* Try to interrupt server status thread to prevent delays. */ + DEBUG_MSG("Sending server status thread an interrupt signal.\n"); + if((err=pthread_kill(servstat_thrid,statusintsig))) { + DEBUG_MSG("pthread_kill failed: %s\n",strerror(err)); + } + } + + DEBUG_MSG("Changing IPs of server section #%d\n",i); + gettimeofday(&now,NULL); + timeout.tv_sec = now.tv_sec + 60; /* time out after 60 seconds */ + timeout.tv_nsec = now.tv_usec * 1000; + while (server_data_users>0) { + if(pthread_cond_timedwait(&server_data_cond, &servers_lock, &timeout) == ETIMEDOUT) { + retval=ETIMEDOUT; + goto unlock_mutex; + } + } + + ata= DA_CREATE(atup_array, n); + if(!ata) { + log_warn("Out of memory in change_servers()."); + retval=ENOMEM; + goto unlock_mutex; + } + da_free(sp->atup_a); + sp->atup_a=ata; + /* Stop trying to discover rootservers + if we set the addresses using this routine. */ + if(sp->rootserver>1) sp->rootserver=1; + } + + for(j=0; jatup_a,j); + if(change) { + SET_PDNSD_A2(&at->a, &DA_INDEX(ar,j)); + at->is_up=sp->preset; + } + if(up>=0) { + at->is_up=up; + at->i_ts=time(NULL); + } + else if(change || at->i_ts) { + /* A test may take a while, and we don't want to hold + up the calling thread. + Instead we set the timestamp to zero and signal + a condition which should wake up the server test thread. + */ + at->i_ts=0; + signal_test=1; + } + } + + if(signal_test) { + if(pthread_equal(servstat_thrid,main_thrid)) + retval=start_servstat_thread(); + else { + retest_flag=1; + retval=pthread_cond_signal(&server_test_cond); + } + } + + unlock_mutex: + pthread_mutex_unlock(&servers_lock); + return retval; +} + + +/* + The signal handler for the signal to tell the server status thread to discontinue testing. +*/ +static void sigint_handler(int signum) +{ + signal_interrupt=1; +} diff --git a/jni/pdnsd/src/servers.h b/jni/pdnsd/src/servers.h new file mode 100644 index 00000000..fd263c0c --- /dev/null +++ b/jni/pdnsd/src/servers.h @@ -0,0 +1,68 @@ +/* servers.h - manage a set of dns servers + + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _SERVERS_H_ +#define _SERVERS_H_ + +#include +#include "consts.h" + +/* Number of ping timeouts before we take a server offline. */ +#define PINGREPEAT 2 + +extern pthread_t servstat_thrid; +extern volatile int signal_interrupt; + + +int start_servstat_thread(void); +void sched_server_test(pdnsd_a *sa, int nadr, int up); +int mark_servers(int i, char* label, int up); +void test_onquery(void); +void lock_server_data(); +void unlock_server_data(); +int exclusive_lock_server_data(int tm); +void exclusive_unlock_server_data(int retest); +int change_servers(int i, addr_array ar, int up); + +inline static int needs_testing(servparm_t *sp) + __attribute__((always_inline)); +inline static int needs_testing(servparm_t *sp) +{ + return ((sp->interval>0 || sp->interval==-2) && (sp->uptest!=C_NONE || sp->scheme[0])); +} + +inline static int needs_intermittent_testing(servparm_t *sp) + __attribute__((always_inline)); +inline static int needs_intermittent_testing(servparm_t *sp) +{ + return (sp->interval>0 && (sp->uptest!=C_NONE || sp->scheme[0])); +} + +inline static int is_interrupted_servstat_thread() + __attribute__((always_inline)); +inline static int is_interrupted_servstat_thread() +{ + return (signal_interrupt && pthread_equal(pthread_self(),servstat_thrid)); +} + +#endif diff --git a/jni/pdnsd/src/sort_namevalues.pl b/jni/pdnsd/src/sort_namevalues.pl new file mode 100644 index 00000000..2014f49f --- /dev/null +++ b/jni/pdnsd/src/sort_namevalues.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w + +use strict; + +my %dic; +my $maxkeylen=0; + +while(<>) { + if(/"(\w+)".*?(\w+)/) { + my $key=$1; my $val=$2; + if($dic{$key}) {die "The key \"$key\" does not have a unique value.\n"} + $dic{$key}=$val; + if(length($key)>$maxkeylen) {$maxkeylen=length($key)} + } + else {die "Can't find key-value pair in following line:\n$_\n"} +} + +my $linenr=0; +foreach my $key (sort(keys %dic)) { + if($linenr++) {print ",\n"} + printf("\t{%-*s%s}",$maxkeylen+4,"\"$key\",",$dic{$key}); +} +print "\n"; + +exit diff --git a/jni/pdnsd/src/status.c b/jni/pdnsd/src/status.c new file mode 100644 index 00000000..4240069d --- /dev/null +++ b/jni/pdnsd/src/status.c @@ -0,0 +1,824 @@ +/* status.c - Allow control of a running server using a socket + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2011 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#ifdef HAVE_ALLOCA_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for offsetof */ +#include "ipvers.h" +#include "status.h" +#include "thread.h" +#include "cache.h" +#include "error.h" +#include "servers.h" +#include "dns_answer.h" +#include "helpers.h" +#include "conf-parser.h" + +#if !defined(HAVE_ALLOCA) && !defined(alloca) +#define alloca malloc +#endif + + +char *sock_path=NULL; +int stat_sock; + + +/* Print an error to the socket */ +static int print_serr(int rs, const char *msg) +{ + uint16_t cmd; + + DEBUG_MSG("Sending error message to control socket: '%s'\n",msg); + cmd=htons(1); + if(write(rs,&cmd,sizeof(cmd))!=sizeof(cmd) || + write_all(rs,msg,strlen(msg))<0) + { + DEBUG_MSG("Error writing to control socket: %s\n",strerror(errno)); + return 0; + } + return 1; +} + +/* Print a success code to the socket */ +static int print_succ(int rs) +{ + uint16_t cmd; + + cmd=htons(0); + if(write(rs,&cmd,sizeof(cmd))!=sizeof(cmd)) { + DEBUG_MSG("Error writing to control socket: %s\n" + "Failed to send success code.\n",strerror(errno)); + return 0; + } + return 1; +} + +/* Read a cmd short */ +static int read_short(int fh, uint16_t *res) +{ + uint16_t cmd; + + if (read(fh,&cmd,sizeof(cmd))!=sizeof(cmd)) { + /* print_serr(fh,"Bad arg."); */ + return 0; + } + *res= ntohs(cmd); + return 1; +} + +/* Read a cmd long */ +static int read_long(int fh, uint32_t *res) +{ + uint32_t cmd; + + if (read(fh,&cmd,sizeof(cmd))!=sizeof(cmd)) { + /* print_serr(fh,"Bad arg."); */ + return 0; + } + *res= ntohl(cmd); + return 1; +} + +/* Read a string preceded by a char count. + A buffer of the right size is allocated to hold the result. + A return value of 1 means success, + -1 means the result is undefined (*res is set to NULL), + 0 means read or allocation error. +*/ +static int read_allocstring(int fh, char **res, unsigned *len) +{ + uint16_t count; + char *buf; + unsigned int nread; + + if(!read_short(fh,&count)) return 0; + if(count==(uint16_t)(~0)) {*res=NULL; return -1;} + if(!(buf=malloc(count+1))) return 0; + nread=0; + while(nread=buflen) return 0; + nread=0; + while(nread=buflen) return 0; + buf[count]='.'; buf[count+1]=0; + } +#endif + return 1; +} + +static void *status_thread (void *p) +{ + THREAD_SIGINIT; + /* (void)p; */ /* To inhibit "unused variable" warning */ + + if (!global.strict_suid) { + if (!run_as(global.run_as)) { + pdnsd_exit(); + } + } + + if (listen(stat_sock,5)==-1) { + log_warn("Error: could not listen on socket: %s.\nStatus readback will be impossible",strerror(errno)); + goto exit_thread; + } + for(;;) { + struct sockaddr_un ra; + socklen_t res=sizeof(ra); + int rs; + if ((rs=accept(stat_sock,(struct sockaddr *)&ra,&res))!=-1) { + uint16_t cmd; + DEBUG_MSG("Status socket query pending.\n"); + if (read_short(rs,&cmd)) { + /* Check magic number in command */ + if((cmd & 0xff00) == CTL_CMDVERNR) { + const char *errmsg; + cmd &= 0xff; + switch(cmd) { + case CTL_STATS: { + struct utsname nm; + DEBUG_MSG("Received STATUS query.\n"); + if(!print_succ(rs)) + break; + uname(&nm); + if(fsprintf(rs,"pdnsd-%s running on %s.\n",VERSION,nm.nodename)<0 || + report_cache_stat(rs)<0 || + report_thread_stat(rs)<0 || + report_conf_stat(rs)<0) + { + DEBUG_MSG("Error writing to control socket: %s\n" + "Failed to send status report.\n",strerror(errno)); + } + } + break; + case CTL_SERVER: { + char *label,*dnsaddr; + int indx; + uint16_t cmd2; + DEBUG_MSG("Received SERVER command.\n"); + if (read_allocstring(rs,&label,NULL)<=0) { + print_serr(rs,"Error reading server label."); + break; + } + if (!read_short(rs,&cmd2)) { + print_serr(rs,"Missing up|down|retest."); + goto free_label_break; + } + if(!read_allocstring(rs, &dnsaddr,NULL)) { + print_serr(rs,"Error reading DNS addresses."); + goto free_label_break; + } + /* Note by Paul Rombouts: + We are about to access server configuration data. + Now that the configuration can be changed during run time, + we should be using locks before accessing server config data, even if it + is read-only access. + However, as long as this is the only thread that calls reload_config_file() + it should be OK to read the server config without locks, but it is + something to keep in mind. + */ + { + char *endptr; + indx=strtol(label,&endptr,0); + if(!*endptr) { + if (indx<0 || indx>=DA_NEL(servers)) { + print_serr(rs,"Server index out of range."); + goto free_dnsaddr_label_break; + } + } + else { + if (!strcmp(label, "all")) + indx=-2; /* all servers */ + else + indx=-1; /* compare names */ + } + } + if(cmd2==CTL_S_UP || cmd2==CTL_S_DOWN || cmd2==CTL_S_RETEST) { + if(!dnsaddr) { + if (indx==-1) { + int i; + for (i=0;idomain=malloc(sz))) { + print_serr(rs,"Out of memory."); + goto free_sla_names_break; + } + memcpy(sl->domain,rhn,sz); + sl->exact=0; + sl->rule=tp; + p = q+1; + } + } + if(empty_cache(sla)) + print_succ(rs); + else + print_serr(rs,"Could not lock the cache."); + free_sla_names_break: + free_slist_array(sla); + free_names_break: + free(names); + } + break; + case CTL_DUMP: { + int rv,exact=0; + unsigned char *nm=NULL; + char buf[DNSNAMEBUFSIZE]; + unsigned char rhn[DNSNAMEBUFSIZE]; + DEBUG_MSG("Received DUMP command.\n"); + if (!(rv=read_domain(rs,buf,sizeof(buf)))) { + print_serr(rs,"Bad domain name."); + break; + } + if(rv>0) { + int sz; + exact=1; nm= ucharp buf; sz=sizeof(buf); + if(buf[0]=='.' && buf[1]) { + exact=0; ++nm; --sz; + } + if ((errmsg=parsestr2rhn(nm,sz,rhn))!=NULL) + goto bad_domain_name; + nm=rhn; + } + if(!print_succ(rs)) + break; + if((rv=dump_cache(rs,nm,exact))<0 || + (!rv && fsprintf(rs,"Could not find %s%s in the cache.\n", + exact?"":nm?"any entries matching ":"any entries", + nm?buf:"")<0)) + { + DEBUG_MSG("Error writing to control socket: %s\n",strerror(errno)); + } + } + break; + incomplete_command: + print_serr(rs,"Malformed or incomplete command."); + break; + bad_arg: + print_serr(rs,"Bad arg."); + break; + bad_domain_name: + print_serr(rs,errmsg); + break; + bad_ttl: + print_serr(rs, "Bad TTL."); + break; + bad_flags: + print_serr(rs, "Bad cache flags."); + break; + out_of_memory: + print_serr(rs,"Out of memory."); + break; + default: + print_serr(rs,"Unknown command."); + } + } + else { + DEBUG_MSG("Incorrect magic number in status-socket command code: %02x\n",cmd>>8); + print_serr(rs,"Command code contains incompatible version number."); + } + } + else { + DEBUG_MSG("short status-socket query\n"); + print_serr(rs,"Command code missing or too short."); + } + close(rs); + usleep_r(100000); /* sleep some time. I do not want the query frequency to be too high. */ + } + else if (errno!=EINTR) { + log_warn("Failed to accept connection on status socket: %s. " + "Status readback will be impossible",strerror(errno)); + break; + } + } + + exit_thread: + stat_pipe=0; + close(stat_sock); + statsock_thrid=main_thrid; + + return NULL; +} + +/* + * Initialize the status socket + */ +void init_stat_sock() +{ + struct sockaddr_un *sa; + /* Should I include the terminating null byte in the calculation of the length parameter + for the socket address? The glibc info page "Details of Local Namespace" tells me I should not, + yet it is immediately followed by an example that contradicts that. + The SUN_LEN macro seems to be defined as + (offsetof(struct sockaddr_un, sun_path) + strlen(sa->sun_path)), + so I conclude it is not necessary to count the null byte, but it probably makes no + difference if you do. + */ + unsigned int sa_len = (offsetof(struct sockaddr_un, sun_path) + strlitlen("/pdnsd.status") + strlen(global.cache_dir)); + + sa=(struct sockaddr_un *)alloca(sa_len+1); + stpcpy(stpcpy(sa->sun_path,global.cache_dir),"/pdnsd.status"); + + if (unlink(sa->sun_path)!=0 && errno!=ENOENT) { /* Delete the socket */ + log_warn("Failed to unlink %s: %s.\nStatus readback will be disabled",sa->sun_path, strerror(errno)); + stat_pipe=0; + return; + } + if ((stat_sock=socket(PF_UNIX,SOCK_STREAM,0))==-1) { + log_warn("Failed to open socket: %s. Status readback will be impossible",strerror(errno)); + stat_pipe=0; + return; + } + sa->sun_family=AF_UNIX; +#ifdef BSD44_SOCKA + sa->sun_len=SUN_LEN(sa); +#endif + /* Early initialization, so that umask can be used race-free. */ + { + mode_t old_mask = umask((S_IRWXU|S_IRWXG|S_IRWXO)&(~global.ctl_perms)); + if (bind(stat_sock,(struct sockaddr *)sa,sa_len)==-1) { + log_warn("Error: could not bind socket: %s.\nStatus readback will be impossible",strerror(errno)); + close(stat_sock); + stat_pipe=0; + } + umask(old_mask); + } + + if(stat_pipe) sock_path= strdup(sa->sun_path); +} + +/* + * Start the status socket thread (see above) + */ +int start_stat_sock() +{ + pthread_t st; + + int rv=pthread_create(&st,&attr_detached,status_thread,NULL); + if (rv) + log_warn("Failed to start status thread. The status socket will be unuseable"); + else { + statsock_thrid=st; + log_info(2,"Status thread started."); + } + return rv; +} diff --git a/jni/pdnsd/src/status.h b/jni/pdnsd/src/status.h new file mode 100644 index 00000000..1d249f79 --- /dev/null +++ b/jni/pdnsd/src/status.h @@ -0,0 +1,59 @@ +/* status.h - Make server status information accessible through a named pipe + + Copyright (C) 2000, 2001 Thomas Moestl + Copyright (C) 2002, 2004, 2008, 2009 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _STATUS_H_ +#define _STATUS_H_ + +#include +#include "conff.h" + +extern char *sock_path; +extern int stat_sock; + +/* The commands for pdnsd-ctl */ +#define CTL_CMDVERNR 0x6800 /* pdnsd-ctl command version (magic number used to check compatibility) */ + +#define CTL_MIN 1 +#define CTL_STATS 1 /* Give out stats (like the "traditional" status pipe) */ +#define CTL_SERVER 2 /* Enable or disable a server */ +#define CTL_RECORD 3 /* Delete or invalidate records */ +#define CTL_SOURCE 4 /* Read a hosts-style file */ +#define CTL_ADD 5 /* Add a record of the given type */ +#define CTL_NEG 6 /* Add a negative cached record */ +#define CTL_CONFIG 7 /* Re-read config file */ +#define CTL_INCLUDE 8 /* Read file as config file, disregarding global and server sections */ +#define CTL_EVAL 9 /* Parse string as if part of config file */ +#define CTL_EMPTY 10 /* Empty the cache */ +#define CTL_DUMP 11 /* Dump cache contents */ +#define CTL_MAX 11 + +#define CTL_S_UP 1 +#define CTL_S_DOWN 2 +#define CTL_S_RETEST 3 +#define CTL_R_DELETE 1 +#define CTL_R_INVAL 2 + +void init_stat_sock(void); +int start_stat_sock(void); + +#endif diff --git a/jni/pdnsd/src/test/Makefile.am b/jni/pdnsd/src/test/Makefile.am new file mode 100644 index 00000000..81da0882 --- /dev/null +++ b/jni/pdnsd/src/test/Makefile.am @@ -0,0 +1,35 @@ + +.PHONY: all clean distclean + +noinst_PROGRAMS = if_up is_local_addr tping random + +## Dirty trick: I demand that these objects be built; then, with the knowledge +## that the object files will end up here, I redefine the link chain. + +TESTADDSRC= +#TESTADDSRC= netdev.c error.c thread.c helpers.c icmp.c +TESTDEPS = netdev.o error.o thread.o helpers.o icmp.o + +TESTOBJS = netdev.o error.o thread.o helpers.o icmp.o + +if_up_SOURCES = if_up.c $(TESTADDSRC) +if_up_LDADD = $(TESTOBJS) @thread_CFLAGS@ +if_up_DEPENDENCIES = $(TESTDEPS) + +is_local_addr_SOURCES = is_local_addr.c $(TESTADDSRC) +is_local_addr_LDADD = $(TESTOBJS) @thread_CFLAGS@ +is_local_addr_DEPENDENCIES = $(TESTDEPS) + +tping_SOURCES = tping.c $(TESTADDSRC) +tping_LDADD = $(TESTOBJS) @thread_CFLAGS@ +tping_DEPENDENCIES = $(TESTDEPS) + +random_SOURCES = random.c $(TESTADDSRC) +random_LDADD = $(TESTOBJS) @thread_CFLAGS@ +random_DEPENDENCIES = $(TESTDEPS) + +# These are Symlinks we want to have in the package +#EXTRA_DIST = conff.h error.h helpers.h icmp.h ipvers.h netdev.h thread.h cacheing + +$(TESTOBJS): %.o: ../%.c + $(COMPILE) @thread_CFLAGS@ -c $< diff --git a/jni/pdnsd/src/test/Makefile.in b/jni/pdnsd/src/test/Makefile.in new file mode 100644 index 00000000..2ad86412 --- /dev/null +++ b/jni/pdnsd/src/test/Makefile.in @@ -0,0 +1,464 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +noinst_PROGRAMS = if_up$(EXEEXT) is_local_addr$(EXEEXT) tping$(EXEEXT) \ + random$(EXEEXT) +subdir = src/test +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am__objects_1 = +am_if_up_OBJECTS = if_up.$(OBJEXT) $(am__objects_1) +if_up_OBJECTS = $(am_if_up_OBJECTS) +am_is_local_addr_OBJECTS = is_local_addr.$(OBJEXT) $(am__objects_1) +is_local_addr_OBJECTS = $(am_is_local_addr_OBJECTS) +am_random_OBJECTS = random.$(OBJEXT) $(am__objects_1) +random_OBJECTS = $(am_random_OBJECTS) +am_tping_OBJECTS = tping.$(OBJEXT) $(am__objects_1) +tping_OBJECTS = $(am_tping_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(if_up_SOURCES) $(is_local_addr_SOURCES) $(random_SOURCES) \ + $(tping_SOURCES) +DIST_SOURCES = $(if_up_SOURCES) $(is_local_addr_SOURCES) \ + $(random_SOURCES) $(tping_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +cachedir = @cachedir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +def_id = @def_id@ +distribution = @distribution@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fullversion = @fullversion@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +packagerelease = @packagerelease@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +specbuild = @specbuild@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +thread_CFLAGS = @thread_CFLAGS@ +threadlib = @threadlib@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTADDSRC = +#TESTADDSRC= netdev.c error.c thread.c helpers.c icmp.c +TESTDEPS = netdev.o error.o thread.o helpers.o icmp.o +TESTOBJS = netdev.o error.o thread.o helpers.o icmp.o +if_up_SOURCES = if_up.c $(TESTADDSRC) +if_up_LDADD = $(TESTOBJS) @thread_CFLAGS@ +if_up_DEPENDENCIES = $(TESTDEPS) +is_local_addr_SOURCES = is_local_addr.c $(TESTADDSRC) +is_local_addr_LDADD = $(TESTOBJS) @thread_CFLAGS@ +is_local_addr_DEPENDENCIES = $(TESTDEPS) +tping_SOURCES = tping.c $(TESTADDSRC) +tping_LDADD = $(TESTOBJS) @thread_CFLAGS@ +tping_DEPENDENCIES = $(TESTDEPS) +random_SOURCES = random.c $(TESTADDSRC) +random_LDADD = $(TESTOBJS) @thread_CFLAGS@ +random_DEPENDENCIES = $(TESTDEPS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/test/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +if_up$(EXEEXT): $(if_up_OBJECTS) $(if_up_DEPENDENCIES) + @rm -f if_up$(EXEEXT) + $(LINK) $(if_up_OBJECTS) $(if_up_LDADD) $(LIBS) +is_local_addr$(EXEEXT): $(is_local_addr_OBJECTS) $(is_local_addr_DEPENDENCIES) + @rm -f is_local_addr$(EXEEXT) + $(LINK) $(is_local_addr_OBJECTS) $(is_local_addr_LDADD) $(LIBS) +random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) + @rm -f random$(EXEEXT) + $(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS) +tping$(EXEEXT): $(tping_OBJECTS) $(tping_DEPENDENCIES) + @rm -f tping$(EXEEXT) + $(LINK) $(tping_OBJECTS) $(tping_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if_up.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/is_local_addr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tping.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + + +.PHONY: all clean distclean + +# These are Symlinks we want to have in the package +#EXTRA_DIST = conff.h error.h helpers.h icmp.h ipvers.h netdev.h thread.h cacheing + +$(TESTOBJS): %.o: ../%.c + $(COMPILE) @thread_CFLAGS@ -c $< + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/jni/pdnsd/src/test/if_up.c b/jni/pdnsd/src/test/if_up.c new file mode 100644 index 00000000..af6ec976 --- /dev/null +++ b/jni/pdnsd/src/test/if_up.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include "../helpers.h" +#include "../conff.h" +#include "../netdev.h" + +short int daemon_p=0; +#if DEBUG>0 +short int debug_p=0; +#endif +short int verbosity=VERBOSITY; +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +short int run_ipv4=DEFAULT_IPV4; +#endif +#ifdef ENABLE_IPV6 +struct in6_addr ipv4_6_prefix; +#endif +pthread_t main_thrid,servstat_thrid; +volatile int signal_interrupt; +#if DEBUG>0 +FILE *dbg_file; +#endif +globparm_t global; + + +int main(int argc, char *argv[]) +{ + if (argc!=2) { + printf("Usage: %s \n",argv[0]); + exit(1); + } + printf("if_up: %s - %s\n",argv[1],if_up(argv[1])?"up":"down"); + return 0; +} diff --git a/jni/pdnsd/src/test/is_local_addr.c b/jni/pdnsd/src/test/is_local_addr.c new file mode 100644 index 00000000..fda517d6 --- /dev/null +++ b/jni/pdnsd/src/test/is_local_addr.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include "../helpers.h" +#include "../conff.h" +#include "../netdev.h" +#include "../ipvers.h" + +short int daemon_p=0; +#if DEBUG>0 +short int debug_p=0; +#endif +short int verbosity=VERBOSITY; +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +short int run_ipv4=DEFAULT_IPV4; +#endif +#ifdef ENABLE_IPV6 +struct in6_addr ipv4_6_prefix; +#endif +pthread_t main_thrid,servstat_thrid; +volatile int signal_interrupt; +#if DEBUG>0 +FILE *dbg_file; +#endif +globparm_t global; + + +int main(int argc, char *argv[]) +{ + pdnsd_a a; + + if (argc!=2) { + printf("Usage: %s
    \n",argv[0]); + exit(1); + } +#ifdef ENABLE_IPV4 + if (inet_aton(argv[1],&a.ipv4)) { +# ifdef ENABLE_IPV6 + run_ipv4=1; +# endif + printf("is %s a local addr: %s\n",argv[1],is_local_addr(&a)?"yes":"no"); + return 0; + } +#endif +#ifdef ENABLE_IPV6 + if (inet_pton(AF_INET6,argv[1],&a.ipv6)) { +# ifdef ENABLE_IPV4 + run_ipv4=0; +# endif + printf("is %s a local addr: %s\n",argv[1],is_local_addr(&a)?"yes":"no"); + return 0; + } +#endif + printf("Adress invalid.\n"); + return 0; +} diff --git a/jni/pdnsd/src/test/random.c b/jni/pdnsd/src/test/random.c new file mode 100644 index 00000000..a447e80c --- /dev/null +++ b/jni/pdnsd/src/test/random.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include "../helpers.h" +#include "../conff.h" + +short int daemon_p=0; +#if DEBUG>0 +short int debug_p=0; +#endif +short int verbosity=VERBOSITY; +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +short int run_ipv4=DEFAULT_IPV4; +#endif +#ifdef ENABLE_IPV6 +struct in6_addr ipv4_6_prefix; +#endif +pthread_t main_thrid,servstat_thrid; +volatile int signal_interrupt; +#if DEBUG>0 +FILE *dbg_file; +#endif +globparm_t global; + + +int main(void) +{ + init_rng(); + printf("%i\n",(int)get_rand16()); + free_rng(); + return 0; +} diff --git a/jni/pdnsd/src/test/tping.c b/jni/pdnsd/src/test/tping.c new file mode 100644 index 00000000..734a25f7 --- /dev/null +++ b/jni/pdnsd/src/test/tping.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include "../helpers.h" +#include "../conff.h" +#include "../icmp.h" +#include "../ipvers.h" + +short int daemon_p=0; +#if DEBUG>0 +short int debug_p=0; +#endif +short int verbosity=VERBOSITY; +#if defined(ENABLE_IPV4) && defined(ENABLE_IPV6) +short int run_ipv4=DEFAULT_IPV4; +#endif +#ifdef ENABLE_IPV6 +struct in6_addr ipv4_6_prefix; +#endif +pthread_t main_thrid,servstat_thrid; +volatile int signal_interrupt; +#if DEBUG>0 +FILE *dbg_file; +#endif +globparm_t global; + + +int main(int argc, char *argv[]) +{ + pdnsd_a a; + + if (argc!=2) { + printf("Usage: %s
    \n",argv[0]); + exit(1); + } +#ifdef ENABLE_IPV4 + if (inet_aton(argv[1],&a.ipv4)) { +# ifdef ENABLE_IPV6 + run_ipv4=1; +# endif + init_ping_socket(); + printf("ping (v4) echo from %s: %i\n",argv[1],ping(&a,100,2)); + return 0; + } +#endif +#ifdef ENABLE_IPV6 + if (inet_pton(AF_INET6,argv[1],&a.ipv6)) { +# ifdef ENABLE_IPV4 + run_ipv4=0; +# endif + init_ping_socket(); + printf("ping (v6) echo from %s: %i\n",argv[1],ping(&a,100,2)); + return 0; + } +#endif + printf("Adress invalid.\n"); + return 0; +} diff --git a/jni/pdnsd/src/thread.c b/jni/pdnsd/src/thread.c new file mode 100644 index 00000000..84c34f6d --- /dev/null +++ b/jni/pdnsd/src/thread.c @@ -0,0 +1,85 @@ +/* thread.c - Threading helpers + + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2002, 2003 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread.h" +#include "error.h" +#include "helpers.h" +#include "conff.h" + + +#if (TARGET==TARGET_LINUX) && !defined(THREADLIB_NPTL) +volatile short int waiting=0; /* Has the main thread already done sigwait() ? */ +#endif +pthread_attr_t attr_detached; +#if DEBUG>0 +pthread_key_t thrid_key; +#endif + +/* This is a handler for signals to the threads. We just hand the sigs on to the main thread. + * Note that this may result in blocked locks. We have no means to open the locks here, because in LinuxThreads + * the mutex functions are not async-signal safe. So, locks may still be active. We account for this by using + * softlocks (see below) in any functions called after sigwait from main(). */ +#if (TARGET==TARGET_LINUX) && !defined(THREADLIB_NPTL) +void thread_sig(int sig) +{ + if (sig==SIGTSTP || sig==SIGTTOU || sig==SIGTTIN) { + /* nonfatal signal. Ignore, because proper handling is very difficult. */ + return; + } + if (waiting) { + log_warn("Caught signal %i.",sig); + if (sig==SIGSEGV || sig==SIGILL || sig==SIGBUS) + crash_msg("A fatal signal occured."); + pthread_kill(main_thrid,SIGTERM); + pthread_exit(NULL); + } else { + crash_msg("An error occured at startup."); + _exit(1); + } +} +#endif + +/* This is now defined as an inline function in thread.h */ +#if 0 +void usleep_r(unsigned long usec) +{ +#if ((TARGET==TARGET_LINUX) || (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN)) && defined(HAVE_USLEEP) + usleep(usec); +#else + struct timeval tv; + + tv.tv_sec=usec/1000000; + tv.tv_usec=usec%1000000; + select(0, NULL, NULL, NULL, tv); +#endif +} +#endif + diff --git a/jni/pdnsd/src/thread.h b/jni/pdnsd/src/thread.h new file mode 100644 index 00000000..12d17dd1 --- /dev/null +++ b/jni/pdnsd/src/thread.h @@ -0,0 +1,143 @@ +/* thread.h - Threading helpers + + Copyright (C) 2000 Thomas Moestl + Copyright (C) 2002, 2003, 2005 Paul A. Rombouts + + This file is part of the pdnsd package. + + pdnsd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + pdnsd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with pdnsd; see the file COPYING. If not, see + . +*/ + + +#ifndef _THREAD_H_ +#define _THREAD_H_ + +#include +#include +#include + +/* --- from main.c */ +extern sigset_t sigs_msk; +/* --- */ + +#if (TARGET==TARGET_LINUX) && !defined(THREADLIB_NPTL) +extern volatile short int waiting; +void thread_sig(int sig); +#endif + +/* These are macros for setting up the signal handling of a new thread. They + * are needed because the LinuxThreads implementation obviously has some + * problems in signal handling, which makes the recommended solution (doing + * sigwait() in one thread and blocking the signals in all threads) impossible. + * So, for Linux, we have to install the fatal_sig handler. + * It seems to me that signal handlers in fact aren't shared between threads + * under Linux. Also, sigwait() does not seem to work as indicated in the docs */ + +/* Note added by Paul Rombouts: In the new Native POSIX Thread Library for Linux (NPTL) + signal handling has changed from per-thread signal handling to POSIX process signal handling, + which makes the recommended solution mentioned by Thomas Moestl possible. + In this case I can simply define THREAD_SIGINIT to be empty. + The signals are blocked in main() before any threads are created, + and we simply never unblock them except by calling sigwait() in main(). */ + +#if (TARGET==TARGET_LINUX) +# ifdef THREADLIB_NPTL +# define THREAD_SIGINIT +# else +# ifdef THREADLIB_LINUXTHREADS2 +# define THREAD_SIGINIT { \ + struct sigaction action; \ + pthread_sigmask(SIG_UNBLOCK,&sigs_msk,NULL); \ + action.sa_handler = thread_sig; \ + action.sa_mask = sigs_msk; \ + action.sa_flags = 0; \ + sigaction(SIGINT,&action,NULL); \ + sigaction(SIGILL,&action,NULL); \ + sigaction(SIGABRT,&action,NULL); \ + sigaction(SIGFPE,&action,NULL); \ + sigaction(SIGSEGV,&action,NULL); \ + sigaction(SIGTSTP,&action,NULL); \ + sigaction(SIGTTOU,&action,NULL); \ + sigaction(SIGTTIN,&action,NULL); \ + sigaction(SIGTERM,&action,NULL); \ + action.sa_handler = SIG_IGN; \ + sigemptyset(&action.sa_mask); \ + action.sa_flags = 0; \ + sigaction(SIGPIPE,&action,NULL); \ + } +# else +# define THREAD_SIGINIT { \ + struct sigaction action; \ + pthread_sigmask(SIG_UNBLOCK,&sigs_msk,NULL); \ + action.sa_handler = thread_sig; \ + action.sa_mask = sigs_msk; \ + action.sa_flags = 0; \ + sigaction(SIGILL,&action,NULL); \ + sigaction(SIGABRT,&action,NULL); \ + sigaction(SIGFPE,&action,NULL); \ + sigaction(SIGSEGV,&action,NULL); \ + sigaction(SIGTSTP,&action,NULL); \ + sigaction(SIGTTOU,&action,NULL); \ + sigaction(SIGTTIN,&action,NULL); \ + action.sa_handler = SIG_IGN; \ + sigemptyset(&action.sa_mask); \ + action.sa_flags = 0; \ + sigaction(SIGPIPE,&action,NULL); \ + } +# endif +# endif +#elif (TARGET==TARGET_BSD) || (TARGET==TARGET_CYGWIN) +#define THREAD_SIGINIT pthread_sigmask(SIG_BLOCK,&sigs_msk,NULL) +#else +# error Unsupported platform! +#endif + + +/* This is a thread-safe usleep(). + Implementation of the BSD usleep function using nanosleep. +*/ +inline static int usleep_r(unsigned long useconds) + __attribute__((always_inline)); +inline static int usleep_r(unsigned long useconds) +{ + struct timespec ts = { tv_sec: (useconds / 1000000), + tv_nsec: (useconds % 1000000) * 1000ul }; + + return nanosleep(&ts, NULL); +} + +/* This is a thread-safe sleep(). + The semantics are somewhat different from the POSIX sleep function, + but it suits our purposes. +*/ +inline static int sleep_r (unsigned int seconds) + __attribute__((always_inline)); +inline static int sleep_r (unsigned int seconds) +{ + struct timespec ts = { tv_sec: seconds, tv_nsec: 0 }; + + return nanosleep(&ts, NULL); +} + + +/* Used for creating detached threads */ +extern pthread_attr_t attr_detached; + +#if DEBUG>0 +/* Key for storing private thread ID's */ +extern pthread_key_t thrid_key; +#endif + +#endif diff --git a/jni/pdnsd/version b/jni/pdnsd/version new file mode 100644 index 00000000..c400a378 --- /dev/null +++ b/jni/pdnsd/version @@ -0,0 +1 @@ +1.2.9b-par diff --git a/libs/arm64-v8a/libtun2socks.so b/libs/arm64-v8a/libtun2socks.so index 9d5b3dd9..a505b69b 100755 Binary files a/libs/arm64-v8a/libtun2socks.so and b/libs/arm64-v8a/libtun2socks.so differ diff --git a/libs/arm64-v8a/pdnsd b/libs/arm64-v8a/pdnsd new file mode 100755 index 00000000..6fd98cae Binary files /dev/null and b/libs/arm64-v8a/pdnsd differ diff --git a/libs/armeabi-v7a/libtun2socks.so b/libs/armeabi-v7a/libtun2socks.so index 04174694..26b6d08d 100755 Binary files a/libs/armeabi-v7a/libtun2socks.so and b/libs/armeabi-v7a/libtun2socks.so differ diff --git a/libs/armeabi-v7a/pdnsd b/libs/armeabi-v7a/pdnsd new file mode 100755 index 00000000..88d8c850 Binary files /dev/null and b/libs/armeabi-v7a/pdnsd differ diff --git a/libs/armeabi/libtun2socks.so b/libs/armeabi/libtun2socks.so new file mode 100755 index 00000000..6eaf2ac3 Binary files /dev/null and b/libs/armeabi/libtun2socks.so differ diff --git a/libs/armeabi/pdnsd b/libs/armeabi/pdnsd new file mode 100755 index 00000000..902c4af4 Binary files /dev/null and b/libs/armeabi/pdnsd differ diff --git a/libs/mips/libtun2socks.so b/libs/mips/libtun2socks.so index ac42c4da..81c1722e 100755 Binary files a/libs/mips/libtun2socks.so and b/libs/mips/libtun2socks.so differ diff --git a/libs/mips/pdnsd b/libs/mips/pdnsd new file mode 100755 index 00000000..eaa18983 Binary files /dev/null and b/libs/mips/pdnsd differ diff --git a/libs/x86/libtun2socks.so b/libs/x86/libtun2socks.so index f80e6f72..0548a83a 100755 Binary files a/libs/x86/libtun2socks.so and b/libs/x86/libtun2socks.so differ diff --git a/libs/x86/pdnsd b/libs/x86/pdnsd new file mode 100755 index 00000000..c26cb120 Binary files /dev/null and b/libs/x86/pdnsd differ diff --git a/res/values/pdnsd.xml b/res/values/pdnsd.xml new file mode 100644 index 00000000..cb4e8025 --- /dev/null +++ b/res/values/pdnsd.xml @@ -0,0 +1,32 @@ + + + +global { + perm_cache=1024; + cache_dir="/data/data/org.torproject.android/app_bin"; + server_port = 8091; + server_ip = 0.0.0.0; + query_method=tcp_only; + min_ttl=15m; + max_ttl=1w; + timeout=10; + daemon=on; + pid_file="/data/data/org.torproject.android/app_bin/pdnsd.pid"; +} + +server { + label= "upstream"; + ip = %s; + port = %d; + uptest = none; +} + +rr { + name=localhost; + reverse=on; + a=127.0.0.1; + owner=localhost; + soa=localhost,root.localhost,42,86400,900,86400,86400; +} + + diff --git a/src/org/torproject/android/OrbotApp.java b/src/org/torproject/android/OrbotApp.java index 4ee1edbf..25818fa4 100644 --- a/src/org/torproject/android/OrbotApp.java +++ b/src/org/torproject/android/OrbotApp.java @@ -31,6 +31,8 @@ public class OrbotApp extends Application implements OrbotConstants public static File fileMeekclient; public static File fileXtables; public static File fileTorRc; + public static File filePdnsd; + @Override public void onCreate() { @@ -48,6 +50,9 @@ public class OrbotApp extends Application implements OrbotConstants fileMeekclient = new File(appBinHome, TorServiceConstants.MEEK_ASSET_KEY); fileXtables = new File(appBinHome, TorServiceConstants.IPTABLES_ASSET_KEY); fileTorRc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY); + filePdnsd = new File(appBinHome, TorServiceConstants.PDNSD_ASSET_KEY); + + } diff --git a/src/org/torproject/android/service/TorResourceInstaller.java b/src/org/torproject/android/service/TorResourceInstaller.java index 2f946a91..97e691cf 100644 --- a/src/org/torproject/android/service/TorResourceInstaller.java +++ b/src/org/torproject/android/service/TorResourceInstaller.java @@ -127,8 +127,8 @@ public class TorResourceInstaller implements TorServiceConstants { streamToFile(is,outFile, false, true); setExecutable(outFile); - is = context.getAssets().open(cpuPath + '/' + TUN2SOCKS_ASSET_KEY + MP3_EXT); - outFile = new File(installFolder, TUN2SOCKS_ASSET_KEY); + is = context.getAssets().open(cpuPath + '/' + PDNSD_ASSET_KEY + MP3_EXT); + outFile = new File(installFolder, PDNSD_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, true); setExecutable(outFile); diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index 952c732d..5513e780 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -647,8 +647,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon if (Prefs.useDebugLogging()) { extraLines.append("Log debug syslog").append('\n'); - extraLines.append("Log info syslog").append('\n'); - + extraLines.append("Log info syslog").append('\n'); + extraLines.append("SafeLogging 0").append('\n'); + //extraLines.append("Log debug stdout").append('\n'); } diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java index 6c8d546e..77b7a9bf 100644 --- a/src/org/torproject/android/service/TorServiceConstants.java +++ b/src/org/torproject/android/service/TorServiceConstants.java @@ -32,18 +32,15 @@ public interface TorServiceConstants { //geoip data file asset key public final static String GEOIP_ASSET_KEY = "geoip"; public final static String GEOIP6_ASSET_KEY = "geoip6"; - - //tun2socks VPN - public final static String TUN2SOCKS_ASSET_KEY = "tun2socks"; - //various console cmds public final static String SHELL_CMD_CHMOD = "chmod"; public final static String SHELL_CMD_KILL = "kill -9"; public final static String SHELL_CMD_RM = "rm"; public final static String SHELL_CMD_PS = "toolbox ps"; public final static String SHELL_CMD_PS_ALT = "ps"; - + + //public final static String SHELL_CMD_PIDOF = "pidof"; public final static String SHELL_CMD_LINK = "ln -s"; public final static String SHELL_CMD_CP = "cp"; @@ -135,14 +132,18 @@ public interface TorServiceConstants { public static final String CMD_VPN_CLEAR = "vpnclear"; public static final String CMD_UPDATE_TRANS_PROXY = "update"; - public static final String BINARY_TOR_VERSION = "0.2.7.5"; + public static final String BINARY_TOR_VERSION = "0.2.7.5-020120160125"; public static final String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED"; //obfsproxy public static final String OBFSCLIENT_ASSET_KEY = "obfs4proxy"; public static final String MEEK_ASSET_KEY = "meek-client"; + //name of the iptables binary public final static String IPTABLES_ASSET_KEY = "xtables"; + //DNS daemon for TCP DNS over TOr + public final static String PDNSD_ASSET_KEY = "pdnsd"; + } diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java index 709a3da4..64854238 100644 --- a/src/org/torproject/android/vpn/OrbotVpnService.java +++ b/src/org/torproject/android/vpn/OrbotVpnService.java @@ -16,13 +16,20 @@ package org.torproject.android.vpn; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; import java.net.InetAddress; import java.util.ArrayList; import java.util.Locale; +import java.util.concurrent.TimeoutException; import org.sufficientlysecure.rootcommands.Shell; import org.sufficientlysecure.rootcommands.command.SimpleCommand; import org.torproject.android.OrbotApp; +import org.torproject.android.R; import org.torproject.android.service.TorServiceConstants; import org.torproject.android.service.TorServiceUtils; import org.torproject.android.settings.AppManager; @@ -30,6 +37,7 @@ import org.torproject.android.settings.TorifiedApp; import android.annotation.TargetApi; import android.app.PendingIntent; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager.NameNotFoundException; @@ -64,6 +72,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + private final static String DEFAULT_ACTUAL_DNS = "208.67.222.222"; + private boolean isRestart = false; @Override @@ -245,11 +255,15 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { Thread.sleep(3000); } + //start PDNSD daemon pointing to OpenDNS + startDNS(DEFAULT_ACTUAL_DNS,53); + + final String vpnName = "OrbotVPN"; final String localhost = "127.0.0.1"; - // final String virtualGateway = "10.0.0.1"; - final String virtualIP = "192.168.10.1"; + final String virtualGateway = "10.10.10.1"; + final String virtualIP = "10.10.10.2"; final String virtualNetMask = "255.255.255.0"; final String dummyDNS = "8.8.8.8"; //this is intercepted by the tun2socks library, but we must put in a valid DNS to start final String defaultRoute = "0.0.0.0"; @@ -257,21 +271,25 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { final String localSocks = localhost + ':' + String.valueOf(TorServiceConstants.SOCKS_PROXY_PORT_DEFAULT); - final String localDNS = localhost + ':' + String.valueOf(TorServiceConstants.TOR_DNS_PORT_DEFAULT); + final String localDNS = virtualGateway + ':' + "8091";//String.valueOf(TorServiceConstants.TOR_DNS_PORT_DEFAULT); final boolean localDnsTransparentProxy = true; Builder builder = new Builder(); builder.setMtu(VPN_MTU); - builder.addAddress(virtualIP,24); - builder.setSession(vpnName); + builder.addAddress(virtualGateway,32); + builder.setSession(vpnName); + + builder.addDnsServer(dummyDNS); + builder.addRoute(dummyDNS,32); + //route all traffic through VPN (we might offer country specific exclude lists in the future) builder.addRoute(defaultRoute,0); - builder.addDnsServer(dummyDNS); - builder.addRoute(dummyDNS,32); - + //handle ipv6 + //builder.addAddress("fdfe:dcba:9876::1", 126); + //builder.addRoute("::", 0); if (mIsLollipop) doLollipopAppRouting(builder); @@ -313,19 +331,19 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { ArrayList apps = AppManager.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext())); - boolean appAllowed = false; + boolean perAppEnabled = false; for (TorifiedApp app : apps) { if (app.isTorified()) { builder.addAllowedApplication(app.getUsername()); - appAllowed = true; + perAppEnabled = true; } } - if (!appAllowed) + if (!perAppEnabled) builder.addDisallowedApplication(getPackageName()); } @@ -346,4 +364,50 @@ public class OrbotVpnService extends VpnService implements Handler.Callback { super.onRevoke(); } + private void startDNS (String dns, int port) throws IOException, TimeoutException + { + makePdnsdConf(this, dns, port,OrbotApp.filePdnsd.getParentFile() ); + + ArrayList customEnv = new ArrayList(); + String baseDirectory = OrbotApp.filePdnsd.getParent(); + Shell shell = Shell.startShell(customEnv, baseDirectory); + + String cmdString = OrbotApp.filePdnsd.getCanonicalPath() + + " -c " + baseDirectory + "/pdnsd.conf"; + + SimpleCommand shellCommand = new SimpleCommand(cmdString); + shell.add(shellCommand).waitForFinish(); + + + } + + public static void makePdnsdConf(Context context, String dns, int port, File fileDir) throws FileNotFoundException { + String conf = String.format(context.getString(R.string.pdnsd_conf), dns, port); + + File f = new File(fileDir,"pdnsd.conf"); + + if (f.exists()) { + f.delete(); + } + + FileOutputStream fos = new FileOutputStream(f, false); + PrintStream ps = new PrintStream(fos); + ps.print(conf); + ps.close(); + + //f.withWriter { out -> out.print conf }; + + + File cache = new File(fileDir,"pdnsd.cache"); + + if (!cache.exists()) { + try { + cache.createNewFile(); + } catch (Exception e) { + + } + } +} + + }