]> git.saurik.com Git - apple/libresolv.git/commitdiff
libresolv-38.tar.gz mac-os-x-106 mac-os-x-1061 mac-os-x-1062 v38
authorApple <opensource@apple.com>
Mon, 20 Apr 2009 21:27:09 +0000 (21:27 +0000)
committerApple <opensource@apple.com>
Mon, 20 Apr 2009 21:27:09 +0000 (21:27 +0000)
18 files changed:
APPLE_LICENSE [new file with mode: 0644]
BUILD [new file with mode: 0644]
Makefile
Makefile.preamble
dns.c
dns_async.c
dns_plugin.c [new file with mode: 0644]
dns_private.h
dns_util.c
nameser.h
ns_print.c
res_mkquery.c
res_private.h
res_query.c
res_send.c
resolv.h
resolver.3
resolver.5

diff --git a/APPLE_LICENSE b/APPLE_LICENSE
new file mode 100644 (file)
index 0000000..fe81a60
--- /dev/null
@@ -0,0 +1,367 @@
+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."
diff --git a/BUILD b/BUILD
new file mode 100644 (file)
index 0000000..5a42a1e
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,191 @@
+#! /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
index 9f285732316f16916f12bb934e735cfd7c73c4c3..1f10d4f8fa45ef50ebeec32962505cfc3abf8202 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,6 @@
-#
-# 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
 
 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
@@ -22,43 +12,45 @@ CFILES = base64.c dns.c dns_async.c dns_util.c dst_api.c\
          res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c\
          res_query.c res_send.c res_sendsigned.c res_update.c
 
          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
index e50fc53f62e68012064e33bfdb30ddb286b44082..046bb8dc29eb66ba3f9f9694791311c7c4238e0f 100644 (file)
@@ -1,3 +1,4 @@
+OTHER_LDFLAGS += -undefined dynamic_lookup
 PUBLIC_HEADER_DIR=/usr/include
 PUBLIC_HEADER_DIR_SUFFIX = 
 ARPA_HEADER_DIR_SUFFIX = /arpa
 PUBLIC_HEADER_DIR=/usr/include
 PUBLIC_HEADER_DIR_SUFFIX = 
 ARPA_HEADER_DIR_SUFFIX = /arpa
diff --git a/dns.c b/dns.c
index 7c5ceb425029576166436d3ea44db690f275d0bc..fa2e658a7733e99fa9505f7de847331b9b01230e 100644 (file)
--- a/dns.c
+++ b/dns.c
 
 #define DNS_RESOLVER_DIR "/etc/resolver"
 
 
 #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 NOTIFY_DIR_NAME "com.apple.system.dns.resolver.dir"
 #define DNS_DELAY_NAME "com.apple.system.dns.delay"
 
 
 #define MDNS_MIN_TTL 2
 
 
 #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);
 extern uint32_t notify_monitor_file(int token, const char *name, int flags);
 
 extern void res_client_close(res_state res);
@@ -472,6 +481,43 @@ _pdns_convert_sc(dns_resolver_t *r)
        return pdns;
 }
 
        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.
  */
 /*
  * Open a named resolver client from the system config data.
  */
@@ -740,8 +786,17 @@ _check_cache(sdns_handle_t *sdns)
        sc_dns_count = 0;
        if ((sc_dns != NULL) && (sc_dns->n_resolver > 0))
        {
        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
                _pdns_check_search_list(sdns->pdns_primary);
        }
        else
