--- /dev/null
+APPLE PUBLIC SOURCE LICENSE
+Version 2.0 - August 6, 2003
+
+Please read this License carefully before downloading this software.
+By downloading or using this software, you are agreeing to be bound by
+the terms of this License. If you do not or cannot agree to the terms
+of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") makes publicly available and
+which contains a notice placed by Apple identifying such program or
+work as "Original Code" and stating that it is subject to the terms of
+this Apple Public Source License version 2.0 ("License"). As used in
+this License:
+
+1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.2 "Contributor" means any person or entity that creates or
+contributes to the creation of Modifications.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Externally Deploy" means: (a) to sublicense, distribute or
+otherwise make Covered Code available, directly or indirectly, to
+anyone other than You; and/or (b) to use Covered Code, alone or as
+part of a Larger Work, in any way to provide a service, including but
+not limited to delivery of content, through electronic communication
+with a client other than You.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of the Original Code, any previous
+Modifications, the combination of Original Code and any previous
+Modifications, and/or any respective portions thereof. When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License. For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non-exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 Unmodified Code. You may use, reproduce, display, perform,
+internally distribute within Your organization, and Externally Deploy
+verbatim, unmodified copies of the Original Code, for commercial or
+non-commercial purposes, provided that in each instance:
+
+(a) You must retain and reproduce in all copies of Original Code the
+copyright and other proprietary notices and disclaimers of Apple as
+they appear in the Original Code, and keep intact all notices in the
+Original Code that refer to this License; and
+
+(b) You must include a copy of this License with every copy of Source
+Code of Covered Code and documentation You distribute or Externally
+Deploy, and You may not offer or impose any terms on such Source Code
+that alter or restrict this License or the recipients' rights
+hereunder, except as permitted under Section 6.
+
+2.2 Modified Code. You may modify Covered Code and use, reproduce,
+display, perform, internally distribute within Your organization, and
+Externally Deploy Your Modifications and Covered Code, for commercial
+or non-commercial purposes, provided that in each instance You also
+meet all of these conditions:
+
+(a) You must satisfy all the conditions of Section 2.1 with respect to
+the Source Code of the Covered Code;
+
+(b) You must duplicate, to the extent it does not already exist, the
+notice in Exhibit A in each file of the Source Code of all Your
+Modifications, and cause the modified files to carry prominent notices
+stating that You changed the files and the date of any change; and
+
+(c) If You Externally Deploy Your Modifications, You must make
+Source Code of all Your Externally Deployed Modifications either
+available to those to whom You have Externally Deployed Your
+Modifications, or publicly available. Source Code of Your Externally
+Deployed Modifications must be released under the terms set forth in
+this License, including the license grants set forth in Section 3
+below, for as long as you Externally Deploy the Covered Code or twelve
+(12) months from the date of initial External Deployment, whichever is
+longer. You should preferably distribute the Source Code of Your
+Externally Deployed Modifications electronically (e.g. download from a
+web site).
+
+2.3 Distribution of Executable Versions. In addition, if You
+Externally Deploy Covered Code (Original Code and/or Modifications) in
+object code, executable form only, You must include a prominent
+notice, in the code itself as well as in related documentation,
+stating that Source Code of the Covered Code is available under the
+terms of this License with information on how and where to obtain such
+Source Code.
+
+2.4 Third Party Rights. You expressly acknowledge and agree that
+although Apple and each Contributor grants the licenses to their
+respective portions of the Covered Code set forth herein, no
+assurances are provided by Apple or any Contributor that the Covered
+Code does not infringe the patent or other intellectual property
+rights of any other entity. Apple and each Contributor disclaim any
+liability to You for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a
+condition to exercising the rights and licenses granted hereunder, You
+hereby assume sole responsibility to secure any other intellectual
+property rights needed, if any. For example, if a third party patent
+license is required to allow You to distribute the Covered Code, it is
+Your responsibility to acquire that license before distributing the
+Covered Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License, You hereby grant to any
+person or entity receiving or distributing Covered Code under this
+License a non-exclusive, royalty-free, perpetual, irrevocable license,
+under Your Applicable Patent Rights and other intellectual property
+rights (other than patent) owned or controlled by You, to use,
+reproduce, display, perform, modify, sublicense, distribute and
+Externally Deploy Your Modifications of the same scope and extent as
+Apple's licenses under Sections 2.1 and 2.2 above.
+
+4. Larger Works. You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product. In each such instance,
+You must make sure the requirements of this License are fulfilled for
+the Covered Code or any portion thereof.
+
+5. Limitations on Patent License. Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein. Modifications and/or Larger Works may require additional
+patent licenses from Apple which Apple may grant in its sole
+discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee for,
+warranty, support, indemnity or liability obligations and/or other
+rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered Code.
+However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple or any Contributor. You
+must obtain the recipient's agreement that any such Additional Terms
+are offered by You alone, and You hereby agree to indemnify, defend
+and hold Apple and every Contributor harmless for any liability
+incurred by or claims asserted against Apple or such Contributor by
+reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be given
+a distinguishing version number. Once Original Code has been published
+under a particular version of this License, You may continue to use it
+under the terms of that version. You may also choose to use such
+Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
+part pre-release, untested, or not fully tested works. The Covered
+Code may contain errors that could cause failures or loss of data, and
+may be incomplete or contain inaccuracies. You expressly acknowledge
+and agree that use of the Covered Code, or any portion thereof, is at
+Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
+WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
+APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
+PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
+ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
+MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
+PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
+INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
+FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
+THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
+ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
+ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
+AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
+You acknowledge that the Covered Code is not intended for use in the
+operation of nuclear facilities, aircraft navigation, communication
+systems, or air traffic control machines in which case the failure of
+the Covered Code could lead to death, personal injury, or severe
+physical or environmental damage.
+
+9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
+EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
+TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
+ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
+TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
+APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
+REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
+INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
+TO YOU. In no event shall Apple's total liability to You for all
+damages (other than as may be required by applicable law) under this
+License exceed the amount of fifty dollars ($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
+"QuickTime", "QuickTime Streaming Server" or any other trademarks,
+service marks, logos or trade names belonging to Apple (collectively
+"Apple Marks") or to any trademark, service mark, logo or trade name
+belonging to any Contributor. You agree not to use any Apple Marks in
+or as part of the name of products derived from the Original Code or
+to endorse or promote products derived from the Original Code other
+than as expressly permitted by and in strict compliance at all times
+with Apple's third party trademark usage guidelines which are posted
+at http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Subject to the licenses granted under this License,
+each Contributor retains all rights, title and interest in and to any
+Modifications made by such Contributor. Apple retains all rights,
+title and interest in and to the Original Code and any Modifications
+made by or on behalf of Apple ("Apple Modifications"), and such Apple
+Modifications will not be automatically subject to this License. Apple
+may, at its sole discretion, choose to license such Apple
+Modifications under this License, or on different terms from those
+contained in this License or may choose not to license them at all.
+
+12. Termination.
+
+12.1 Termination. This License and the rights granted hereunder will
+terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach;
+
+(b) immediately in the event of the circumstances described in Section
+13.5(b); or
+
+(c) automatically without notice from Apple if You, at any time during
+the term of this License, commence an action for patent infringement
+against Apple; provided that Apple did not first commence
+an action for patent infringement against You in that instance.
+
+12.2 Effect of Termination. Upon termination, You agree to immediately
+stop any further use, reproduction, modification, sublicensing and
+distribution of the Covered Code. All sublicenses to the Covered Code
+which have been properly granted prior to termination shall survive
+any termination of this License. Provisions which, by their nature,
+should remain in effect beyond the termination of this License shall
+survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
+12.2 and 13. No party will be liable to any other for compensation,
+indemnity or damages of any sort solely as a result of terminating
+this License in accordance with its terms, and termination of this
+License will be without prejudice to any other right or remedy of
+any party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights in
+the Covered Code include only those rights customarily provided to the
+public as defined in this License. This customary commercial license
+in technical data and software is provided in accordance with FAR
+12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation). Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties. This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between or among You, Apple or any Contributor, and
+You will not represent to the contrary, whether expressly, by
+implication, appearance or otherwise.
+
+13.3 Independent Development. Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction. Failure by Apple or any Contributor to
+enforce any provision of this License will not be deemed a waiver of
+future enforcement of that or any other provision. Any law or
+regulation which provides that the language of a contract shall be
+construed against the drafter will not apply to this License.
+
+13.5 Severability. (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect. (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution. Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law. This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof. This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
+Reserved.
+
+This file contains Original Code and/or Modifications of Original Code
+as defined in and that are subject to the Apple Public Source License
+Version 2.0 (the 'License'). You may not use this file except in
+compliance with the License. Please obtain a copy of the License at
+http://www.opensource.apple.com/apsl/ and read it before using this
+file.
+
+The Original Code and all software distributed under the License are
+distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+Please see the License for the specific language governing rights and
+limitations under the License."
--- /dev/null
+#! /bin/sh
+# This script will build resolver library
+#
+
+TARGET=resolver
+echo
+echo "=================================================="
+echo $TARGET
+echo "=================================================="
+
+PROJECT_ROOT=../netinfo.build/root
+TARGET_DYNAMIC_LIB=libresolv.9.dylib
+TARGET_LIB_LINK=libresolv.dylib
+TARGET_STATIC_LIB=libresolv.a
+TARGET_VERSION=A
+TARGET_DIR=usr/lib
+COMPAT_VERS=1.0.0
+CURR_VERS=2.0.0
+TARGET_MAN_DIR=/usr/share/man/man5
+
+BLD=$TARGET.build
+DERIVED_SRC_DIR=$BLD/derived_src
+OBJECT_DIR=$BLD/objects
+
+DST_DIR=$PROJECT_ROOT/$TARGET_DIR
+PUBLIC_HEADERS_DIR=$PROJECT_ROOT/usr/include
+PRIVATE_HEADERS_DIR=$PROJECT_ROOT/usr/local/include
+PROJECT_HEADERS_DIR=../netinfo.build/ProjectHeaders
+MAN_DIR=${PROJECT_ROOT}${TARGET_MAN_DIR}
+
+CFLAGS="-g -dynamic -fno-common -Wall -D_REENTRANT"
+INCLUDE="-I. -I$PUBLIC_HEADERS_DIR"
+LIBS=
+nm /usr/lib/libSystem.B.dylib | grep -q pselect
+if [ $? = 1 ]; then
+ CFLAGS="$CFLAGS -DNEED_PSELECT"
+fi
+
+CLEAN=0
+BUILD=1
+
+while [ $# != 0 ]; do
+ if [ ${1}x = cleanx ]; then
+ CLEAN=1
+ BUILD=0
+ fi
+
+ if [ ${1}x = freshx ]; then
+ CLEAN=1
+ BUILD=1
+ fi
+
+ shift
+done
+
+if [ $CLEAN = 1 ]; then
+ echo "Cleaning $TARGET"
+ rm -rf $BLD
+ rm -rf .gdb_history
+fi
+
+if [ $BUILD = 0 ]; then
+ echo "Done"
+ exit 0
+fi
+
+if [ ! -d $BLD ]; then
+ mkdir $BLD
+fi
+if [ ! -d $DERIVED_SRC_DIR ]; then
+ mkdir $DERIVED_SRC_DIR
+ ln -s ../.. $DERIVED_SRC_DIR/NetInfo
+fi
+if [ ! -d $OBJECT_DIR ]; then
+ mkdir $OBJECT_DIR
+fi
+
+if [ ! -d $DST_DIR ]; then
+ if [ -f /bin/mkdirs ]; then
+ mkdirs $DST_DIR
+ else
+ mkdir -p $DST_DIR
+ fi
+fi
+
+if [ ! -d $PUBLIC_HEADERS_DIR ]; then
+ if [ -f /bin/mkdirs ]; then
+ mkdirs $PUBLIC_HEADERS_DIR
+ mkdirs $PUBLIC_HEADERS_DIR/arpa
+ else
+ mkdir -p $PUBLIC_HEADERS_DIR
+ mkdir -p $PUBLIC_HEADERS_DIR/arpa
+ fi
+fi
+
+if [ ! -d $PRIVATE_HEADERS_DIR ]; then
+ if [ -f /bin/mkdirs ]; then
+ mkdirs $PRIVATE_HEADERS_DIR
+ else
+ mkdir -p $PRIVATE_HEADERS_DIR
+ fi
+fi
+
+if [ ! -d $PROJECT_HEADERS_DIR ]; then
+ if [ -f /bin/mkdirs ]; then
+ mkdirs $PROJECT_HEADERS_DIR
+ else
+ mkdir -p $PROJECT_HEADERS_DIR
+ fi
+fi
+
+if [ ! -f $PUBLIC_HEADERS_DIR/dns.h ]; then
+ echo "cp dns.h $PUBLIC_HEADERS_DIR"
+ cp dns.h $PUBLIC_HEADERS_DIR
+fi
+
+if [ ! -f $PUBLIC_HEADERS_DIR/dns_util.h ]; then
+ echo "cp dns_util.h $PUBLIC_HEADERS_DIR"
+ cp dns_util.h $PUBLIC_HEADERS_DIR
+fi
+
+if [ ! -f $PRIVATE_HEADERS_DIR/dns_private.h ]; then
+ echo "cp dns_private.h $PRIVATE_HEADERS_DIR"
+ cp dns_private.h $PRIVATE_HEADERS_DIR
+fi
+
+if [ ! -f $PROJECT_HEADERS_DIR/dns_private.h ]; then
+ echo "cp dns_private.h $PROJECT_HEADERS_DIR"
+ cp dns_private.h $PROJECT_HEADERS_DIR
+fi
+
+if [ ! -f $PUBLIC_HEADERS_DIR/resolv.h ]; then
+ echo "cp resolv.h $PUBLIC_HEADERS_DIR"
+ cp resolv.h $PUBLIC_HEADERS_DIR
+fi
+
+if [ ! -f $PUBLIC_HEADERS_DIR/nameser.h ]; then
+ echo "cp nameser.h $PUBLIC_HEADERS_DIR"
+ cp nameser.h $PUBLIC_HEADERS_DIR
+ echo "ln -s ../nameser.h $PUBLIC_HEADERS_DIR/arpa/nameser.h"
+ ln -s ../nameser.h $PUBLIC_HEADERS_DIR/arpa/nameser.h
+fi
+
+if [ ! -d $MAN_DIR ]; then
+ if [ -f /bin/mkdirs ]; then
+ mkdirs $MAN_DIR
+ else
+ mkdir -p $MAN_DIR
+ fi
+fi
+
+if [ ! -f $MAN_DIR/resolver.5 ]; then
+ echo "cp resolver.5 $MAN_DIR"
+ cp resolver.5 $MAN_DIR
+fi
+
+MAKE_TARGET=0
+if [ ! -f $DST_DIR/$TARGET_DYNAMIC_LIB ]; then
+ MAKE_TARGET=1
+fi
+
+for c in *.[mc]
+do
+ OBJ=`echo $c | sed 's/..$/.o/'`
+ SRC=$c
+ DST=$OBJECT_DIR/$OBJ
+
+ MAKEIT=1
+ if [ -f $DST ]; then
+ RECENT=`/bin/ls -1t $DST $SRC | head -1`
+ if [ $RECENT = $DST ]; then
+ MAKEIT=0
+ fi
+ fi
+
+ if [ $MAKEIT = 1 ]; then
+ MAKE_TARGET=1
+ echo cc -c $CFLAGS $INCLUDE -o $DST $SRC
+ cc -c $CFLAGS $INCLUDE -o $DST $SRC
+ fi
+done
+
+if [ $MAKE_TARGET = 1 ]; then
+ echo libtool -dynamic -install_name /${TARGET_DIR}/${TARGET_DYNAMIC_LIB} -compatibility_version $COMPAT_VERS -current_version $CURR_VERS -arch_only ppc -o $DST_DIR/${TARGET_DYNAMIC_LIB} $OBJECT_DIR/*.o -lcc_dynamic -framework System
+ libtool -dynamic -install_name /${TARGET_DIR}/${TARGET_DYNAMIC_LIB} -compatibility_version $COMPAT_VERS -current_version $CURR_VERS -arch_only ppc -o $DST_DIR/${TARGET_DYNAMIC_LIB} $OBJECT_DIR/*.o -lcc_dynamic -ldnsinfo -framework System
+ echo "ln -s $TARGET_DYNAMIC_LIB $DST_DIR/${TARGET_LIB_LINK}"
+ ln -s $TARGET_DYNAMIC_LIB $DST_DIR/${TARGET_LIB_LINK}
+fi
+
+echo "Finished building $TARGET"
+exit 0
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = resolv
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Library
+Project = resolv
+ProductType = dylib
+Install_Dir = /usr/lib
HFILES = dns.h dns_private.h dns_util.h dst.h dst_internal.h\
nameser.h res_debug.h res_private.h res_update.h resolv.h
res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c\
res_query.c res_send.c res_sendsigned.c res_update.c
-OTHERSRCS = Makefile Makefile.postamble Makefile.preamble resolver.3 resolver_so.3 resolver.5
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CURRENTLY_ACTIVE_VERSION = YES
-DEPLOY_WITH_VERSION_NAME = 9
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = library.make
-NEXTSTEP_INSTALLDIR = /usr/lib
-LIBS = -ldnsinfo
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
+# NOTE dns_plugin.c is not included in CFILES since it isn't part of the dylib
-PUBLIC_HEADERS = dns.h dns_util.h nameser.h resolv.h
+MANPAGES = resolver.3 resolver.5
-PROJECT_HEADERS = dns.h dns_private.h dns_util.h dst.h dst_internal.h\
- nameser.h res_debug.h res_private.h res_update.h\
- resolv.h
+Install_Headers = dns.h dns_util.h nameser.h resolv.h
+Install_Private_Headers = dns_private.h
+Library_Version = 9
+Extra_CC_Flags = -Wall -Werror -fno-common -I.
-WINDOWS_PUBLIC_HEADERS_DIR = LOCAL_DEVELOPER_DIR/Headers/$(NAME)
+PRODUCT = $(shell tconf --product)
+ifeq "$(PRODUCT)" "iPhone"
+Extra_CC_Flags += -DUSE_DNS_PSELECT
+endif
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-include $(MAKEFILEDIR)/platform.make
+build:: dns.so
--include Makefile.preamble
+PLUGIN_LD_Flags = -L$(SYMROOT) -lresolv.9
+PLUGIN_CC_Flags = -bundle
-include $(MAKEFILEDIR)/$(MAKEFILE)
+PLUGIN_DEST = $(DSTROOT)/$(DESTDIR)usr/lib/info
--include Makefile.postamble
+dns.so: dns_plugin.c
+ cc -c $(CFLAGS) dns_plugin.c
+ cc $(PLUGIN_CC_Flags) $(LDFLAGS) $(PLUGIN_LD_Flags) -o $(SYMROOT)/dns.so dns_plugin.o
+ dsymutil --out=$(SYMROOT)/dns.so.dSYM $(SYMROOT)/dns.so || exit 0
+ $(INSTALL_DIRECTORY) $(PLUGIN_DEST)
+ $(INSTALL_LIBRARY) $(SYMROOT)/dns.so $(PLUGIN_DEST)
+ strip -S $(PLUGIN_DEST)/dns.so
--include Makefile.dependencies
+after_install:
+ $(INSTALL_DIRECTORY) $(DSTROOT)/usr/include/arpa
+ $(LN) -sf ../nameser.h $(DSTROOT)/usr/include/arpa
+ @for FILE in \
+ dn_comp.3 dn_expand.3 dn_skipname.3 \
+ ns_get16.3 ns_get32.3 ns_put16.3 ns_put32.3 \
+ res_init.3 res_mkquery.3 res_query.3 res_search.3 res_send.3 ; do \
+ $(INSTALL_FILE) resolver_so.3 $(DSTROOT)/usr/share/man/man3/$${FILE} ; \
+ done
+OTHER_LDFLAGS += -undefined dynamic_lookup
PUBLIC_HEADER_DIR=/usr/include
PUBLIC_HEADER_DIR_SUFFIX =
ARPA_HEADER_DIR_SUFFIX = /arpa
#define DNS_RESOLVER_DIR "/etc/resolver"
+#define NOTIFY_DNS_CONTROL_NAME "com.apple.system.dns"
+#define DNS_CONTROL_FLAG_DEBUG 0x0000000000000001LL
+#define DNS_CONTROL_FLAG_NO_MDNS 0x0000000000000002LL
+
#define NOTIFY_DIR_NAME "com.apple.system.dns.resolver.dir"
#define DNS_DELAY_NAME "com.apple.system.dns.delay"
#define MDNS_MIN_TTL 2
+static int dns_control_token = -1;
+static int dns_control_mdns = 1;
+static int dns_control_debug = 0;
+static pthread_mutex_t dns_control_lock = PTHREAD_MUTEX_INITIALIZER;
+
extern uint32_t notify_monitor_file(int token, const char *name, int flags);
extern void res_client_close(res_state res);
return pdns;
}
+static pdns_handle_t *
+_mdns_primary(dns_resolver_t *r)
+{
+ pdns_handle_t *pdns;
+ char *val, *p;
+ int i;
+
+ pdns = _pdns_build_start(r->domain);
+ if (r->domain == NULL) _pdns_build(pdns, "default", NULL);
+
+ p = getenv("RES_RETRY_TIMEOUT");
+ if (p != NULL) pdns->send_timeout = atoi(p);
+
+ p = getenv("RES_RETRY");
+ if (p != NULL) pdns->res->retry= atoi(p);
+
+ if (r->n_search > MAXDNSRCH) r->n_search = MAXDNSRCH;
+ for (i = 0; i < r->n_search; i++)
+ {
+ val = NULL;
+ asprintf(&val, "%s", r->search[i]);
+ if (val == NULL)
+ {
+ _pdns_free(pdns);
+ return NULL;
+ }
+
+ _pdns_build(pdns, "search", val);
+ free(val);
+ }
+
+ _pdns_build(pdns, "mdns", NULL);
+
+ _pdns_build_finish(pdns);
+ return pdns;
+}
+
/*
* Open a named resolver client from the system config data.
*/
sc_dns_count = 0;
if ((sc_dns != NULL) && (sc_dns->n_resolver > 0))
{
- sc_dns_count = sc_dns->n_resolver;
- sdns->pdns_primary = _pdns_convert_sc(sc_dns->resolver[0]);
+ if (sdns->flags & DNS_FLAG_FORWARD_TO_MDNSRESPONDER)
+ {
+ sc_dns_count = 1;
+ sdns->pdns_primary = _mdns_primary(sc_dns->resolver[0]);
+ }
+ else
+ {
+ sc_dns_count = sc_dns->n_resolver;
+ sdns->pdns_primary = _pdns_convert_sc(sc_dns->resolver[0]);
+ }
+
_pdns_check_search_list(sdns->pdns_primary);
}
else
}
static uint32_t
-_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, uint32_t nlabels, pdns_handle_t ***pdns)
+_pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, pdns_handle_t ***pdns)
{
char *p, *vname;
int i, j, k, count;
{
if (sdns->client[i]->name == NULL) continue;
- /* Special case: Don't send to ".local[.]" queries to mDNSResponder if nlabels > 2 */
- if ((nlabels > 2) && (sdns->client[i]->flags & DNS_FLAG_FORWARD_TO_MDNSRESPONDER) && (!strcasecmp(sdns->client[i]->name, "local"))) continue;
-
if (!strcasecmp(sdns->client[i]->name, p))
{
if (count == 0)
if (count != 0) return count;
- return _pdns_get_default_handles(sdns, pdns);;
+ return _pdns_get_default_handles(sdns, pdns);
}
static void
dns_open(const char *name)
{
dns_private_handle_t *dns;
+ struct stat sb;
+ int check, status, local_control;
+ uint64_t control;
dns = (dns_private_handle_t *)calloc(1, sizeof(dns_private_handle_t));
if (dns == NULL) return NULL;
- if (name == NULL)
+ /* set up control notification if necessary */
+ if (dns_control_token == -1)
+ {
+ pthread_mutex_lock(&dns_control_lock);
+ if (dns_control_token == -1) status = notify_register_check(NOTIFY_DNS_CONTROL_NAME, &dns_control_token);
+ pthread_mutex_unlock(&dns_control_lock);
+ }
+
+ /* check for dns flags */
+ if (dns_control_token != -1)
+ {
+ pthread_mutex_lock(&dns_control_lock);
+ status = notify_check(dns_control_token, &check);
+ if ((status == 0) && (check == 1))
+ {
+ /* notification was triggered */
+ status = notify_get_state(dns_control_token, &control);
+ if (status == 0)
+ {
+ if (control & DNS_CONTROL_FLAG_NO_MDNS) dns_control_mdns = 0;
+ if (control & DNS_CONTROL_FLAG_DEBUG) dns_control_debug = 1;
+ }
+ }
+
+ pthread_mutex_unlock(&dns_control_lock);
+ }
+
+ if (name == NULL) local_control = dns_control_mdns;
+ else if (!strcmp(name, MDNS_HANDLE_NAME)) local_control = 2;
+ else local_control = 0;
+
+ if ((name == NULL) && (local_control == 0))
{
dns->handle_type = DNS_PRIVATE_HANDLE_TYPE_SUPER;
dns->sdns = (sdns_handle_t *)calloc(1, sizeof(sdns_handle_t));
dns->sdns->notify_delay_token = -1;
_dns_open_notify(dns->sdns);
+ memset(&sb, 0, sizeof(struct stat));
+ dns_set_debug((dns_handle_t)dns, dns_control_debug);
+
+ return (dns_handle_t)dns;
+ }
+
+ if (local_control != 0)
+ {
+ dns->handle_type = DNS_PRIVATE_HANDLE_TYPE_SUPER;
+ dns->sdns = (sdns_handle_t *)calloc(1, sizeof(sdns_handle_t));
+ if (dns->sdns == NULL)
+ {
+ free(dns);
+ return NULL;
+ }
+
+ dns->sdns->flags = DNS_FLAG_FORWARD_TO_MDNSRESPONDER;
+ dns->sdns->notify_sys_config_token = -1;
+ dns->sdns->notify_dir_token = -1;
+ dns->sdns->notify_delay_token = -1;
+ if (local_control == 1) _dns_open_notify(dns->sdns);
+
+ memset(&sb, 0, sizeof(struct stat));
+ dns_set_debug((dns_handle_t)dns, dns_control_debug);
+
return (dns_handle_t)dns;
}
return NULL;
}
+ dns_set_debug((dns_handle_t)dns, dns_control_debug);
return (dns_handle_t)dns;
}
}
static int
-_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, uint32_t nlabels, int *min)
+_sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min)
{
char *qname;
pdns_handle_t **pdns;
*min = -1;
m = -1;
- pdns_count = _pdns_get_handles_for_name(sdns, name, nlabels, &pdns);
+ pdns_count = _pdns_get_handles_for_name(sdns, name, &pdns);
if (pdns_count == 0) return -1;
_sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type, uint32_t fqdn, uint32_t recurse, char *buf, uint32_t len, struct sockaddr *from, uint32_t *fromlen, int *min)
{
pdns_handle_t *primary, **pdns;
- int i, n, ndots, nlabels, status;
+ int i, n, ndots, status;
int m, tmin, minstate;
char *dot, *qname;
uint32_t pdns_count;
/* the last dot is the last character, name is fully qualified */
if ((fqdn == 0) && (dot != NULL) && (*(dot + 1) == '\0')) fqdn = 1;
- /* number of labels */
- nlabels = n + 1 - fqdn;
-
/*
* If n >= ndots, or it's a FQDN, or if it's a PTR query,
* we try a query with the name "as is".
if ((n >= ndots) || (fqdn == 1) || (type == ns_t_ptr))
{
tmin = -1;
- status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, nlabels, &tmin);
+ status = _sdns_send(sdns, name, class, type, fqdn, buf, len, from, fromlen, &tmin);
if (status > 0) return status;
if (tmin < 0) minstate = -1;
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 - 2008 Apple, Inc. All rights reserved.
*
- * @APPLE_LICENSE_headER_START@
+ * @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 2003 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
*
* The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_headER_END@
+ * @APPLE_LICENSE_HEADER_END@
*/
#include <stdlib.h>
#include <arpa/inet.h>
#include <dns.h>
#include <dns_util.h>
+#include <stdarg.h>
+#include <si_module.h>
-typedef struct
-{
- uint32_t datalen;
- char *databuf;
- uint32_t _size;
- uint32_t _dict;
- uint32_t _key;
- uint32_t _vlist;
- uint32_t _val;
-} kvbuf_t;
+extern void *LI_ils_create(char *fmt, ...);
+
+/*
+ typedef void (*dns_async_callback)(int32_t status, char *buf, uint32_t len, struct sockaddr *from, int fromlen, void *context);
+*/
typedef struct
{
- uint32_t kcount;
- const char **key;
- uint32_t *vcount;
- const char ***val;
-} kvdict_t;
+ void *orig_callback;
+ void *orig_context;
+ si_mod_t *dns;
+} _dns_context_t;
-typedef struct
+static void
+_dns_callback(si_item_t *item, uint32_t status, void *ctx)
{
- uint32_t count;
- uint32_t curr;
- kvdict_t *dict;
- kvbuf_t *kv;
-} kvarray_t;
+ _dns_context_t *my_ctx;
+ si_dnspacket_t *res;
+ char *packet;
+ struct sockaddr *from;
+ uint32_t pl;
+ int fl;
-extern kvbuf_t *kvbuf_new(void);
-extern void kvbuf_add_dict(kvbuf_t *kv);
-extern void kvbuf_add_key(kvbuf_t *kv, const char *key);
-extern void kvbuf_add_val(kvbuf_t *kv, const char *val);
-extern void kvbuf_free(kvbuf_t *kv);
-extern void kvarray_free(kvarray_t *kva);
-extern uint32_t kvbuf_get_val_len(const char *val);
-extern kern_return_t LI_DSLookupGetProcedureNumber(const char *name, int *procno);
-extern kern_return_t LI_async_start(mach_port_t *p, uint32_t proc, kvbuf_t *query, void *callback, void *context);
-extern kern_return_t LI_async_handle_reply(void *msg, kvarray_t **reply, void **callback, void **context);
-extern kern_return_t LI_async_receive(mach_port_t p, kvarray_t **reply);
-extern void LI_async_call_cancel(mach_port_t p, void **context);
-extern uint32_t kvbuf_get_len(const char *p);
+ if (ctx == NULL) return;
+
+ my_ctx = (_dns_context_t *)ctx;
+ if (my_ctx->orig_callback == NULL)
+ {
+ si_item_release(item);
+ si_module_release(my_ctx->dns);
+ free(my_ctx);
+ return;
+ }
-static kvbuf_t *
-dns_make_query(const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search)
-{
- kvbuf_t *request;
- char str[128];
+ if (status >= SI_STATUS_INTERNAL) status = NO_RECOVERY;
- if (name == NULL) return NULL;
+ packet = NULL;
+ pl = 0;
+ from = NULL;
+ fl = 0;
- request = kvbuf_new();
- if (request == NULL) return NULL;
-
- kvbuf_add_dict(request);
-
- /* Encode name */
- kvbuf_add_key(request, "domain");
- kvbuf_add_val(request, name);
+ res = NULL;
+ if (item != NULL) res = (si_dnspacket_t *)((char *)item + sizeof(si_item_t));
- /* Encode class */
- snprintf(str, 128, "%hu", dnsclass);
- kvbuf_add_key(request, "class");
- kvbuf_add_val(request, str);
+ if ((res != NULL) && (res->dns_packet_len > 0))
+ {
+ packet = malloc(res->dns_packet_len);
+ if (packet == NULL) status = NO_RECOVERY;
+ else
+ {
+ pl = res->dns_packet_len;
+ memcpy(packet, res->dns_packet, res->dns_packet_len);
+
+ if (res->dns_server_len > 0)
+ {
+ from = malloc(res->dns_server_len);
+ if (from == NULL)
+ {
+ status = NO_RECOVERY;
+ free(packet);
+ packet = NULL;
+ pl = 0;
+ }
+ else
+ {
+ fl = res->dns_server_len;
+ memcpy(from, res->dns_server, res->dns_server_len);
+ }
+ }
+ }
+ }
- /* Encode type */
- snprintf(str, 128, "%hu", dnstype);
- kvbuf_add_key(request, "type");
- kvbuf_add_val(request, str);
+ si_item_release(item);
- /* Encode do_search */
- snprintf(str, 128, "%hu", do_search);
- kvbuf_add_key(request, "search");
- kvbuf_add_val(request, str);
+ ((dns_async_callback)(my_ctx->orig_callback))(status, packet, pl, from, fl, my_ctx->orig_context);
- return request;
+ si_module_release(my_ctx->dns);
+ free(my_ctx);
}
int32_t
dns_async_start(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search, dns_async_callback callback, void *context)
{
- int32_t status;
- kvbuf_t *request;
- static int proc = -1;
+ si_mod_t *dns;
+ int call;
+ uint32_t c, t;
+ _dns_context_t *my_ctx;
*p = MACH_PORT_NULL;
if (name == NULL) return NO_RECOVERY;
- if (proc < 0)
+ dns = si_module_with_name("mdns");
+ if (dns == NULL) return NO_RECOVERY;
+
+ my_ctx = (_dns_context_t *)calloc(1, sizeof(_dns_context_t));
+ if (my_ctx == NULL)
{
- status = LI_DSLookupGetProcedureNumber("dns_proxy", &proc);
- if (status != KERN_SUCCESS) return NO_RECOVERY;
+ si_module_release(dns);
+ return NO_RECOVERY;
}
- request = dns_make_query(name, dnsclass, dnstype, do_search);
- if (request == NULL) return NO_RECOVERY;
+ my_ctx->orig_callback = callback;
+ my_ctx->orig_context = context;
+ my_ctx->dns = dns;
+
+ call = SI_CALL_DNS_QUERY;
+ if (do_search != 0) call = SI_CALL_DNS_SEARCH;
+
+ c = dnsclass;
+ t = dnstype;
+
+ *p = si_async_call(dns, call, name, NULL, c, t, 0, 0, (void *)_dns_callback, (void *)my_ctx);
+ if (*p == MACH_PORT_NULL)
+ {
+ free(my_ctx);
+ si_module_release(dns);
+ return NO_RECOVERY;
+ }
- status = LI_async_start(p, proc, request, (void *)callback, context);
-
- kvbuf_free(request);
- if (status != 0) return NO_RECOVERY;
return 0;
}
void
dns_async_cancel(mach_port_t p)
{
- LI_async_call_cancel(p, NULL);
+ si_async_cancel(p);
}
int32_t
return dns_async_start(p, name, dnsclass, dnstype, do_search, NULL, NULL);
}
-static int
-dns_extract_data(kvarray_t *in, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen)
-{
- int32_t status;
- struct in_addr addr4;
- struct sockaddr_in sin4;
- struct in6_addr addr6;
- struct sockaddr_in6 sin6;
- uint32_t d, k, kcount;
-
- if (in == NULL) return -1;
- if (buf == NULL) return -1;
- if (len == NULL) return -1;
- if (from == NULL) return -1;
- if (fromlen == NULL) return -1;
-
- *buf = NULL;
- *len = 0;
- *from = NULL;
- *fromlen = 0;
-
- d = in->curr;
- in->curr++;
-
- if (d >= in->count) return -1;
-
- kcount = in->dict[d].kcount;
-
- for (k = 0; k < kcount; k++)
- {
- if (!strcmp(in->dict[d].key[k], "data"))
- {
- if (in->dict[d].vcount[k] == 0) continue;
- if (*buf != NULL) continue;
-
- /*
- * dns_proxy contains binary data, possibly with embedded nuls,
- * so we extract the string length from the kvbuf_t reply that
- * Libinfo got from directory services, rather than calling strlen().
- */
- *len = kvbuf_get_len(in->dict[d].val[k][0]);
- if (*len == 0) continue;
-
- *buf = malloc(*len);
- if (*buf == NULL) return -1;
-
- memcpy(*buf, in->dict[d].val[k][0], *len);
- }
- else if (!strcmp(in->dict[d].key[k], "server"))
- {
- if (in->dict[d].vcount[k] == 0) continue;
- if (*from != NULL) continue;
-
- memset(&addr4, 0, sizeof(struct in_addr));
- memset(&sin4, 0, sizeof(struct sockaddr_in));
-
- memset(&addr6, 0, sizeof(struct in6_addr));
- memset(&sin6, 0, sizeof(struct sockaddr_in6));
-
- status = inet_pton(AF_INET6, in->dict[d].val[k][0], &addr6);
- if (status == 1)
- {
- sin6.sin6_addr = addr6;
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- *from = (struct sockaddr *)calloc(1, sin6.sin6_len);
- memcpy(*from, &sin6, sin6.sin6_len);
- *fromlen = sin6.sin6_len;
- }
-
- status = inet_pton(AF_INET, in->dict[d].val[k][0], &addr4);
- if (status == 1)
- {
- sin4.sin_addr = addr4;
- sin4.sin_family = AF_INET;
- sin4.sin_len = sizeof(struct sockaddr_in);
- *from = (struct sockaddr *)calloc(1, sin4.sin_len);
- memcpy(*from, &sin4, sin4.sin_len);
- *fromlen = sin4.sin_len;
- }
- }
- }
-
- return 0;
-}
-
+/* unsupported */
int32_t
dns_async_receive(mach_port_t p, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen)
{
- kern_return_t status;
- kvarray_t *reply;
-
- reply = NULL;
-
- status = LI_async_receive(p, &reply);
- if (status != 0) return NO_RECOVERY;
- if (reply == NULL) return HOST_NOT_FOUND;
-
- status = dns_extract_data(reply, buf, len, from, fromlen);
- kvarray_free(reply);
- if (status != 0) return NO_RECOVERY;
-
- if (*buf == NULL) return NO_DATA;
-
return 0;
}
int32_t
dns_async_handle_reply(void *msg)
{
- dns_async_callback callback;
- void *context;
- char *buf;
- kvarray_t *reply;
- kern_return_t status;
- struct sockaddr *from;
- uint32_t len, fromlen;
-
- callback = (dns_async_callback)NULL;
- context = NULL;
- reply = NULL;
- buf = NULL;
- len = 0;
- from = NULL;
- fromlen = 0;
-
- status = LI_async_handle_reply(msg, &reply, (void **)&callback, &context);
- if (status != KERN_SUCCESS)
- {
- if (status == MIG_REPLY_MISMATCH) return 0;
- callback(NO_RECOVERY, NULL, 0, NULL, 0, context);
- return NO_RECOVERY;
- }
-
- status = dns_extract_data(reply, &buf, &len, &from, &fromlen);
- kvarray_free(reply);
- if (status != 0)
- {
- callback(NO_RECOVERY, NULL, 0, NULL, 0, context);
- return 0;
- }
-
- if (buf == NULL)
- {
- callback(NO_DATA, NULL, 0, NULL, 0, context);
- return NO_DATA;
- }
-
- callback(0, buf, len, from, fromlen, context);
-
+ si_async_handle_reply(msg);
return 0;
}
-
--- /dev/null
+/*
+ * Copyright (c) 2008 Apple, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <dns.h>
+#include <dns_util.h>
+#include <resolv.h>
+#include <nameser.h>
+#include <pthread.h>
+#include <si_module.h>
+#include <ils.h>
+#include <dns_private.h>
+
+/* from dns_util.c */
+#define DNS_MAX_RECEIVE_SIZE 65536
+
+#define MDNS_HANDLE_NAME "*MDNS*"
+
+#define DNS_HANDLE_BUSY 0x00000001
+#define MDNS_HANDLE_BUSY 0x00000002
+
+#define MODULE_DNS 0
+#define MODULE_MDNS 1
+
+static pthread_mutex_t dns_plugin_lock = PTHREAD_MUTEX_INITIALIZER;
+
+typedef struct
+{
+ struct hostent host;
+ int alias_count;
+ int addr_count;
+ uint64_t ttl;
+} dns_build_hostent_t;
+
+typedef struct
+{
+ dns_handle_t dns;
+ dns_handle_t mdns;
+ uint32_t flags;
+} dns_plugin_private_t;
+
+#define DNS_FLAGS_RCODE_MASK 0x000f
+static const char hexchar[] = "0123456789abcdef";
+
+static dns_handle_t
+dns_checkout_handle(si_mod_t *si)
+{
+ dns_plugin_private_t *pp;
+ dns_handle_t dns;
+
+ if (si == NULL) return NULL;
+
+ pthread_mutex_lock(&dns_plugin_lock);
+ if (si->private == NULL)
+ {
+ pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
+ si->private = pp;
+ }
+
+ dns = NULL;
+ pp = (dns_plugin_private_t *)si->private;
+
+ if (pp == NULL)
+ {
+ /* shouldn't happen */
+ dns = dns_open(NULL);
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return dns;
+ }
+
+ if ((pp->flags & DNS_HANDLE_BUSY) == 0)
+ {
+ if (pp->dns == NULL) pp->dns = dns_open(NULL);
+ pp->flags |= DNS_HANDLE_BUSY;
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return pp->dns;
+ }
+
+ /* main dns handle is busy - create a temporary one */
+ dns = dns_open(NULL);
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return dns;
+}
+
+static dns_handle_t
+mdns_checkout_handle(si_mod_t *si)
+{
+ dns_plugin_private_t *pp;
+ dns_handle_t dns;
+
+ if (si == NULL) return NULL;
+
+ pthread_mutex_lock(&dns_plugin_lock);
+ if (si->private == NULL)
+ {
+ pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
+ si->private = pp;
+ }
+
+ dns = NULL;
+ pp = (dns_plugin_private_t *)si->private;
+
+ if (pp == NULL)
+ {
+ /* shouldn't happen */
+ dns = dns_open(MDNS_HANDLE_NAME);
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return dns;
+ }
+
+ if ((pp->flags & MDNS_HANDLE_BUSY) == 0)
+ {
+ if (pp->mdns == NULL) pp->mdns = dns_open(MDNS_HANDLE_NAME);
+ pp->flags |= MDNS_HANDLE_BUSY;
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return pp->mdns;
+ }
+
+ /* main mdns handle is busy - create a temporary one */
+ dns = dns_open(MDNS_HANDLE_NAME);
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return dns;
+}
+
+static void
+dns_checkin_handle(si_mod_t *si, dns_handle_t dns)
+{
+ dns_plugin_private_t *pp;
+
+ if (si == NULL) return;
+ if (dns == NULL) return;
+
+ pthread_mutex_lock(&dns_plugin_lock);
+ if (si->private == NULL)
+ {
+ /* shouldn't happen */
+ pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
+ si->private = pp;
+ }
+
+ pp = (dns_plugin_private_t *)si->private;
+
+ if (pp == NULL)
+ {
+ /* shouldn't happen */
+ dns_free(dns);
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return;
+ }
+
+ if (pp->dns == dns)
+ {
+ pp->flags &= ~DNS_HANDLE_BUSY;
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return;
+ }
+ else if (pp->mdns == dns)
+ {
+ pp->flags &= ~MDNS_HANDLE_BUSY;
+ pthread_mutex_unlock(&dns_plugin_lock);
+ return;
+ }
+
+ dns_free(dns);
+ pthread_mutex_unlock(&dns_plugin_lock);
+}
+
+static char *
+dns_reverse_ipv4(const char *addr)
+{
+ union
+ {
+ uint32_t a;
+ unsigned char b[4];
+ } ab;
+ char *p;
+
+ if (addr == NULL) return NULL;
+
+ memcpy(&(ab.a), addr, 4);
+
+ asprintf(&p, "%u.%u.%u.%u.in-addr.arpa.", ab.b[3], ab.b[2], ab.b[1], ab.b[0]);
+ return p;
+}
+
+static char *
+dns_reverse_ipv6(const char *addr)
+{
+ char x[65], *p;
+ int i, j;
+ u_int8_t d, hi, lo;
+
+ if (addr == NULL) return NULL;
+
+ x[64] = '\0';
+ j = 63;
+ for (i = 0; i < 16; i++)
+ {
+ d = addr[i];
+ lo = d & 0x0f;
+ hi = d >> 4;
+ x[j--] = '.';
+ x[j--] = hexchar[hi];
+ x[j--] = '.';
+ x[j--] = hexchar[lo];
+ }
+
+ p = calloc(1, 75);
+ if (p == NULL) return NULL;
+
+ memmove(p, x, 64);
+ strcat(p, "ip6.arpa.");
+
+ return p;
+}
+
+static char *
+dns_lower_case(const char *s)
+{
+ int i;
+ char *t;
+
+ if (s == NULL) return NULL;
+ t = malloc(strlen(s) + 1);
+
+ for (i = 0; s[i] != '\0'; i++)
+ {
+ if ((s[i] >= 'A') && (s[i] <= 'Z')) t[i] = s[i] + 32;
+ else t[i] = s[i];
+ }
+ t[i] = '\0';
+ return t;
+}
+
+static int
+dns_host_merge_alias(const char *name, dns_build_hostent_t *h)
+{
+ int i;
+
+ if (name == NULL) return 0;
+ if (h == NULL) return 0;
+
+ if ((h->host.h_name != NULL) && (!strcmp(name, h->host.h_name))) return 0;
+ for (i = 0; i < h->alias_count; i++) if (!strcmp(name, h->host.h_aliases[i])) return 0;
+
+ h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count + 2) * sizeof(char *));
+ if (h->host.h_aliases == NULL)
+ {
+ h->alias_count = 0;
+ return -1;
+ }
+
+ h->host.h_aliases[h->alias_count] = dns_lower_case(name);
+ h->alias_count++;
+ h->host.h_aliases[h->alias_count] = NULL;
+
+ return 0;
+}
+
+static int
+dns_host_append_addr(const char *addr, uint32_t len, dns_build_hostent_t *h)
+{
+ if (addr == NULL) return 0;
+ if (h == NULL) return 0;
+
+ if (h->addr_count == 0) h->host.h_addr_list = (char **)calloc(2, sizeof(char *));
+ else h->host.h_addr_list = (char **)reallocf(h->host.h_addr_list, (h->addr_count + 2) * sizeof(char *));
+
+ if (h->host.h_addr_list == NULL)
+ {
+ h->addr_count = 0;
+ return -1;
+ }
+
+ h->host.h_addr_list[h->addr_count] = malloc(len);
+ if (h->host.h_addr_list[h->addr_count] == NULL) return -1;
+
+ memcpy(h->host.h_addr_list[h->addr_count], addr, len);
+ h->addr_count++;
+ h->host.h_addr_list[h->addr_count] = NULL;
+
+ return 0;
+}
+
+static void
+dns_plugin_clear_host(dns_build_hostent_t *h)
+{
+ uint32_t i;
+ char **aliases;
+
+ if (h == NULL) return;
+
+ if (h->host.h_name != NULL) free(h->host.h_name);
+ h->host.h_name = NULL;
+
+ aliases = h->host.h_aliases;
+ if (aliases != NULL)
+ {
+ while (*aliases != NULL) free(*aliases++);
+ free(h->host.h_aliases);
+ }
+
+ h->host.h_aliases = NULL;
+
+ if (h->host.h_addr_list != NULL)
+ {
+ for (i = 0; h->host.h_addr_list[i] != NULL; i++) free(h->host.h_addr_list[i]);
+ free(h->host.h_addr_list);
+ }
+
+ h->host.h_addr_list = NULL;
+}
+
+static int
+dns_reply_to_hostent(dns_reply_t *r, int af, const char *addr, dns_build_hostent_t *h)
+{
+ int i, got_data, got_addr;
+ int ptrx, cnamex;
+
+ if (r == NULL) return -1;
+ if (r->status != DNS_STATUS_OK) return -1;
+ if ((r->header->flags & DNS_FLAGS_RCODE_MASK) != ns_r_noerror) return -1;
+
+ if (r == NULL) return -1;
+ if (r->header == NULL) return -1;
+ if (r->header->ancount == 0) return -1;
+
+ got_data = 0;
+ got_addr = 0;
+ ptrx = -1;
+ cnamex = -1;
+
+ for (i = 0; i < r->header->ancount; i++)
+ {
+ if ((af == AF_INET) && (r->answer[i]->dnstype == ns_t_a))
+ {
+ got_data++;
+ got_addr++;
+ dns_host_append_addr((const char *)&(r->answer[i]->data.A->addr), 4, h);
+ if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
+ else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
+ }
+
+ else if ((af == AF_INET6) && (r->answer[i]->dnstype == ns_t_aaaa))
+ {
+ got_data++;
+ got_addr++;
+ dns_host_append_addr((const char *)&(r->answer[i]->data.AAAA->addr), 16, h);
+ if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
+ else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
+ }
+
+ else if (r->answer[i]->dnstype == ns_t_cname)
+ {
+ got_data++;
+ if (cnamex == -1) cnamex = i;
+ if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
+ else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
+ }
+
+ else if (r->answer[i]->dnstype == ns_t_ptr)
+ {
+ got_data++;
+ if (ptrx == -1) ptrx = i;
+ if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
+ else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
+ }
+ }
+
+ if (addr != NULL)
+ {
+ if (af == AF_INET)
+ {
+ got_addr++;
+ dns_host_append_addr(addr, 4, h);
+ }
+ else if (af == AF_INET6)
+ {
+ got_addr++;
+ dns_host_append_addr(addr, 16, h);
+ }
+ }
+
+ if (got_data == 0) return -1;
+ if (got_addr == 0) return -1;
+
+ h->host.h_addrtype = af;
+ if (af == AF_INET) h->host.h_length = 4;
+ else h->host.h_length = 16;
+
+ if (ptrx != -1)
+ {
+ /* use name from PTR record */
+ h->host.h_name = dns_lower_case(r->answer[ptrx]->data.PTR->name);
+ }
+ else if (cnamex != -1)
+ {
+ /* use name from CNAME record */
+ h->host.h_name = dns_lower_case(r->answer[cnamex]->data.CNAME->name);
+ }
+ else
+ {
+ /* use name in first answer */
+ h->host.h_name = dns_lower_case(r->answer[0]->name);
+ }
+
+ for (i = 0; i < r->header->ancount; i++)
+ {
+ if (r->answer[i]->dnstype == ns_t_cname)
+ {
+ dns_host_merge_alias(r->answer[cnamex]->data.CNAME->name, h);
+ dns_host_merge_alias(r->answer[cnamex]->name, h);
+ }
+ }
+
+ if (h->alias_count == 0) h->host.h_aliases = (char **)calloc(1, sizeof(char *));
+
+ return 0;
+}
+
+static si_item_t *
+_internal_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err, int which)
+{
+ uint32_t type;
+ dns_reply_t *r;
+ dns_build_hostent_t h;
+ si_item_t *out;
+ dns_handle_t dns;
+ uint64_t bb;
+ int status;
+
+ if (err != NULL) *err = SI_STATUS_NO_ERROR;
+
+ if (name == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ if (af == AF_INET) type = ns_t_a;
+ else if (af == AF_INET6) type = ns_t_aaaa;
+ else
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ r = NULL;
+ dns = NULL;
+
+ if (which == MODULE_DNS) dns = dns_checkout_handle(si);
+ else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
+
+ if (dns == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ r = dns_lookup(dns, name, ns_c_in, type);
+ dns_checkin_handle(si, dns);
+
+ if (r == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
+ return NULL;
+ }
+
+ memset(&h, 0, sizeof(dns_build_hostent_t));
+
+ status = dns_reply_to_hostent(r, af, NULL, &h);
+ dns_free_reply(r);
+
+ if (status < 0)
+ {
+ dns_plugin_clear_host(&h);
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ bb = h.ttl + time(NULL);
+
+ if (af == AF_INET)
+ {
+ out = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
+ }
+ else
+ {
+ out = (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
+ }
+
+ dns_plugin_clear_host(&h);
+
+ if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+
+ return out;
+}
+
+si_item_t *
+dns_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+{
+ return _internal_host_byname(si, name, af, err, MODULE_DNS);
+}
+
+si_item_t *
+mdns_host_byname(si_mod_t *si, const char *name, int af, uint32_t *err)
+{
+ return _internal_host_byname(si, name, af, err, MODULE_MDNS);
+}
+
+static si_item_t *
+_internal_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err, int which)
+{
+ uint32_t type;
+ dns_reply_t *r;
+ dns_build_hostent_t h;
+ char *name;
+ si_item_t *out;
+ dns_handle_t dns;
+ socklen_t len;
+ uint64_t bb;
+ int cat;
+ struct sockaddr_storage from;
+ uint32_t fromlen;
+
+ if (err != NULL) *err = SI_STATUS_NO_ERROR;
+
+ if (addr == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ if (si == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ fromlen = sizeof(struct sockaddr_storage);
+ memset(&from, 0, fromlen);
+
+ name = NULL;
+ type = ns_t_ptr;
+
+ len = 0;
+ cat = -1;
+
+ if (af == AF_INET)
+ {
+ len = 4;
+ name = dns_reverse_ipv4(addr);
+ cat = CATEGORY_HOST_IPV4;
+ }
+ else if (af == AF_INET6)
+ {
+ len = 16;
+ name = dns_reverse_ipv6(addr);
+ cat = CATEGORY_HOST_IPV6;
+ }
+ else
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ r = NULL;
+ dns = NULL;
+
+ if (which == MODULE_DNS) dns = dns_checkout_handle(si);
+ else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
+
+ if (dns == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ r = dns_lookup(dns, name, ns_c_in, type);
+ dns_checkin_handle(si, dns);
+
+ free(name);
+ if (r == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
+ return NULL;
+ }
+
+ memset(&h, 0, sizeof(dns_build_hostent_t));
+
+ if (dns_reply_to_hostent(r, af, addr, &h) < 0)
+ {
+ dns_plugin_clear_host(&h);
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ bb = h.ttl + time(NULL);
+ out = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, cat, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
+
+ dns_plugin_clear_host(&h);
+
+ if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+
+ return out;
+}
+
+si_item_t *
+dns_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+{
+ return _internal_host_byaddr(si, addr, af, err, MODULE_DNS);
+}
+
+si_item_t *
+mdns_host_byaddr(si_mod_t *si, const void *addr, int af, uint32_t *err)
+{
+ return _internal_host_byaddr(si, addr, af, err, MODULE_MDNS);
+}
+
+/*
+ * We support dns_async_start / cancel / handle_reply using dns_item_call
+ */
+static si_item_t *
+_internal_item_call(si_mod_t *si, int call, const char *name, const char *ignored, uint32_t class, uint32_t type, uint32_t *err, int which)
+{
+ dns_handle_t dns;
+ char buf[DNS_MAX_RECEIVE_SIZE];
+ int len;
+ struct sockaddr_storage from;
+ uint32_t fromlen;
+ si_item_t *out;
+
+ if (err != NULL) *err = SI_STATUS_NO_ERROR;
+ if ((call != SI_CALL_DNS_QUERY) && (call != SI_CALL_DNS_SEARCH))
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ if (name == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ dns = NULL;
+
+ if (which == MODULE_DNS) dns = dns_checkout_handle(si);
+ else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
+
+ if (dns == NULL)
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+ return NULL;
+ }
+
+ fromlen = sizeof(struct sockaddr_storage);
+ memset(&from, 0, fromlen);
+
+ len = 0;
+ if (call == SI_CALL_DNS_QUERY) len = dns_query(dns, name, class, type, buf, sizeof(buf), (struct sockaddr *)&from, &fromlen);
+ else if (call == SI_CALL_DNS_SEARCH) len = dns_search(dns, name, class, type, buf, sizeof(buf), (struct sockaddr *)&from, &fromlen);
+
+ dns_checkin_handle(si, dns);
+
+ if ((len <= 0) || (len > DNS_MAX_RECEIVE_SIZE))
+ {
+ if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
+ return NULL;
+ }
+
+ out = (si_item_t *)LI_ils_create("L4488@@", (unsigned long)si, CATEGORY_DNSPACKET, 1, 0LL, 0LL, len, buf, fromlen, &from);
+ if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
+
+ return out;
+}
+
+si_item_t *
+dns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, uint32_t class, uint32_t type, uint32_t *err)
+{
+ return _internal_item_call(si, call, name, ignored, class, type, err, MODULE_DNS);
+}
+
+si_item_t *
+mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, uint32_t class, uint32_t type, uint32_t *err)
+{
+ return _internal_item_call(si, call, name, ignored, class, type, err, MODULE_MDNS);
+}
+
+int
+dns_is_valid(si_mod_t *si, si_item_t *item)
+{
+ uint64_t now;
+ si_mod_t *src;
+
+ if (si == NULL) return 0;
+ if (item == NULL) return 0;
+ if (si->name == NULL) return 0;
+ if (item->src == NULL) return 0;
+
+ src = (si_mod_t *)item->src;
+
+ if (src->name == NULL) return 0;
+ if (string_not_equal(si->name, src->name)) return 0;
+
+ now = time(NULL);
+ if (item->validation_a < now) return 0;
+ return 1;
+}
+
+int
+mdns_is_valid(si_mod_t *si, si_item_t *item)
+{
+ return 0;
+}
+
+void
+dns_close(si_mod_t *si)
+{
+ dns_plugin_private_t *pp;
+
+ if (si == NULL) return;
+
+ pp = (dns_plugin_private_t *)si->private;
+ if (pp == NULL) return;
+
+ if (pp->dns != NULL) dns_free(pp->dns);
+ free(si->private);
+}
+
+int
+dns_init(si_mod_t *si)
+{
+ if (si == NULL) return 1;
+
+ si->vers = 1;
+
+ si->sim_close = dns_close;
+ si->sim_is_valid = dns_is_valid;
+ si->sim_host_byname = dns_host_byname;
+ si->sim_host_byaddr = dns_host_byaddr;
+ si->sim_item_call = dns_item_call;
+
+ return 0;
+}
+
+void
+mdns_close(si_mod_t *si)
+{
+ dns_close(si);
+}
+
+int
+mdns_init(si_mod_t *si)
+{
+ if (si == NULL) return 1;
+
+ si->vers = 1;
+
+ si->sim_close = dns_close;
+ si->sim_is_valid = mdns_is_valid;
+ si->sim_host_byname = mdns_host_byname;
+ si->sim_host_byaddr = mdns_host_byaddr;
+ si->sim_item_call = mdns_item_call;
+
+ return 0;
+}
+
#include <sys/cdefs.h>
+#define MDNS_HANDLE_NAME "*MDNS*"
+
#define DNS_FLAG_DEBUG 0x00000001
#define DNS_FLAG_CHECK_RESOLVER_DIR 0x00000002
#define DNS_FLAG_HAVE_IPV6_SERVER 0x00000004
r->name = _dns_parse_domain_name(p, x, remaining);
if (r->name == NULL)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
if (*remaining < 10)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_a:
if (*remaining < 4)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_aaaa:
if (*remaining < 16)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.CNAME->name = _dns_parse_domain_name(p, x, remaining);
if (r->data.CNAME->name == NULL)
{
- free(r->data.CNAME);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
break;
r->data.SOA->mname = _dns_parse_domain_name(p, x, remaining);
if (r->data.SOA->mname == NULL)
{
- free(r->data.SOA);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.SOA->rname = _dns_parse_domain_name(p, x, remaining);
if (r->data.SOA->rname == NULL)
{
- free(r->data.SOA->mname);
- free(r->data.SOA);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
if (*remaining < 20)
{
- free(r->data.SOA->mname);
- free(r->data.SOA->rname);
- free(r->data.SOA);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_wks:
if (*remaining < 5)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.HINFO->cpu = _dns_parse_string(p, x, remaining);
if (r->data.HINFO->cpu == NULL)
{
- free(r->data.HINFO);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.HINFO->os = _dns_parse_string(p, x, remaining);
if (r->data.HINFO->os == NULL)
{
- free(r->data.HINFO->cpu);
- free(r->data.HINFO);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.MINFO->rmailbx = _dns_parse_domain_name(p, x, remaining);
if (r->data.MINFO->rmailbx == NULL)
{
- free(r->data.MINFO);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.MINFO->emailbx = _dns_parse_domain_name(p, x, remaining);
if (r->data.MINFO->emailbx == NULL)
{
- free(r->data.MINFO->rmailbx);
- free(r->data.MINFO);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_mx:
if (*remaining < 2)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.MX->name = _dns_parse_domain_name(p, x, remaining);
if (r->data.MX->name == NULL)
{
- free(r->data.MX);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.TXT->strings[r->data.TXT->string_count] = _dns_parse_string(p, x, remaining);
if (r->data.TXT->strings[r->data.TXT->string_count] == NULL)
{
- free(r->data.TXT->strings);
- free(r->data.TXT);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.TXT->string_count++;
r->data.RP->mailbox = _dns_parse_domain_name(p, x, remaining);
if (r->data.RP->mailbox == NULL)
{
- free(r->data.RP);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.RP->txtdname = _dns_parse_domain_name(p, x, remaining);
if (r->data.RP->txtdname == NULL)
{
- free(r->data.RP->mailbox);
- free(r->data.RP);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_afsdb:
if (*remaining < 4)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.AFSDB->hostname = _dns_parse_domain_name(p, x, remaining);
if (r->data.AFSDB->hostname == NULL)
{
- free(r->data.AFSDB);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.X25->psdn_address = _dns_parse_string(p, x, remaining);
if (r->data.X25->psdn_address == NULL)
{
- free(r->data.X25);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.ISDN->isdn_address = _dns_parse_string(p, x, remaining);
if (r->data.ISDN->isdn_address == NULL)
{
- free(r->data.ISDN);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.ISDN->subaddress = _dns_parse_string(p, x, remaining);
if (r->data.ISDN->subaddress == NULL)
{
- free(r->data.ISDN->isdn_address);
- free(r->data.ISDN);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
}
case ns_t_rt:
if (*remaining < 2)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.RT->intermediate = _dns_parse_domain_name(p, x, remaining);
if (r->data.RT->intermediate == NULL)
{
- free(r->data.RT);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_loc:
if (*remaining < 16)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
case ns_t_srv:
if (*remaining < 6)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
r->data.SRV->target = _dns_parse_domain_name(p, x, remaining);
if (r->data.SRV->target == NULL)
{
- free(r->data.SRV);
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
default:
if (*remaining < rdlen)
{
- free(r);
+ dns_free_resource_record(r);
return NULL;
}
switch (r->dnstype)
{
case ns_t_a:
- free(r->data.A);
+ if (r->data.A != NULL) free(r->data.A);
break;
case ns_t_aaaa:
- free(r->data.AAAA);
+ if (r->data.AAAA != NULL) free(r->data.AAAA);
break;
case ns_t_ns:
case ns_t_mg:
case ns_t_mr:
case ns_t_ptr:
- free(r->data.CNAME->name);
- free(r->data.CNAME);
+ if (r->data.CNAME != NULL)
+ {
+ if (r->data.CNAME->name != NULL) free(r->data.CNAME->name);
+ free(r->data.CNAME);
+ }
break;
case ns_t_soa:
- free(r->data.SOA->mname);
- free(r->data.SOA->rname);
- free(r->data.SOA);
+ if (r->data.SOA != NULL)
+ {
+ if (r->data.SOA->mname != NULL) free(r->data.SOA->mname);
+ if (r->data.SOA->rname != NULL) free(r->data.SOA->rname);
+ free(r->data.SOA);
+ }
break;
case ns_t_wks:
- free(r->data.WKS->map);
- free(r->data.WKS);
+ if (r->data.WKS != NULL)
+ {
+ if (r->data.WKS->map != NULL) free(r->data.WKS->map);
+ free(r->data.WKS);
+ }
break;
case ns_t_hinfo:
- free(r->data.HINFO->cpu);
- free(r->data.HINFO->os);
- free(r->data.HINFO);
+ if (r->data.HINFO != NULL)
+ {
+ if (r->data.HINFO->cpu != NULL) free(r->data.HINFO->cpu);
+ if (r->data.HINFO->os != NULL) free(r->data.HINFO->os);
+ free(r->data.HINFO);
+ }
break;
case ns_t_minfo:
- free(r->data.MINFO->rmailbx);
- free(r->data.MINFO->emailbx);
- free(r->data.MINFO);
+ if (r->data.MINFO != NULL)
+ {
+ if (r->data.MINFO->rmailbx != NULL) free(r->data.MINFO->rmailbx);
+ if (r->data.MINFO->emailbx != NULL) free(r->data.MINFO->emailbx);
+ free(r->data.MINFO);
+ }
break;
case ns_t_mx:
- free(r->data.MX->name);
- free(r->data.MX);
+ if (r->data.MX != NULL)
+ {
+ if (r->data.MX->name != NULL) free(r->data.MX->name);
+ free(r->data.MX);
+ }
break;
case ns_t_txt:
- for (i=0; i<r->data.TXT->string_count; i++)
+ if (r->data.TXT != NULL)
{
- free(r->data.TXT->strings[i]);
+ for (i = 0; i < r->data.TXT->string_count; i++) free(r->data.TXT->strings[i]);
+ if (r->data.TXT->strings != NULL) free(r->data.TXT->strings);
+ free(r->data.TXT);
}
- if (r->data.TXT->strings != NULL)
- free(r->data.TXT->strings);
- free(r->data.TXT);
break;
case ns_t_rp:
- free(r->data.RP->mailbox);
- free(r->data.RP->txtdname);
- free(r->data.RP);
+ if (r->data.RP != NULL)
+ {
+ if (r->data.RP->mailbox != NULL) free(r->data.RP->mailbox);
+ if (r->data.RP->txtdname != NULL) free(r->data.RP->txtdname);
+ free(r->data.RP);
+ }
break;
case ns_t_afsdb:
- free(r->data.AFSDB->hostname);
- free(r->data.AFSDB);
+ if (r->data.AFSDB != NULL)
+ {
+ if (r->data.AFSDB->hostname != NULL) free(r->data.AFSDB->hostname);
+ free(r->data.AFSDB);
+ }
break;
case ns_t_x25:
- free(r->data.X25->psdn_address);
- free(r->data.X25);
+ if (r->data.X25 != NULL)
+ {
+ if (r->data.X25->psdn_address != NULL) free(r->data.X25->psdn_address);
+ free(r->data.X25);
+ }
break;
case ns_t_isdn:
- free(r->data.ISDN->isdn_address);
- if (r->data.ISDN->subaddress != NULL)
- free(r->data.ISDN->subaddress);
- free(r->data.ISDN);
+ if (r->data.ISDN != NULL)
+ {
+ if (r->data.ISDN->isdn_address != NULL) free(r->data.ISDN->isdn_address);
+ if (r->data.ISDN->subaddress != NULL) free(r->data.ISDN->subaddress);
+ free(r->data.ISDN);
+ }
break;
case ns_t_rt:
- free(r->data.RT->intermediate);
- free(r->data.RT);
+ if (r->data.RT != NULL)
+ {
+ if (r->data.RT->intermediate != NULL) free(r->data.RT->intermediate);
+ free(r->data.RT);
+ }
break;
case ns_t_loc:
- free(r->data.LOC);
+ if (r->data.LOC != NULL) free(r->data.LOC);
break;
case ns_t_srv:
- free(r->data.SRV->target);
- free(r->data.SRV);
+ if (r->data.SRV != NULL)
+ {
+ if (r->data.SRV->target != NULL) free(r->data.SRV->target);
+ free(r->data.SRV);
+ }
+ break;
+
+ case ns_t_invalid:
break;
case ns_t_null:
default:
- free(r->data.DNSNULL->data);
- free(r->data.DNSNULL);
+ if (r->data.DNSNULL != NULL)
+ {
+ if (r->data.DNSNULL->data != NULL) free(r->data.DNSNULL->data);
+ free(r->data.DNSNULL);
+ }
break;
}
#define _NAMESER_9_H_
#ifdef BIND_8_COMPAT
-#include <arpa/nameser8_compat.h>
-#else
+#include <arpa/nameser_compat.h>
+#endif
#include <sys/param.h>
#if (!defined(BSD)) || (BSD < 199306)
int ns_samename __P((const char *, const char *));
__END_DECLS
-#endif /* !BIND_8_COMPAT */
#endif /* !_NAMESER_9_H_ */
int n, m;
char *p;
- len = SPRINTF((tmp, "\\# %u (\t; %s", edata - rdata, comment));
+ len = SPRINTF((tmp, "\\# %u (\t; %s", (unsigned int)(edata - rdata), comment));
T(addstr(tmp, len, &buf, &buflen));
while (rdata < edata) {
p = tmp;
u_char *dnptrs[20], **dpp, **lastdnptr;
#ifdef __APPLE__
- n = (int)newrr_in; n = 0;
+ n = 0;
#else
UNUSED(newrr_in);
#endif
*/
extern uint32_t notify_register_plain(const char *name, int *out_token);
-__private_extern__ int res_query_mDNSResponder(res_state statp, const char *name, int class, int type, u_char *answer, int anslen, struct sockaddr *from, uint32_t *fromlen);
+extern int res_query_mDNSResponder(res_state statp, const char *name, int class, int type, u_char *answer, int anslen, struct sockaddr *from, uint32_t *fromlen);
int dns_res_once(struct sockaddr *server, struct timeval *timeout, int options, const char *name, int class, int type, u_char *res, int *reslen);
*/
void res_interrupt_requests_enable(void);
void res_interrupt_requests_disable(void);
-void res_interrupt_requests(void* token);
-void* res_init_interrupt_token(void);
-void res_delete_interrupt_token(void* token);
+void res_interrupt_request(void *token);
+void *res_init_interrupt_token(void);
+void res_delete_interrupt_token(void *token);
#endif
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+#include <notify.h>
+#include <pthread.h>
#ifndef __APPLE__
#include "port_after.h"
#endif
+/* interrupt mechanism is implemented in res_send.c */
+__private_extern__ int interrupt_pipe_enabled;
+__private_extern__ pthread_key_t interrupt_pipe_key;
+
/* Options. Leave them on. */
#define DEBUG
u_char *answer;
size_t anslen;
size_t ansmaxlen;
+ uint16_t lastanstype;
uint32_t ifnum;
+ uint32_t res_flags;
DNSServiceFlags flags;
DNSServiceErrorType error;
};
context->flags = flags;
context->error = errorCode;
- if (errorCode != kDNSServiceErr_NoError) return;
+ if (errorCode != kDNSServiceErr_NoError)
+ {
+ if (context->res_flags & RES_DEBUG) printf(";; res_query_mDNSResponder callback [%s %hu %hu]: error %u\n", fullname, rrtype, rrclass, errorCode);
+ return;
+ }
buflen = context->ansmaxlen - context->anslen;
- if (buflen < NS_HFIXEDSZ) return;
+ if (buflen < NS_HFIXEDSZ)
+ {
+ if (context->res_flags & RES_DEBUG) printf(";; res_query_mDNSResponder callback [%s %hu %hu]: malformed reply\n", fullname, rrtype, rrclass);
+ return;
+ }
dnlist[0] = context->answer + NS_HFIXEDSZ;
dnlist[1] = NULL;
cp = context->answer + context->anslen;
n = dn_comp((char *)fullname, cp, buflen, dnlist, &dnlist[1]);
- if (n < 0) return;
+ if (n < 0)
+ {
+ if (context->res_flags & RES_DEBUG) printf(";; res_query_mDNSResponder callback [%s %hu %hu]: name mismatch\n", fullname, rrtype, rrclass);
+ return;
+ }
/*
* Check that there is enough space in the buffer for the resource name (n),
* the resource record data (rdlen) and the resource record header (10).
*/
- if (buflen < n + rdlen + 10) return;
+ if (buflen < n + rdlen + 10)
+ {
+ if (context->res_flags & RES_DEBUG) printf(";; res_query_mDNSResponder callback [%s %hu %hu]: insufficient buffer space for reply\n", fullname, rrtype, rrclass);
+ return;
+ }
+
+ if (context->res_flags & RES_DEBUG) printf(";; res_query_mDNSResponder callback for %s %hu %hu\n", fullname, rrtype, rrclass);
cp += n;
buflen -= n;
context->anslen = (size_t)(cp - context->answer);
+ context->lastanstype = rrtype;
+
/*
* Save the interface number for the first AAAA record for link-local addresses.
* It's used by getaddrinfo to set the scope id.
return 1;
}
-__private_extern__ int
+int
res_query_mDNSResponder(res_state statp, const char *name, int class, int type, u_char *answer, int anslen, struct sockaddr *from, uint32_t *fromlen)
{
DNSServiceRef sdRef;
DNSServiceErrorType result;
struct res_query_context context;
- int i, kq, n, wait;
- struct kevent kv;
+ int i, kq, n, wait, cancelled, notify_token, status;
+ struct kevent mevent, ievent, event;
struct timeval ctv;
struct timespec now, finish, timeout;
HEADER *ans;
uint32_t iface;
uint16_t nibble;
- char *qname;
+ char *qname, *notify_name;
+ int *interrupt_pipe;
+ uint64_t exit_requested;
+
+ interrupt_pipe = NULL;
result = 0;
kq = -1;
ans = (HEADER *)answer;
-
+ cancelled = 0;
ans->rcode = 0;
memset(&context, 0, sizeof(struct res_query_context));
/* Build a dummy DNS header with question for the answer */
+ context.res_flags = statp->options;
context.answer = answer;
context.ansmaxlen = anslen;
context.anslen = res_nmkquery(statp, ns_o_query, name, class, type, NULL, 0, NULL, answer, anslen);
}
}
+ if (statp->options & RES_DEBUG) printf(";; res_query_mDNSResponder\n");
+
result = DNSServiceQueryRecord(&sdRef, kDNSServiceFlagsReturnIntermediates, iface, qname, type, class, res_query_callback, &context);
if (iface != 0) free(qname);
finish.tv_sec = ctv.tv_sec + statp->retrans;
finish.tv_nsec = ctv.tv_usec * 1000;
- EV_SET(&kv, DNSServiceRefSockFD(sdRef), EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0);
+ /* add mdns reply FD to kqueue */
+ EV_SET(&mevent, DNSServiceRefSockFD(sdRef), EVFILT_READ, EV_ADD, 0, 0, 0);
+ n = kevent(kq, &mevent, 1, NULL, 0, NULL);
+ if (n != 0) return 0;
+
+ /* add interrupt pipe to kqueue if interrupt is enabled */
+ if (interrupt_pipe_enabled != 0)
+ {
+ interrupt_pipe = pthread_getspecific(interrupt_pipe_key);
+ if (interrupt_pipe != NULL)
+ {
+ if (interrupt_pipe[0] >= 0)
+ {
+ EV_SET(&ievent, interrupt_pipe[0], EVFILT_READ, EV_ADD, 0, 0, (void *)name);
+ /* allow this to fail silently (should never happen, but it would only break interrupts */
+ n = kevent(kq, &ievent, 1, NULL, 0, NULL);
+ }
+ }
+ }
+
+ /*
+ * Get notification token
+ * we use a self-notification token to allow a caller
+ * to signal the thread doing this DNS query to quit.
+ */
+ notify_name = NULL;
+ notify_token = -1;
+
+ asprintf(¬ify_name, "self.thread.%lu", (unsigned long)pthread_self());
+ if (notify_name != NULL)
+ {
+ status = notify_register_plain(notify_name, ¬ify_token);
+ free(notify_name);
+ }
wait = 1;
while (wait == 1)
{
- n = kevent(kq, &kv, 1, &kv, 1, &timeout);
+ memset(&event, 0, sizeof(struct kevent));
+ n = kevent(kq, NULL, 0, &event, 1, &timeout);
+
+ if (notify_token != -1)
+ {
+ exit_requested = 0;
+ status = notify_get_state(notify_token, &exit_requested);
+ if (exit_requested == ThreadStateExitRequested)
+ {
+ /* interrupted */
+ if (statp->options & RES_DEBUG) printf(";; cancelled\n");
+ cancelled = 1;
+ break;
+ }
+ }
if (n < 0)
{
h_errno = TRY_AGAIN;
wait = 0;
}
+ else if (event.udata == (void *)name)
+ {
+ /* interrupted */
+ if (statp->options & RES_DEBUG) printf(";; cancelled\n");
+ cancelled = 1;
+ break;
+ }
else
{
result = DNSServiceProcessResult(sdRef);
wait = 0;
}
- if ((ans->ancount > 0) && ((context.flags & kDNSServiceFlagsMoreComing) == 0)) wait = 0;
+ if ((ans->ancount > 0) && ((context.flags & kDNSServiceFlagsMoreComing) == 0) && ((context.lastanstype != ns_t_cname) || (type == ns_t_cname))) wait = 0;
}
keep_waiting:
}
}
+ if (notify_token != -1) notify_cancel(notify_token);
DNSServiceRefDeallocate(sdRef);
close(kq);
- if (ans->ancount == 0) context.anslen = -1;
+ if ((ans->ancount == 0) || (cancelled == 1)) context.anslen = -1;
if ((from != NULL) && (fromlen != NULL) && (context.ifnum != 0))
{
static void Aerror(const res_state, FILE *, const char *, int, const struct sockaddr *, int);
static void Perror(const res_state, FILE *, const char *, int);
static int sock_eq(struct sockaddr *, struct sockaddr *);
-#ifdef NEED_PSELECT
-static int pselect(int, void *, void *, void *, struct timespec *, const sigset_t *);
+#ifdef USE_DNS_PSELECT
+static int dns_pselect(int, void *, void *, void *, struct timespec *, const sigset_t *);
#endif
static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
-static int interrupt_pipe_enabled = 0;
-static pthread_key_t interrupt_pipe_key;
+
+/* interrupt mechanism is shared with res_query.c */
+int interrupt_pipe_enabled = 0;
+pthread_key_t interrupt_pipe_key;
static int
bind_random(int sock)
return (evTimeSpec(now));
}
-#ifdef NEED_PSELECT
+#ifdef USE_DNS_PSELECT
static struct timeval
evTimeVal(struct timespec ts)
{
finish = evAddTime(now, timeout);
#endif /* __APPLE__ */
goto nonow;
- wait:
+wait:
now = evNowTime();
- nonow:
+nonow:
if (notify_token != -1)
{
if (evCmpTime(finish, now) > 0) timeout = evSubTime(finish, now);
else timeout = evConsTime(0, 0);
+#ifdef USE_DNS_PSELECT
+ n = dns_pselect(nfds, &dsmask, NULL, NULL, &timeout, NULL);
+#else
n = pselect(nfds, &dsmask, NULL, NULL, &timeout, NULL);
+#endif
if (n == 0)
{
Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
}
}
-#ifdef NEED_PSELECT
-/* XXX needs to move to the porting library. */
+#ifdef USE_DNS_PSELECT
static int
-pselect(int nfds, void *rfds, void *wfds, void *efds, struct timespec *tsp, const sigset_t *sigmask)
+dns_pselect(int nfds, void *rfds, void *wfds, void *efds, struct timespec *tsp, const sigset_t *sigmask)
{
struct timeval tv, *tvp = NULL;
sigset_t sigs;
#ifndef _RESOLV_9_H_
#define _RESOLV_9_H_
-#ifdef BIND_8_COMPAT
-#include <resolv8_compat.h>
-#else
-
#include <sys/param.h>
#if (!defined(BSD)) || (BSD < 199306)
# include <sys/bitypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
-#include <arpa/nameser.h>
-
+#include <nameser.h>
/*
* Revision information. This is the release date in YYYYMMDD format.
int res_getservers __P((res_state, union res_sockaddr_union *, int));
__END_DECLS
-#endif /* !BIND_8_COMPAT */
#endif /* !_RESOLV_9_H_ */
.Fa answer
buffer with length
.Fa anslen
-supplied by the caller.
+supplied by the caller. Constants for
+.Fa type
+and
+.Fa class
+are defined in
+.Aq Pa arpa/nameser.h .
.Pp
The
.Fn res_search
entry
expands the compressed domain name
.Fa comp_dn
-to a full domain name
+to a full domain name.
The compressed name is contained in a query or reply message;
.Fa msg
is a pointer to the beginning of the message.
This option is normally not required by the Mac OS X DNS search system
when the resolver configuration is read from a file in the
.Pa /etc/resolver
-directroy.
+directory.
In that case the file name is used as the domain name.
However,
.Sx domain
file and
in the files found in the
.Pa /etc/resolver
-directroy.
+directory.
However, client configurations are not limited to file storage.
The implementation of the DNS multi-client search strategy may also locate
client configuratins in other data sources, such as the System Configuration