@@ -882,7 +937,7 @@ _pdns_get_default_handles(sdns_handle_t *sdns, pdns_handle_t ***pdns)
 }
 
 static uint32_t
 }
 
 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;
 {
        char *p, *vname;
        int i, j, k, count;
@@ -906,9 +961,6 @@ _pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, uint32_t nlabe
                {
                        if (sdns->client[i]->name == NULL) continue;
 
                {
                        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 (!strcasecmp(sdns->client[i]->name, p))
                        {
                                if (count == 0)
@@ -942,7 +994,7 @@ _pdns_get_handles_for_name(sdns_handle_t *sdns, const char *name, uint32_t nlabe
 
        if (count != 0) return count;
 
 
        if (count != 0) return count;
 
-       return _pdns_get_default_handles(sdns, pdns);;
+       return _pdns_get_default_handles(sdns, pdns);
 }
 
 static void
 }
 
 static void
@@ -1024,11 +1076,45 @@ dns_handle_t
 dns_open(const char *name)
 {
        dns_private_handle_t *dns;
 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;
 
 
        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->handle_type = DNS_PRIVATE_HANDLE_TYPE_SUPER;
                dns->sdns = (sdns_handle_t *)calloc(1, sizeof(sdns_handle_t));
@@ -1044,6 +1130,31 @@ dns_open(const char *name)
                dns->sdns->notify_delay_token = -1;
                _dns_open_notify(dns->sdns);
 
                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 (dns_handle_t)dns;
        }
 
@@ -1059,6 +1170,7 @@ dns_open(const char *name)
                return NULL;
        }
 
                return NULL;
        }
 
+       dns_set_debug((dns_handle_t)dns, dns_control_debug);
        return (dns_handle_t)dns;
 }
 
        return (dns_handle_t)dns;
 }
 
@@ -1358,7 +1470,7 @@ _pdns_search(sdns_handle_t *sdns, pdns_handle_t *pdns, const char *name, uint32_
 }
 
 static int
 }
 
 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;
 {
        char *qname;
        pdns_handle_t **pdns;
@@ -1373,7 +1485,7 @@ _sdns_send(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t type,
        *min = -1;
        m = -1;
 
        *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;
 
 
        if (pdns_count == 0) return -1;
 
@@ -1412,7 +1524,7 @@ __private_extern__ int
 _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;
 _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;
        int m, tmin, minstate;
        char *dot, *qname;
        uint32_t pdns_count;
@@ -1455,9 +1567,6 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ
        /* the last dot is the last character, name is fully qualified */
        if ((fqdn == 0) && (dot != NULL) && (*(dot + 1) == '\0')) fqdn = 1;
 
        /* 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, or it's a FQDN, or if it's a PTR query,
         * we try a query with the name "as is".
@@ -1465,7 +1574,7 @@ _sdns_search(sdns_handle_t *sdns, const char *name, uint32_t class, uint32_t typ
        if ((n >= ndots) || (fqdn == 1) || (type == ns_t_ptr))
        {
                tmin = -1;
        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;
                if (status > 0) return status;
 
                if (tmin < 0) minstate = -1;
index 9aa367ac807b32abc0023bab5795e95f12b9f4fd..66bff8bf97f850935c81212560905a85acccebfa 100644 (file)
@@ -1,25 +1,24 @@
 /*
 /*
- * 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
  * 
  * 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,
  * 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 <stdlib.h>
 #include <arpa/inet.h>
 #include <dns.h>
 #include <dns_util.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
 {
 
 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
 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;
 
 
        *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)
 {
        return 0;
 }
 
 void
 dns_async_cancel(mach_port_t p)
 {
-       LI_async_call_cancel(p, NULL);
+       si_async_cancel(p);
 }
 
 int32_t
 }
 
 int32_t
@@ -149,156 +170,16 @@ dns_async_send(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dns
        return dns_async_start(p, name, dnsclass, dnstype, do_search, NULL, NULL);
 }
 
        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)
 {
 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)
 {
        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;
 }
        return 0;
 }
-
diff --git a/dns_plugin.c b/dns_plugin.c
new file mode 100644 (file)
index 0000000..58d8de6
--- /dev/null
@@ -0,0 +1,791 @@
+/*
+ * 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;
+}
+
index 1ca315d095e5eb5ce19b23c07a1d6986faa1807e..8320ab73c0629881588492ca4f8b5a73da448239 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <sys/cdefs.h>
 
 
 #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
 #define DNS_FLAG_DEBUG                    0x00000001
 #define DNS_FLAG_CHECK_RESOLVER_DIR       0x00000002
 #define DNS_FLAG_HAVE_IPV6_SERVER         0x00000004
index adb13249f617c7dcff6554980a2175ab2ade4c2d..b09c8170837a0370ae4a35c16d5da7584f51c905 100644 (file)
@@ -332,13 +332,13 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
        r->name = _dns_parse_domain_name(p, x, remaining);
        if (r->name == NULL)
        {
        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)
        {
                return NULL;
        }
 
        if (*remaining < 10)
        {
-               free(r);
+               dns_free_resource_record(r);
                return NULL;
        }
 
                return NULL;
        }
 
@@ -357,7 +357,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_a:
                        if (*remaining < 4)
                        {
                case ns_t_a:
                        if (*remaining < 4)
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -371,7 +371,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_aaaa:
                        if (*remaining < 16)
                        {
                case ns_t_aaaa:
                        if (*remaining < 16)
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -398,8 +398,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.CNAME->name = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.CNAME->name == 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;
                                return NULL;
                        }
                        break;
@@ -411,26 +410,20 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.SOA->mname = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.SOA->mname == NULL)
                        {
                        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)
                        {
                                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) 
                        {
                                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;
                        }
 
                                return NULL;
                        }
 
@@ -446,7 +439,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_wks:
                        if (*remaining < 5) 
                        {
                case ns_t_wks:
                        if (*remaining < 5) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -483,17 +476,14 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.HINFO->cpu = _dns_parse_string(p, x, remaining);
                        if (r->data.HINFO->cpu == 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)
                        {
                                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;
                        }
 
                                return NULL;
                        }
 
@@ -506,17 +496,14 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.MINFO->rmailbx = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.MINFO->rmailbx == 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)
                        {
                                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;
                        }
 
                                return NULL;
                        }
 
@@ -525,7 +512,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_mx:
                        if (*remaining < 2) 
                        {
                case ns_t_mx:
                        if (*remaining < 2) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -538,8 +525,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.MX->name = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.MX->name == 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;
                        }
 
                                return NULL;
                        }
 
@@ -565,9 +551,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                                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)
                                {
                                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++;
                                        return NULL;
                                }
                                r->data.TXT->string_count++;
@@ -582,17 +566,14 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.RP->mailbox = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.RP->mailbox == NULL)
                        {
                        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)
                        {
                                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;
                        }
 
                                return NULL;
                        }
 
@@ -601,7 +582,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_afsdb:
                        if (*remaining < 4) 
                        {
                case ns_t_afsdb:
                        if (*remaining < 4) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -613,8 +594,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.AFSDB->hostname = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.AFSDB->hostname == 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;
                        }
 
                                return NULL;
                        }
 
@@ -627,8 +607,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.X25->psdn_address = _dns_parse_string(p, x, remaining);
                        if (r->data.X25->psdn_address == 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;
                        }
 
                                return NULL;
                        }
 
@@ -641,8 +620,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.ISDN->isdn_address = _dns_parse_string(p, x, remaining);
                        if (r->data.ISDN->isdn_address == 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;
                        }
 
                                return NULL;
                        }
 
@@ -651,9 +629,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                                r->data.ISDN->subaddress = _dns_parse_string(p, x, remaining);
                                if (r->data.ISDN->subaddress == 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;
                                }
                        }
                                        return NULL;
                                }
                        }
@@ -667,7 +643,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_rt:
                        if (*remaining < 2) 
                        {
                case ns_t_rt:
                        if (*remaining < 2) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -680,8 +656,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.RT->intermediate = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.RT->intermediate == 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;
                        }
 
                                return NULL;
                        }
 
@@ -690,7 +665,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_loc:
                        if (*remaining < 16) 
                        {
                case ns_t_loc:
                        if (*remaining < 16) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -711,7 +686,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                case ns_t_srv:
                        if (*remaining < 6) 
                        {
                case ns_t_srv:
                        if (*remaining < 6) 
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -726,8 +701,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                        r->data.SRV->target = _dns_parse_domain_name(p, x, remaining);
                        if (r->data.SRV->target == 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;
                        }
 
                                return NULL;
                        }
 
@@ -737,7 +711,7 @@ _dns_parse_resource_record_internal(const char *p, char **x, int32_t *remaining)
                default:
                        if (*remaining < rdlen)
                        {
                default:
                        if (*remaining < rdlen)
                        {
-                               free(r);
+                               dns_free_resource_record(r);
                                return NULL;
                        }
 
                                return NULL;
                        }
 
@@ -915,11 +889,11 @@ dns_free_resource_record(dns_resource_record_t *r)
        switch (r->dnstype)
        {
                case ns_t_a:
        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:
                        break;
 
                case ns_t_aaaa:
-                       free(r->data.AAAA);
+                       if (r->data.AAAA != NULL) free(r->data.AAAA);
                        break;
 
                case ns_t_ns:
                        break;
 
                case ns_t_ns:
@@ -930,90 +904,130 @@ dns_free_resource_record(dns_resource_record_t *r)
                case ns_t_mg:
                case ns_t_mr:
                case ns_t_ptr:
                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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        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:
                        break;
 
                case ns_t_loc:
-                       free(r->data.LOC);
+                       if (r->data.LOC != NULL) free(r->data.LOC);
                        break;
 
                case ns_t_srv:
                        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:
                        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;
        }
 
                        break;
        }
 
index 8f402034e2933604ab34d33ae62d3c85e6913741..978ba5c17a8b2176499baad6fc4388169b587fe5 100644 (file)
--- a/nameser.h
+++ b/nameser.h
@@ -56,8 +56,8 @@
 #define _NAMESER_9_H_
 
 #ifdef BIND_8_COMPAT
 #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)
 
 #include <sys/param.h>
 #if (!defined(BSD)) || (BSD < 199306)
@@ -584,5 +584,4 @@ int         ns_makecanon __P((const char *, char *, size_t));
 int            ns_samename __P((const char *, const char *));
 __END_DECLS
 
 int            ns_samename __P((const char *, const char *));
 __END_DECLS
 
-#endif /* !BIND_8_COMPAT */
 #endif /* !_NAMESER_9_H_ */
 #endif /* !_NAMESER_9_H_ */
index fd9c71f10ceadd7a7239ef949e6b1579fcc7e947..1029839ae8ed1e6363bd8f9d289c2995aa427e25 100644 (file)
@@ -718,7 +718,7 @@ ns_sprintrrf(const u_char *msg, size_t msglen,
        int n, m;
        char *p;
 
        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;
        T(addstr(tmp, len, &buf, &buflen));
        while (rdata < edata) {
                p = tmp;
index 09e1cf30d5b9e4289f444eef519f011378e1be8d..7dcf45b7d567f38a799c0ca3f683351a875a1486 100644 (file)
@@ -115,7 +115,7 @@ res_nmkquery(res_state statp,
        u_char *dnptrs[20], **dpp, **lastdnptr;
 
 #ifdef __APPLE__
        u_char *dnptrs[20], **dpp, **lastdnptr;
 
 #ifdef __APPLE__
-       n = (int)newrr_in; n = 0;
+       n = 0;
 #else
        UNUSED(newrr_in);
 #endif
 #else
        UNUSED(newrr_in);
 #endif
index b9e076d3074acf8b259018f142f7518e10c6fcc5..34bf952fa22e1c39b97522a2aba733ac8afd12c5 100644 (file)
@@ -94,7 +94,7 @@ void res_client_close(res_state res);
  */
 extern uint32_t notify_register_plain(const char *name, int *out_token);
 
  */
 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);
 
 
 int dns_res_once(struct sockaddr *server, struct timeval *timeout, int options, const char *name, int class, int type, u_char *res, int *reslen);
 
@@ -103,8 +103,8 @@ int dns_res_once(struct sockaddr *server, struct timeval *timeout, int options,
  */
 void res_interrupt_requests_enable(void);
 void res_interrupt_requests_disable(void);
  */
 void res_interrupt_requests_enable(void);
 void res_interrupt_requests_disable(void);
-void res_interrupt_requests(void* token);
-voidres_init_interrupt_token(void);
-void res_delete_interrupt_token(voidtoken);
+void res_interrupt_request(void *token);
+void *res_init_interrupt_token(void);
+void res_delete_interrupt_token(void *token);
 
 #endif
 
 #endif
index 7df8c6c42a36230a12a9fe2992ca953aeb575616..d2e3760ac9958ff56e5c347ed2f6a5e765369bd8 100644 (file)
@@ -94,10 +94,16 @@ static const char rcsid[] = "$Id: res_query.c,v 1.1 2006/03/01 19:01:38 majka Ex
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
+#include <notify.h>
+#include <pthread.h>
 #ifndef __APPLE__
 #include "port_after.h"
 #endif
 
 #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
 
 /* Options.  Leave them on. */
 #define DEBUG
 
@@ -135,7 +141,9 @@ struct res_query_context
        u_char *answer;
        size_t anslen;
        size_t ansmaxlen;
        u_char *answer;
        size_t anslen;
        size_t ansmaxlen;
+       uint16_t lastanstype;
        uint32_t ifnum;
        uint32_t ifnum;
+       uint32_t res_flags;
        DNSServiceFlags flags;
        DNSServiceErrorType error;
 };
        DNSServiceFlags flags;
        DNSServiceErrorType error;
 };
@@ -155,10 +163,18 @@ res_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
        context->flags = flags;
        context->error = errorCode;
 
        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;
 
        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;
 
        dnlist[0] = context->answer + NS_HFIXEDSZ;
        dnlist[1] = NULL;
@@ -166,13 +182,23 @@ res_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
        cp = context->answer + context->anslen;
 
        n = dn_comp((char *)fullname, cp, buflen, dnlist, &dnlist[1]);
        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).
         */
 
        /*
         * 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;
 
        cp += n;
        buflen -= n;
@@ -197,6 +223,8 @@ res_query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
 
        context->anslen = (size_t)(cp - context->answer);
 
 
        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.
        /* 
         * Save the interface number for the first AAAA record for link-local addresses.
         * It's used by getaddrinfo to set the scope id.
@@ -266,29 +294,34 @@ _is_rev_link_local(const char *name)
        return 1;
 }
 
        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;
 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;
        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;
        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 */
        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);
        context.answer = answer;
        context.ansmaxlen = anslen;
        context.anslen = res_nmkquery(statp, ns_o_query, name, class, type, NULL, 0, NULL, answer, anslen);
@@ -338,6 +371,8 @@ res_query_mDNSResponder(res_state statp, const char *name, int class, int type,
                }
        }
 
                }
        }
 
+       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);
 
        result = DNSServiceQueryRecord(&sdRef, kDNSServiceFlagsReturnIntermediates, iface, qname, type, class, res_query_callback, &context);
        if (iface != 0) free(qname);
 
@@ -356,12 +391,59 @@ res_query_mDNSResponder(res_state statp, const char *name, int class, int type,
        finish.tv_sec = ctv.tv_sec + statp->retrans;
        finish.tv_nsec = ctv.tv_usec * 1000;
 
        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(&notify_name, "self.thread.%lu", (unsigned long)pthread_self());
+       if (notify_name != NULL) 
+       {
+               status = notify_register_plain(notify_name, &notify_token);
+               free(notify_name);
+       }
 
        wait = 1;
        while (wait == 1)
        {
 
        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)
                {
 
                if (n < 0)
                {
@@ -374,6 +456,13 @@ res_query_mDNSResponder(res_state statp, const char *name, int class, int type,
                        h_errno = TRY_AGAIN;
                        wait = 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);
                else
                {
                        result = DNSServiceProcessResult(sdRef);
@@ -384,7 +473,7 @@ res_query_mDNSResponder(res_state statp, const char *name, int class, int type,
                                wait = 0;
                        }
 
                                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:
                }
 
        keep_waiting:
@@ -410,10 +499,11 @@ res_query_mDNSResponder(res_state statp, const char *name, int class, int type,
                }
        }
 
                }
        }
 
+       if (notify_token != -1) notify_cancel(notify_token);
        DNSServiceRefDeallocate(sdRef);
        close(kq);
 
        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))
        {
 
        if ((from != NULL) && (fromlen != NULL) && (context.ifnum != 0))
        {
index 1018e6c247e05f2e0c2e1316b1ecb42254ab9e2d..d731ca269bf1c4b88154f9907922c14225587210 100644 (file)
@@ -146,13 +146,15 @@ static int                send_dg(res_state, const u_char *, int, u_char *, int *, int *, int,
 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 *);
 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;
 #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)
 
 static int
 bind_random(int sock)
@@ -297,7 +299,7 @@ evNowTime()
        return (evTimeSpec(now));
 }
 
        return (evTimeSpec(now));
 }
 
-#ifdef NEED_PSELECT
+#ifdef USE_DNS_PSELECT
 static struct timeval
 evTimeVal(struct timespec ts)
 {
 static struct timeval
 evTimeVal(struct timespec ts)
 {
@@ -1324,11 +1326,11 @@ send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int *anssiz
        finish = evAddTime(now, timeout);
 #endif /* __APPLE__ */
        goto nonow;
        finish = evAddTime(now, timeout);
 #endif /* __APPLE__ */
        goto nonow;
- wait:
 
 
+wait:
        now = evNowTime();
 
        now = evNowTime();
 
- nonow:
+nonow:
 
        if (notify_token != -1)
        {
 
        if (notify_token != -1)
        {
@@ -1357,7 +1359,11 @@ send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int *anssiz
        if (evCmpTime(finish, now) > 0) timeout = evSubTime(finish, now);
        else timeout = evConsTime(0, 0);
 
        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);
        n = pselect(nfds, &dsmask, NULL, NULL, &timeout, NULL);
+#endif
        if (n == 0)
        {
                Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
        if (n == 0)
        {
                Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
@@ -1553,10 +1559,9 @@ sock_eq(struct sockaddr *a, struct sockaddr *b)
        }
 }
 
        }
 }
 
-#ifdef NEED_PSELECT
-/* XXX needs to move to the porting library. */
+#ifdef USE_DNS_PSELECT
 static int
 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;
 {
        struct timeval tv, *tvp = NULL;
        sigset_t sigs;
index 2a36c2237a6e9d5c1dc6a9b0713efbd3ad925fc3..d2dbd439c3b181e6018e4f25c8d8796ecbc783c2 100644 (file)
--- a/resolv.h
+++ b/resolv.h
 #ifndef _RESOLV_9_H_
 #define        _RESOLV_9_H_
 
 #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/param.h>
 #if (!defined(BSD)) || (BSD < 199306)
 # include <sys/bitypes.h>
@@ -82,8 +78,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <stdio.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.
 
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
@@ -495,5 +490,4 @@ void                res_setservers __P((res_state, const union res_sockaddr_union *, int));
 int            res_getservers __P((res_state, union res_sockaddr_union *, int));
 __END_DECLS
 
 int            res_getservers __P((res_state, union res_sockaddr_union *, int));
 __END_DECLS
 
-#endif /* !BIND_8_COMPAT */
 #endif /* !_RESOLV_9_H_ */
 #endif /* !_RESOLV_9_H_ */
index cd03597a21fc2efe8e573d95a68d06ed2070cd87..9f891417ff7d093cb083e0ab3a4f178610a93cdd 100644 (file)
@@ -260,7 +260,12 @@ The reply message is left in the
 .Fa answer
 buffer with length
 .Fa anslen
 .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
 .Pp
 The
 .Fn res_search
@@ -350,7 +355,7 @@ The
 entry
 expands the compressed domain name
 .Fa comp_dn
 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.
 The compressed name is contained in a query or reply message;
 .Fa msg
 is a pointer to the beginning of the message.
index 81618077cdf3cfe08c98518e5edb1fcd73818ae2..27b5444e51f747e7d02cb4233e3110d161c84c0e 100644 (file)
@@ -86,7 +86,7 @@ Domain name associated with this resolver configuration.
 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
 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
 In that case the file name is used as the domain name.
 However, 
 .Sx domain
@@ -212,7 +212,7 @@ These are at present located by the system in the
 file and
 in the files found in the 
 .Pa /etc/resolver
 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
 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