diff --git a/admin-root/about.html b/admin-root/about.html
index 8186a1f0..cbe0991d 100644
--- a/admin-root/about.html
+++ b/admin-root/about.html
@@ -31,7 +31,6 @@ http://www.fireflymediaserver.org.
This program makes use of the following libraries and packages:
-- Apple's Bonjour v107.3 licensed under the Apache 2.0 License
- Fabrice Bellard's FFmpeg, licensed under the GPL License
- D. Richard Hipp's SQLite database, dedicated to the public domain
- Underbit Technologies' libid3tag, licensed under the GPL License
diff --git a/admin-root/apache-2.0.html b/admin-root/apache-2.0.html
deleted file mode 100644
index 677acd78..00000000
--- a/admin-root/apache-2.0.html
+++ /dev/null
@@ -1,9 +0,0 @@
-@include hdr.html@
-
-Apache 2.0 License
-
-
-@include apache-2.0.txt@
-
-
-@include ftr.html@
diff --git a/admin-root/apache-2.0.txt b/admin-root/apache-2.0.txt
deleted file mode 100644
index d6456956..00000000
--- a/admin-root/apache-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/configure.in b/configure.in
index 0cd36468..c7b5afa7 100644
--- a/configure.in
+++ b/configure.in
@@ -39,7 +39,6 @@ fi
AC_DEFINE_UNQUOTED(CONFFILE,"${CONFFILE}",Where the config file is)
-rend_posix=true
rend_avahi=false
db_sqlite=false
db_sqlite3=false
@@ -80,7 +79,7 @@ AC_ARG_ENABLE(sqlite3,[ --enable-sqlite3 Enable sqlite3 db backend],
AC_ARG_ENABLE(mdns,[ --enable-mdns Enable mDNS support],
[ case "${enableval}" in
yes) ;;
- no) rend_posix=false; rend_howl=false; rend_avahi=false; CPPFLAGS="${CPPFLAGS} -DWITHOUT_MDNS";;
+ no) rend_howl=false; rend_avahi=false; CPPFLAGS="${CPPFLAGS} -DWITHOUT_MDNS";;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-mdns);;
esac ])
@@ -90,7 +89,7 @@ AC_ARG_ENABLE(nslu2,[ --enable-nslu2 Build for NSLU2/uNSLUng],
AC_ARG_ENABLE(avahi,[ --enable-avahi Use avahi 0.6 or later],
[ case "${enableval}" in
yes) PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6 ]);
- rend_avahi=true; rend_howl=false; rend_posix=false; LDFLAGS="${LDFLAGS} $AVAHI_LIBS";
+ rend_avahi=true; rend_howl=false; LDFLAGS="${LDFLAGS} $AVAHI_LIBS";
CPPFLAGS="${CPPFLAGS} $AVAHI_CFLAGS -DWITH_AVAHI";;
no) rend_avahi=false;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-avahi);;
@@ -98,7 +97,7 @@ AC_ARG_ENABLE(avahi,[ --enable-avahi Use avahi 0.6 or later],
AC_ARG_ENABLE(howl,[ --enable-howl Use howl 0.9.2 or later],
[ case "${enableval}" in
- yes) rend_howl=true; rend_posix=false; rend_avahi=false; LIBS="${LIBS} -lhowl";
+ yes) rend_howl=true; rend_avahi=false; LIBS="${LIBS} -lhowl";
CPPFLAGS="${CPPFLAGS} -DWITH_HOWL";;
no) rend_howl=false;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-howl);;
@@ -137,7 +136,6 @@ AC_ARG_ENABLE(ssl,[ --enable-ssl Enable SSL support in web server],
CPPFLAGS="${CPPFLAGS} -DUSE_SSL"; use_ssl=true; )
AM_CONDITIONAL(COND_REND_HOWL, test x$rend_howl = xtrue)
-AM_CONDITIONAL(COND_REND_POSIX, test x$rend_posix = xtrue)
AM_CONDITIONAL(COND_REND_AVAHI, test x$rend_avahi = xtrue)
AM_CONDITIONAL(COND_OGGVORBIS, test x$use_oggvorbis = xtrue)
AM_CONDITIONAL(COND_FLAC, test x$use_flac = xtrue)
@@ -171,36 +169,6 @@ dnl Darwin's stupid cpp preprocessor....
echo Host type is $host
CPPFLAGS="$CPPFLAGS -DHOST='\"$host\"'"
-dnl
-dnl The apple mDNS stuff wants these compile flags.
-dnl
-
-case $host in
-*solaris*)
- CPPFLAGS="$CPPFLAGS -DNOT_HAVE_DAEMON -DNOT_HAVE_SA_LEN "
- CPPFLAGS="$CPPFLAGS -DNOT_HAVE_SOCKLEN_T -DNOT_HAVE_IF_NAMETOINDEX "
- CPPFLAGS="$CPPFLAGS -DLOG_PERROR=0 -D_XPG4_2 -D__EXTENSIONS__ "
- CPPFLAGS="$CPPFLAGS -DHAVE_BROKEN_RECVIF_NAME "
- CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
- LIBS="${LIBS} -lnsl -lsocket -lresolv";;
-*freebsd*)
- CPPFLAGS="$CPPFLAGS -DFREEBSD"
- LDFLAGS="${LDFLAGS} -Wl,--export-dynamic";;
-*linux*)
- CPPFLAGS="$CPPFLAGS -DNOT_HAVE_SA_LEN -DUSES_NETLINK -DHAVE_LINUX"
- LDFLAGS="${LDFLAGS} -Wl,--export-dynamic";;
-*openbsd*)
- CPPFLAGS="$CPPFLAGS -DHAVE_BROKEN_RECVDSTADDR"
- LDFLAGS="${LDFLAGS} -Wl,--export-dynamic";;
-*darwin*)
- CPPFLAGS="$CPPFLAGS -no-cpp-precomp -DMAC"
- LDFLAGS="$LDFLAGS -framework CoreFoundation"
-
- AM_CONDITIONAL(COND_REND_OSX,true)
- AM_CONDITIONAL(COND_REND_HOWL,false)
- AM_CONDITIONAL(COND_REND_POSIX,false);;
-esac
-
dnl Checks for libraries.
AC_ARG_WITH(static-libs,
[--with-static-libs[[=DIR]] use static libs in DIR],[
@@ -492,4 +460,4 @@ if test x$use_iconv = xtrue; then
LDFLAGS="${LDFLAGS} ${LIBICONV}"
fi
-AC_OUTPUT(src/Makefile src/plugins/Makefile admin-root/Makefile admin-root/lib-js/Makefile admin-root/lib-js/script.aculo.us/Makefile contrib/Makefile contrib/init.d/Makefile src/mdns/Makefile Makefile)
+AC_OUTPUT(src/Makefile src/plugins/Makefile admin-root/Makefile admin-root/lib-js/Makefile admin-root/lib-js/script.aculo.us/Makefile contrib/Makefile contrib/init.d/Makefile Makefile)
diff --git a/src/Makefile.am b/src/Makefile.am
index aef72a82..59940ea7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,13 +7,6 @@ bin_PROGRAMS = wavstreamer
LDADD=
-if COND_REND_POSIX
-SUBDIRS += mdns
-AM_CPPFLAGS = -I./mdns
-LDADD+=mdns/libmdns.la
-PRENDSRC=rend-unix.c rend-posix.c
-endif
-
if COND_REND_HOWL
HRENDSRC=rend-howl.c rend-unix.c
endif
@@ -72,11 +65,11 @@ mt_daapd_SOURCES = main.c daapd.h rend.h webserver.c \
os-unix.h os-unix.c os.h plugin.c plugin.h db-sql-updates.c \
memdebug.c memdebug.h ssl.h io.h io.c io-errors.h io-plugin.h \
bsd-snprintf.c bsd-snprintf.h \
- $(PRENDSRC) $(ORENDSRC) $(HRENDSRC) $(ARENDSRC) $(OGGVORBISSRC) \
+ $(ORENDSRC) $(HRENDSRC) $(ARENDSRC) $(OGGVORBISSRC) \
$(FLACSRC) $(MUSEPACKSRC) $(SQLITEDB) $(SQLITE3DB) $(SQLDB) $(GDBM) \
$(UPNP)
-EXTRA_DIST = rend-howl.c rend-posix.c rend-osx.c scan-mpc.c \
+EXTRA_DIST = rend-howl.c rend-osx.c scan-mpc.c \
scan-ogg.c scan-flac.c db-sql.c db-sql.h \
db-sql-sqlite2.h db-sql-sqlite2.c \
db-sql-sqlite3.h db-sql-sqlite3.c \
diff --git a/src/mdns/DNSCommon.c b/src/mdns/DNSCommon.c
deleted file mode 100644
index 34186343..00000000
--- a/src/mdns/DNSCommon.c
+++ /dev/null
@@ -1,2179 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- Change History (most recent first):
-
-$Log: DNSCommon.c,v $
-Revision 1.100.2.1 2006/08/29 06:24:22 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.100 2006/06/08 22:58:46 cheshire
- IPv6 link-local address prefix is FE80::/10, not FE80::/16
-
-Revision 1.99 2006/05/18 01:32:33 cheshire
- iChat: Lost connection with Bonjour
-(mDNSResponder insufficiently defensive against malformed browsing PTR responses)
-
-Revision 1.98 2006/03/19 17:00:58 cheshire
-Define symbol MaxMsg instead of using hard-coded constant value '80'
-
-Revision 1.97 2006/03/18 21:47:56 cheshire
- Improve logic for delaying packets after repeated interface transitions
-
-Revision 1.96 2006/03/10 21:51:42 cheshire
- After record update, old record sometimes remains in cache
-Split out SameRDataBody() into a separate routine so it can be called from other code
-
-Revision 1.95 2006/03/08 22:43:11 cheshire
-Use "localdomain" symbol instead of literal string
-
-Revision 1.94 2006/03/02 21:59:55 cheshire
- Spurious warning "GetLargeResourceRecord: m->rec appears to be already in use"
-Improve sanity checks & debugging support in GetLargeResourceRecord()
-
-Revision 1.93 2006/03/02 20:30:47 cheshire
-Improved GetRRDisplayString to also show priority, weight, and port for SRV records
-
-Revision 1.92 2005/09/16 21:06:49 cheshire
-Use mDNS_TimeNow_NoLock macro, instead of writing "mDNSPlatformRawTime() + m->timenow_adjust" all over the place
-
-Revision 1.91 2005/07/10 22:10:37 cheshire
-The getOptRdata routine implicitly assumes the destination ResourceRecord is large enough to
-hold MaximumRDSize bytes, but its parameter was a generic ResourceRecord, which need not be that
-large. Changing the parameter to a LargeCacheRecord makes it clearer what the routine requires.
-
-Revision 1.90 2005/03/21 00:33:51 shersche
- Fix build warnings on Win32 platform
-
-Revision 1.89 2005/03/17 18:59:38 ksekar
- Properly parse multiple LLQ Options per packet on Windows
-
-Revision 1.88 2005/03/16 00:42:32 ksekar
- Long-lived queries not working on Windows
-
-Revision 1.87 2005/02/25 04:21:00 cheshire
- mDNS -F returns the same domain multiple times with different casing
-
-Revision 1.86 2005/02/18 00:43:12 cheshire
- mDNSResponder should auto-truncate service names that are too long
-
-Revision 1.85 2005/02/10 22:35:17 cheshire
- Update name
-
-Revision 1.84 2005/02/03 00:44:38 cheshire
- DNSServiceUpdateRecord returns kDNSServiceErr_Invalid when rdlen=0, rdata=NULL
-
-Revision 1.83 2005/01/27 22:57:55 cheshire
-Fix compile errors on gcc4
-
-Revision 1.82 2005/01/19 03:27:03 cheshire
- CPU Spin in mDNSResponder
-GetNextScheduledEvent() needs to check LocalRecordReady()
-
-Revision 1.81 2004/12/18 03:13:45 cheshire
- kDNSServiceInterfaceIndexLocalOnly should return all local records
-
-Revision 1.80 2004/12/16 21:46:43 cheshire
-Add DNSTypeName case for kDNSType_SOA
-
-Revision 1.79 2004/12/16 21:38:37 cheshire
-Add DNSTypeName case for kDNSType_NS
-
-Revision 1.78 2004/12/16 21:27:37 ksekar
-Fixed build failures when compiled with verbose debugging messages
-
-Revision 1.77 2004/12/16 20:12:59 cheshire
- Cache memory management improvements
-
-Revision 1.76 2004/12/16 08:05:29 shersche
-Remove extranenous semicolons that cause compilation errors on Windows
-
-Revision 1.75 2004/12/15 02:11:22 ksekar
- Don't check for Dynamic DNS hostname uniqueness
-
-Revision 1.74 2004/12/09 22:49:15 ksekar
- Wide-Area Goodbyes broken
-
-Revision 1.73 2004/12/07 22:49:06 cheshire
- BIND doesn't allow zero-length TXT records
-
-Revision 1.72 2004/12/06 21:15:20 ksekar
- mDNSResponder crashed in CheckServiceRegistrations
-
-Revision 1.71 2004/12/04 02:12:45 cheshire
- mDNSResponder puts LargeCacheRecord on the stack
-
-Revision 1.70 2004/12/03 19:52:44 ksekar
-Use PutResourceRecordTTLJumbo for putDeletionRecord()
-
-Revision 1.69 2004/12/03 07:20:50 ksekar
- Wide-Area: Registration of large TXT record fails
-
-Revision 1.68 2004/11/24 00:10:43 cheshire
- For unicast operations, verify that service types are legal
-
-Revision 1.67 2004/10/26 03:52:02 cheshire
-Update checkin comments
-
-Revision 1.66 2004/10/23 01:16:00 cheshire
- uDNS operations not always reliable on multi-homed hosts
-
-Revision 1.65 2004/10/20 02:15:09 cheshire
-Add case in GetRRDisplayString() to display NS rdata
-
-Revision 1.64 2004/10/13 00:24:02 cheshire
-Disable "array is too small to include a terminating null character" warning on Windows
-
-Revision 1.63 2004/10/10 06:57:14 cheshire
-Change definition of "localdomain" to make code compile a little smaller
-
-Revision 1.62 2004/10/06 01:44:19 cheshire
- Resolving too quickly sometimes returns stale TXT record
-
-Revision 1.61 2004/09/30 00:24:56 ksekar
- Dynamically update default registration domains on config change
-
-Revision 1.60 2004/09/27 23:25:30 cheshire
-Fix compiler warning: soa.serial is signed, not unsigned
-
-Revision 1.59 2004/09/27 22:53:45 ksekar
-Fixed getLargeResourceRecord for SOA rdata.
-
-Revision 1.58 2004/09/25 02:41:39 cheshire
- Deliver near-pending "remove" events before new "add" events
-
-Revision 1.57 2004/09/25 02:24:27 cheshire
-Removed unused rr->UseCount
-
-Revision 1.56 2004/09/24 20:57:39 cheshire
- Eliminate inappropriate casts that cause misaligned-address errors
-
-Revision 1.55 2004/09/17 01:08:48 cheshire
-Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
- The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
- declared in that file are ONLY appropriate to single-address-space embedded applications.
- For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
-
-Revision 1.54 2004/09/17 00:49:51 cheshire
-Get rid of now-unused GetResourceRecord -- the correct (safe) routine to use
-is GetLargeResourceRecord
-
-Revision 1.53 2004/09/17 00:31:51 cheshire
-For consistency with ipv6, renamed rdata field 'ip' to 'ipv4'
-
-Revision 1.52 2004/09/17 00:19:10 cheshire
-For consistency with AllDNSLinkGroupv6, rename AllDNSLinkGroup to AllDNSLinkGroupv4
-
-Revision 1.51 2004/09/16 02:29:39 cheshire
-Moved mDNS_Lock/mDNS_Unlock to DNSCommon.c; Added necessary locking around
-uDNS_ReceiveMsg, uDNS_StartQuery, uDNS_UpdateRecord, uDNS_RegisterService
-
-Revision 1.50 2004/09/16 01:58:14 cheshire
-Fix compiler warnings
-
-Revision 1.49 2004/09/14 23:42:35 cheshire
- Need to seed random number generator from platform-layer data
-
-Revision 1.48 2004/09/14 23:27:46 cheshire
-Fix compile errors
-
-Revision 1.47 2004/08/25 02:50:04 cheshire
- Browses are no longer piggybacking on other browses
-Make mDNSSameAddress() recognise that two mDNSAddrType_None addresses are necessarily equal
-
-Revision 1.46 2004/08/18 17:35:40 ksekar
-: Feature #9586: Need support for Legacy NAT gateways
-
-Revision 1.45 2004/08/15 18:26:00 cheshire
-Don't use strcpy() on "struct domainname" objects; use AssignDomainName() instead
-(A "struct domainname" is a collection of packed pascal strings, not a C string.)
-
-Revision 1.44 2004/08/13 23:46:58 cheshire
-"asyncronous" -> "asynchronous"
-
-Revision 1.43 2004/08/12 02:55:46 ksekar
-Fix param order error moving putPrereqNameNotInUse from uDNS.c using
-ustrcpy macro to DNSCommon.c using mDNSPlatformStrCopy().
-
-Revision 1.42 2004/08/10 23:19:14 ksekar
-: DNS Extension daemon for Wide Area Service Discovery
-Moved routines/constants to allow extern access for garbage collection daemon
-
-Revision 1.41 2004/08/10 01:10:01 cheshire
- Current method of doing subtypes causes name collisions
-Minor revision from Roger Pantos
-
-Revision 1.40 2004/08/04 22:10:46 cheshire
- Current method of doing subtypes causes name collisions
-Change to use "._sub." instead of ".s." to mark subtypes.
-
-Revision 1.39 2004/07/13 21:24:24 rpantos
-Fix for .
-
-Revision 1.38 2004/06/18 21:08:58 cheshire
- Applications are registering invalid records
-Attempts to create domain names like "www..apple.com." now logged to aid debugging
-
-Revision 1.37 2004/06/18 20:25:42 cheshire
- Add a syslog message if someone tries to use "local.arpa".
-
-Revision 1.36 2004/06/18 19:09:59 cheshire
- Current method of doing subtypes causes name collisions
-
-Revision 1.35 2004/06/05 00:14:44 cheshire
-Fix signed/unsigned and other compiler warnings
-
-Revision 1.34 2004/06/04 00:25:25 cheshire
-Fix misaligned write exception that occurs on some platforms
-
-Revision 1.33 2004/06/04 00:16:18 cheshire
-Remove non-portable use of 'inline'
-
-Revision 1.32 2004/06/03 03:09:58 ksekar
-: Garbage Collection for Dynamic Updates
-
-Revision 1.31 2004/05/28 23:42:36 ksekar
-: Feature: DNS server->client notification on record changes (#7805)
-
-Revision 1.30 2004/05/26 09:08:04 bradley
-Added cast to correct structure pointer when allocating domain name list element to fix C++ builds.
-
-Revision 1.29 2004/05/18 23:51:25 cheshire
-Tidy up all checkin comments to use consistent "" format for bug numbers
-
-Revision 1.28 2004/05/13 04:54:20 ksekar
-Unified list copy/free code. Added symetric list for
-
-Revision 1.27 2004/04/22 20:29:07 cheshire
-Log error message if no count field passed to PutResourceRecordTTL()
-
-Revision 1.26 2004/04/22 04:07:01 cheshire
-Fix from Bob Bradley: Don't try to do inline functions on compilers that don't support it
-
-Revision 1.25 2004/04/22 03:05:28 cheshire
-kDNSClass_ANY should be kDNSQClass_ANY
-
-Revision 1.24 2004/04/22 02:51:20 cheshire
-Use common code for HINFO/TXT and TSIG cases in putRData
-
-Revision 1.23 2004/04/15 00:51:28 bradley
-Minor tweaks for Windows and C++ builds. Added casts for signed/unsigned integers and 64-bit pointers.
-Prefix some functions with mDNS to avoid conflicts. Disable benign warnings on Microsoft compilers.
-
-Revision 1.22 2004/04/14 23:09:28 ksekar
-Support for TSIG signed dynamic updates.
-
-Revision 1.21 2004/04/09 16:47:28 cheshire
-: mDNSResponder escape handling inconsistent with BIND
-
-Revision 1.20 2004/04/09 16:37:15 cheshire
-Suggestion from Bob Bradley:
-Move NumCacheRecordsForInterfaceID() to DNSCommon.c so it's available to all platform layers
-
-Revision 1.19 2004/04/02 19:34:38 cheshire
-Fix broken comment
-
-Revision 1.18 2004/03/30 06:45:00 cheshire
-Compiler warning fixes from Don Woodward at Roku Labs
-
-Revision 1.17 2004/03/19 22:25:20 cheshire
-: Need to limit service types to fourteen characters
-Won't actually do this for now, but keep the code around just in case
-
-Revision 1.16 2004/03/08 02:45:35 cheshire
-Minor change to make a couple of the log messages a bit shorter
-
-Revision 1.15 2004/03/08 02:44:09 cheshire
-: Need to limit service types to fourteen characters
-
-Revision 1.14 2004/02/21 02:06:24 cheshire
-Can't use anonymous unions -- they're non-standard and don't work on all compilers
-
-Revision 1.13 2004/02/06 23:04:18 ksekar
-Basic Dynamic Update support via mDNS_Register (dissabled via
-UNICAST_REGISTRATION #define)
-
-Revision 1.12 2004/02/03 22:37:10 cheshire
-Delete unused (commented-out) code
-
-Revision 1.11 2004/02/03 22:35:34 cheshire
-: Should not allow empty string for resolve domain
-
-Revision 1.10 2004/02/03 19:47:36 ksekar
-Added an asynchronous state machine mechanism to uDNS.c, including
-calls to find the parent zone for a domain name. Changes include code
-in repository previously dissabled via "#if 0 incomplete". Codepath
-is currently unused, and will be called to create update records, etc.
-
-Revision 1.9 2004/01/27 20:15:22 cheshire
-: Time to prune obsolete code for listening on port 53
-
-Revision 1.8 2004/01/24 23:24:36 cheshire
-Expanded out the list of local domains to reduce risk of mistakes in future
-
-Revision 1.7 2004/01/24 08:32:30 bradley
-Mask values with 0xFF before casting to avoid runtime truncation errors on Windows debug builds.
-Separated octal-escaped sequences preceding decimal digits to avoid errors with some compilers wanting
-to signal potentially hidden errors about the subsequent digit not being part of the octal sequence.
-
-Revision 1.6 2004/01/24 04:59:15 cheshire
-Fixes so that Posix/Linux, OS9, Windows, and VxWorks targets build again
-
-Revision 1.5 2004/01/23 23:23:14 ksekar
-Added TCP support for truncated unicast messages.
-
-Revision 1.4 2004/01/22 02:15:33 cheshire
-: Link-local reverse-mapping domains need to be resolved using link-local multicast
-
-Revision 1.3 2004/01/21 21:16:29 cheshire
-Minor tidy-up: Deleted a bunch of blank lines, trailing spaces, tabs, etc.
-
-Revision 1.2 2003/12/13 05:47:48 bradley
-Made local ptr const to fix error when assigning from const structure. Disable benign conditional
-expression is constant warning when building with Microsoft compilers.
-
-Revision 1.1 2003/12/13 03:05:27 ksekar
-: DynDNS: Unicast query of service records
-
- */
-
-// Set mDNS_InstantiateInlines to tell mDNSEmbeddedAPI.h to instantiate inline functions, if necessary
-#define mDNS_InstantiateInlines 1
-#include "DNSCommon.h"
-
-// Disable certain benign warnings with Microsoft compilers
-#if (defined(_MSC_VER))
- // Disable "conditional expression is constant" warning for debug macros.
- // Otherwise, this generates warnings for the perfectly natural construct "while(1)"
- // If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
- #pragma warning(disable:4127)
- // Disable "array is too small to include a terminating null character" warning
- // -- domain labels have an initial length byte, not a terminating null character
- #pragma warning(disable:4295)
-#endif
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - DNameList copy/deallocation routines
-#endif
-
-mDNSexport DNameListElem *mDNS_CopyDNameList(const DNameListElem *orig)
- {
- DNameListElem *copy = mDNSNULL, *newelem;
- const DNameListElem *ptr;
-
- for (ptr = orig; ptr; ptr = ptr->next)
- {
- newelem = (DNameListElem*)mDNSPlatformMemAllocate(sizeof(DNameListElem));
- if (!newelem) { LogMsg("ERROR: malloc"); return mDNSNULL; }
- AssignDomainName(&newelem->name, &ptr->name);
- newelem->next = copy;
- copy = newelem;
- }
- return copy;
- }
-
-mDNSexport void mDNS_FreeDNameList(DNameListElem *list)
- {
- DNameListElem *fptr;
-
- while (list)
- {
- fptr = list;
- list = list->next;
- mDNSPlatformMemFree(fptr);
- }
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - General Utility Functions
-#endif
-
-// return true for RFC1918 private addresses
-mDNSexport mDNSBool IsPrivateV4Addr(mDNSAddr *addr)
- {
- mDNSu8 *b;
-
- if (addr->type != mDNSAddrType_IPv4) return mDNSfalse;
- b = addr->ip.v4.b;
-
- return ((b[0] == 10) || // 10/8 prefix
- (b[0] == 172 && b[1] > 15 && b[1] < 32) || // 172.16/12
- (b[0] == 192 && b[1] == 168)); // 192.168/16
- }
-
-mDNSexport const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf)
- {
- while (intf && !intf->InterfaceActive) intf = intf->next;
- return(intf);
- }
-
-mDNSexport mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf)
- {
- const NetworkInterfaceInfo *next = GetFirstActiveInterface(intf->next);
- if (next) return(next->InterfaceID); else return(mDNSNULL);
- }
-
-mDNSexport mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id)
- {
- mDNSu32 slot, used = 0;
- CacheGroup *cg;
- CacheRecord *rr;
- FORALL_CACHERECORDS(slot, cg, rr)
- if (rr->resrec.InterfaceID == id) used++;
- return(used);
- }
-
-mDNSexport char *DNSTypeName(mDNSu16 rrtype)
- {
- switch (rrtype)
- {
- case kDNSType_A: return("Addr");
- case kDNSType_NS: return("NS");
- case kDNSType_CNAME:return("CNAME");
- case kDNSType_SOA: return("SOA");
- case kDNSType_NULL: return("NULL");
- case kDNSType_PTR: return("PTR");
- case kDNSType_HINFO:return("HINFO");
- case kDNSType_TXT: return("TXT");
- case kDNSType_AAAA: return("AAAA");
- case kDNSType_SRV: return("SRV");
- case kDNSQType_ANY: return("ANY");
- default: {
- static char buffer[16];
- mDNS_snprintf(buffer, sizeof(buffer), "(%d)", rrtype);
- return(buffer);
- }
- }
- }
-
-// Note slight bug: this code uses the rdlength from the ResourceRecord object, to display
-// the rdata from the RDataBody object. Sometimes this could be the wrong length -- but as
-// long as this routine is only used for debugging messages, it probably isn't a big problem.
-mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *rr, RDataBody *rd, char *buffer)
- {
- #define Max (MaxMsg-1)
- char *ptr = buffer;
- mDNSu32 length = mDNS_snprintf(buffer, Max, "%4d %##s %s ", rr->rdlength, rr->name->c, DNSTypeName(rr->rrtype));
- switch (rr->rrtype)
- {
- case kDNSType_A: mDNS_snprintf(buffer+length, Max-length, "%.4a", &rd->ipv4); break;
-
- case kDNSType_NS: // Same as PTR
- case kDNSType_CNAME:// Same as PTR
- case kDNSType_PTR: mDNS_snprintf(buffer+length, Max-length, "%##s", rd->name.c); break;
-
- case kDNSType_HINFO:// Display this the same as TXT (just show first string)
- case kDNSType_TXT: mDNS_snprintf(buffer+length, Max-length, "%#s", rd->txt.c); break;
-
- case kDNSType_AAAA: mDNS_snprintf(buffer+length, Max-length, "%.16a", &rd->ipv6); break;
- case kDNSType_SRV: mDNS_snprintf(buffer+length, Max-length, "%u %u %u %##s",
- rd->srv.priority, rd->srv.weight, mDNSVal16(rd->srv.port), rd->srv.target.c); break;
- default: mDNS_snprintf(buffer+length, Max-length, "RDLen %d: %s", rr->rdlength, rd->data); break;
- }
- for (ptr = buffer; *ptr; ptr++) if (*ptr < ' ') *ptr='.';
- return(buffer);
- }
-
-mDNSexport mDNSu32 mDNSRandom(mDNSu32 max)
- {
- static mDNSu32 seed = 0;
- mDNSu32 mask = 1;
-
- if (!seed)
- {
- int i;
- seed = mDNSPlatformRandomSeed(); // Pick an initial seed
- for (i=0; i<100; i++) seed = seed * 21 + 1; // And mix it up a bit
- }
- while (mask < max) mask = (mask << 1) | 1;
- do seed = seed * 21 + 1; while ((seed & mask) > max);
- return (seed & mask);
- }
-
-mDNSexport mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max)
- {
- mDNSu32 mask = 1;
- while (mask < max) mask = (mask << 1) | 1;
- do seed = seed * 21 + 1; while ((seed & mask) > max);
- return (seed & mask);
- }
-
-mDNSexport mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2)
- {
- if (ip1->type == ip2->type)
- {
- switch (ip1->type)
- {
- case mDNSAddrType_None : return(mDNStrue); // Empty addresses have no data and are therefore always equal
- case mDNSAddrType_IPv4 : return(mDNSBool)(mDNSSameIPv4Address(ip1->ip.v4, ip2->ip.v4));
- case mDNSAddrType_IPv6 : return(mDNSBool)(mDNSSameIPv6Address(ip1->ip.v6, ip2->ip.v6));
- }
- }
- return(mDNSfalse);
- }
-
-mDNSexport mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
- {
- switch(ip->type)
- {
- case mDNSAddrType_IPv4: return(mDNSBool)(ip->ip.v4.NotAnInteger == AllDNSLinkGroupv4.NotAnInteger);
- case mDNSAddrType_IPv6: return(mDNSBool)(ip->ip.v6.l[0] == AllDNSLinkGroupv6.l[0] &&
- ip->ip.v6.l[1] == AllDNSLinkGroupv6.l[1] &&
- ip->ip.v6.l[2] == AllDNSLinkGroupv6.l[2] &&
- ip->ip.v6.l[3] == AllDNSLinkGroupv6.l[3] );
- default: return(mDNSfalse);
- }
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - Domain Name Utility Functions
-#endif
-
-mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
- {
- int i;
- const int len = *a++;
-
- if (len > MAX_DOMAIN_LABEL)
- { debugf("Malformed label (too long)"); return(mDNSfalse); }
-
- if (len != *b++) return(mDNSfalse);
- for (i=0; ic;
- const mDNSu8 * b = d2->c;
- const mDNSu8 *const max = d1->c + MAX_DOMAIN_NAME; // Maximum that's valid
-
- while (*a || *b)
- {
- if (a + 1 + *a >= max)
- { debugf("Malformed domain name (more than 255 characters)"); return(mDNSfalse); }
- if (!SameDomainLabel(a, b)) return(mDNSfalse);
- a += 1 + *a;
- b += 1 + *b;
- }
-
- return(mDNStrue);
- }
-
-mDNSexport mDNSBool IsLocalDomain(const domainname *d)
- {
- // Domains that are defined to be resolved via link-local multicast are:
- // local., 254.169.in-addr.arpa., and {8,9,A,B}.E.F.ip6.arpa.
- static const domainname *nL = (domainname*)"\x5" "local";
- static const domainname *nR = (domainname*)"\x3" "254" "\x3" "169" "\x7" "in-addr" "\x4" "arpa";
- static const domainname *n8 = (domainname*)"\x1" "8" "\x1" "e" "\x1" "f" "\x3" "ip6" "\x4" "arpa";
- static const domainname *n9 = (domainname*)"\x1" "9" "\x1" "e" "\x1" "f" "\x3" "ip6" "\x4" "arpa";
- static const domainname *nA = (domainname*)"\x1" "a" "\x1" "e" "\x1" "f" "\x3" "ip6" "\x4" "arpa";
- static const domainname *nB = (domainname*)"\x1" "b" "\x1" "e" "\x1" "f" "\x3" "ip6" "\x4" "arpa";
-
- const domainname *d1, *d2, *d3, *d4, *d5, *d6; // Top-level domain, second-level domain, etc.
- d1 = d2 = d3 = d4 = d5 = d6 = mDNSNULL;
- while (d->c[0])
- {
- d6 = d5; d5 = d4; d4 = d3; d3 = d2; d2 = d1; d1 = d;
- d = (domainname*)(d->c + 1 + d->c[0]);
- }
-
- if (d1 && SameDomainName(d1, nL)) return(mDNStrue);
- if (d4 && SameDomainName(d4, nR)) return(mDNStrue);
- if (d6 && SameDomainName(d6, n8)) return(mDNStrue);
- if (d6 && SameDomainName(d6, n9)) return(mDNStrue);
- if (d6 && SameDomainName(d6, nA)) return(mDNStrue);
- if (d6 && SameDomainName(d6, nB)) return(mDNStrue);
- return(mDNSfalse);
- }
-
-// Returns length of a domain name INCLUDING the byte for the final null label
-// i.e. for the root label "." it returns one
-// For the FQDN "com." it returns 5 (length byte, three data bytes, final zero)
-// Legal results are 1 (just root label) to 255 (MAX_DOMAIN_NAME)
-// If the given domainname is invalid, result is 256
-mDNSexport mDNSu16 DomainNameLength(const domainname *const name)
- {
- const mDNSu8 *src = name->c;
- while (*src)
- {
- if (*src > MAX_DOMAIN_LABEL) return(MAX_DOMAIN_NAME+1);
- src += 1 + *src;
- if (src - name->c >= MAX_DOMAIN_NAME) return(MAX_DOMAIN_NAME+1);
- }
- return((mDNSu16)(src - name->c + 1));
- }
-
-// CompressedDomainNameLength returns the length of a domain name INCLUDING the byte
-// for the final null label i.e. for the root label "." it returns one.
-// E.g. for the FQDN "foo.com." it returns 9
-// (length, three data bytes, length, three more data bytes, final zero).
-// In the case where a parent domain name is provided, and the given name is a child
-// of that parent, CompressedDomainNameLength returns the length of the prefix portion
-// of the child name, plus TWO bytes for the compression pointer.
-// E.g. for the name "foo.com." with parent "com.", it returns 6
-// (length, three data bytes, two-byte compression pointer).
-mDNSexport mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent)
- {
- const mDNSu8 *src = name->c;
- if (parent && parent->c[0] == 0) parent = mDNSNULL;
- while (*src)
- {
- if (*src > MAX_DOMAIN_LABEL) return(MAX_DOMAIN_NAME+1);
- if (parent && SameDomainName((domainname *)src, parent)) return((mDNSu16)(src - name->c + 2));
- src += 1 + *src;
- if (src - name->c >= MAX_DOMAIN_NAME) return(MAX_DOMAIN_NAME+1);
- }
- return((mDNSu16)(src - name->c + 1));
- }
-
-// AppendLiteralLabelString appends a single label to an existing (possibly empty) domainname.
-// The C string contains the label as-is, with no escaping, etc.
-// Any dots in the name are literal dots, not label separators
-// If successful, AppendLiteralLabelString returns a pointer to the next unused byte
-// in the domainname bufer (i.e., the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
-// AppendLiteralLabelString returns mDNSNULL.
-mDNSexport mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *cstr)
- {
- mDNSu8 * ptr = name->c + DomainNameLength(name) - 1; // Find end of current name
- const mDNSu8 *const lim1 = name->c + MAX_DOMAIN_NAME - 1; // Limit of how much we can add (not counting final zero)
- const mDNSu8 *const lim2 = ptr + 1 + MAX_DOMAIN_LABEL;
- const mDNSu8 *const lim = (lim1 < lim2) ? lim1 : lim2;
- mDNSu8 *lengthbyte = ptr++; // Record where the length is going to go
-
- while (*cstr && ptr < lim) *ptr++ = (mDNSu8)*cstr++; // Copy the data
- *lengthbyte = (mDNSu8)(ptr - lengthbyte - 1); // Fill in the length byte
- *ptr++ = 0; // Put the null root label on the end
- if (*cstr) return(mDNSNULL); // Failure: We didn't successfully consume all input
- else return(ptr); // Success: return new value of ptr
- }
-
-// AppendDNSNameString appends zero or more labels to an existing (possibly empty) domainname.
-// The C string is in conventional DNS syntax:
-// Textual labels, escaped as necessary using the usual DNS '\' notation, separated by dots.
-// If successful, AppendDNSNameString returns a pointer to the next unused byte
-// in the domainname bufer (i.e., the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
-// AppendDNSNameString returns mDNSNULL.
-mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstring)
- {
- const char *cstr = cstring;
- mDNSu8 * ptr = name->c + DomainNameLength(name) - 1; // Find end of current name
- const mDNSu8 *const lim = name->c + MAX_DOMAIN_NAME - 1; // Limit of how much we can add (not counting final zero)
- while (*cstr && ptr < lim) // While more characters, and space to put them...
- {
- mDNSu8 *lengthbyte = ptr++; // Record where the length is going to go
- if (*cstr == '.') { LogMsg("AppendDNSNameString: Illegal empty label in name \"%s\"", cstring); return(mDNSNULL); }
- while (*cstr && *cstr != '.' && ptr < lim) // While we have characters in the label...
- {
- mDNSu8 c = (mDNSu8)*cstr++; // Read the character
- if (c == '\\') // If escape character, check next character
- {
- c = (mDNSu8)*cstr++; // Assume we'll just take the next character
- if (mdnsIsDigit(cstr[-1]) && mdnsIsDigit(cstr[0]) && mdnsIsDigit(cstr[1]))
- { // If three decimal digits,
- int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
- int v1 = cstr[ 0] - '0';
- int v2 = cstr[ 1] - '0';
- int val = v0 * 100 + v1 * 10 + v2;
- if (val <= 255) { c = (mDNSu8)val; cstr += 2; } // If valid three-digit decimal value, use it
- }
- }
- *ptr++ = c; // Write the character
- }
- if (*cstr) cstr++; // Skip over the trailing dot (if present)
- if (ptr - lengthbyte - 1 > MAX_DOMAIN_LABEL) // If illegal label, abort
- return(mDNSNULL);
- *lengthbyte = (mDNSu8)(ptr - lengthbyte - 1); // Fill in the length byte
- }
-
- *ptr++ = 0; // Put the null root label on the end
- if (*cstr) return(mDNSNULL); // Failure: We didn't successfully consume all input
- else return(ptr); // Success: return new value of ptr
- }
-
-// AppendDomainLabel appends a single label to a name.
-// If successful, AppendDomainLabel returns a pointer to the next unused byte
-// in the domainname bufer (i.e., the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
-// AppendDomainLabel returns mDNSNULL.
-mDNSexport mDNSu8 *AppendDomainLabel(domainname *const name, const domainlabel *const label)
- {
- int i;
- mDNSu8 *ptr = name->c + DomainNameLength(name) - 1;
-
- // Check label is legal
- if (label->c[0] > MAX_DOMAIN_LABEL) return(mDNSNULL);
-
- // Check that ptr + length byte + data bytes + final zero does not exceed our limit
- if (ptr + 1 + label->c[0] + 1 > name->c + MAX_DOMAIN_NAME) return(mDNSNULL);
-
- for (i=0; i<=label->c[0]; i++) *ptr++ = label->c[i]; // Copy the label data
- *ptr++ = 0; // Put the null root label on the end
- return(ptr);
- }
-
-mDNSexport mDNSu8 *AppendDomainName(domainname *const name, const domainname *const append)
- {
- mDNSu8 * ptr = name->c + DomainNameLength(name) - 1; // Find end of current name
- const mDNSu8 *const lim = name->c + MAX_DOMAIN_NAME - 1; // Limit of how much we can add (not counting final zero)
- const mDNSu8 * src = append->c;
- while(src[0])
- {
- int i;
- if (ptr + 1 + src[0] > lim) return(mDNSNULL);
- for (i=0; i<=src[0]; i++) *ptr++ = src[i];
- *ptr = 0; // Put the null root label on the end
- src += i;
- }
- return(ptr);
- }
-
-// MakeDomainLabelFromLiteralString makes a single domain label from a single literal C string (with no escaping).
-// If successful, MakeDomainLabelFromLiteralString returns mDNStrue.
-// If unable to convert the whole string to a legal domain label (i.e. because length is more than 63 bytes) then
-// MakeDomainLabelFromLiteralString makes a legal domain label from the first 63 bytes of the string and returns mDNSfalse.
-// In some cases silently truncated oversized names to 63 bytes is acceptable, so the return result may be ignored.
-// In other cases silent truncation may not be acceptable, so in those cases the calling function needs to check the return result.
-mDNSexport mDNSBool MakeDomainLabelFromLiteralString(domainlabel *const label, const char *cstr)
- {
- mDNSu8 * ptr = label->c + 1; // Where we're putting it
- const mDNSu8 *const limit = label->c + 1 + MAX_DOMAIN_LABEL; // The maximum we can put
- while (*cstr && ptr < limit) *ptr++ = (mDNSu8)*cstr++; // Copy the label
- label->c[0] = (mDNSu8)(ptr - label->c - 1); // Set the length byte
- return(*cstr == 0); // Return mDNStrue if we successfully consumed all input
- }
-
-// MakeDomainNameFromDNSNameString makes a native DNS-format domainname from a C string.
-// The C string is in conventional DNS syntax:
-// Textual labels, escaped as necessary using the usual DNS '\' notation, separated by dots.
-// If successful, MakeDomainNameFromDNSNameString returns a pointer to the next unused byte
-// in the domainname bufer (i.e., the next byte after the terminating zero).
-// If unable to construct a legal domain name (i.e. label more than 63 bytes, or total more than 255 bytes)
-// MakeDomainNameFromDNSNameString returns mDNSNULL.
-mDNSexport mDNSu8 *MakeDomainNameFromDNSNameString(domainname *const name, const char *cstr)
- {
- name->c[0] = 0; // Make an empty domain name
- return(AppendDNSNameString(name, cstr)); // And then add this string to it
- }
-
-mDNSexport char *ConvertDomainLabelToCString_withescape(const domainlabel *const label, char *ptr, char esc)
- {
- const mDNSu8 * src = label->c; // Domain label we're reading
- const mDNSu8 len = *src++; // Read length of this (non-null) label
- const mDNSu8 *const end = src + len; // Work out where the label ends
- if (len > MAX_DOMAIN_LABEL) return(mDNSNULL); // If illegal label, abort
- while (src < end) // While we have characters in the label
- {
- mDNSu8 c = *src++;
- if (esc)
- {
- if (c == '.' || c == esc) // If character is a dot or the escape character
- *ptr++ = esc; // Output escape character
- else if (c <= ' ') // If non-printing ascii,
- { // Output decimal escape sequence
- *ptr++ = esc;
- *ptr++ = (char) ('0' + (c / 100) );
- *ptr++ = (char) ('0' + (c / 10) % 10);
- c = (mDNSu8)('0' + (c ) % 10);
- }
- }
- *ptr++ = (char)c; // Copy the character
- }
- *ptr = 0; // Null-terminate the string
- return(ptr); // and return
- }
-
-// Note: To guarantee that there will be no possible overrun, cstr must be at least MAX_ESCAPED_DOMAIN_NAME (1005 bytes)
-mDNSexport char *ConvertDomainNameToCString_withescape(const domainname *const name, char *ptr, char esc)
- {
- const mDNSu8 *src = name->c; // Domain name we're reading
- const mDNSu8 *const max = name->c + MAX_DOMAIN_NAME; // Maximum that's valid
-
- if (*src == 0) *ptr++ = '.'; // Special case: For root, just write a dot
-
- while (*src) // While more characters in the domain name
- {
- if (src + 1 + *src >= max) return(mDNSNULL);
- ptr = ConvertDomainLabelToCString_withescape((const domainlabel *)src, ptr, esc);
- if (!ptr) return(mDNSNULL);
- src += 1 + *src;
- *ptr++ = '.'; // Write the dot after the label
- }
-
- *ptr++ = 0; // Null-terminate the string
- return(ptr); // and return
- }
-
-// RFC 1034 rules:
-// Host names must start with a letter, end with a letter or digit,
-// and have as interior characters only letters, digits, and hyphen.
-// This was subsequently modified in RFC 1123 to allow the first character to be either a letter or a digit
-
-mDNSexport void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel)
- {
- const mDNSu8 * src = &UTF8Name[1];
- const mDNSu8 *const end = &UTF8Name[1] + UTF8Name[0];
- mDNSu8 * ptr = &hostlabel->c[1];
- const mDNSu8 *const lim = &hostlabel->c[1] + MAX_DOMAIN_LABEL;
- while (src < end)
- {
- // Delete apostrophes from source name
- if (src[0] == '\'') { src++; continue; } // Standard straight single quote
- if (src + 2 < end && src[0] == 0xE2 && src[1] == 0x80 && src[2] == 0x99)
- { src += 3; continue; } // Unicode curly apostrophe
- if (ptr < lim)
- {
- if (mdnsValidHostChar(*src, (ptr > &hostlabel->c[1]), (src < end-1))) *ptr++ = *src;
- else if (ptr > &hostlabel->c[1] && ptr[-1] != '-') *ptr++ = '-';
- }
- src++;
- }
- while (ptr > &hostlabel->c[1] && ptr[-1] == '-') ptr--; // Truncate trailing '-' marks
- hostlabel->c[0] = (mDNSu8)(ptr - &hostlabel->c[1]);
- }
-
-mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
- const domainlabel *name, const domainname *type, const domainname *const domain)
- {
- int i, len;
- mDNSu8 *dst = fqdn->c;
- const mDNSu8 *src;
- const char *errormsg;
-
- // In the case where there is no name (and ONLY in that case),
- // a single-label subtype is allowed as the first label of a three-part "type"
- if (!name && type)
- {
- const mDNSu8 *s0 = type->c;
- if (s0[0] && s0[0] < 0x40) // If legal first label (at least one character, and no more than 63)
- {
- const mDNSu8 * s1 = s0 + 1 + s0[0];
- if (s1[0] && s1[0] < 0x40) // and legal second label (at least one character, and no more than 63)
- {
- const mDNSu8 *s2 = s1 + 1 + s1[0];
- if (s2[0] && s2[0] < 0x40 && s2[1+s2[0]] == 0) // and we have three and only three labels
- {
- static const mDNSu8 SubTypeLabel[5] = "\x04_sub";
- src = s0; // Copy the first label
- len = *src;
- for (i=0; i <= len; i++) *dst++ = *src++;
- for (i=0; i < (int)sizeof(SubTypeLabel); i++) *dst++ = SubTypeLabel[i];
- type = (domainname *)s1;
-
- // Special support for queries done by some third-party network monitoring software
- // For these queries, we retract the "._sub" we just added between the subtype and the main type
- if (SameDomainName((domainname*)s0, (domainname*)"\x09_services\x07_dns-sd\x04_udp") ||
- SameDomainName((domainname*)s0, (domainname*)"\x09_services\x05_mdns\x04_udp"))
- dst -= sizeof(SubTypeLabel);
- }
- }
- }
- }
-
- if (name && name->c[0])
- {
- src = name->c; // Put the service name into the domain name
- len = *src;
- if (len >= 0x40) { errormsg="Service instance name too long"; goto fail; }
- for (i=0; i<=len; i++) *dst++ = *src++;
- }
- else
- name = (domainlabel*)""; // Set this up to be non-null, to avoid errors if we have to call LogMsg() below
-
- src = type->c; // Put the service type into the domain name
- len = *src;
- if (len < 2 || len >= 0x40 || (len > 15 && !SameDomainName(domain, &localdomain)))
- {
- errormsg="Application protocol name must be underscore plus 1-14 characters. See ";
- goto fail;
- }
- if (src[1] != '_') { errormsg="Application protocol name must begin with underscore"; goto fail; }
- for (i=2; i<=len; i++)
- if (!mdnsIsLetter(src[i]) && !mdnsIsDigit(src[i]) && src[i] != '-' && src[i] != '_')
- { errormsg="Application protocol name must contain only letters, digits, and hyphens"; goto fail; }
- for (i=0; i<=len; i++) *dst++ = *src++;
-
- len = *src;
- if (!(len == 4 && src[1] == '_' &&
- (((src[2] | 0x20) == 'u' && (src[3] | 0x20) == 'd') || ((src[2] | 0x20) == 't' && (src[3] | 0x20) == 'c')) &&
- (src[4] | 0x20) == 'p'))
- { errormsg="Transport protocol name must be _udp or _tcp"; goto fail; }
- for (i=0; i<=len; i++) *dst++ = *src++;
-
- if (*src) { errormsg="Service type must have only two labels"; goto fail; }
-
- *dst = 0;
- if (!domain->c[0]) { errormsg="Service domain must be non-empty"; goto fail; }
- if (SameDomainName(domain, (domainname*)"\x05" "local" "\x04" "arpa"))
- { errormsg="Illegal domain \"local.arpa.\" Use \"local.\" (or empty string)"; goto fail; }
- dst = AppendDomainName(fqdn, domain);
- if (!dst) { errormsg="Service domain too long"; goto fail; }
- return(dst);
-
-fail:
- LogMsg("ConstructServiceName: %s: %#s.%##s%##s", errormsg, name->c, type->c, domain->c);
- return(mDNSNULL);
- }
-
-// A service name has the form: instance.application-protocol.transport-protocol.domain
-// DeconstructServiceName is currently fairly forgiving: It doesn't try to enforce character
-// set or length limits for the protocol names, and the final domain is allowed to be empty.
-// However, if the given FQDN doesn't contain at least three labels,
-// DeconstructServiceName will reject it and return mDNSfalse.
-mDNSexport mDNSBool DeconstructServiceName(const domainname *const fqdn,
- domainlabel *const name, domainname *const type, domainname *const domain)
- {
- int i, len;
- const mDNSu8 *src = fqdn->c;
- const mDNSu8 *max = fqdn->c + MAX_DOMAIN_NAME;
- mDNSu8 *dst;
-
- dst = name->c; // Extract the service name
- len = *src;
- if (!len) { debugf("DeconstructServiceName: FQDN empty!"); return(mDNSfalse); }
- if (len >= 0x40) { debugf("DeconstructServiceName: Instance name too long"); return(mDNSfalse); }
- for (i=0; i<=len; i++) *dst++ = *src++;
-
- dst = type->c; // Extract the service type
- len = *src;
- if (!len) { debugf("DeconstructServiceName: FQDN contains only one label!"); return(mDNSfalse); }
- if (len >= 0x40) { debugf("DeconstructServiceName: Application protocol name too long"); return(mDNSfalse); }
- for (i=0; i<=len; i++) *dst++ = *src++;
-
- len = *src;
- if (!len) { debugf("DeconstructServiceName: FQDN contains only two labels!"); return(mDNSfalse); }
- if (len >= 0x40) { debugf("DeconstructServiceName: Transport protocol name too long"); return(mDNSfalse); }
- for (i=0; i<=len; i++) *dst++ = *src++;
- *dst++ = 0; // Put terminator on the end of service type
-
- dst = domain->c; // Extract the service domain
- while (*src)
- {
- len = *src;
- if (len >= 0x40)
- { debugf("DeconstructServiceName: Label in service domain too long"); return(mDNSfalse); }
- if (src + 1 + len + 1 >= max)
- { debugf("DeconstructServiceName: Total service domain too long"); return(mDNSfalse); }
- for (i=0; i<=len; i++) *dst++ = *src++;
- }
- *dst++ = 0; // Put the null root label on the end
-
- return(mDNStrue);
- }
-
-// Notes on UTF-8:
-// 0xxxxxxx represents a 7-bit ASCII value from 0x00 to 0x7F
-// 10xxxxxx is a continuation byte of a multi-byte character
-// 110xxxxx is the first byte of a 2-byte character (11 effective bits; values 0x 80 - 0x 800-1)
-// 1110xxxx is the first byte of a 3-byte character (16 effective bits; values 0x 800 - 0x 10000-1)
-// 11110xxx is the first byte of a 4-byte character (21 effective bits; values 0x 10000 - 0x 200000-1)
-// 111110xx is the first byte of a 5-byte character (26 effective bits; values 0x 200000 - 0x 4000000-1)
-// 1111110x is the first byte of a 6-byte character (31 effective bits; values 0x4000000 - 0x80000000-1)
-//
-// UTF-16 surrogate pairs are used in UTF-16 to encode values larger than 0xFFFF.
-// Although UTF-16 surrogate pairs are not supposed to appear in legal UTF-8, we want to be defensive
-// about that too. (See , "What are surrogates?")
-// The first of pair is a UTF-16 value in the range 0xD800-0xDBFF (11101101 1010xxxx 10xxxxxx in UTF-8),
-// and the second is a UTF-16 value in the range 0xDC00-0xDFFF (11101101 1011xxxx 10xxxxxx in UTF-8).
-
-mDNSexport mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max)
- {
- if (length > max)
- {
- mDNSu8 c1 = string[max]; // First byte after cut point
- mDNSu8 c2 = (max+1 < length) ? string[max+1] : 0xB0; // Second byte after cut point
- length = max; // Trim length down
- while (length > 0)
- {
- // Check if the byte right after the chop point is a UTF-8 continuation byte,
- // or if the character right after the chop point is the second of a UTF-16 surrogate pair.
- // If so, then we continue to chop more bytes until we get to a legal chop point.
- mDNSBool continuation = ((c1 & 0xC0) == 0x80);
- mDNSBool secondsurrogate = (c1 == 0xED && (c2 & 0xF0) == 0xB0);
- if (!continuation && !secondsurrogate) break;
- c2 = c1;
- c1 = string[--length];
- }
- // Having truncated characters off the end of our string, also cut off any residual white space
- while (length > 0 && string[length-1] <= ' ') length--;
- }
- return(length);
- }
-
-// Returns true if a rich text label ends in " (nnn)", or if an RFC 1034
-// name ends in "-nnn", where n is some decimal number.
-mDNSexport mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText)
- {
- mDNSu16 l = name->c[0];
-
- if (RichText)
- {
- if (l < 4) return mDNSfalse; // Need at least " (2)"
- if (name->c[l--] != ')') return mDNSfalse; // Last char must be ')'
- if (!mdnsIsDigit(name->c[l])) return mDNSfalse; // Preceeded by a digit
- l--;
- while (l > 2 && mdnsIsDigit(name->c[l])) l--; // Strip off digits
- return (name->c[l] == '(' && name->c[l - 1] == ' ');
- }
- else
- {
- if (l < 2) return mDNSfalse; // Need at least "-2"
- if (!mdnsIsDigit(name->c[l])) return mDNSfalse; // Last char must be a digit
- l--;
- while (l > 2 && mdnsIsDigit(name->c[l])) l--; // Strip off digits
- return (name->c[l] == '-');
- }
- }
-
-// removes an auto-generated suffix (appended on a name collision) from a label. caller is
-// responsible for ensuring that the label does indeed contain a suffix. returns the number
-// from the suffix that was removed.
-mDNSexport mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText)
- {
- mDNSu32 val = 0, multiplier = 1;
-
- // Chop closing parentheses from RichText suffix
- if (RichText && name->c[0] >= 1 && name->c[name->c[0]] == ')') name->c[0]--;
-
- // Get any existing numerical suffix off the name
- while (mdnsIsDigit(name->c[name->c[0]]))
- { val += (name->c[name->c[0]] - '0') * multiplier; multiplier *= 10; name->c[0]--; }
-
- // Chop opening parentheses or dash from suffix
- if (RichText)
- {
- if (name->c[0] >= 2 && name->c[name->c[0]] == '(' && name->c[name->c[0]-1] == ' ') name->c[0] -= 2;
- }
- else
- {
- if (name->c[0] >= 1 && name->c[name->c[0]] == '-') name->c[0] -= 1;
- }
-
- return(val);
- }
-
-// appends a numerical suffix to a label, with the number following a whitespace and enclosed
-// in parentheses (rich text) or following two consecutive hyphens (RFC 1034 domain label).
-mDNSexport void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichText)
- {
- mDNSu32 divisor = 1, chars = 2; // Shortest possible RFC1034 name suffix is 2 characters ("-2")
- if (RichText) chars = 4; // Shortest possible RichText suffix is 4 characters (" (2)")
-
- // Truncate trailing spaces from RichText names
- if (RichText) while (name->c[name->c[0]] == ' ') name->c[0]--;
-
- while (val >= divisor * 10) { divisor *= 10; chars++; }
-
- name->c[0] = (mDNSu8) TruncateUTF8ToLength(name->c+1, name->c[0], MAX_DOMAIN_LABEL - chars);
-
- if (RichText) { name->c[++name->c[0]] = ' '; name->c[++name->c[0]] = '('; }
- else { name->c[++name->c[0]] = '-'; }
-
- while (divisor)
- {
- name->c[++name->c[0]] = (mDNSu8)('0' + val / divisor);
- val %= divisor;
- divisor /= 10;
- }
-
- if (RichText) name->c[++name->c[0]] = ')';
- }
-
-mDNSexport void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText)
- {
- mDNSu32 val = 0;
-
- if (LabelContainsSuffix(name, RichText))
- val = RemoveLabelSuffix(name, RichText);
-
- // If no existing suffix, start by renaming "Foo" as "Foo (2)" or "Foo-2" as appropriate.
- // If existing suffix in the range 2-9, increment it.
- // If we've had ten conflicts already, there are probably too many hosts trying to use the same name,
- // so add a random increment to improve the chances of finding an available name next time.
- if (val == 0) val = 2;
- else if (val < 10) val++;
- else val += 1 + mDNSRandom(99);
-
- AppendLabelSuffix(name, val, RichText);
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - Resource Record Utility Functions
-#endif
-
-mDNSexport mDNSu32 RDataHashValue(mDNSu16 const rdlength, const RDataBody *const rdb)
- {
- mDNSu32 sum = 0;
- int i;
- for (i=0; i+1 < rdlength; i+=2)
- {
- sum += (((mDNSu32)(rdb->data[i])) << 8) | rdb->data[i+1];
- sum = (sum<<3) | (sum>>29);
- }
- if (i < rdlength)
- {
- sum += ((mDNSu32)(rdb->data[i])) << 8;
- }
- return(sum);
- }
-
-// r1 has to be a full ResourceRecord including rrtype and rdlength
-// r2 is just a bare RDataBody, which MUST be the same rrtype and rdlength as r1
-mDNSexport mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2)
- {
- switch(r1->rrtype)
- {
- case kDNSType_CNAME:// Same as PTR
- case kDNSType_PTR: return(SameDomainName(&r1->rdata->u.name, &r2->name));
-
- case kDNSType_SRV: return(mDNSBool)( r1->rdata->u.srv.priority == r2->srv.priority &&
- r1->rdata->u.srv.weight == r2->srv.weight &&
- r1->rdata->u.srv.port.NotAnInteger == r2->srv.port.NotAnInteger &&
- SameDomainName(&r1->rdata->u.srv.target, &r2->srv.target) );
-
- default: return(mDNSPlatformMemSame(r1->rdata->u.data, r2->data, r1->rdlength));
- }
- }
-
-mDNSexport mDNSBool SameRData(const ResourceRecord *const r1, const ResourceRecord *const r2)
- {
- if (r1->rrtype != r2->rrtype) return(mDNSfalse);
- if (r1->rdlength != r2->rdlength) return(mDNSfalse);
- if (r1->rdatahash != r2->rdatahash) return(mDNSfalse);
- return(SameRDataBody(r1, &r2->rdata->u));
- }
-
-mDNSexport mDNSBool SameResourceRecord(ResourceRecord *r1, ResourceRecord *r2)
- {
- return (r1->namehash == r2->namehash &&
- r1->rrtype == r2->rrtype &&
- SameDomainName(r1->name, r2->name) &&
- SameRData(r1, r2));
- }
-
-mDNSexport mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
- {
- if (rr->InterfaceID &&
- q ->InterfaceID && q->InterfaceID != mDNSInterface_LocalOnly &&
- rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
-
- // RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
- if (rr->rrtype != kDNSType_CNAME && rr->rrtype != q->qtype && q->qtype != kDNSQType_ANY ) return(mDNSfalse);
- if ( rr->rrclass != q->qclass && q->qclass != kDNSQClass_ANY) return(mDNSfalse);
- return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
- }
-
-mDNSexport mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate)
- {
- const RDataBody *rd = &rr->rdata->u;
- const domainname *const name = estimate ? rr->name : mDNSNULL;
- switch (rr->rrtype)
- {
- case kDNSType_A: return(sizeof(rd->ipv4));
- case kDNSType_CNAME:// Same as PTR
- case kDNSType_NS: // Same as PTR
- case kDNSType_PTR: return(CompressedDomainNameLength(&rd->name, name));
- case kDNSType_HINFO:return(mDNSu16)(2 + (int)rd->data[0] + (int)rd->data[1 + (int)rd->data[0]]);
- case kDNSType_NULL: // Same as TXT -- not self-describing, so have to just trust rdlength
- case kDNSType_TXT: return(rr->rdlength); // TXT is not self-describing, so have to just trust rdlength
- case kDNSType_AAAA: return(sizeof(rd->ipv6));
- case kDNSType_SRV: return(mDNSu16)(6 + CompressedDomainNameLength(&rd->srv.target, name));
- case kDNSType_SOA: return (mDNSu16)(CompressedDomainNameLength(&rd->soa.mname, name) +
- CompressedDomainNameLength(&rd->soa.rname, name) +
- 5 * sizeof(mDNSOpaque32));
- case kDNSType_OPT: return(rr->rdlength);
- default: debugf("Warning! Don't know how to get length of resource type %d", rr->rrtype);
- return(rr->rdlength);
- }
- }
-
-mDNSexport mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd)
- {
- mDNSu16 len;
-
- switch(rrtype)
- {
- case kDNSType_A: return(rdlength == sizeof(mDNSv4Addr));
-
- case kDNSType_NS: // Same as PTR
- case kDNSType_MD: // Same as PTR
- case kDNSType_MF: // Same as PTR
- case kDNSType_CNAME:// Same as PTR
- //case kDNSType_SOA not checked
- case kDNSType_MB: // Same as PTR
- case kDNSType_MG: // Same as PTR
- case kDNSType_MR: // Same as PTR
- //case kDNSType_NULL not checked (no specified format, so always valid)
- //case kDNSType_WKS not checked
- case kDNSType_PTR: if (!rdlength) return(mDNSfalse);
- len = DomainNameLength(&rd->u.name);
- return(len <= MAX_DOMAIN_NAME && rdlength == len);
-
- case kDNSType_HINFO:// Same as TXT (roughly)
- case kDNSType_MINFO:// Same as TXT (roughly)
- case kDNSType_TXT: if (!rdlength) return(mDNSfalse); // TXT record has to be at least one byte (RFC 1035)
- {
- const mDNSu8 *ptr = rd->u.txt.c;
- const mDNSu8 *end = rd->u.txt.c + rdlength;
- while (ptr < end) ptr += 1 + ptr[0];
- return (ptr == end);
- }
-
- case kDNSType_AAAA: return(rdlength == sizeof(mDNSv6Addr));
-
- case kDNSType_MX: if (!rdlength) return(mDNSfalse);
- len = DomainNameLength(&rd->u.mx.exchange);
- return(len <= MAX_DOMAIN_NAME && rdlength == 2+len);
-
- case kDNSType_SRV: if (!rdlength) return(mDNSfalse);
- len = DomainNameLength(&rd->u.srv.target);
- return(len <= MAX_DOMAIN_NAME && rdlength == 6+len);
-
- default: return(mDNStrue); // Allow all other types without checking
- }
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark -
-#pragma mark - DNS Message Creation Functions
-#endif
-
-mDNSexport void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags)
- {
- h->id = id;
- h->flags = flags;
- h->numQuestions = 0;
- h->numAnswers = 0;
- h->numAuthorities = 0;
- h->numAdditionals = 0;
- }
-
-mDNSexport const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname)
- {
- const mDNSu8 *result = end - *domname - 1;
-
- if (*domname == 0) return(mDNSNULL); // There's no point trying to match just the root label
-
- // This loop examines each possible starting position in packet, starting end of the packet and working backwards
- while (result >= base)
- {
- // If the length byte and first character of the label match, then check further to see
- // if this location in the packet will yield a useful name compression pointer.
- if (result[0] == domname[0] && result[1] == domname[1])
- {
- const mDNSu8 *name = domname;
- const mDNSu8 *targ = result;
- while (targ + *name < end)
- {
- // First see if this label matches
- int i;
- const mDNSu8 *pointertarget;
- for (i=0; i <= *name; i++) if (targ[i] != name[i]) break;
- if (i <= *name) break; // If label did not match, bail out
- targ += 1 + *name; // Else, did match, so advance target pointer
- name += 1 + *name; // and proceed to check next label
- if (*name == 0 && *targ == 0) return(result); // If no more labels, we found a match!
- if (*name == 0) break; // If no more labels to match, we failed, so bail out
-
- // The label matched, so now follow the pointer (if appropriate) and then see if the next label matches
- if (targ[0] < 0x40) continue; // If length value, continue to check next label
- if (targ[0] < 0xC0) break; // If 40-BF, not valid
- if (targ+1 >= end) break; // Second byte not present!
- pointertarget = base + (((mDNSu16)(targ[0] & 0x3F)) << 8) + targ[1];
- if (targ < pointertarget) break; // Pointertarget must point *backwards* in the packet
- if (pointertarget[0] >= 0x40) break; // Pointertarget must point to a valid length byte
- targ = pointertarget;
- }
- }
- result--; // We failed to match at this search position, so back up the tentative result pointer and try again
- }
- return(mDNSNULL);
- }
-
-// Put a string of dot-separated labels as length-prefixed labels
-// domainname is a fully-qualified name (i.e. assumed to be ending in a dot, even if it doesn't)
-// msg points to the message we're building (pass mDNSNULL if we don't want to use compression pointers)
-// end points to the end of the message so far
-// ptr points to where we want to put the name
-// limit points to one byte past the end of the buffer that we must not overrun
-// domainname is the name to put
-mDNSexport mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg,
- mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name)
- {
- const mDNSu8 *const base = (const mDNSu8 *)msg;
- const mDNSu8 * np = name->c;
- const mDNSu8 *const max = name->c + MAX_DOMAIN_NAME; // Maximum that's valid
- const mDNSu8 * pointer = mDNSNULL;
- const mDNSu8 *const searchlimit = ptr;
-
- while (*np && ptr < limit-1) // While we've got characters in the name, and space to write them in the message...
- {
- if (*np > MAX_DOMAIN_LABEL)
- { LogMsg("Malformed domain name %##s (label more than 63 bytes)", name->c); return(mDNSNULL); }
-
- // This check correctly allows for the final trailing root label:
- // e.g.
- // Suppose our domain name is exactly 255 bytes long, including the final trailing root label.
- // Suppose np is now at name->c[248], and we're about to write our last non-null label ("local").
- // We know that max will be at name->c[255]
- // That means that np + 1 + 5 == max - 1, so we (just) pass the "if" test below, write our
- // six bytes, then exit the loop, write the final terminating root label, and the domain
- // name we've written is exactly 255 bytes long, exactly at the correct legal limit.
- // If the name is one byte longer, then we fail the "if" test below, and correctly bail out.
- if (np + 1 + *np >= max)
- { LogMsg("Malformed domain name %##s (more than 255 bytes)", name->c); return(mDNSNULL); }
-
- if (base) pointer = FindCompressionPointer(base, searchlimit, np);
- if (pointer) // Use a compression pointer if we can
- {
- mDNSu16 offset = (mDNSu16)(pointer - base);
- *ptr++ = (mDNSu8)(0xC0 | (offset >> 8));
- *ptr++ = (mDNSu8)( offset & 0xFF);
- return(ptr);
- }
- else // Else copy one label and try again
- {
- int i;
- mDNSu8 len = *np++;
- if (ptr + 1 + len >= limit) return(mDNSNULL);
- *ptr++ = len;
- for (i=0; i> 8 ) & 0xFF);
- ptr[1] = (mDNSu8)((val ) & 0xFF);
- return ptr + sizeof(mDNSOpaque16);
- }
-
-mDNSlocal mDNSu8 *putVal32(mDNSu8 *ptr, mDNSu32 val)
- {
- ptr[0] = (mDNSu8)((val >> 24) & 0xFF);
- ptr[1] = (mDNSu8)((val >> 16) & 0xFF);
- ptr[2] = (mDNSu8)((val >> 8) & 0xFF);
- ptr[3] = (mDNSu8)((val ) & 0xFF);
- return ptr + sizeof(mDNSu32);
- }
-
-mDNSlocal mDNSu8 *putOptRData(mDNSu8 *ptr, const mDNSu8 *limit, ResourceRecord *rr)
- {
- int nput = 0;
- rdataOpt *opt;
-
- while (nput < rr->rdlength)
- {
- // check if space for opt/optlen
- if (ptr + (2 * sizeof(mDNSu16)) > limit) goto space_err;
- opt = (rdataOpt *)(rr->rdata->u.data + nput);
- ptr = putVal16(ptr, opt->opt);
- ptr = putVal16(ptr, opt->optlen);
- nput += 2 * sizeof(mDNSu16);
- if (opt->opt == kDNSOpt_LLQ)
- {
- if (ptr + LLQ_OPTLEN > limit) goto space_err;
- ptr = putVal16(ptr, opt->OptData.llq.vers);
- ptr = putVal16(ptr, opt->OptData.llq.llqOp);
- ptr = putVal16(ptr, opt->OptData.llq.err);
- mDNSPlatformMemCopy(opt->OptData.llq.id, ptr, 8); // 8-byte id
- ptr += 8;
- ptr = putVal32(ptr, opt->OptData.llq.lease);
- nput += LLQ_OPTLEN;
- }
- else if (opt->opt == kDNSOpt_Lease)
- {
- if (ptr + sizeof(mDNSs32) > limit) goto space_err;
- ptr = putVal32(ptr, opt->OptData.lease);
- nput += sizeof(mDNSs32);
- }
- else { LogMsg("putOptRData - unknown option %d", opt->opt); return mDNSNULL; }
- }
-
- return ptr;
-
- space_err:
- LogMsg("ERROR: putOptRData - out of space");
- return mDNSNULL;
- }
-
-mDNSlocal mDNSu16 getVal16(const mDNSu8 **ptr)
- {
- mDNSu16 val = (mDNSu16)(((mDNSu16)(*ptr)[0]) << 8 | (*ptr)[1]);
- *ptr += sizeof(mDNSOpaque16);
- return val;
- }
-
-mDNSlocal const mDNSu8 *getOptRdata(const mDNSu8 *ptr, const mDNSu8 *const limit, LargeCacheRecord *const cr, mDNSu16 pktRDLen)
- {
- int nread = 0;
- ResourceRecord *const rr = &cr->r.resrec;
- rdataOpt *opt = (rdataOpt *)rr->rdata->u.data;
-
- while (nread < pktRDLen && (mDNSu8 *)opt < rr->rdata->u.data + MaximumRDSize - sizeof(rdataOpt))
- {
- // space for opt + optlen
- if (nread + (2 * sizeof(mDNSu16)) > rr->rdata->MaxRDLength) goto space_err;
- opt->opt = getVal16(&ptr);
- opt->optlen = getVal16(&ptr);
- nread += 2 * sizeof(mDNSu16);
- if (opt->opt == kDNSOpt_LLQ)
- {
- if ((unsigned)(limit - ptr) < LLQ_OPTLEN) goto space_err;
- opt->OptData.llq.vers = getVal16(&ptr);
- opt->OptData.llq.llqOp = getVal16(&ptr);
- opt->OptData.llq.err = getVal16(&ptr);
- mDNSPlatformMemCopy(ptr, opt->OptData.llq.id, 8);
- ptr += 8;
- opt->OptData.llq.lease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
- if (opt->OptData.llq.lease > 0x70000000UL / mDNSPlatformOneSecond)
- opt->OptData.llq.lease = 0x70000000UL / mDNSPlatformOneSecond;
- ptr += sizeof(mDNSOpaque32);
- nread += LLQ_OPTLEN;
- }
- else if (opt->opt == kDNSOpt_Lease)
- {
- if ((unsigned)(limit - ptr) < sizeof(mDNSs32)) goto space_err;
-
- opt->OptData.lease = (mDNSu32) ((mDNSu32)ptr[0] << 24 | (mDNSu32)ptr[1] << 16 | (mDNSu32)ptr[2] << 8 | ptr[3]);
- if (opt->OptData.lease > 0x70000000UL / mDNSPlatformOneSecond)
- opt->OptData.lease = 0x70000000UL / mDNSPlatformOneSecond;
- ptr += sizeof(mDNSs32);
- nread += sizeof(mDNSs32);
- }
- else { LogMsg("ERROR: getOptRdata - unknown opt %d", opt->opt); return mDNSNULL; }
- opt++; // increment pointer into rdatabody
- }
-
- rr->rdlength = pktRDLen;
- return ptr;
-
- space_err:
- LogMsg("ERROR: getLLQRdata - out of space");
- return mDNSNULL;
- }
-
-mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, ResourceRecord *rr)
- {
- switch (rr->rrtype)
- {
- case kDNSType_A: if (rr->rdlength != 4)
- {
- debugf("putRData: Illegal length %d for kDNSType_A", rr->rdlength);
- return(mDNSNULL);
- }
- if (ptr + 4 > limit) return(mDNSNULL);
- *ptr++ = rr->rdata->u.ipv4.b[0];
- *ptr++ = rr->rdata->u.ipv4.b[1];
- *ptr++ = rr->rdata->u.ipv4.b[2];
- *ptr++ = rr->rdata->u.ipv4.b[3];
- return(ptr);
-
- case kDNSType_CNAME:// Same as PTR
- case kDNSType_PTR: return(putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.name));
-
- case kDNSType_AAAA: if (rr->rdlength != sizeof(rr->rdata->u.ipv6))
- {
- debugf("putRData: Illegal length %d for kDNSType_AAAA", rr->rdlength);
- return(mDNSNULL);
- }
- if (ptr + sizeof(rr->rdata->u.ipv6) > limit) return(mDNSNULL);
- mDNSPlatformMemCopy(&rr->rdata->u.ipv6, ptr, sizeof(rr->rdata->u.ipv6));
- return(ptr + sizeof(rr->rdata->u.ipv6));
-
- case kDNSType_SRV: if (ptr + 6 > limit) return(mDNSNULL);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.priority >> 8);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.priority & 0xFF);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.weight >> 8);
- *ptr++ = (mDNSu8)(rr->rdata->u.srv.weight & 0xFF);
- *ptr++ = rr->rdata->u.srv.port.b[0];
- *ptr++ = rr->rdata->u.srv.port.b[1];
- return(putDomainNameAsLabels(msg, ptr, limit, &rr->rdata->u.srv.target));
- case kDNSType_OPT: return putOptRData(ptr, limit, rr);
-
- default: debugf("putRData: Warning! Writing unknown resource type %d as raw data", rr->rrtype);
- // Fall through to common code below
- case kDNSType_HINFO:
- case kDNSType_TXT:
- case kDNSType_TSIG: if (ptr + rr->rdlength > limit) return(mDNSNULL);
- mDNSPlatformMemCopy(rr->rdata->u.data, ptr, rr->rdlength);
- return(ptr + rr->rdlength);
- }
- }
-
-mDNSexport mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit)
- {
- mDNSu8 *endofrdata;
- mDNSu16 actualLength;
-
- if (rr->RecordType == kDNSRecordTypeUnregistered)
- {
- LogMsg("PutResourceRecord ERROR! Attempt to put kDNSRecordTypeUnregistered %##s (%s)", rr->name->c, DNSTypeName(rr->rrtype));
- return(ptr);
- }
-
- ptr = putDomainNameAsLabels(msg, ptr, limit, rr->name);
- if (!ptr || ptr + 10 >= limit) return(mDNSNULL); // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rr->rrtype >> 8);
- ptr[1] = (mDNSu8)(rr->rrtype & 0xFF);
- ptr[2] = (mDNSu8)(rr->rrclass >> 8);
- ptr[3] = (mDNSu8)(rr->rrclass & 0xFF);
- ptr[4] = (mDNSu8)((ttl >> 24) & 0xFF);
- ptr[5] = (mDNSu8)((ttl >> 16) & 0xFF);
- ptr[6] = (mDNSu8)((ttl >> 8) & 0xFF);
- ptr[7] = (mDNSu8)( ttl & 0xFF);
- endofrdata = putRData(msg, ptr+10, limit, rr);
- if (!endofrdata) { verbosedebugf("Ran out of space in PutResourceRecord for %##s (%s)", rr->name->c, DNSTypeName(rr->rrtype)); return(mDNSNULL); }
-
- // Go back and fill in the actual number of data bytes we wrote
- // (actualLength can be less than rdlength when domain name compression is used)
- actualLength = (mDNSu16)(endofrdata - ptr - 10);
- ptr[8] = (mDNSu8)(actualLength >> 8);
- ptr[9] = (mDNSu8)(actualLength & 0xFF);
-
- if (count) (*count)++;
- else LogMsg("PutResourceRecordTTL: ERROR: No target count to update for %##s (%s)", rr->name->c, DNSTypeName(rr->rrtype));
- return(endofrdata);
- }
-
-mDNSexport mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32
- maxttl)
- {
- if (maxttl > rr->rroriginalttl) maxttl = rr->rroriginalttl;
- return(PutResourceRecordTTL(msg, ptr, count, rr, maxttl));
- }
-
-mDNSexport mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit,
- mDNSu16 *count, const AuthRecord *rr)
- {
- ptr = putDomainNameAsLabels(msg, ptr, limit, rr->resrec.name);
- if (!ptr || ptr + 10 > limit) return(mDNSNULL); // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rr->resrec.rrtype >> 8); // Put type
- ptr[1] = (mDNSu8)(rr->resrec.rrtype & 0xFF);
- ptr[2] = (mDNSu8)(rr->resrec.rrclass >> 8); // Put class
- ptr[3] = (mDNSu8)(rr->resrec.rrclass & 0xFF);
- ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0; // TTL is zero
- ptr[8] = ptr[9] = 0; // RDATA length is zero
- (*count)++;
- return(ptr + 10);
- }
-
-mDNSexport mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass)
- {
- ptr = putDomainNameAsLabels(msg, ptr, limit, name);
- if (!ptr || ptr+4 >= limit) return(mDNSNULL); // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rrtype >> 8);
- ptr[1] = (mDNSu8)(rrtype & 0xFF);
- ptr[2] = (mDNSu8)(rrclass >> 8);
- ptr[3] = (mDNSu8)(rrclass & 0xFF);
- msg->h.numQuestions++;
- return(ptr+4);
- }
-
-// for dynamic updates
-mDNSexport mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass)
- {
- ptr = putDomainNameAsLabels(msg, ptr, limit, zone);
- if (!ptr || ptr + 4 > limit) return mDNSNULL; // If we're out-of-space, return NULL
- *ptr++ = (mDNSu8)(kDNSType_SOA >> 8);
- *ptr++ = (mDNSu8)(kDNSType_SOA & 0xFF);
- *ptr++ = zoneClass.b[0];
- *ptr++ = zoneClass.b[1];
- msg->h.mDNS_numZones++;
- return ptr;
- }
-
-// for dynamic updates
-mDNSexport mDNSu8 *putPrereqNameNotInUse(domainname *name, DNSMessage *msg, mDNSu8 *ptr, mDNSu8 *end)
- {
- AuthRecord prereq;
-
- mDNSPlatformMemZero(&prereq, sizeof(AuthRecord));
- mDNS_SetupResourceRecord(&prereq, mDNSNULL, mDNSInterface_Any, kDNSQType_ANY, kStandardTTL, 0, mDNSNULL, mDNSNULL);
- AssignDomainName(prereq.resrec.name, name);
- prereq.resrec.rrtype = kDNSQType_ANY;
- prereq.resrec.rrclass = kDNSClass_NONE;
- ptr = putEmptyResourceRecord(msg, ptr, end, &msg->h.mDNS_numPrereqs, &prereq);
- return ptr;
- }
-
-// for dynamic updates
-mDNSexport mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr)
- {
- mDNSu16 origclass;
- // deletion: specify record w/ TTL 0, class NONE
-
- origclass = rr->rrclass;
- rr->rrclass = kDNSClass_NONE;
- ptr = PutResourceRecordTTLJumbo(msg, ptr, &msg->h.mDNS_numUpdates, rr, 0);
- rr->rrclass = origclass;
- return ptr;
- }
-
-mDNSexport mDNSu8 *putDeleteRRSet(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype)
- {
- const mDNSu8 *limit = msg->data + AbsoluteMaxDNSMessageData;
- mDNSu16 class = kDNSQClass_ANY;
-
- ptr = putDomainNameAsLabels(msg, ptr, limit, name);
- if (!ptr || ptr + 10 >= limit) return mDNSNULL; // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rrtype >> 8);
- ptr[1] = (mDNSu8)(rrtype & 0xFF);
- ptr[2] = (mDNSu8)(class >> 8);
- ptr[3] = (mDNSu8)(class & 0xFF);
- ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0; // zero ttl
- ptr[8] = ptr[9] = 0; // zero rdlength/rdata
-
- msg->h.mDNS_numUpdates++;
- return ptr + 10;
- }
-
-// for dynamic updates
-mDNSexport mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name)
- {
- const mDNSu8 *limit = msg->data + AbsoluteMaxDNSMessageData;
- mDNSu16 class = kDNSQClass_ANY;
- mDNSu16 rrtype = kDNSQType_ANY;
-
- ptr = putDomainNameAsLabels(msg, ptr, limit, name);
- if (!ptr || ptr + 10 >= limit) return mDNSNULL; // If we're out-of-space, return mDNSNULL
- ptr[0] = (mDNSu8)(rrtype >> 8);
- ptr[1] = (mDNSu8)(rrtype & 0xFF);
- ptr[2] = (mDNSu8)(class >> 8);
- ptr[3] = (mDNSu8)(class & 0xFF);
- ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0; // zero ttl
- ptr[8] = ptr[9] = 0; // zero rdlength/rdata
-
- msg->h.mDNS_numUpdates++;
- return ptr + 10;
- }
-
-// for dynamic updates
-mDNSexport mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease)
- {
- AuthRecord rr;
- ResourceRecord *opt = &rr.resrec;
- rdataOpt *optRD;
-
- mDNSPlatformMemZero(&rr, sizeof(AuthRecord));
- mDNS_SetupResourceRecord(&rr, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, 0, mDNSNULL, mDNSNULL);
-
- opt->RecordType = kDNSRecordTypeKnownUnique; // to avoid warnings in other layers
- opt->rrtype = kDNSType_OPT;
- opt->rdlength = LEASE_OPT_RDLEN;
- opt->rdestimate = LEASE_OPT_RDLEN;
-
- optRD = &rr.resrec.rdata->u.opt;
- optRD->opt = kDNSOpt_Lease;
- optRD->optlen = sizeof(mDNSs32);
- optRD->OptData.lease = lease;
- end = PutResourceRecordTTLJumbo(msg, end, &msg->h.numAdditionals, opt, 0);
- if (!end) { LogMsg("ERROR: putUpdateLease - PutResourceRecordTTL"); return mDNSNULL; }
-
- return end;
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - DNS Message Parsing Functions
-#endif
-
-mDNSexport mDNSu32 DomainNameHashValue(const domainname *const name)
- {
- mDNSu32 sum = 0;
- const mDNSu8 *c;
-
- for (c = name->c; c[0] != 0 && c[1] != 0; c += 2)
- {
- sum += ((mDNSIsUpperCase(c[0]) ? c[0] + 'a' - 'A' : c[0]) << 8) |
- (mDNSIsUpperCase(c[1]) ? c[1] + 'a' - 'A' : c[1]);
- sum = (sum<<3) | (sum>>29);
- }
- if (c[0]) sum += ((mDNSIsUpperCase(c[0]) ? c[0] + 'a' - 'A' : c[0]) << 8);
- return(sum);
- }
-
-mDNSexport void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength)
- {
- domainname *target;
- if (NewRData)
- {
- rr->rdata = NewRData;
- rr->rdlength = rdlength;
- }
- // Must not try to get target pointer until after updating rr->rdata
- target = GetRRDomainNameTarget(rr);
- rr->rdlength = GetRDLength(rr, mDNSfalse);
- rr->rdestimate = GetRDLength(rr, mDNStrue);
- rr->rdatahash = target ? DomainNameHashValue(target) : RDataHashValue(rr->rdlength, &rr->rdata->u);
- }
-
-mDNSexport const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end)
- {
- mDNSu16 total = 0;
-
- if (ptr < (mDNSu8*)msg || ptr >= end)
- { debugf("skipDomainName: Illegal ptr not within packet boundaries"); return(mDNSNULL); }
-
- while (1) // Read sequence of labels
- {
- const mDNSu8 len = *ptr++; // Read length of this label
- if (len == 0) return(ptr); // If length is zero, that means this name is complete
- switch (len & 0xC0)
- {
- case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
- { debugf("skipDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
- if (total + 1 + len >= MAX_DOMAIN_NAME) // Remember: expect at least one more byte for the root label
- { debugf("skipDomainName: Malformed domain name (more than 255 characters)"); return(mDNSNULL); }
- ptr += len;
- total += 1 + len;
- break;
-
- case 0x40: debugf("skipDomainName: Extended EDNS0 label types 0x%X not supported", len); return(mDNSNULL);
- case 0x80: debugf("skipDomainName: Illegal label length 0x%X", len); return(mDNSNULL);
- case 0xC0: return(ptr+1);
- }
- }
- }
-
-// Routine to fetch an FQDN from the DNS message, following compression pointers if necessary.
-mDNSexport const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
- domainname *const name)
- {
- const mDNSu8 *nextbyte = mDNSNULL; // Record where we got to before we started following pointers
- mDNSu8 *np = name->c; // Name pointer
- const mDNSu8 *const limit = np + MAX_DOMAIN_NAME; // Limit so we don't overrun buffer
-
- if (ptr < (mDNSu8*)msg || ptr >= end)
- { debugf("getDomainName: Illegal ptr not within packet boundaries"); return(mDNSNULL); }
-
- *np = 0; // Tentatively place the root label here (may be overwritten if we have more labels)
-
- while (1) // Read sequence of labels
- {
- const mDNSu8 len = *ptr++; // Read length of this label
- if (len == 0) break; // If length is zero, that means this name is complete
- switch (len & 0xC0)
- {
- int i;
- mDNSu16 offset;
-
- case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
- { debugf("getDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
- if (np + 1 + len >= limit) // Remember: expect at least one more byte for the root label
- { debugf("getDomainName: Malformed domain name (more than 255 characters)"); return(mDNSNULL); }
- *np++ = len;
- for (i=0; ic);
- return(mDNSNULL);
-
- case 0x80: debugf("getDomainName: Illegal label length 0x%X in domain name %##s", len, name->c); return(mDNSNULL);
-
- case 0xC0: offset = (mDNSu16)((((mDNSu16)(len & 0x3F)) << 8) | *ptr++);
- if (!nextbyte) nextbyte = ptr; // Record where we got to before we started following pointers
- ptr = (mDNSu8 *)msg + offset;
- if (ptr < (mDNSu8*)msg || ptr >= end)
- { debugf("getDomainName: Illegal compression pointer not within packet boundaries"); return(mDNSNULL); }
- if (*ptr & 0xC0)
- { debugf("getDomainName: Compression pointer must point to real label"); return(mDNSNULL); }
- break;
- }
- }
-
- if (nextbyte) return(nextbyte);
- else return(ptr);
- }
-
-mDNSexport const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end)
- {
- mDNSu16 pktrdlength;
-
- ptr = skipDomainName(msg, ptr, end);
- if (!ptr) { debugf("skipResourceRecord: Malformed RR name"); return(mDNSNULL); }
-
- if (ptr + 10 > end) { debugf("skipResourceRecord: Malformed RR -- no type/class/ttl/len!"); return(mDNSNULL); }
- pktrdlength = (mDNSu16)((mDNSu16)ptr[8] << 8 | ptr[9]);
- ptr += 10;
- if (ptr + pktrdlength > end) { debugf("skipResourceRecord: RDATA exceeds end of packet"); return(mDNSNULL); }
-
- return(ptr + pktrdlength);
- }
-
-mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
- const mDNSu8 *end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *largecr)
- {
- CacheRecord *rr = &largecr->r;
- mDNSu16 pktrdlength;
-
- if (largecr == &m->rec && largecr->r.resrec.RecordType)
- LogMsg("GetLargeResourceRecord: m->rec appears to be already in use for %s", CRDisplayString(m, &largecr->r));
-
- rr->next = mDNSNULL;
- rr->resrec.name = &largecr->namestorage;
-
- rr->NextInKAList = mDNSNULL;
- rr->TimeRcvd = m ? m->timenow : 0;
- rr->DelayDelivery = 0;
- rr->NextRequiredQuery = m ? m->timenow : 0; // Will be updated to the real value when we call SetNextCacheCheckTime()
- rr->LastUsed = m ? m->timenow : 0;
- rr->CRActiveQuestion = mDNSNULL;
- rr->UnansweredQueries = 0;
- rr->LastUnansweredTime= 0;
- rr->MPUnansweredQ = 0;
- rr->MPLastUnansweredQT= 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
- rr->NextInCFList = mDNSNULL;
-
- rr->resrec.InterfaceID = InterfaceID;
- ptr = getDomainName(msg, ptr, end, rr->resrec.name);
- if (!ptr) { debugf("GetResourceRecord: Malformed RR name"); return(mDNSNULL); }
-
- if (ptr + 10 > end) { debugf("GetResourceRecord: Malformed RR -- no type/class/ttl/len!"); return(mDNSNULL); }
-
- rr->resrec.rrtype = (mDNSu16) ((mDNSu16)ptr[0] << 8 | ptr[1]);
- rr->resrec.rrclass = (mDNSu16)(((mDNSu16)ptr[2] << 8 | ptr[3]) & kDNSClass_Mask);
- rr->resrec.rroriginalttl = (mDNSu32) ((mDNSu32)ptr[4] << 24 | (mDNSu32)ptr[5] << 16 | (mDNSu32)ptr[6] << 8 | ptr[7]);
- if (rr->resrec.rroriginalttl > 0x70000000UL / mDNSPlatformOneSecond && (mDNSs32)rr->resrec.rroriginalttl != -1)
- rr->resrec.rroriginalttl = 0x70000000UL / mDNSPlatformOneSecond;
- // Note: We don't have to adjust m->NextCacheCheck here -- this is just getting a record into memory for
- // us to look at. If we decide to copy it into the cache, then we'll update m->NextCacheCheck accordingly.
- pktrdlength = (mDNSu16)((mDNSu16)ptr[8] << 8 | ptr[9]);
- if (ptr[2] & (kDNSClass_UniqueRRSet >> 8))
- RecordType |= kDNSRecordTypePacketUniqueMask;
- ptr += 10;
- if (ptr + pktrdlength > end) { debugf("GetResourceRecord: RDATA exceeds end of packet"); return(mDNSNULL); }
- end = ptr + pktrdlength; // Adjust end to indicate the end of the rdata for this resource record
-
- rr->resrec.rdata = (RData*)&rr->rdatastorage;
- rr->resrec.rdata->MaxRDLength = MaximumRDSize;
-
- if (!RecordType) LogMsg("GetLargeResourceRecord: No RecordType for %##s", rr->resrec.name->c);
-
- switch (rr->resrec.rrtype)
- {
- case kDNSType_A: rr->resrec.rdata->u.ipv4.b[0] = ptr[0];
- rr->resrec.rdata->u.ipv4.b[1] = ptr[1];
- rr->resrec.rdata->u.ipv4.b[2] = ptr[2];
- rr->resrec.rdata->u.ipv4.b[3] = ptr[3];
- break;
-
- case kDNSType_CNAME:// Same as PTR
- case kDNSType_NS:
- case kDNSType_PTR: if (!getDomainName(msg, ptr, end, &rr->resrec.rdata->u.name))
- { debugf("GetResourceRecord: Malformed CNAME/PTR RDATA name"); return(mDNSNULL); }
- //debugf("%##s PTR %##s rdlen %d", rr->resrec.name.c, rr->resrec.rdata->u.name.c, pktrdlength);
- break;
-
- case kDNSType_NULL: //Same as TXT
- case kDNSType_HINFO://Same as TXT
- case kDNSType_TXT: if (pktrdlength > rr->resrec.rdata->MaxRDLength)
- {
- debugf("GetResourceRecord: %s rdata size (%d) exceeds storage (%d)",
- DNSTypeName(rr->resrec.rrtype), pktrdlength, rr->resrec.rdata->MaxRDLength);
- return(mDNSNULL);
- }
- rr->resrec.rdlength = pktrdlength;
- mDNSPlatformMemCopy(ptr, rr->resrec.rdata->u.data, pktrdlength);
- break;
-
- case kDNSType_AAAA: mDNSPlatformMemCopy(ptr, &rr->resrec.rdata->u.ipv6, sizeof(rr->resrec.rdata->u.ipv6));
- break;
-
- case kDNSType_SRV: rr->resrec.rdata->u.srv.priority = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
- rr->resrec.rdata->u.srv.weight = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]);
- rr->resrec.rdata->u.srv.port.b[0] = ptr[4];
- rr->resrec.rdata->u.srv.port.b[1] = ptr[5];
- if (!getDomainName(msg, ptr+6, end, &rr->resrec.rdata->u.srv.target))
- { debugf("GetResourceRecord: Malformed SRV RDATA name"); return(mDNSNULL); }
- //debugf("%##s SRV %##s rdlen %d", rr->resrec.name.c, rr->resrec.rdata->u.srv.target.c, pktrdlength);
- break;
-
- case kDNSType_SOA: ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.soa.mname);
- if (!ptr) { debugf("GetResourceRecord: Malformed SOA RDATA mname"); return mDNSNULL; }
- ptr = getDomainName(msg, ptr, end, &rr->resrec.rdata->u.soa.rname);
- if (!ptr) { debugf("GetResourceRecord: Malformed SOA RDATA rname"); return mDNSNULL; }
- if (ptr + 0x14 != end) { debugf("GetResourceRecord: Malformed SOA RDATA"); return mDNSNULL; }
- rr->resrec.rdata->u.soa.serial = (mDNSs32) ((mDNSs32)ptr[0x00] << 24 | (mDNSs32)ptr[0x01] << 16 | (mDNSs32)ptr[0x02] << 8 | ptr[0x03]);
- rr->resrec.rdata->u.soa.refresh = (mDNSu32) ((mDNSu32)ptr[0x04] << 24 | (mDNSu32)ptr[0x05] << 16 | (mDNSu32)ptr[0x06] << 8 | ptr[0x07]);
- rr->resrec.rdata->u.soa.retry = (mDNSu32) ((mDNSu32)ptr[0x08] << 24 | (mDNSu32)ptr[0x09] << 16 | (mDNSu32)ptr[0x0A] << 8 | ptr[0x0B]);
- rr->resrec.rdata->u.soa.expire = (mDNSu32) ((mDNSu32)ptr[0x0C] << 24 | (mDNSu32)ptr[0x0D] << 16 | (mDNSu32)ptr[0x0E] << 8 | ptr[0x0F]);
- rr->resrec.rdata->u.soa.min = (mDNSu32) ((mDNSu32)ptr[0x10] << 24 | (mDNSu32)ptr[0x11] << 16 | (mDNSu32)ptr[0x12] << 8 | ptr[0x13]);
- break;
-
- case kDNSType_OPT: getOptRdata(ptr, end, largecr, pktrdlength); break;
-
- default: if (pktrdlength > rr->resrec.rdata->MaxRDLength)
- {
- debugf("GetResourceRecord: rdata %d (%s) size (%d) exceeds storage (%d)",
- rr->resrec.rrtype, DNSTypeName(rr->resrec.rrtype), pktrdlength, rr->resrec.rdata->MaxRDLength);
- return(mDNSNULL);
- }
- debugf("GetResourceRecord: Warning! Reading resource type %d (%s) as opaque data",
- rr->resrec.rrtype, DNSTypeName(rr->resrec.rrtype));
- // Note: Just because we don't understand the record type, that doesn't
- // mean we fail. The DNS protocol specifies rdlength, so we can
- // safely skip over unknown records and ignore them.
- // We also grab a binary copy of the rdata anyway, since the caller
- // might know how to interpret it even if we don't.
- rr->resrec.rdlength = pktrdlength;
- mDNSPlatformMemCopy(ptr, rr->resrec.rdata->u.data, pktrdlength);
- break;
- }
-
- rr->resrec.namehash = DomainNameHashValue(rr->resrec.name);
- SetNewRData(&rr->resrec, mDNSNULL, 0);
-
- // Success! Now fill in RecordType to show this record contains valid data
- rr->resrec.RecordType = RecordType;
- return(ptr + pktrdlength);
- }
-
-mDNSexport const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end)
- {
- ptr = skipDomainName(msg, ptr, end);
- if (!ptr) { debugf("skipQuestion: Malformed domain name in DNS question section"); return(mDNSNULL); }
- if (ptr+4 > end) { debugf("skipQuestion: Malformed DNS question section -- no query type and class!"); return(mDNSNULL); }
- return(ptr+4);
- }
-
-mDNSexport const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
- DNSQuestion *question)
- {
- question->InterfaceID = InterfaceID;
- ptr = getDomainName(msg, ptr, end, &question->qname);
- if (!ptr) { debugf("Malformed domain name in DNS question section"); return(mDNSNULL); }
- if (ptr+4 > end) { debugf("Malformed DNS question section -- no query type and class!"); return(mDNSNULL); }
-
- question->qnamehash = DomainNameHashValue(&question->qname);
- question->qtype = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]); // Get type
- question->qclass = (mDNSu16)((mDNSu16)ptr[2] << 8 | ptr[3]); // and class
- return(ptr+4);
- }
-
-mDNSexport const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end)
- {
- int i;
- const mDNSu8 *ptr = msg->data;
- for (i = 0; i < msg->h.numQuestions && ptr; i++) ptr = skipQuestion(msg, ptr, end);
- return(ptr);
- }
-
-mDNSexport const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end)
- {
- int i;
- const mDNSu8 *ptr = LocateAnswers(msg, end);
- for (i = 0; i < msg->h.numAnswers && ptr; i++) ptr = skipResourceRecord(msg, ptr, end);
- return(ptr);
- }
-
-mDNSexport const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end)
- {
- int i;
- const mDNSu8 *ptr = LocateAuthorities(msg, end);
- for (i = 0; i < msg->h.numAuthorities; i++) ptr = skipResourceRecord(msg, ptr, end);
- return (ptr);
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark -
-#pragma mark - Packet Sending Functions
-#endif
-
-mDNSexport mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
- mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, int sd, uDNS_AuthInfo *authInfo)
- {
- mStatus status;
- int nsent;
- mDNSs32 msglen;
- mDNSu8 lenbuf[2];
- mDNSu16 numQuestions = msg->h.numQuestions;
- mDNSu16 numAnswers = msg->h.numAnswers;
- mDNSu16 numAuthorities = msg->h.numAuthorities;
- mDNSu16 numAdditionals = msg->h.numAdditionals;
- mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
-
- // Put all the integer values in IETF byte-order (MSB first, LSB second)
- *ptr++ = (mDNSu8)(numQuestions >> 8);
- *ptr++ = (mDNSu8)(numQuestions & 0xFF);
- *ptr++ = (mDNSu8)(numAnswers >> 8);
- *ptr++ = (mDNSu8)(numAnswers & 0xFF);
- *ptr++ = (mDNSu8)(numAuthorities >> 8);
- *ptr++ = (mDNSu8)(numAuthorities & 0xFF);
- *ptr++ = (mDNSu8)(numAdditionals >> 8);
- *ptr++ = (mDNSu8)(numAdditionals & 0xFF);
-
- if (authInfo)
- {
- end = DNSDigest_SignMessage(msg, &end, &numAdditionals, authInfo);
- if (!end) return mStatus_UnknownErr;
- }
-
- // Send the packet on the wire
-
- if (sd >= 0)
- {
- msglen = (mDNSu16)(end - (mDNSu8 *)msg);
- lenbuf[0] = (mDNSu8)(msglen >> 8); // host->network byte conversion
- lenbuf[1] = (mDNSu8)(msglen & 0xFF);
- nsent = mDNSPlatformWriteTCP(sd, (char*)lenbuf, 2);
- //!!!KRS make sure kernel is sending these as 1 packet!
- if (nsent != 2) goto tcp_error;
- nsent = mDNSPlatformWriteTCP(sd, (char *)msg, msglen);
- if (nsent != msglen) goto tcp_error;
- status = mStatus_NoError;
- }
- else
- {
- status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, dst, dstport);
- }
-
- // Put all the integer values back the way they were before we return
- msg->h.numQuestions = numQuestions;
- msg->h.numAnswers = numAnswers;
- msg->h.numAuthorities = numAuthorities;
- msg->h.numAdditionals = (mDNSu16)(authInfo ? numAdditionals - 1 : numAdditionals);
-
- return(status);
-
- tcp_error:
- LogMsg("mDNSSendDNSMessage: error sending message over tcp");
- return mStatus_UnknownErr;
- }
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - RR List Management & Task Management
-#endif
-
-mDNSexport void mDNS_Lock(mDNS *const m)
- {
- // MUST grab the platform lock FIRST!
- mDNSPlatformLock(m);
-
- // Normally, mDNS_reentrancy is zero and so is mDNS_busy
- // However, when we call a client callback mDNS_busy is one, and we increment mDNS_reentrancy too
- // If that client callback does mDNS API calls, mDNS_reentrancy and mDNS_busy will both be one
- // If mDNS_busy != mDNS_reentrancy that's a bad sign
- if (m->mDNS_busy != m->mDNS_reentrancy)
- LogMsg("mDNS_Lock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
-
- // If this is an initial entry into the mDNSCore code, set m->timenow
- // else, if this is a re-entrant entry into the mDNSCore code, m->timenow should already be set
- if (m->mDNS_busy == 0)
- {
- if (m->timenow)
- LogMsg("mDNS_Lock: m->timenow already set (%ld/%ld)", m->timenow, mDNS_TimeNow_NoLock(m));
- m->timenow = mDNS_TimeNow_NoLock(m);
- if (m->timenow == 0) m->timenow = 1;
- }
- else if (m->timenow == 0)
- {
- LogMsg("mDNS_Lock: m->mDNS_busy is %ld but m->timenow not set", m->mDNS_busy);
- m->timenow = mDNS_TimeNow_NoLock(m);
- if (m->timenow == 0) m->timenow = 1;
- }
-
- if (m->timenow_last - m->timenow > 0)
- {
- m->timenow_adjust += m->timenow_last - m->timenow;
-// LogMsg("mDNSPlatformRawTime went backwards by %ld ticks; setting correction factor to %ld", m->timenow_last - m->timenow, m->timenow_adjust);
- m->timenow = m->timenow_last;
- }
- m->timenow_last = m->timenow;
-
- // Increment mDNS_busy so we'll recognise re-entrant calls
- m->mDNS_busy++;
- }
-
-mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
- {
- mDNSs32 e = m->timenow + 0x78000000;
- if (m->mDNSPlatformStatus != mStatus_NoError || m->SleepState) return(e);
- if (m->NewQuestions)
- {
- if (m->NewQuestions->DelayAnswering) e = m->NewQuestions->DelayAnswering;
- else return(m->timenow);
- }
- if (m->NewLocalOnlyQuestions) return(m->timenow);
- if (m->NewLocalRecords && LocalRecordReady(m->NewLocalRecords)) return(m->timenow);
- if (m->SuppressSending) return(m->SuppressSending);
-#ifndef UNICAST_DISABLED
- if (e - m->uDNS_info.nextevent > 0) e = m->uDNS_info.nextevent;
-#endif
- if (e - m->NextCacheCheck > 0) e = m->NextCacheCheck;
- if (e - m->NextScheduledQuery > 0) e = m->NextScheduledQuery;
- if (e - m->NextScheduledProbe > 0) e = m->NextScheduledProbe;
- if (e - m->NextScheduledResponse > 0) e = m->NextScheduledResponse;
- return(e);
- }
-
-mDNSexport void mDNS_Unlock(mDNS *const m)
- {
- // Decrement mDNS_busy
- m->mDNS_busy--;
-
- // Check for locking failures
- if (m->mDNS_busy != m->mDNS_reentrancy)
- LogMsg("mDNS_Unlock: Locking failure! mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
-
- // If this is a final exit from the mDNSCore code, set m->NextScheduledEvent and clear m->timenow
- if (m->mDNS_busy == 0)
- {
- m->NextScheduledEvent = GetNextScheduledEvent(m);
- if (m->timenow == 0) LogMsg("mDNS_Unlock: ERROR! m->timenow aready zero");
- m->timenow = 0;
- }
-
- // MUST release the platform lock LAST!
- mDNSPlatformUnlock(m);
- }
diff --git a/src/mdns/DNSCommon.h b/src/mdns/DNSCommon.h
deleted file mode 100644
index 3ec6fc34..00000000
--- a/src/mdns/DNSCommon.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- Change History (most recent first):
-
-$Log: DNSCommon.h,v $
-Revision 1.34.2.1 2006/08/29 06:24:22 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.34 2006/03/18 21:47:56 cheshire
- Improve logic for delaying packets after repeated interface transitions
-
-Revision 1.33 2006/03/10 21:51:41 cheshire
- After record update, old record sometimes remains in cache
-Split out SameRDataBody() into a separate routine so it can be called from other code
-
-Revision 1.32 2005/03/21 00:33:51 shersche
- Fix build warnings on Win32 platform
-
-Revision 1.31 2005/02/18 00:43:11 cheshire
- mDNSResponder should auto-truncate service names that are too long
-
-Revision 1.30 2005/01/19 03:12:44 cheshire
-Move LocalRecordReady() macro from mDNS.c to DNSCommon.h
-
-Revision 1.29 2004/12/15 02:11:22 ksekar
- Don't check for Dynamic DNS hostname uniqueness
-
-Revision 1.28 2004/12/06 21:15:22 ksekar
- mDNSResponder crashed in CheckServiceRegistrations
-
-Revision 1.27 2004/12/03 07:20:50 ksekar
- Wide-Area: Registration of large TXT record fails
-
-Revision 1.26 2004/12/03 05:18:33 ksekar
- mDNSResponder needs to return more specific TSIG errors
-
-Revision 1.25 2004/10/26 03:52:02 cheshire
-Update checkin comments
-
-Revision 1.24 2004/10/23 01:16:00 cheshire
- uDNS operations not always reliable on multi-homed hosts
-
-Revision 1.23 2004/10/03 23:18:58 cheshire
-Move address comparison macros from DNSCommon.h to mDNSEmbeddedAPI.h
-
-Revision 1.22 2004/09/30 00:24:56 ksekar
- Dynamically update default registration domains on config change
-
-Revision 1.21 2004/09/17 01:08:48 cheshire
-Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
- The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
- declared in that file are ONLY appropriate to single-address-space embedded applications.
- For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
-
-Revision 1.20 2004/09/17 00:49:51 cheshire
-Get rid of now-unused GetResourceRecord -- the correct (safe) routine to use
-is GetLargeResourceRecord
-
-Revision 1.19 2004/09/16 21:59:15 cheshire
-For consistency with zerov6Addr, rename zeroIPAddr to zerov4Addr
-
-Revision 1.18 2004/09/16 02:29:39 cheshire
-Moved mDNS_Lock/mDNS_Unlock to DNSCommon.c; Added necessary locking around
-uDNS_ReceiveMsg, uDNS_StartQuery, uDNS_UpdateRecord, uDNS_RegisterService
-
-Revision 1.17 2004/09/14 23:27:46 cheshire
-Fix compile errors
-
-Revision 1.16 2004/08/13 23:46:58 cheshire
-"asyncronous" -> "asynchronous"
-
-Revision 1.15 2004/08/10 23:19:14 ksekar
-: DNS Extension daemon for Wide Area Service Discovery
-Moved routines/constants to allow extern access for garbage collection daemon
-
-Revision 1.14 2004/05/28 23:42:36 ksekar
-: Feature: DNS server->client notification on record changes (#7805)
-
-Revision 1.13 2004/05/18 23:51:25 cheshire
-Tidy up all checkin comments to use consistent "" format for bug numbers
-
-Revision 1.12 2004/04/22 04:03:59 cheshire
-Headers should use "extern" declarations, not "mDNSexport"
-
-Revision 1.11 2004/04/14 23:09:28 ksekar
-Support for TSIG signed dynamic updates.
-
-Revision 1.10 2004/03/13 01:57:33 ksekar
-: DynDNS: Dynamic update of service records
-
-Revision 1.9 2004/02/21 08:56:58 bradley
-Wrap prototypes with extern "C" for C++ builds.
-
-Revision 1.8 2004/02/06 23:04:18 ksekar
-Basic Dynamic Update support via mDNS_Register (dissabled via
-UNICAST_REGISTRATION #define)
-
-Revision 1.7 2004/02/03 19:47:36 ksekar
-Added an asynchronous state machine mechanism to uDNS.c, including
-calls to find the parent zone for a domain name. Changes include code
-in repository previously dissabled via "#if 0 incomplete". Codepath
-is currently unused, and will be called to create update records, etc.
-
-Revision 1.6 2004/01/27 20:15:22 cheshire
-: Time to prune obsolete code for listening on port 53
-
-Revision 1.5 2004/01/24 03:40:56 cheshire
-Move mDNSAddrIsDNSMulticast() from DNSCommon.h to mDNSEmbeddedAPI.h so embedded clients can use it
-
-Revision 1.4 2004/01/24 03:38:27 cheshire
-Fix minor syntactic error: Headers should use "extern" declarations, not "mDNSexport"
-
-Revision 1.3 2004/01/23 23:23:14 ksekar
-Added TCP support for truncated unicast messages.
-
-Revision 1.2 2004/01/21 21:12:23 cheshire
-Add missing newline at end of file to make Unix tools happier
-
-Revision 1.1 2003/12/13 03:05:27 ksekar
-: DynDNS: Unicast query of service records
-
-
- */
-
-#ifndef __DNSCOMMON_H_
-#define __DNSCOMMON_H_
-
-#include "mDNSEmbeddedAPI.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark - DNS Protocol Constants
-#endif
-
-typedef enum
- {
- kDNSFlag0_QR_Mask = 0x80, // Query or response?
- kDNSFlag0_QR_Query = 0x00,
- kDNSFlag0_QR_Response = 0x80,
-
- kDNSFlag0_OP_Mask = 0x78, // Operation type
- kDNSFlag0_OP_StdQuery = 0x00,
- kDNSFlag0_OP_Iquery = 0x08,
- kDNSFlag0_OP_Status = 0x10,
- kDNSFlag0_OP_Unused3 = 0x18,
- kDNSFlag0_OP_Notify = 0x20,
- kDNSFlag0_OP_Update = 0x28,
-
- kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
-
- kDNSFlag0_AA = 0x04, // Authoritative Answer?
- kDNSFlag0_TC = 0x02, // Truncated?
- kDNSFlag0_RD = 0x01, // Recursion Desired?
- kDNSFlag1_RA = 0x80, // Recursion Available?
-
- kDNSFlag1_Zero = 0x40, // Reserved; must be zero
- kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
- kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
-
- kDNSFlag1_RC = 0x0F, // Response code
- kDNSFlag1_RC_NoErr = 0x00,
- kDNSFlag1_RC_FmtErr = 0x01,
- kDNSFlag1_RC_SrvErr = 0x02,
- kDNSFlag1_RC_NXDomain = 0x03,
- kDNSFlag1_RC_NotImpl = 0x04,
- kDNSFlag1_RC_Refused = 0x05,
- kDNSFlag1_RC_YXDomain = 0x06,
- kDNSFlag1_RC_YXRRSet = 0x07,
- kDNSFlag1_RC_NXRRSet = 0x08,
- kDNSFlag1_RC_NotAuth = 0x09,
- kDNSFlag1_RC_NotZone = 0x0A
- } DNS_Flags;
-
-typedef enum
- {
- TSIG_ErrBadSig = 16,
- TSIG_ErrBadKey = 17,
- TSIG_ErrBadTime = 18
- } TSIG_ErrorCode;
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - General Utility Functions
-#endif
-
-extern const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf);
-extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
-
-extern mDNSu32 mDNSRandom(mDNSu32 max);
-extern mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max);
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - Domain Name Utility Functions
-#endif
-
-#define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
-#define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
-#define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
-#define mdnsIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
-
-#define mdnsValidHostChar(X, notfirst, notlast) (mdnsIsLetter(X) || mdnsIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
-
-extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
-
-extern mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max);
-extern mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText);
-extern mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText);
-extern void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichText);
-extern void mDNS_HostNameCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
-#define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - Resource Record Utility Functions
-#endif
-
-extern mDNSu32 RDataHashValue(mDNSu16 const rdlength, const RDataBody *const rdb);
-
-extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2);
-extern mDNSBool SameRData(const ResourceRecord *const r1, const ResourceRecord *const r2);
-
-extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
-
-extern mDNSBool SameResourceRecord(ResourceRecord *r1, ResourceRecord *r2);
-
-extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
-
-#define GetRRDomainNameTarget(RR) ( \
- ((RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_NS) \
- ? &(RR)->rdata->u.name : \
- ((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
-
-extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
-#define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique && (X)->resrec.RecordType != kDNSRecordTypeDeregistering)
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark -
-#pragma mark - DNS Message Creation Functions
-#endif
-
-extern void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags);
-extern const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname);
-
-extern mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name);
-
-extern mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, ResourceRecord *rr);
-
-// If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
-// but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
-
-extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
-
-#define PutResourceRecordTTL(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
- ((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? (msg)->data + NormalMaxDNSMessageData : (msg)->data + AbsoluteMaxDNSMessageData)
-
-#define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
- (msg)->data + AbsoluteMaxDNSMessageData)
-
-extern mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 maxttl);
-
-extern mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, mDNSu16 *count, const AuthRecord *rr);
-
-extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
-
-extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
-
-extern mDNSu8 *putPrereqNameNotInUse(domainname *name, DNSMessage *msg, mDNSu8 *ptr, mDNSu8 *end);
-
-extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr);
-
-extern mDNSu8 *putDeleteRRSet(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype);
-
-extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
-
-extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
-
-#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - DNS Message Parsing Functions
-#endif
-
-extern mDNSu32 DomainNameHashValue(const domainname *const name);
-
-extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
-
-
-extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
-
-extern const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
- domainname *const name);
-
-extern const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
-
-extern const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
- const mDNSu8 * end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *largecr);
-
-extern const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
-
-extern const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
- DNSQuestion *question);
-
-extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
-
-extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
-
-extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark -
-#pragma mark - Packet Sending Functions
-#endif
-
-extern mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
- mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, int sd, uDNS_AuthInfo *authInfo);
-
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
-#pragma mark - RR List Management & Task Management
-#endif
-
-extern void mDNS_Lock(mDNS *const m);
-extern void mDNS_Unlock(mDNS *const m);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif // __DNSCOMMON_H_
diff --git a/src/mdns/DNSDigest.c b/src/mdns/DNSDigest.c
deleted file mode 100644
index 91b7078c..00000000
--- a/src/mdns/DNSDigest.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- Change History (most recent first):
-
-$Log: DNSDigest.c,v $
-Revision 1.15.2.1 2006/08/29 06:24:22 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.15 2006/06/20 04:12:30 cheshire
- DNS Update broken
-
-Revision 1.14 2006/02/25 23:12:07 cheshire
- Fix to avoid code generation warning/error on FreeBSD 7
-
-Revision 1.13 2004/12/16 20:12:59 cheshire
- Cache memory management improvements
-
-Revision 1.12 2004/12/03 07:20:50 ksekar
- Wide-Area: Registration of large TXT record fails
-
-Revision 1.11 2004/12/02 01:10:27 cheshire
-Fix to compile cleanly on 64-bit x86
-
-Revision 1.10 2004/11/01 20:36:04 ksekar
- mDNSResponder should not receive Keychain Notifications
-
-Revision 1.9 2004/10/26 09:00:12 cheshire
-Save a few bytes by creating HMAC_MD5_AlgName as a C string instead of a 256-byte object
-
-Revision 1.8 2004/09/17 01:08:48 cheshire
-Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
- The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
- declared in that file are ONLY appropriate to single-address-space embedded applications.
- For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
-
-Revision 1.7 2004/08/15 18:36:38 cheshire
-Don't use strcpy() and strlen() on "struct domainname" objects;
-use AssignDomainName() and DomainNameLength() instead
-(A "struct domainname" is a collection of packed pascal strings, not a C string.)
-
-Revision 1.6 2004/06/02 00:17:46 ksekar
-Referenced original OpenSSL license headers in source file description.
-
-Revision 1.5 2004/05/20 18:37:37 cheshire
-Fix compiler warnings
-
-Revision 1.4 2004/04/22 20:28:20 cheshire
-Use existing facility of PutResourceRecordTTL() to update count field for us
-
-Revision 1.3 2004/04/22 03:05:28 cheshire
-kDNSClass_ANY should be kDNSQClass_ANY
-
-Revision 1.2 2004/04/15 00:51:28 bradley
-Minor tweaks for Windows and C++ builds. Added casts for signed/unsigned integers and 64-bit pointers.
-Prefix some functions with mDNS to avoid conflicts. Disable benign warnings on Microsoft compilers.
-
-Revision 1.1 2004/04/14 23:09:28 ksekar
-Support for TSIG signed dynamic updates.
-
-
-
-*/
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "mDNSEmbeddedAPI.h"
-#include "DNSCommon.h"
-
-// Disable certain benign warnings with Microsoft compilers
-#if(defined(_MSC_VER))
- // Disable "conditional expression is constant" warning for debug macros.
- // Otherwise, this generates warnings for the perfectly natural construct "while(1)"
- // If someone knows a variant way of writing "while(1)" that doesn't generate warning messages, please let us know
- #pragma warning(disable:4127)
-#endif
-
- // ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark - MD5 Hash Functions
-#endif
-
-
-/* The source for the has is derived CommonCrypto files CommonDigest.h, md32_common.h, md5_locl.h, md5_locl.h, and openssl/md5.h.
- * The following changes have been made to the original sources:
- * replaced CC_LONG w/ mDNSu32
- * replaced CC_MD5* with MD5*
- * replaced CC_LONG w/ mDNSu32, removed conditional #defines from md5.h
- * removed extern decls for MD5_Init/Update/Final from CommonDigest.h
- * removed APPLE_COMMON_DIGEST specific #defines from md5_locl.h
- *
- * Note: machine archetecure specific conditionals from the original sources are turned off, but are left in the code
- * to aid in platform-specific optimizations and debugging.
- * Sources originally distributed under the following license headers:
- * CommonDigest.c - APSL
- *
- * md32_Common.h
- * ====================================================================
- * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *
- * md5_dgst.c, md5_locl.h
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- *
- */
-
-//from CommonDigest.h
-
-#define MD5_DIGEST_LENGTH 16 /* digest length in bytes */
-#define MD5_BLOCK_BYTES 64 /* block size in bytes */
-#define MD5_BLOCK_LONG (MD5_BLOCK_BYTES / sizeof(mDNSu32))
-
-typedef struct MD5state_st
-{
- mDNSu32 A,B,C,D;
- mDNSu32 Nl,Nh;
- mDNSu32 data[MD5_BLOCK_LONG];
- int num;
-} MD5_CTX;
-
-
-// from openssl/md5.h
-
-#define MD5_CBLOCK 64
-#define MD5_LBLOCK (MD5_CBLOCK/4)
-#define MD5_DIGEST_LENGTH 16
-
-int MD5_Init(MD5_CTX *c);
-int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
-int MD5_Final(unsigned char *md, MD5_CTX *c);
-void MD5_Transform(MD5_CTX *c, const unsigned char *b);
-
-// From md5_locl.h
-
-#ifndef MD5_LONG_LOG2
-#define MD5_LONG_LOG2 2 /* default to 32 bits */
-#endif
-
-#ifdef MD5_ASM
-# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
-# define md5_block_host_order md5_block_asm_host_order
-# elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
- void md5_block_asm_data_order_aligned (MD5_CTX *c, const mDNSu32 *p,int num);
-# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned
-# endif
-#endif
-
-void md5_block_host_order (MD5_CTX *c, const void *p,int num);
-void md5_block_data_order (MD5_CTX *c, const void *p,int num);
-
-#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
-/*
- * *_block_host_order is expected to handle aligned data while
- * *_block_data_order - unaligned. As algorithm and host (x86)
- * are in this case of the same "endianness" these two are
- * otherwise indistinguishable. But normally you don't want to
- * call the same function because unaligned access in places
- * where alignment is expected is usually a "Bad Thing". Indeed,
- * on RISCs you get punished with BUS ERROR signal or *severe*
- * performance degradation. Intel CPUs are in turn perfectly
- * capable of loading unaligned data without such drastic side
- * effect. Yes, they say it's slower than aligned load, but no
- * exception is generated and therefore performance degradation
- * is *incomparable* with RISCs. What we should weight here is
- * costs of unaligned access against costs of aligning data.
- * According to my measurements allowing unaligned access results
- * in ~9% performance improvement on Pentium II operating at
- * 266MHz. I won't be surprised if the difference will be higher
- * on faster systems:-)
- *
- *
- */
-#define md5_block_data_order md5_block_host_order
-#endif
-
-#define DATA_ORDER_IS_LITTLE_ENDIAN
-
-#define HASH_LONG mDNSu32
-#define HASH_LONG_LOG2 MD5_LONG_LOG2
-#define HASH_CTX MD5_CTX
-#define HASH_CBLOCK MD5_CBLOCK
-#define HASH_LBLOCK MD5_LBLOCK
-
-#define HASH_UPDATE MD5_Update
-#define HASH_TRANSFORM MD5_Transform
-#define HASH_FINAL MD5_Final
-
-#define HASH_MAKE_STRING(c,s) do { \
- unsigned long ll; \
- ll=(c)->A; HOST_l2c(ll,(s)); \
- ll=(c)->B; HOST_l2c(ll,(s)); \
- ll=(c)->C; HOST_l2c(ll,(s)); \
- ll=(c)->D; HOST_l2c(ll,(s)); \
- } while (0)
-#define HASH_BLOCK_HOST_ORDER md5_block_host_order
-#if !defined(L_ENDIAN) || defined(md5_block_data_order)
-#define HASH_BLOCK_DATA_ORDER md5_block_data_order
-/*
- * Little-endians (Intel and Alpha) feel better without this.
- * It looks like memcpy does better job than generic
- * md5_block_data_order on copying-n-aligning input data.
- * But frankly speaking I didn't expect such result on Alpha.
- * On the other hand I've got this with egcs-1.0.2 and if
- * program is compiled with another (better?) compiler it
- * might turn out other way around.
- *
- *
- */
-#endif
-
-
-// from md32_common.h
-
-/*
- * This is a generic 32 bit "collector" for message digest algorithms.
- * Whenever needed it collects input character stream into chunks of
- * 32 bit values and invokes a block function that performs actual hash
- * calculations.
- *
- * Porting guide.
- *
- * Obligatory macros:
- *
- * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
- * this macro defines byte order of input stream.
- * HASH_CBLOCK
- * size of a unit chunk HASH_BLOCK operates on.
- * HASH_LONG
- * has to be at lest 32 bit wide, if it's wider, then
- * HASH_LONG_LOG2 *has to* be defined along
- * HASH_CTX
- * context structure that at least contains following
- * members:
- * typedef struct {
- * ...
- * HASH_LONG Nl,Nh;
- * HASH_LONG data[HASH_LBLOCK];
- * int num;
- * ...
- * } HASH_CTX;
- * HASH_UPDATE
- * name of "Update" function, implemented here.
- * HASH_TRANSFORM
- * name of "Transform" function, implemented here.
- * HASH_FINAL
- * name of "Final" function, implemented here.
- * HASH_BLOCK_HOST_ORDER
- * name of "block" function treating *aligned* input message
- * in host byte order, implemented externally.
- * HASH_BLOCK_DATA_ORDER
- * name of "block" function treating *unaligned* input message
- * in original (data) byte order, implemented externally (it
- * actually is optional if data and host are of the same
- * "endianess").
- * HASH_MAKE_STRING
- * macro convering context variables to an ASCII hash string.
- *
- * Optional macros:
- *
- * B_ENDIAN or L_ENDIAN
- * defines host byte-order.
- * HASH_LONG_LOG2
- * defaults to 2 if not states otherwise.
- * HASH_LBLOCK
- * assumed to be HASH_CBLOCK/4 if not stated otherwise.
- * HASH_BLOCK_DATA_ORDER_ALIGNED
- * alternative "block" function capable of treating
- * aligned input message in original (data) order,
- * implemented externally.
- *
- * MD5 example:
- *
- * #define DATA_ORDER_IS_LITTLE_ENDIAN
- *
- * #define HASH_LONG mDNSu32
- * #define HASH_LONG_LOG2 mDNSu32_LOG2
- * #define HASH_CTX MD5_CTX
- * #define HASH_CBLOCK MD5_CBLOCK
- * #define HASH_LBLOCK MD5_LBLOCK
- * #define HASH_UPDATE MD5_Update
- * #define HASH_TRANSFORM MD5_Transform
- * #define HASH_FINAL MD5_Final
- * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
- * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
- *
- *
- */
-
-#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-#error "DATA_ORDER must be defined!"
-#endif
-
-#ifndef HASH_CBLOCK
-#error "HASH_CBLOCK must be defined!"
-#endif
-#ifndef HASH_LONG
-#error "HASH_LONG must be defined!"
-#endif
-#ifndef HASH_CTX
-#error "HASH_CTX must be defined!"
-#endif
-
-#ifndef HASH_UPDATE
-#error "HASH_UPDATE must be defined!"
-#endif
-#ifndef HASH_TRANSFORM
-#error "HASH_TRANSFORM must be defined!"
-#endif
-#ifndef HASH_FINAL
-#error "HASH_FINAL must be defined!"
-#endif
-
-#ifndef HASH_BLOCK_HOST_ORDER
-#error "HASH_BLOCK_HOST_ORDER must be defined!"
-#endif
-
-#if 0
-/*
- * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
- * isn't defined.
- */
-#ifndef HASH_BLOCK_DATA_ORDER
-#error "HASH_BLOCK_DATA_ORDER must be defined!"
-#endif
-#endif
-
-#ifndef HASH_LBLOCK
-#define HASH_LBLOCK (HASH_CBLOCK/4)
-#endif
-
-#ifndef HASH_LONG_LOG2
-#define HASH_LONG_LOG2 2
-#endif
-
-/*
- * Engage compiler specific rotate intrinsic function if available.
- */
-#undef ROTATE
-#ifndef PEDANTIC
-# if 0 /* defined(_MSC_VER) */
-# define ROTATE(a,n) _lrotl(a,n)
-# elif defined(__MWERKS__)
-# if defined(__POWERPC__)
-# define ROTATE(a,n) (unsigned MD32_REG_T)__rlwinm((int)a,n,0,31)
-# elif defined(__MC68K__)
- /* Motorola specific tweak. */
-# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
-# else
-# define ROTATE(a,n) __rol(a,n)
-# endif
-# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
- /*
- * Some GNU C inline assembler templates. Note that these are
- * rotates by *constant* number of bits! But that's exactly
- * what we need here...
- *
- *
- */
-# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
-# define ROTATE(a,n) ({ register unsigned int ret; \
- asm ( \
- "roll %1,%0" \
- : "=r"(ret) \
- : "I"(n), "0"(a) \
- : "cc"); \
- ret; \
- })
-# elif defined(__powerpc) || defined(__ppc)
-# define ROTATE(a,n) ({ register unsigned int ret; \
- asm ( \
- "rlwinm %0,%1,%2,0,31" \
- : "=r"(ret) \
- : "r"(a), "I"(n)); \
- ret; \
- })
-# endif
-# endif
-
-/*
- * Engage compiler specific "fetch in reverse byte order"
- * intrinsic function if available.
- */
-# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
- /* some GNU C inline assembler templates by */
-# if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY)
-# define BE_FETCH32(a) ({ register unsigned int l=(a);\
- asm ( \
- "bswapl %0" \
- : "=r"(l) : "0"(l)); \
- l; \
- })
-# elif defined(__powerpc)
-# define LE_FETCH32(a) ({ register unsigned int l; \
- asm ( \
- "lwbrx %0,0,%1" \
- : "=r"(l) \
- : "r"(a)); \
- l; \
- })
-
-# elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
-# define LE_FETCH32(a) ({ register unsigned int l; \
- asm ( \
- "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
- : "=r"(l) \
- : "r"(a)); \
- l; \
- })
-# endif
-# endif
-#endif /* PEDANTIC */
-
-#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
-/* A nice byte order reversal from Wei Dai */
-#ifdef ROTATE
-/* 5 instructions with rotate instruction, else 9 */
-#define REVERSE_FETCH32(a,l) ( \
- l=*(const HASH_LONG *)(a), \
- ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
- )
-#else
-/* 6 instructions with rotate instruction, else 8 */
-#define REVERSE_FETCH32(a,l) ( \
- l=*(const HASH_LONG *)(a), \
- l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
- ROTATE(l,16) \
- )
-/*
- * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
- * It's rewritten as above for two reasons:
- * - RISCs aren't good at long constants and have to explicitely
- * compose 'em with several (well, usually 2) instructions in a
- * register before performing the actual operation and (as you
- * already realized:-) having same constant should inspire the
- * compiler to permanently allocate the only register for it;
- * - most modern CPUs have two ALUs, but usually only one has
- * circuitry for shifts:-( this minor tweak inspires compiler
- * to schedule shift instructions in a better way...
- *
- *
- */
-#endif
-#endif
-
-#ifndef ROTATE
-#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-#endif
-
-/*
- * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
- * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
- * and host are of the same "endianess". It's possible to mask
- * this with blank #define HASH_BLOCK_DATA_ORDER though...
- *
- *
- */
-#if defined(B_ENDIAN)
-# if defined(DATA_ORDER_IS_BIG_ENDIAN)
-# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-# endif
-# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-# ifndef HOST_FETCH32
-# ifdef LE_FETCH32
-# define HOST_FETCH32(p,l) LE_FETCH32(p)
-# elif defined(REVERSE_FETCH32)
-# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-# endif
-# endif
-# endif
-#elif defined(L_ENDIAN)
-# if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-# endif
-# elif defined(DATA_ORDER_IS_BIG_ENDIAN)
-# ifndef HOST_FETCH32
-# ifdef BE_FETCH32
-# define HOST_FETCH32(p,l) BE_FETCH32(p)
-# elif defined(REVERSE_FETCH32)
-# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-# endif
-# endif
-# endif
-#endif
-
-#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
-#ifndef HASH_BLOCK_DATA_ORDER
-#error "HASH_BLOCK_DATA_ORDER must be defined!"
-#endif
-#endif
-
-#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-
-#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
- l|=(((unsigned long)(*((c)++)))<<16), \
- l|=(((unsigned long)(*((c)++)))<< 8), \
- l|=(((unsigned long)(*((c)++))) ), \
- l)
-#define HOST_p_c2l(c,l,n) { \
- switch (n) { \
- case 0: l =((unsigned long)(*((c)++)))<<24; \
- case 1: l|=((unsigned long)(*((c)++)))<<16; \
- case 2: l|=((unsigned long)(*((c)++)))<< 8; \
- case 3: l|=((unsigned long)(*((c)++))); \
- } }
-#define HOST_p_c2l_p(c,l,sc,len) { \
- switch (sc) { \
- case 0: l =((unsigned long)(*((c)++)))<<24; \
- if (--len == 0) break; \
- case 1: l|=((unsigned long)(*((c)++)))<<16; \
- if (--len == 0) break; \
- case 2: l|=((unsigned long)(*((c)++)))<< 8; \
- } }
-/* NOTE the pointer is not incremented at the end of this */
-#define HOST_c2l_p(c,l,n) { \
- l=0; (c)+=n; \
- switch (n) { \
- case 3: l =((unsigned long)(*(--(c))))<< 8; \
- case 2: l|=((unsigned long)(*(--(c))))<<16; \
- case 1: l|=((unsigned long)(*(--(c))))<<24; \
- } }
-#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16)&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
- *((c)++)=(unsigned char)(((l) )&0xff), \
- l)
-
-#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-
-#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
- l|=(((unsigned long)(*((c)++)))<< 8), \
- l|=(((unsigned long)(*((c)++)))<<16), \
- l|=(((unsigned long)(*((c)++)))<<24), \
- l)
-#define HOST_p_c2l(c,l,n) { \
- switch (n) { \
- case 0: l =((unsigned long)(*((c)++))); \
- case 1: l|=((unsigned long)(*((c)++)))<< 8; \
- case 2: l|=((unsigned long)(*((c)++)))<<16; \
- case 3: l|=((unsigned long)(*((c)++)))<<24; \
- } }
-#define HOST_p_c2l_p(c,l,sc,len) { \
- switch (sc) { \
- case 0: l =((unsigned long)(*((c)++))); \
- if (--len == 0) break; \
- case 1: l|=((unsigned long)(*((c)++)))<< 8; \
- if (--len == 0) break; \
- case 2: l|=((unsigned long)(*((c)++)))<<16; \
- } }
-/* NOTE the pointer is not incremented at the end of this */
-#define HOST_c2l_p(c,l,n) { \
- l=0; (c)+=n; \
- switch (n) { \
- case 3: l =((unsigned long)(*(--(c))))<<16; \
- case 2: l|=((unsigned long)(*(--(c))))<< 8; \
- case 1: l|=((unsigned long)(*(--(c)))); \
- } }
-#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
- *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
- *((c)++)=(unsigned char)(((l)>>16)&0xff), \
- *((c)++)=(unsigned char)(((l)>>24)&0xff), \
- l)
-
-#endif
-
-/*
- * Time for some action:-)
- */
-
-int HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
- {
- const unsigned char *data=(const unsigned char *)data_;
- register HASH_LONG * p;
- register unsigned long l;
- int sw,sc,ew,ec;
-
- if (len==0) return 1;
-
- l=(c->Nl+(len<<3))&0xffffffffL;
- /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
- * Wei Dai for pointing it out. */
- if (l < c->Nl) /* overflow */
- c->Nh++;
- c->Nh+=(len>>29);
- c->Nl=l;
-
- if (c->num != 0)
- {
- p=c->data;
- sw=c->num>>2;
- sc=c->num&0x03;
-
- if ((c->num+len) >= HASH_CBLOCK)
- {
- l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
- for (; swnum);
- c->num=0;
- /* drop through and do the rest */
- }
- else
- {
- c->num+=len;
- if ((sc+len) < 4) /* ugly, add char's to a word */
- {
- l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
- }
- else
- {
- ew=(c->num>>2);
- ec=(c->num&0x03);
- if (sc)
- l=p[sw];
- HOST_p_c2l(data,l,sc);
- p[sw++]=l;
- for (; sw < ew; sw++)
- {
- HOST_c2l(data,l); p[sw]=l;
- }
- if (ec)
- {
- HOST_c2l_p(data,l,ec); p[sw]=l;
- }
- }
- return 1;
- }
- }
-
- sw=(int)(len/HASH_CBLOCK);
- if (sw > 0)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- /*
- * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
- * only if sizeof(HASH_LONG)==4.
- */
- if ((((unsigned long)data)%4) == 0)
- {
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- while (sw--)
- {
- memcpy (p=c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
- data+=HASH_CBLOCK;
- len-=HASH_CBLOCK;
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- {
- HASH_BLOCK_DATA_ORDER(c,data,sw);
- sw*=HASH_CBLOCK;
- data+=sw;
- len-=sw;
- }
-#endif
- }
-
- if (len!=0)
- {
- p = c->data;
- c->num = (int)len;
- ew=(int)(len>>2); /* words to copy */
- ec=(int)(len&0x03);
- for (; ew; ew--,p++)
- {
- HOST_c2l(data,l); *p=l;
- }
- HOST_c2l_p(data,l,ec);
- *p=l;
- }
- return 1;
- }
-
-
-void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
- {
-#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
- if ((((unsigned long)data)%4) == 0)
- /* data is properly aligned so that we can cast it: */
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
- else
-#if !defined(HASH_BLOCK_DATA_ORDER)
- {
- memcpy (c->data,data,HASH_CBLOCK);
- HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
- }
-#endif
-#endif
-#if defined(HASH_BLOCK_DATA_ORDER)
- HASH_BLOCK_DATA_ORDER (c,data,1);
-#endif
- }
-
-
-int HASH_FINAL (unsigned char *md, HASH_CTX *c)
- {
- register HASH_LONG *p;
- register unsigned long l;
- register int i,j;
- static const unsigned char end[4]={0x80,0x00,0x00,0x00};
- const unsigned char *cp=end;
-
- /* c->num should definitly have room for at least one more byte. */
- p=c->data;
- i=c->num>>2;
- j=c->num&0x03;
-
-#if 0
- /* purify often complains about the following line as an
- * Uninitialized Memory Read. While this can be true, the
- * following p_c2l macro will reset l when that case is true.
- * This is because j&0x03 contains the number of 'valid' bytes
- * already in p[i]. If and only if j&0x03 == 0, the UMR will
- * occur but this is also the only time p_c2l will do
- * l= *(cp++) instead of l|= *(cp++)
- * Many thanks to Alex Tang for pickup this
- * 'potential bug' */
-#ifdef PURIFY
- if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
-#endif
- l=p[i];
-#else
- l = (j==0) ? 0 : p[i];
-#endif
- HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
-
- if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
- {
- if (iNh;
- p[HASH_LBLOCK-1]=c->Nl;
-#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
- p[HASH_LBLOCK-2]=c->Nl;
- p[HASH_LBLOCK-1]=c->Nh;
-#endif
- HASH_BLOCK_HOST_ORDER (c,p,1);
-
-#ifndef HASH_MAKE_STRING
-#error "HASH_MAKE_STRING must be defined!"
-#else
- HASH_MAKE_STRING(c,md);
-#endif
-
- c->num=0;
- /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
- * but I'm not worried :-)
- OPENSSL_cleanse((void *)c,sizeof(HASH_CTX));
- */
- return 1;
- }
-
-#ifndef MD32_REG_T
-#define MD32_REG_T long
-/*
- * This comment was originaly written for MD5, which is why it
- * discusses A-D. But it basically applies to all 32-bit digests,
- * which is why it was moved to common header file.
- *
- * In case you wonder why A-D are declared as long and not
- * as mDNSu32. Doing so results in slight performance
- * boost on LP64 architectures. The catch is we don't
- * really care if 32 MSBs of a 64-bit register get polluted
- * with eventual overflows as we *save* only 32 LSBs in
- * *either* case. Now declaring 'em long excuses the compiler
- * from keeping 32 MSBs zeroed resulting in 13% performance
- * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
- * Well, to be honest it should say that this *prevents*
- * performance degradation.
- *
- * Apparently there're LP64 compilers that generate better
- * code if A-D are declared int. Most notably GCC-x86_64
- * generates better code.
- *
- */
-#endif
-
-
-// from md5_locl.h (continued)
-
-/*
-#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
-#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
-*/
-
-/* As pointed out by Wei Dai , the above can be
- * simplified to the code below. Wei attributes these optimizations
- * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
- */
-#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
-#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
-#define H(b,c,d) ((b) ^ (c) ^ (d))
-#define I(b,c,d) (((~(d)) | (b)) ^ (c))
-
-#define R0(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+F((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };\
-
-#define R1(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+G((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
-
-#define R2(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+H((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
-
-#define R3(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+I((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
-
-// from md5_dgst.c
-
-
-/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
- */
-
-#define INIT_DATA_A (unsigned long)0x67452301L
-#define INIT_DATA_B (unsigned long)0xefcdab89L
-#define INIT_DATA_C (unsigned long)0x98badcfeL
-#define INIT_DATA_D (unsigned long)0x10325476L
-
-int MD5_Init(MD5_CTX *c)
- {
- c->A=INIT_DATA_A;
- c->B=INIT_DATA_B;
- c->C=INIT_DATA_C;
- c->D=INIT_DATA_D;
- c->Nl=0;
- c->Nh=0;
- c->num=0;
- return 1;
- }
-
-#ifndef md5_block_host_order
-void md5_block_host_order (MD5_CTX *c, const void *data, int num)
- {
- const mDNSu32 *X=(const mDNSu32 *)data;
- register unsigned MD32_REG_T A,B,C,D;
-
- A=c->A;
- B=c->B;
- C=c->C;
- D=c->D;
-
- for (;num--;X+=HASH_LBLOCK)
- {
- /* Round 0 */
- R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
- R0(D,A,B,C,X[ 1],12,0xe8c7b756L);
- R0(C,D,A,B,X[ 2],17,0x242070dbL);
- R0(B,C,D,A,X[ 3],22,0xc1bdceeeL);
- R0(A,B,C,D,X[ 4], 7,0xf57c0fafL);
- R0(D,A,B,C,X[ 5],12,0x4787c62aL);
- R0(C,D,A,B,X[ 6],17,0xa8304613L);
- R0(B,C,D,A,X[ 7],22,0xfd469501L);
- R0(A,B,C,D,X[ 8], 7,0x698098d8L);
- R0(D,A,B,C,X[ 9],12,0x8b44f7afL);
- R0(C,D,A,B,X[10],17,0xffff5bb1L);
- R0(B,C,D,A,X[11],22,0x895cd7beL);
- R0(A,B,C,D,X[12], 7,0x6b901122L);
- R0(D,A,B,C,X[13],12,0xfd987193L);
- R0(C,D,A,B,X[14],17,0xa679438eL);
- R0(B,C,D,A,X[15],22,0x49b40821L);
- /* Round 1 */
- R1(A,B,C,D,X[ 1], 5,0xf61e2562L);
- R1(D,A,B,C,X[ 6], 9,0xc040b340L);
- R1(C,D,A,B,X[11],14,0x265e5a51L);
- R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL);
- R1(A,B,C,D,X[ 5], 5,0xd62f105dL);
- R1(D,A,B,C,X[10], 9,0x02441453L);
- R1(C,D,A,B,X[15],14,0xd8a1e681L);
- R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L);
- R1(A,B,C,D,X[ 9], 5,0x21e1cde6L);
- R1(D,A,B,C,X[14], 9,0xc33707d6L);
- R1(C,D,A,B,X[ 3],14,0xf4d50d87L);
- R1(B,C,D,A,X[ 8],20,0x455a14edL);
- R1(A,B,C,D,X[13], 5,0xa9e3e905L);
- R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L);
- R1(C,D,A,B,X[ 7],14,0x676f02d9L);
- R1(B,C,D,A,X[12],20,0x8d2a4c8aL);
- /* Round 2 */
- R2(A,B,C,D,X[ 5], 4,0xfffa3942L);
- R2(D,A,B,C,X[ 8],11,0x8771f681L);
- R2(C,D,A,B,X[11],16,0x6d9d6122L);
- R2(B,C,D,A,X[14],23,0xfde5380cL);
- R2(A,B,C,D,X[ 1], 4,0xa4beea44L);
- R2(D,A,B,C,X[ 4],11,0x4bdecfa9L);
- R2(C,D,A,B,X[ 7],16,0xf6bb4b60L);
- R2(B,C,D,A,X[10],23,0xbebfbc70L);
- R2(A,B,C,D,X[13], 4,0x289b7ec6L);
- R2(D,A,B,C,X[ 0],11,0xeaa127faL);
- R2(C,D,A,B,X[ 3],16,0xd4ef3085L);
- R2(B,C,D,A,X[ 6],23,0x04881d05L);
- R2(A,B,C,D,X[ 9], 4,0xd9d4d039L);
- R2(D,A,B,C,X[12],11,0xe6db99e5L);
- R2(C,D,A,B,X[15],16,0x1fa27cf8L);
- R2(B,C,D,A,X[ 2],23,0xc4ac5665L);
- /* Round 3 */
- R3(A,B,C,D,X[ 0], 6,0xf4292244L);
- R3(D,A,B,C,X[ 7],10,0x432aff97L);
- R3(C,D,A,B,X[14],15,0xab9423a7L);
- R3(B,C,D,A,X[ 5],21,0xfc93a039L);
- R3(A,B,C,D,X[12], 6,0x655b59c3L);
- R3(D,A,B,C,X[ 3],10,0x8f0ccc92L);
- R3(C,D,A,B,X[10],15,0xffeff47dL);
- R3(B,C,D,A,X[ 1],21,0x85845dd1L);
- R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL);
- R3(D,A,B,C,X[15],10,0xfe2ce6e0L);
- R3(C,D,A,B,X[ 6],15,0xa3014314L);
- R3(B,C,D,A,X[13],21,0x4e0811a1L);
- R3(A,B,C,D,X[ 4], 6,0xf7537e82L);
- R3(D,A,B,C,X[11],10,0xbd3af235L);
- R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
- R3(B,C,D,A,X[ 9],21,0xeb86d391L);
-
- A = c->A += A;
- B = c->B += B;
- C = c->C += C;
- D = c->D += D;
- }
- }
-#endif
-
-#ifndef md5_block_data_order
-#ifdef X
-#undef X
-#endif
-void md5_block_data_order (MD5_CTX *c, const void *data_, int num)
- {
- const unsigned char *data=data_;
- register unsigned MD32_REG_T A,B,C,D,l;
-#ifndef MD32_XARRAY
- /* See comment in crypto/sha/sha_locl.h for details. */
- unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
- XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
-# define X(i) XX##i
-#else
- mDNSu32 XX[MD5_LBLOCK];
-# define X(i) XX[i]
-#endif
-
- A=c->A;
- B=c->B;
- C=c->C;
- D=c->D;
-
- for (;num--;)
- {
- HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
- /* Round 0 */
- R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l;
- R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l;
- R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l;
- R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l;
- R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l;
- R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l;
- R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l;
- R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l;
- R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l;
- R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l;
- R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l;
- R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l;
- R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l;
- R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l;
- R0(C,D,A,B,X(14),17,0xa679438eL);
- R0(B,C,D,A,X(15),22,0x49b40821L);
- /* Round 1 */
- R1(A,B,C,D,X( 1), 5,0xf61e2562L);
- R1(D,A,B,C,X( 6), 9,0xc040b340L);
- R1(C,D,A,B,X(11),14,0x265e5a51L);
- R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
- R1(A,B,C,D,X( 5), 5,0xd62f105dL);
- R1(D,A,B,C,X(10), 9,0x02441453L);
- R1(C,D,A,B,X(15),14,0xd8a1e681L);
- R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
- R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
- R1(D,A,B,C,X(14), 9,0xc33707d6L);
- R1(C,D,A,B,X( 3),14,0xf4d50d87L);
- R1(B,C,D,A,X( 8),20,0x455a14edL);
- R1(A,B,C,D,X(13), 5,0xa9e3e905L);
- R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
- R1(C,D,A,B,X( 7),14,0x676f02d9L);
- R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
- /* Round 2 */
- R2(A,B,C,D,X( 5), 4,0xfffa3942L);
- R2(D,A,B,C,X( 8),11,0x8771f681L);
- R2(C,D,A,B,X(11),16,0x6d9d6122L);
- R2(B,C,D,A,X(14),23,0xfde5380cL);
- R2(A,B,C,D,X( 1), 4,0xa4beea44L);
- R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
- R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
- R2(B,C,D,A,X(10),23,0xbebfbc70L);
- R2(A,B,C,D,X(13), 4,0x289b7ec6L);
- R2(D,A,B,C,X( 0),11,0xeaa127faL);
- R2(C,D,A,B,X( 3),16,0xd4ef3085L);
- R2(B,C,D,A,X( 6),23,0x04881d05L);
- R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
- R2(D,A,B,C,X(12),11,0xe6db99e5L);
- R2(C,D,A,B,X(15),16,0x1fa27cf8L);
- R2(B,C,D,A,X( 2),23,0xc4ac5665L);
- /* Round 3 */
- R3(A,B,C,D,X( 0), 6,0xf4292244L);
- R3(D,A,B,C,X( 7),10,0x432aff97L);
- R3(C,D,A,B,X(14),15,0xab9423a7L);
- R3(B,C,D,A,X( 5),21,0xfc93a039L);
- R3(A,B,C,D,X(12), 6,0x655b59c3L);
- R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
- R3(C,D,A,B,X(10),15,0xffeff47dL);
- R3(B,C,D,A,X( 1),21,0x85845dd1L);
- R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
- R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
- R3(C,D,A,B,X( 6),15,0xa3014314L);
- R3(B,C,D,A,X(13),21,0x4e0811a1L);
- R3(A,B,C,D,X( 4), 6,0xf7537e82L);
- R3(D,A,B,C,X(11),10,0xbd3af235L);
- R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
- R3(B,C,D,A,X( 9),21,0xeb86d391L);
-
- A = c->A += A;
- B = c->B += B;
- C = c->C += C;
- D = c->D += D;
- }
- }
-#endif
-
-
-
- // ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark - base64 -> binary conversion
-#endif
-
-static const char Base64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const char Pad64 = '=';
-
-
-#define mDNSisspace(x) (x == '\t' || x == '\n' || x == '\v' || x == '\f' || x == '\r' || x == ' ')
-
-static const char *mDNSstrchr(const char *s, int c)
- {
- while (1)
- {
- if (c == *s) return s;
- if (!*s) return mDNSNULL;
- s++;
- }
- }
-
-// skips all whitespace anywhere.
-// converts characters, four at a time, starting at (or after)
-// src from base - 64 numbers into three 8 bit bytes in the target area.
-// it returns the number of data bytes stored at the target, or -1 on error.
-// adapted from BIND sources
-
-mDNSexport mDNSs32 DNSDigest_Base64ToBin(const char *src, mDNSu8 *target, mDNSu32 targsize)
- {
- int tarindex, state, ch;
- const char *pos;
-
- state = 0;
- tarindex = 0;
-
- while ((ch = *src++) != '\0') {
- if (mDNSisspace(ch)) /* Skip whitespace anywhere. */
- continue;
-
- if (ch == Pad64)
- break;
-
- pos = mDNSstrchr(Base64, ch);
- if (pos == 0) /* A non-base64 character. */
- return (-1);
-
- switch (state) {
- case 0:
- if (target) {
- if ((mDNSu32)tarindex >= targsize)
- return (-1);
- target[tarindex] = (mDNSu8)((pos - Base64) << 2);
- }
- state = 1;
- break;
- case 1:
- if (target) {
- if ((mDNSu32)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 4;
- target[tarindex+1] = (mDNSu8)(((pos - Base64) & 0x0f) << 4);
- }
- tarindex++;
- state = 2;
- break;
- case 2:
- if (target) {
- if ((mDNSu32)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 2;
- target[tarindex+1] = (mDNSu8)(((pos - Base64) & 0x03) << 6);
- }
- tarindex++;
- state = 3;
- break;
- case 3:
- if (target) {
- if ((mDNSu32)tarindex >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64);
- }
- tarindex++;
- state = 0;
- break;
- default:
- return -1;
- }
- }
-
- /*
- * We are done decoding Base-64 chars. Let's see if we ended
- * on a byte boundary, and/or with erroneous trailing characters.
- */
-
- if (ch == Pad64) { /* We got a pad char. */
- ch = *src++; /* Skip it, get next. */
- switch (state) {
- case 0: /* Invalid = in first position */
- case 1: /* Invalid = in second position */
- return (-1);
-
- case 2: /* Valid, means one byte of info */
- /* Skip any number of spaces. */
- for ((void)mDNSNULL; ch != '\0'; ch = *src++)
- if (!mDNSisspace(ch))
- break;
- /* Make sure there is another trailing = sign. */
- if (ch != Pad64)
- return (-1);
- ch = *src++; /* Skip the = */
- /* Fall through to "single trailing =" case. */
- /* FALLTHROUGH */
-
- case 3: /* Valid, means two bytes of info */
- /*
- * We know this char is an =. Is there anything but
- * whitespace after it?
- */
- for ((void)mDNSNULL; ch != '\0'; ch = *src++)
- if (!mDNSisspace(ch))
- return (-1);
-
- /*
- * Now make sure for cases 2 and 3 that the "extra"
- * bits that slopped past the last full byte were
- * zeros. If we don't check them, they become a
- * subliminal channel.
- */
- if (target && target[tarindex] != 0)
- return (-1);
- }
- } else {
- /*
- * We ended by seeing the end of the string. Make sure we
- * have no partial bytes lying around.
- */
- if (state != 0)
- return (-1);
- }
-
- return (tarindex);
- }
-
-
- // ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark - API exported to mDNS Core
-#endif
-
-// Constants
-#define HMAC_IPAD 0x36
-#define HMAC_OPAD 0x5c
-#define MD5_LEN 16
-
-#define HMAC_MD5_AlgName (*(const domainname*) "\010" "hmac-md5" "\007" "sig-alg" "\003" "reg" "\003" "int")
-
-// Adapted from Appendix, RFC 2104
-mDNSexport void DNSDigest_ConstructHMACKey(uDNS_AuthInfo *info, const mDNSu8 *key, mDNSu32 len)
- {
- MD5_CTX k;
- mDNSu8 buf[MD5_LEN];
- int i;
-
- // If key is longer than HMAC_LEN reset it to MD5(key)
- if (len > HMAC_LEN)
- {
- MD5_Init(&k);
- MD5_Update(&k, key, len);
- MD5_Final(buf, &k);
- key = buf;
- len = MD5_LEN;
- }
-
- // store key in pads
- mDNSPlatformMemZero(info->key.ipad, HMAC_LEN);
- mDNSPlatformMemZero(info->key.opad, HMAC_LEN);
- mDNSPlatformMemCopy(key, info->key.ipad, len);
- mDNSPlatformMemCopy(key, info->key.opad, len);
-
- // XOR key with ipad and opad values
- for (i = 0; i < HMAC_LEN; i++)
- {
- info->key.ipad[i] ^= HMAC_IPAD;
- info->key.opad[i] ^= HMAC_OPAD;
- }
-
- }
-
-mDNSexport mDNSu8 *DNSDigest_SignMessage(DNSMessage *msg, mDNSu8 **end, mDNSu16 *numAdditionals, uDNS_AuthInfo *info)
- {
- AuthRecord tsig;
- mDNSu8 *countPtr, *rdata;
- mDNSu32 utc32;
- mDNSu8 utc48[6];
- mDNSu8 digest[MD5_LEN];
- mDNSu8 *ptr = *end;
- mDNSu32 len;
- mDNSOpaque16 buf;
- MD5_CTX c;
-
- // Init MD5 context, digest inner key pad and message
- MD5_Init(&c);
- MD5_Update(&c, info->key.ipad, HMAC_LEN);
- MD5_Update(&c, (mDNSu8 *)msg, (unsigned long)(*end - (mDNSu8 *)msg));
-
- // Construct TSIG RR, digesting variables as apporpriate
- mDNSPlatformMemZero(&tsig, sizeof(AuthRecord));
- mDNS_SetupResourceRecord(&tsig, mDNSNULL, 0, kDNSType_TSIG, 0, kDNSRecordTypeKnownUnique, mDNSNULL, mDNSNULL);
-
- // key name
- AssignDomainName(tsig.resrec.name, &info->keyname);
- MD5_Update(&c, info->keyname.c, DomainNameLength(&info->keyname));
-
- // class
- tsig.resrec.rrclass = kDNSQClass_ANY;
- buf = mDNSOpaque16fromIntVal(kDNSQClass_ANY);
- MD5_Update(&c, buf.b, sizeof(mDNSOpaque16));
-
- // ttl
- tsig.resrec.rroriginalttl = 0;
- MD5_Update(&c, (mDNSu8 *)&tsig.resrec.rroriginalttl, sizeof(tsig.resrec.rroriginalttl));
-
- // alg name
- AssignDomainName(&tsig.resrec.rdata->u.name, &HMAC_MD5_AlgName);
- len = DomainNameLength(&HMAC_MD5_AlgName);
- rdata = tsig.resrec.rdata->u.data + len;
- MD5_Update(&c, HMAC_MD5_AlgName.c, len);
-
- // time
- // get UTC (universal time), convert to 48-bit unsigned in network byte order
- utc32 = (mDNSu32)mDNSPlatformUTC();
- if (utc32 == (unsigned)-1) { LogMsg("ERROR: DNSDigest_SignMessage - mDNSPlatformUTC returned bad time -1"); return mDNSNULL; }
- utc48[0] = 0;
- utc48[1] = 0;
- utc48[2] = (mDNSu8)((utc32 >> 24) & 0xff);
- utc48[3] = (mDNSu8)((utc32 >> 16) & 0xff);
- utc48[4] = (mDNSu8)((utc32 >> 8) & 0xff);
- utc48[5] = (mDNSu8)( utc32 & 0xff);
-
- mDNSPlatformMemCopy(utc48, rdata, 6);
- rdata += 6;
- MD5_Update(&c, utc48, 6);
-
- // 300 sec is fudge recommended in RFC 2485
- rdata[0] = (mDNSu8)((300 >> 8) & 0xff);
- rdata[1] = (mDNSu8)( 300 & 0xff);
- MD5_Update(&c, rdata, sizeof(mDNSOpaque16));
- rdata += sizeof(mDNSOpaque16);
-
- // digest error and other data len (both zero) - we'll add them to the rdata later
- buf.NotAnInteger = 0;
- MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // error
- MD5_Update(&c, buf.b, sizeof(mDNSOpaque16)); // other data len
-
- // finish the message & tsig var hash
- MD5_Final(digest, &c);
-
- // perform outer MD5 (outer key pad, inner digest)
- MD5_Init(&c);
- MD5_Update(&c, info->key.opad, HMAC_LEN);
- MD5_Update(&c, digest, MD5_LEN);
- MD5_Final(digest, &c);
-
- // set remaining rdata fields
- rdata[0] = (mDNSu8)((MD5_LEN >> 8) & 0xff);
- rdata[1] = (mDNSu8)( MD5_LEN & 0xff);
- rdata += sizeof(mDNSOpaque16);
- mDNSPlatformMemCopy(digest, rdata, MD5_LEN); // MAC
- rdata += MD5_LEN;
- rdata[0] = msg->h.id.b[0]; // original ID
- rdata[1] = msg->h.id.b[1];
- rdata[2] = 0; // no error
- rdata[3] = 0;
- rdata[4] = 0; // other data len
- rdata[5] = 0;
- rdata += 6;
-
- tsig.resrec.rdlength = (mDNSu16)(rdata - tsig.resrec.rdata->u.data);
- *end = PutResourceRecordTTLJumbo(msg, ptr, numAdditionals, &tsig.resrec, 0);
- if (!*end) { LogMsg("ERROR: DNSDigest_SignMessage - could not put TSIG"); return mDNSNULL; }
-
- // update num additionals
- countPtr = (mDNSu8 *)&msg->h.numAdditionals; // increment (network-byte ordered) header value
- *countPtr++ = (mDNSu8)(*numAdditionals >> 8);
- *countPtr++ = (mDNSu8)(*numAdditionals & 0xFF);
-
- return *end;
- }
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/mdns/GenLinkedList.c b/src/mdns/GenLinkedList.c
deleted file mode 100755
index d9f90334..00000000
--- a/src/mdns/GenLinkedList.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- File: GenLinkedList.c
-
- Contains: implementation of generic linked lists.
-
- Version: 1.0
- Tabs: 4 spaces
-
- Change History (most recent first):
-
-$Log: GenLinkedList.c,v $
-Revision 1.4 2006/08/14 23:24:56 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.3 2004/04/22 21:14:42 cheshire
-Fix comment spelling mistake
-
-Revision 1.2 2004/02/05 07:41:08 cheshire
-Add Log header
-
-*/
-
-#include "GenLinkedList.h"
-
-
-// Return the link pointer contained within element e at offset o.
-#define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
-
-// Assign the link pointer l to element e at offset o.
-#define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
-
-
-// GenLinkedList /////////////////////////////////////////////////////////////
-
-void InitLinkedList( GenLinkedList *pList, size_t linkOffset)
-/* Initialize the block of memory pointed to by pList as a linked list. */
-{
- pList->Head = NULL;
- pList->Tail = NULL;
- pList->LinkOffset = linkOffset;
-}
-
-
-void AddToTail( GenLinkedList *pList, void *elem)
-/* Add a linked list element to the tail of the list. */
-{
- if ( pList->Tail) {
- ASSIGNLINK( pList->Tail, elem, pList->LinkOffset);
- } else
- pList->Head = elem;
- ASSIGNLINK( elem, NULL, pList->LinkOffset);
-
- pList->Tail = elem;
-}
-
-
-void AddToHead( GenLinkedList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
- ASSIGNLINK( elem, pList->Head, pList->LinkOffset);
- if ( pList->Tail == NULL)
- pList->Tail = elem;
-
- pList->Head = elem;
-}
-
-
-int RemoveFromList( GenLinkedList *pList, void *elem)
-/* Remove a linked list element from the list. Return 0 if it was not found. */
-/* If the element is removed, its link will be set to NULL. */
-{
-void *iElem, *lastElem;
-
- for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset)) {
- if ( iElem == elem) {
- if ( lastElem) { // somewhere past the head
- ASSIGNLINK( lastElem, GETLINK( elem, pList->LinkOffset), pList->LinkOffset);
- } else { // at the head
- pList->Head = GETLINK( elem, pList->LinkOffset);
- }
- if ( pList->Tail == elem)
- pList->Tail = lastElem ? lastElem : NULL;
- ASSIGNLINK( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem)
-/* Replace an element in the list with a new element, in the same position. */
-{
-void *iElem, *lastElem;
-
- if ( elemInList == NULL || newElem == NULL)
- return 0;
-
- for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset))
- {
- if ( iElem == elemInList)
- {
- ASSIGNLINK( newElem, GETLINK( elemInList, pList->LinkOffset), pList->LinkOffset);
- if ( lastElem) // somewhere past the head
- {
- ASSIGNLINK( lastElem, newElem, pList->LinkOffset);
- }
- else // at the head
- {
- pList->Head = newElem;
- }
- if ( pList->Tail == elemInList)
- pList->Tail = newElem;
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-// GenDoubleLinkedList /////////////////////////////////////////////////////////
-
-void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
- size_t backLinkOffset)
-/* Initialize the block of memory pointed to by pList as a double linked list. */
-{
- pList->Head = NULL;
- pList->Tail = NULL;
- pList->FwdLinkOffset = fwdLinkOffset;
- pList->BackLinkOffset = backLinkOffset;
-}
-
-
-void DLLAddToHead( GenDoubleLinkedList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
-void *pNext;
-
- pNext = pList->Head;
-
- // fix up the forward links
- ASSIGNLINK( elem, pList->Head, pList->FwdLinkOffset);
- pList->Head = elem;
-
- // fix up the backward links
- if ( pNext) {
- ASSIGNLINK( pNext, elem, pList->BackLinkOffset);
- } else
- pList->Tail = elem;
- ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
-}
-
-
-void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem)
-/* Remove a linked list element from the list. */
-/* When the element is removed, its link will be set to NULL. */
-{
-void *pNext, *pPrev;
-
- pNext = GETLINK( elem, pList->FwdLinkOffset);
- pPrev = GETLINK( elem, pList->BackLinkOffset);
-
- // fix up the forward links
- if ( pPrev)
- ASSIGNLINK( pPrev, pNext, pList->FwdLinkOffset);
- else
- pList->Head = pNext;
-
- // fix up the backward links
- if ( pNext)
- ASSIGNLINK( pNext, pPrev, pList->BackLinkOffset);
- else
- pList->Tail = pPrev;
-
- ASSIGNLINK( elem, NULL, pList->FwdLinkOffset);
- ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
-}
-
-
-// GenLinkedOffsetList /////////////////////////////////////////////////////
-
-// Extract the Next offset from element
-#define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
-
-static void AssignOffsetLink( void *elem, void *link, size_t linkOffset);
-
-
-static void AssignOffsetLink( void *elem, void *link, size_t linkOffset)
-// Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
-{
- GETOFFSET( elem, linkOffset) = link ? (size_t) link - (size_t) elem : 0;
-}
-
-
-void *GetHeadPtr( GenLinkedOffsetList *pList)
-/* Return a pointer to the head element of a list, or NULL if none. */
-{
- return pList->Head ? ( (char*) (pList) + pList->Head) : NULL;
-}
-
-
-void *GetTailPtr( GenLinkedOffsetList *pList)
-/* Return a pointer to the tail element of a list, or NULL if none. */
-{
- return pList->Tail ? ( (char*) (pList) + pList->Tail) : NULL;
-}
-
-
-void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem)
-/* Return the link pointer contained within element e for pList, or NULL if it is 0. */
-{
-size_t nextOffset;
-
- nextOffset = GETOFFSET( elem, pList->LinkOffset);
-
- return nextOffset ? (char*) elem + nextOffset : NULL;
-}
-
-
-void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset)
-/* Initialize the block of memory pointed to by pList as a linked list. */
-{
- pList->Head = 0;
- pList->Tail = 0;
- pList->LinkOffset = linkOffset;
-}
-
-
-void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem)
-/* Add a linked list element to the tail of the list. */
-{
- if ( pList->Tail) {
- AssignOffsetLink( GetTailPtr( pList), elem, pList->LinkOffset);
- } else
- pList->Head = (size_t) elem - (size_t) pList;
- AssignOffsetLink( elem, NULL, pList->LinkOffset);
-
- pList->Tail = (size_t) elem - (size_t) pList;
-}
-
-
-void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
- AssignOffsetLink( elem, GetHeadPtr( pList), pList->LinkOffset);
- if ( pList->Tail == 0)
- pList->Tail = (size_t) elem - (size_t) pList;
-
- pList->Head = (size_t) elem - (size_t) pList;
-}
-
-
-int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem)
-/* Remove a linked list element from the list. Return 0 if it was not found. */
-/* If the element is removed, its link will be set to NULL. */
-{
-void *iElem, *lastElem;
-
- for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
- iElem = GetOffsetLink( pList, iElem))
- {
- if ( iElem == elem) {
- if ( lastElem) { // somewhere past the head
- AssignOffsetLink( lastElem, GetOffsetLink( pList, elem), pList->LinkOffset);
- } else { // at the head
- iElem = GetOffsetLink( pList, elem);
- pList->Head = iElem ? (size_t) iElem - (size_t) pList : 0;
- }
- if ( GetTailPtr( pList) == elem)
- pList->Tail = lastElem ? (size_t) lastElem - (size_t) pList : 0;
- AssignOffsetLink( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem)
-/* Replace an element in the list with a new element, in the same position. */
-{
-void *iElem, *lastElem;
-
- if ( elemInList == NULL || newElem == NULL)
- return 0;
-
- for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
- iElem = GetOffsetLink( pList, iElem))
- {
- if ( iElem == elemInList)
- {
- AssignOffsetLink( newElem, GetOffsetLink( pList, elemInList), pList->LinkOffset);
- if ( lastElem) // somewhere past the head
- {
- AssignOffsetLink( lastElem, newElem, pList->LinkOffset);
- }
- else // at the head
- {
- pList->Head = (size_t) newElem - (size_t) pList;
- }
- if ( GetTailPtr( pList) == elemInList)
- pList->Tail = (size_t) newElem - (size_t) pList;
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
diff --git a/src/mdns/GenLinkedList.h b/src/mdns/GenLinkedList.h
deleted file mode 100755
index 4df6e67c..00000000
--- a/src/mdns/GenLinkedList.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- File: GenLinkedList.c
-
- Contains: interface to generic linked lists.
-
- Version: 1.0
- Tabs: 4 spaces
-
- Change History (most recent first):
-
-$Log: GenLinkedList.h,v $
-Revision 1.3 2006/08/14 23:24:56 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.2 2004/02/05 07:41:08 cheshire
-Add Log header
-
-*/
-
-#ifndef __GenLinkedList__
-#define __GenLinkedList__
-
-
-#include
-
-
-struct GenLinkedList
-{
- void *Head,
- *Tail;
- size_t LinkOffset;
-};
-typedef struct GenLinkedList GenLinkedList;
-
-
-void InitLinkedList( GenLinkedList *pList, size_t linkOffset);
-
-void AddToHead( GenLinkedList *pList, void *elem);
-void AddToTail( GenLinkedList *pList, void *elem);
-
-int RemoveFromList( GenLinkedList *pList, void *elem);
-
-int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem);
-
-
-
-struct GenDoubleLinkedList
-{
- void *Head,
- *Tail;
- size_t FwdLinkOffset,
- BackLinkOffset;
-};
-typedef struct GenDoubleLinkedList GenDoubleLinkedList;
-
-
-void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
- size_t backLinkOffset);
-
-void DLLAddToHead( GenDoubleLinkedList *pList, void *elem);
-
-void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem);
-
-
-
-/* A GenLinkedOffsetList is like a GenLinkedList that stores the *Next field as a signed */
-/* offset from the address of the beginning of the element, rather than as a pointer. */
-
-struct GenLinkedOffsetList
-{
- size_t Head,
- Tail;
- size_t LinkOffset;
-};
-typedef struct GenLinkedOffsetList GenLinkedOffsetList;
-
-
-void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset);
-
-void *GetHeadPtr( GenLinkedOffsetList *pList);
-void *GetTailPtr( GenLinkedOffsetList *pList);
-void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem);
-
-void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem);
-void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem);
-
-int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem);
-
-int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem);
-
-
-#endif // __GenLinkedList__
diff --git a/src/mdns/Makefile.am b/src/mdns/Makefile.am
deleted file mode 100644
index 8773796b..00000000
--- a/src/mdns/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-AM_CPPFLAGS = -I..
-
-noinst_LTLIBRARIES = libmdns.la
-libmdns_la_SOURCES = mDNS.c mDNSPosix.c mDNSPosix.h mDNSUNP.c mDNSUNP.h \
- DNSCommon.h DNSCommon.c uDNS.c uDNS.h mDNSEmbeddedAPI.h \
- mDNSDebug.h DNSDigest.c GenLinkedList.c GenLinkedList.h \
- dns_sd.h mDNSDebug.c
-
-
-
-
diff --git a/src/mdns/dns_sd.h b/src/mdns/dns_sd.h
deleted file mode 100755
index b7eb8a22..00000000
--- a/src/mdns/dns_sd.h
+++ /dev/null
@@ -1,1722 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DNS_SD_H
-#define _DNS_SD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* standard calling convention under Win32 is __stdcall */
-/* Note: When compiling Intel EFI (Extensible Firmware Interface) under MS Visual Studio, the */
-/* _WIN32 symbol is defined by the compiler even though it's NOT compiling code for Windows32 */
-#if defined(_WIN32) && !defined(EFI32) && !defined(EFI64)
-#define DNSSD_API __stdcall
-#else
-#define DNSSD_API
-#endif
-
-/* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
-#if defined(__FreeBSD__) && (__FreeBSD__ < 5)
-#include
-
-/* Likewise, on Sun, standard integer types are in sys/types.h */
-#elif defined(__sun__)
-#include
-
-/* EFI does not have stdint.h, or anything else equivalent */
-#elif defined(EFI32) || defined(EFI64)
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef UINT16 uint16_t;
-typedef INT16 int16_t;
-typedef UINT32 uint32_t;
-typedef INT32 int32_t;
-
-/* Windows has its own differences */
-#elif defined(_WIN32)
-#include
-#define _UNUSED
-#define bzero(a, b) memset(a, 0, b)
-#ifndef _MSL_STDINT_H
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef UINT16 uint16_t;
-typedef INT16 int16_t;
-typedef UINT32 uint32_t;
-typedef INT32 int32_t;
-#endif
-
-/* All other Posix platforms use stdint.h */
-#else
-#include
-#endif
-
-/* DNSServiceRef, DNSRecordRef
- *
- * Opaque internal data types.
- * Note: client is responsible for serializing access to these structures if
- * they are shared between concurrent threads.
- */
-
-typedef struct _DNSServiceRef_t *DNSServiceRef;
-typedef struct _DNSRecordRef_t *DNSRecordRef;
-
-/* General flags used in functions defined below */
-enum
- {
- kDNSServiceFlagsMoreComing = 0x1,
- /* MoreComing indicates to a callback that at least one more result is
- * queued and will be delivered following immediately after this one.
- * Applications should not update their UI to display browse
- * results when the MoreComing flag is set, because this would
- * result in a great deal of ugly flickering on the screen.
- * Applications should instead wait until until MoreComing is not set,
- * and then update their UI.
- * When MoreComing is not set, that doesn't mean there will be no more
- * answers EVER, just that there are no more answers immediately
- * available right now at this instant. If more answers become available
- * in the future they will be delivered as usual.
- */
-
- kDNSServiceFlagsAdd = 0x2,
- kDNSServiceFlagsDefault = 0x4,
- /* Flags for domain enumeration and browse/query reply callbacks.
- * "Default" applies only to enumeration and is only valid in
- * conjuction with "Add". An enumeration callback with the "Add"
- * flag NOT set indicates a "Remove", i.e. the domain is no longer
- * valid.
- */
-
- kDNSServiceFlagsNoAutoRename = 0x8,
- /* Flag for specifying renaming behavior on name conflict when registering
- * non-shared records. By default, name conflicts are automatically handled
- * by renaming the service. NoAutoRename overrides this behavior - with this
- * flag set, name conflicts will result in a callback. The NoAutorename flag
- * is only valid if a name is explicitly specified when registering a service
- * (i.e. the default name is not used.)
- */
-
- kDNSServiceFlagsShared = 0x10,
- kDNSServiceFlagsUnique = 0x20,
- /* Flag for registering individual records on a connected
- * DNSServiceRef. Shared indicates that there may be multiple records
- * with this name on the network (e.g. PTR records). Unique indicates that the
- * record's name is to be unique on the network (e.g. SRV records).
- */
-
- kDNSServiceFlagsBrowseDomains = 0x40,
- kDNSServiceFlagsRegistrationDomains = 0x80,
- /* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
- * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
- * enumerates domains recommended for registration.
- */
-
- kDNSServiceFlagsLongLivedQuery = 0x100,
- /* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
-
- kDNSServiceFlagsAllowRemoteQuery = 0x200,
- /* Flag for creating a record for which we will answer remote queries
- * (queries from hosts more than one hop away; hosts not directly connected to the local link).
- */
-
- kDNSServiceFlagsForceMulticast = 0x400,
- /* Flag for signifying that a query or registration should be performed exclusively via multicast DNS,
- * even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
- */
-
- kDNSServiceFlagsReturnCNAME = 0x800
- /* Flag for returning CNAME records in the DNSServiceQueryRecord call. CNAME records are
- * normally followed without indicating to the client that there was a CNAME record.
- */
- };
-
-/*
- * The values for DNS Classes and Types are listed in RFC 1035, and are available
- * on every OS in its DNS header file. Unfortunately every OS does not have the
- * same header file containing DNS Class and Type constants, and the names of
- * the constants are not consistent. For example, BIND 8 uses "T_A",
- * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
- * For this reason, these constants are also listed here, so that code using
- * the DNS-SD programming APIs can use these constants, so that the same code
- * can compile on all our supported platforms.
- */
-
-enum
- {
- kDNSServiceClass_IN = 1 /* Internet */
- };
-
-enum
- {
- kDNSServiceType_A = 1, /* Host address. */
- kDNSServiceType_NS = 2, /* Authoritative server. */
- kDNSServiceType_MD = 3, /* Mail destination. */
- kDNSServiceType_MF = 4, /* Mail forwarder. */
- kDNSServiceType_CNAME = 5, /* Canonical name. */
- kDNSServiceType_SOA = 6, /* Start of authority zone. */
- kDNSServiceType_MB = 7, /* Mailbox domain name. */
- kDNSServiceType_MG = 8, /* Mail group member. */
- kDNSServiceType_MR = 9, /* Mail rename name. */
- kDNSServiceType_NULL = 10, /* Null resource record. */
- kDNSServiceType_WKS = 11, /* Well known service. */
- kDNSServiceType_PTR = 12, /* Domain name pointer. */
- kDNSServiceType_HINFO = 13, /* Host information. */
- kDNSServiceType_MINFO = 14, /* Mailbox information. */
- kDNSServiceType_MX = 15, /* Mail routing information. */
- kDNSServiceType_TXT = 16, /* One or more text strings. */
- kDNSServiceType_RP = 17, /* Responsible person. */
- kDNSServiceType_AFSDB = 18, /* AFS cell database. */
- kDNSServiceType_X25 = 19, /* X_25 calling address. */
- kDNSServiceType_ISDN = 20, /* ISDN calling address. */
- kDNSServiceType_RT = 21, /* Router. */
- kDNSServiceType_NSAP = 22, /* NSAP address. */
- kDNSServiceType_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
- kDNSServiceType_SIG = 24, /* Security signature. */
- kDNSServiceType_KEY = 25, /* Security key. */
- kDNSServiceType_PX = 26, /* X.400 mail mapping. */
- kDNSServiceType_GPOS = 27, /* Geographical position (withdrawn). */
- kDNSServiceType_AAAA = 28, /* IPv6 Address. */
- kDNSServiceType_LOC = 29, /* Location Information. */
- kDNSServiceType_NXT = 30, /* Next domain (security). */
- kDNSServiceType_EID = 31, /* Endpoint identifier. */
- kDNSServiceType_NIMLOC = 32, /* Nimrod Locator. */
- kDNSServiceType_SRV = 33, /* Server Selection. */
- kDNSServiceType_ATMA = 34, /* ATM Address */
- kDNSServiceType_NAPTR = 35, /* Naming Authority PoinTeR */
- kDNSServiceType_KX = 36, /* Key Exchange */
- kDNSServiceType_CERT = 37, /* Certification record */
- kDNSServiceType_A6 = 38, /* IPv6 Address (deprecated) */
- kDNSServiceType_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
- kDNSServiceType_SINK = 40, /* Kitchen sink (experimentatl) */
- kDNSServiceType_OPT = 41, /* EDNS0 option (meta-RR) */
- kDNSServiceType_TKEY = 249, /* Transaction key */
- kDNSServiceType_TSIG = 250, /* Transaction signature. */
- kDNSServiceType_IXFR = 251, /* Incremental zone transfer. */
- kDNSServiceType_AXFR = 252, /* Transfer zone of authority. */
- kDNSServiceType_MAILB = 253, /* Transfer mailbox records. */
- kDNSServiceType_MAILA = 254, /* Transfer mail agent records. */
- kDNSServiceType_ANY = 255 /* Wildcard match. */
- };
-
-
-/* possible error code values */
-enum
- {
- kDNSServiceErr_NoError = 0,
- kDNSServiceErr_Unknown = -65537, /* 0xFFFE FFFF */
- kDNSServiceErr_NoSuchName = -65538,
- kDNSServiceErr_NoMemory = -65539,
- kDNSServiceErr_BadParam = -65540,
- kDNSServiceErr_BadReference = -65541,
- kDNSServiceErr_BadState = -65542,
- kDNSServiceErr_BadFlags = -65543,
- kDNSServiceErr_Unsupported = -65544,
- kDNSServiceErr_NotInitialized = -65545,
- kDNSServiceErr_AlreadyRegistered = -65547,
- kDNSServiceErr_NameConflict = -65548,
- kDNSServiceErr_Invalid = -65549,
- kDNSServiceErr_Firewall = -65550,
- kDNSServiceErr_Incompatible = -65551, /* client library incompatible with daemon */
- kDNSServiceErr_BadInterfaceIndex = -65552,
- kDNSServiceErr_Refused = -65553,
- kDNSServiceErr_NoSuchRecord = -65554,
- kDNSServiceErr_NoAuth = -65555,
- kDNSServiceErr_NoSuchKey = -65556,
- kDNSServiceErr_NATTraversal = -65557,
- kDNSServiceErr_DoubleNAT = -65558,
- kDNSServiceErr_BadTime = -65559
- /* mDNS Error codes are in the range
- * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
- };
-
-
-/* Maximum length, in bytes, of a service name represented as a */
-/* literal C-String, including the terminating NULL at the end. */
-
-#define kDNSServiceMaxServiceName 64
-
-/* Maximum length, in bytes, of a domain name represented as an *escaped* C-String */
-/* including the final trailing dot, and the C-String terminating NULL at the end. */
-
-#define kDNSServiceMaxDomainName 1005
-
-/*
- * Notes on DNS Name Escaping
- * -- or --
- * "Why is kDNSServiceMaxDomainName 1005, when the maximum legal domain name is 255 bytes?"
- *
- * All strings used in DNS-SD are UTF-8 strings.
- * With few exceptions, most are also escaped using standard DNS escaping rules:
- *
- * '\\' represents a single literal '\' in the name
- * '\.' represents a single literal '.' in the name
- * '\ddd', where ddd is a three-digit decimal value from 000 to 255,
- * represents a single literal byte with that value.
- * A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
- *
- * The exceptions, that do not use escaping, are the routines where the full
- * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
- * In these routines, the "servicename" is NOT escaped. It does not need to be, since
- * it is, by definition, just a single literal string. Any characters in that string
- * represent exactly what they are. The "regtype" portion is, technically speaking,
- * escaped, but since legal regtypes are only allowed to contain letters, digits,
- * and hyphens, there is nothing to escape, so the issue is moot. The "domain"
- * portion is also escaped, though most domains in use on the public Internet
- * today, like regtypes, don't contain any characters that need to be escaped.
- * As DNS-SD becomes more popular, rich-text domains for service discovery will
- * become common, so software should be written to cope with domains with escaping.
- *
- * The servicename may be up to 63 bytes of UTF-8 text (not counting the C-String
- * terminating NULL at the end). The regtype is of the form _service._tcp or
- * _service._udp, where the "service" part is 1-14 characters, which may be
- * letters, digits, or hyphens. The domain part of the three-part name may be
- * any legal domain, providing that the resulting servicename+regtype+domain
- * name does not exceed 255 bytes.
- *
- * For most software, these issues are transparent. When browsing, the discovered
- * servicenames should simply be displayed as-is. When resolving, the discovered
- * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
- * When a DNSServiceResolve() succeeds, the returned fullname is already in
- * the correct format to pass to standard system DNS APIs such as res_query().
- * For converting from servicename/regtype/domain to a single properly-escaped
- * full DNS name, the helper function DNSServiceConstructFullName() is provided.
- *
- * The following (highly contrived) example illustrates the escaping process.
- * Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
- * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
- * The full (escaped) DNS name of this service's SRV record would be:
- * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
- */
-
-
-/*
- * Constants for specifying an interface index
- *
- * Specific interface indexes are identified via a 32-bit unsigned integer returned
- * by the if_nametoindex() family of calls.
- *
- * If the client passes 0 for interface index, that means "do the right thing",
- * which (at present) means, "if the name is in an mDNS local multicast domain
- * (e.g. 'local.', '254.169.in-addr.arpa.', '{8,9,A,B}.E.F.ip6.arpa.') then multicast
- * on all applicable interfaces, otherwise send via unicast to the appropriate
- * DNS server." Normally, most clients will use 0 for interface index to
- * automatically get the default sensible behaviour.
- *
- * If the client passes a positive interface index, then for multicast names that
- * indicates to do the operation only on that one interface. For unicast names the
- * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
- *
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
- * a service, then that service will be found *only* by other local clients
- * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
- * or kDNSServiceInterfaceIndexAny.
- * If a client has a 'private' service, accessible only to other processes
- * running on the same machine, this allows the client to advertise that service
- * in a way such that it does not inadvertently appear in service lists on
- * all the other machines on the network.
- *
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
- * then it will find *all* records registered on that same local machine.
- * Clients explicitly wishing to discover *only* LocalOnly services can
- * accomplish this by inspecting the interfaceIndex of each service reported
- * to their DNSServiceBrowseReply() callback function, and discarding those
- * where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
- */
-
-#define kDNSServiceInterfaceIndexAny 0
-#define kDNSServiceInterfaceIndexLocalOnly ( (uint32_t) -1 )
-
-
-typedef uint32_t DNSServiceFlags;
-typedef int32_t DNSServiceErrorType;
-
-
-/*********************************************************************************************
- *
- * Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
- *
- *********************************************************************************************/
-
-
-/* DNSServiceRefSockFD()
- *
- * Access underlying Unix domain socket for an initialized DNSServiceRef.
- * The DNS Service Discovery implmementation uses this socket to communicate between
- * the client and the mDNSResponder daemon. The application MUST NOT directly read from
- * or write to this socket. Access to the socket is provided so that it can be used as a
- * run loop source, or in a select() loop: when data is available for reading on the socket,
- * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
- * the socket, and pass it to the appropriate application callback. By using a run loop or
- * select(), results from the daemon can be processed asynchronously. Without using these
- * constructs, DNSServiceProcessResult() will block until the response from the daemon arrives.
- * The client is responsible for ensuring that the data on the socket is processed in a timely
- * fashion - the daemon may terminate its connection with a client that does not clear its
- * socket buffer.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- * return value: The DNSServiceRef's underlying socket descriptor, or -1 on
- * error.
- */
-
-int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
-
-
-/* DNSServiceProcessResult()
- *
- * Read a reply from the daemon, calling the appropriate application callback. This call will
- * block until the daemon's response is received. Use DNSServiceRefSockFD() in
- * conjunction with a run loop or select() to determine the presence of a response from the
- * server before calling this function to process the reply without blocking. Call this function
- * at any point if it is acceptable to block until the daemon's response arrives. Note that the
- * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
- * a reply from the daemon - the daemon may terminate its connection with a client that does not
- * process the daemon's responses.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls
- * that take a callback parameter.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
-
-
-/* DNSServiceRefDeallocate()
- *
- * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
- * Any services or records registered with this DNSServiceRef will be deregistered. Any
- * Browse, Resolve, or Query operations called with this reference will be terminated.
- *
- * Note: If the reference's underlying socket is used in a run loop or select() call, it should
- * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
- * socket.
- *
- * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
- * created via this reference will be invalidated by this call - the resource records are
- * deregistered, and their DNSRecordRefs may not be used in subsequent functions. Similarly,
- * if the reference was initialized with DNSServiceRegister, and an extra resource record was
- * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
- * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
- * functions.
- *
- * Note: This call is to be used only with the DNSServiceRef defined by this API. It is
- * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
- * DNSServiceDiscovery.h API.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- */
-
-void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
-
-
-/*********************************************************************************************
- *
- * Domain Enumeration
- *
- *********************************************************************************************/
-
-/* DNSServiceEnumerateDomains()
- *
- * Asynchronously enumerate domains available for browsing and registration.
- *
- * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
- * are to be found.
- *
- * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
- * and are escaped using standard DNS escaping rules.
- * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
- * A graphical browser displaying a hierarchical tree-structured view should cut
- * the names at the bare dots to yield individual labels, then de-escape each
- * label according to the escaping rules, and then display the resulting UTF-8 text.
- *
- * DNSServiceDomainEnumReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceEnumerateDomains().
- *
- * flags: Possible values are:
- * kDNSServiceFlagsMoreComing
- * kDNSServiceFlagsAdd
- * kDNSServiceFlagsDefault
- *
- * interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
- * interface is determined via the if_nametoindex() family of calls.)
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
- * the failure that occurred (other parameters are undefined if errorCode is nonzero).
- *
- * replyDomain: The name of the domain.
- *
- * context: The context pointer passed to DNSServiceEnumerateDomains.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceDomainEnumReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *replyDomain,
- void *context
- );
-
-
-/* DNSServiceEnumerateDomains() Parameters:
- *
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the enumeration operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Possible values are:
- * kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
- * kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
- * for registration.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to look for domains.
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to enumerate domains on
- * all interfaces. See "Constants for specifying an interface index" for more details.
- *
- * callBack: The function to be called when a domain is found or the call asynchronously
- * fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceDomainEnumReply callBack,
- void *context /* may be NULL */
- );
-
-
-/*********************************************************************************************
- *
- * Service Registration
- *
- *********************************************************************************************/
-
-/* Register a service that is discovered via Browse() and Resolve() calls.
- *
- *
- * DNSServiceRegisterReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceRegister().
- *
- * flags: Currently unused, reserved for future use.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts,
- * if the kDNSServiceFlagsNoAutoRename flag was used when registering.)
- * Other parameters are undefined if errorCode is nonzero.
- *
- * name: The service name registered (if the application did not specify a name in
- * DNSServiceRegister(), this indicates what name was automatically chosen).
- *
- * regtype: The type of service registered, as it was passed to the callout.
- *
- * domain: The domain on which the service was registered (if the application did not
- * specify a domain in DNSServiceRegister(), this indicates the default domain
- * on which the service was registered).
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceRegisterReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- void *context
- );
-
-
-/* DNSServiceRegister() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the registration will remain active indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the service
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to register on all
- * available interfaces. See "Constants for specifying an interface index" for more details.
- *
- * flags: Indicates the renaming behavior on name conflict (most applications
- * will pass 0). See flag definitions above for details.
- *
- * name: If non-NULL, specifies the service name to be registered.
- * Most applications will not specify a name, in which case the computer
- * name is used (this name is communicated to the client via the callback).
- * If a name is specified, it must be 1-63 bytes of UTF-8 text.
- * If the name is longer than 63 bytes it will be automatically truncated
- * to a legal length, unless the NoAutoRename flag is set,
- * in which case kDNSServiceErr_BadParam will be returned.
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp"). The service type must be an underscore, followed
- * by 1-14 characters, which may be letters, digits, or hyphens.
- * The transport protocol must be "_tcp" or "_udp". New service types
- * should be registered at .
- *
- * domain: If non-NULL, specifies the domain on which to advertise the service.
- * Most applications will not specify a domain, instead automatically
- * registering in the default domain(s).
- *
- * host: If non-NULL, specifies the SRV target host name. Most applications
- * will not specify a host, instead automatically using the machine's
- * default host name(s). Note that specifying a non-NULL host does NOT
- * create an address record for that host - the application is responsible
- * for ensuring that the appropriate address record exists, or creating it
- * via DNSServiceRegisterRecord().
- *
- * port: The port, in network byte order, on which the service accepts connections.
- * Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
- * by browsing, but will cause a name conflict if another client tries to
- * register that same name). Most clients will not use placeholder services.
- *
- * txtLen: The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
- *
- * txtRecord: The TXT record rdata. A non-NULL txtRecord MUST be a properly formatted DNS
- * TXT record, i.e. ...
- * Passing NULL for the txtRecord is allowed as a synonym for txtLen=1, txtRecord="",
- * i.e. it creates a TXT record of length one containing a single empty string.
- * RFC 1035 doesn't allow a TXT record to contain *zero* strings, so a single empty
- * string is the smallest legal DNS TXT record.
- * As with the other parameters, the DNSServiceRegister call copies the txtRecord
- * data; e.g. if you allocated the storage for the txtRecord parameter with malloc()
- * then you can safely free that memory right after the DNSServiceRegister call returns.
- *
- * callBack: The function to be called when the registration completes or asynchronously
- * fails. The client MAY pass NULL for the callback - The client will NOT be notified
- * of the default values picked on its behalf, and the client will NOT be notified of any
- * asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
- * of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
- * The client may still deregister the service at any time via DNSServiceRefDeallocate().
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegister
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name, /* may be NULL */
- const char *regtype,
- const char *domain, /* may be NULL */
- const char *host, /* may be NULL */
- uint16_t port,
- uint16_t txtLen,
- const void *txtRecord, /* may be NULL */
- DNSServiceRegisterReply callBack, /* may be NULL */
- void *context /* may be NULL */
- );
-
-
-/* DNSServiceAddRecord()
- *
- * Add a record to a registered service. The name of the record will be the same as the
- * registered service's name.
- * The record can later be updated or deregistered by passing the RecordRef initialized
- * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *
- * Note that the DNSServiceAddRecord/UpdateRecord/RemoveRecord are *NOT* thread-safe
- * with respect to a single DNSServiceRef. If you plan to have multiple threads
- * in your program simultaneously add, update, or remove records from the same
- * DNSServiceRef, then it's the caller's responsibility to use a mutext lock
- * or take similar appropriate precautions to serialize those calls.
- *
- *
- * Parameters;
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
- * invalidated and may not be used further.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rrtype: The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
- *
- * rdlen: The length, in bytes, of the rdata.
- *
- * rdata: The raw rdata to be contained in the added resource record.
- *
- * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred (the RecordRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceAddRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint16_t rrtype,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
- );
-
-
-/* DNSServiceUpdateRecord
- *
- * Update a registered resource record. The record must either be:
- * - The primary txt record of a service registered via DNSServiceRegister()
- * - A record added to a registered service via DNSServiceAddRecord()
- * - An individual record registered by DNSServiceRegisterRecord()
- *
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef that was initialized by DNSServiceRegister()
- * or DNSServiceCreateConnection().
- *
- * RecordRef: A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
- * service's primary txt record.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rdlen: The length, in bytes, of the new rdata.
- *
- * rdata: The new rdata to be contained in the updated resource record.
- *
- * ttl: The time to live of the updated resource record, in seconds.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef, /* may be NULL */
- DNSServiceFlags flags,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
- );
-
-
-/* DNSServiceRemoveRecord
- *
- * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
- * an record registered individually via DNSServiceRegisterRecord().
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister() (if the
- * record being removed was registered via DNSServiceAddRecord()) or by
- * DNSServiceCreateConnection() (if the record being removed was registered via
- * DNSServiceRegisterRecord()).
- *
- * recordRef: A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
- * or DNSServiceRegisterRecord().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags
- );
-
-
-/*********************************************************************************************
- *
- * Service Discovery
- *
- *********************************************************************************************/
-
-/* Browse for instances of a service.
- *
- *
- * DNSServiceBrowseReply() Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceBrowse().
- *
- * flags: Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
- * See flag definitions for details.
- *
- * interfaceIndex: The interface on which the service is advertised. This index should
- * be passed to DNSServiceResolve() when resolving the service.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * serviceName: The discovered service name. This name should be displayed to the user,
- * and stored for subsequent use in the DNSServiceResolve() call.
- *
- * regtype: The service type, which is usually (but not always) the same as was passed
- * to DNSServiceBrowse(). One case where the discovered service type may
- * not be the same as the requested service type is when using subtypes:
- * The client may want to browse for only those ftp servers that allow
- * anonymous connections. The client will pass the string "_ftp._tcp,_anon"
- * to DNSServiceBrowse(), but the type of the service that's discovered
- * is simply "_ftp._tcp". The regtype for each discovered service instance
- * should be stored along with the name, so that it can be passed to
- * DNSServiceResolve() when the service is later resolved.
- *
- * domain: The domain of the discovered service instance. This may or may not be the
- * same as the domain that was passed to DNSServiceBrowse(). The domain for each
- * discovered service instance should be stored along with the name, so that
- * it can be passed to DNSServiceResolve() when the service is later resolved.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceBrowseReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *serviceName,
- const char *regtype,
- const char *replyDomain,
- void *context
- );
-
-
-/* DNSServiceBrowse() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the browse operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to browse for services
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to browse on all available
- * interfaces. See "Constants for specifying an interface index" for more details.
- *
- * regtype: The service type being browsed for followed by the protocol, separated by a
- * dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- *
- * domain: If non-NULL, specifies the domain on which to browse for services.
- * Most applications will not specify a domain, instead browsing on the
- * default domain(s).
- *
- * callBack: The function to be called when an instance of the service being browsed for
- * is found, or if the call asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceBrowse
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *regtype,
- const char *domain, /* may be NULL */
- DNSServiceBrowseReply callBack,
- void *context /* may be NULL */
- );
-
-
-/* DNSServiceResolve()
- *
- * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
- * txt record.
- *
- * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
- * DNSServiceQueryRecord() instead, as it is more efficient for this task.
- *
- * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
- * DNSServiceRefDeallocate().
- *
- * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record
- * and a single TXT record. To resolve non-standard services with multiple SRV or TXT records,
- * DNSServiceQueryRecord() should be used.
- *
- * DNSServiceResolveReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceResolve().
- *
- * flags: Currently unused, reserved for future use.
- *
- * interfaceIndex: The interface on which the service was resolved.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * fullname: The full service domain name, in the form ...
- * (This name is escaped following standard DNS rules, making it suitable for
- * passing to standard system DNS APIs such as res_query(), or to the
- * special-purpose functions included in this API that take fullname parameters.
- * See "Notes on DNS Name Escaping" earlier in this file for more details.)
- *
- * hosttarget: The target hostname of the machine providing the service. This name can
- * be passed to functions like gethostbyname() to identify the host's IP address.
- *
- * port: The port, in network byte order, on which connections are accepted for this service.
- *
- * txtLen: The length of the txt record, in bytes.
- *
- * txtRecord: The service's primary txt record, in standard txt record format.
- *
- * context: The context pointer that was passed to the callout.
- *
- * NOTE: In earlier versions of this header file, the txtRecord parameter was declared "const char *"
- * This is incorrect, since it contains length bytes which are values in the range 0 to 255, not -128 to +127.
- * Depending on your compiler settings, this change may cause signed/unsigned mismatch warnings.
- * These should be fixed by updating your own callback function definition to match the corrected
- * function signature using "const unsigned char *txtRecord". Making this change may also fix inadvertent
- * bugs in your callback function, where it could have incorrectly interpreted a length byte with value 250
- * as being -6 instead, with various bad consequences ranging from incorrect operation to software crashes.
- * If you need to maintain portable code that will compile cleanly with both the old and new versions of
- * this header file, you should update your callback function definition to use the correct unsigned value,
- * and then in the place where you pass your callback function to DNSServiceResolve(), use a cast to eliminate
- * the compiler warning, e.g.:
- * DNSServiceResolve(sd, flags, index, name, regtype, domain, (DNSServiceResolveReply)MyCallback, context);
- * This will ensure that your code compiles cleanly without warnings (and more importantly, works correctly)
- * with both the old header and with the new corrected version.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceResolveReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- const char *hosttarget,
- uint16_t port,
- uint16_t txtLen,
- const unsigned char *txtRecord,
- void *context
- );
-
-
-/* DNSServiceResolve() Parameters
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the resolve operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: The interface on which to resolve the service. If this resolve call is
- * as a result of a currently active DNSServiceBrowse() operation, then the
- * interfaceIndex should be the index reported in the DNSServiceBrowseReply
- * callback. If this resolve call is using information previously saved
- * (e.g. in a preference file) for later use, then use interfaceIndex 0, because
- * the desired service may now be reachable via a different physical interface.
- * See "Constants for specifying an interface index" for more details.
- *
- * name: The name of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * regtype: The type of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * domain: The domain of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceResolve
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
- DNSServiceResolveReply callBack,
- void *context /* may be NULL */
- );
-
-
-/*********************************************************************************************
- *
- * Special Purpose Calls (most applications will not use these)
- *
- *********************************************************************************************/
-
-/* DNSServiceCreateConnection()
- *
- * Create a connection to the daemon allowing efficient registration of
- * multiple individual records.
- *
- *
- * Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
- * the reference (via DNSServiceRefDeallocate()) severs the
- * connection and deregisters all records registered on this connection.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred (in which
- * case the DNSServiceRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
-
-
-/* DNSServiceRegisterRecord
- *
- * Register an individual resource record on a connected DNSServiceRef.
- *
- * Note that name conflicts occurring for records registered via this call must be handled
- * by the client in the callback.
- *
- *
- * DNSServiceRegisterRecordReply() parameters:
- *
- * sdRef: The connected DNSServiceRef initialized by
- * DNSServiceCreateConnection().
- *
- * RecordRef: The DNSRecordRef initialized by DNSServiceRegisterRecord(). If the above
- * DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
- * invalidated, and may not be used further.
- *
- * flags: Currently unused, reserved for future use.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts.)
- * Other parameters are undefined if errorCode is nonzero.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
- typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- void *context
- );
-
-
-/* DNSServiceRegisterRecord() Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceCreateConnection().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * (To deregister ALL records registered on a single connected DNSServiceRef
- * and deallocate each of their corresponding DNSServiceRecordRefs, call
- * DNSServiceRefDealloocate()).
- *
- * flags: Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
- * (see flag type definitions for details).
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the record
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the record to be registered on all interfaces.
- * See "Constants for specifying an interface index" for more details.
- *
- * fullname: The full domain name of the resource record.
- *
- * rrtype: The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN)
- *
- * rdlen: Length, in bytes, of the rdata.
- *
- * rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
- *
- * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails (e.g. because of a name conflict.)
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSRecordRef is
- * not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- DNSServiceRegisterRecordReply callBack,
- void *context /* may be NULL */
- );
-
-
-/* DNSServiceQueryRecord
- *
- * Query for an arbitrary DNS record.
- *
- *
- * DNSServiceQueryRecordReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceQueryRecord().
- *
- * flags: Possible values are kDNSServiceFlagsMoreComing and
- * kDNSServiceFlagsAdd. The Add flag is NOT set for PTR records
- * with a ttl of 0, i.e. "Remove" events.
- *
- * interfaceIndex: The interface on which the query was resolved (the index for a given
- * interface is determined via the if_nametoindex() family of calls).
- * See "Constants for specifying an interface index" for more details.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * errorCode is nonzero.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- * ttl: The resource record's time to live, in seconds.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceQueryRecordReply)
- (
- DNSServiceRef DNSServiceRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- void *context
- );
-
-
-/* DNSServiceQueryRecord() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the query operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
- * query in a non-local domain. Without setting this flag, unicast queries
- * will be one-shot - that is, only answers available at the time of the call
- * will be returned. By setting this flag, answers (including Add and Remove
- * events) that become available after the initial call is made will generate
- * callbacks. This flag has no effect on link-local multicast queries.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to issue the query
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the name to be queried for on all
- * interfaces. See "Constants for specifying an interface index" for more details.
- *
- * fullname: The full domain name of the resource record to be queried for.
- *
- * rrtype: The numerical type of the resource record to be queried for
- * (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- DNSServiceQueryRecordReply callBack,
- void *context /* may be NULL */
- );
-
-
-/* DNSServiceReconfirmRecord
- *
- * Instruct the daemon to verify the validity of a resource record that appears to
- * be out of date (e.g. because tcp connection to a service's target failed.)
- * Causes the record to be flushed from the daemon's cache (as well as all other
- * daemons' caches on the network) if the record is determined to be invalid.
- *
- * Parameters:
- *
- * flags: Currently unused, reserved for future use.
- *
- * interfaceIndex: If non-zero, specifies the interface of the record in question.
- * Passing 0 causes all instances of this record to be reconfirmed.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
- (
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata
- );
-
-
-/*********************************************************************************************
- *
- * General Utility Functions
- *
- *********************************************************************************************/
-
-/* DNSServiceConstructFullName()
- *
- * Concatenate a three-part domain name (as returned by the above callbacks) into a
- * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
- * strings where necessary.
- *
- * Parameters:
- *
- * fullName: A pointer to a buffer that where the resulting full domain name is to be written.
- * The buffer must be kDNSServiceMaxDomainName (1005) bytes in length to
- * accommodate the longest legal domain name without buffer overrun.
- *
- * service: The service name - any dots or backslashes must NOT be escaped.
- * May be NULL (to construct a PTR record name, e.g.
- * "_ftp._tcp.apple.com.").
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp").
- *
- * domain: The domain name, e.g. "apple.com.". Literal dots or backslashes,
- * if any, must be escaped, e.g. "1st\. Floor.apple.com."
- *
- * return value: Returns 0 on success, -1 on error.
- *
- */
-
-int DNSSD_API DNSServiceConstructFullName
- (
- char *fullName,
- const char *service, /* may be NULL */
- const char *regtype,
- const char *domain
- );
-
-
-/*********************************************************************************************
- *
- * TXT Record Construction Functions
- *
- *********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record construction is something like:
- *
- * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
- * TXTRecordCreate();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * ...
- * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
- * TXTRecordDeallocate();
- * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
- */
-
-
-/* TXTRecordRef
- *
- * Opaque internal data type.
- * Note: Represents a DNS-SD TXT record.
- */
-
-typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignment; } TXTRecordRef;
-
-
-/* TXTRecordCreate()
- *
- * Creates a new empty TXTRecordRef referencing the specified storage.
- *
- * If the buffer parameter is NULL, or the specified storage size is not
- * large enough to hold a key subsequently added using TXTRecordSetValue(),
- * then additional memory will be added as needed using malloc().
- *
- * On some platforms, when memory is low, malloc() may fail. In this
- * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
- * error condition will need to be handled as appropriate by the caller.
- *
- * You can avoid the need to handle this error condition if you ensure
- * that the storage you initially provide is large enough to hold all
- * the key/value pairs that are to be added to the record.
- * The caller can precompute the exact length required for all of the
- * key/value pairs to be added, or simply provide a fixed-sized buffer
- * known in advance to be large enough.
- * A no-value (key-only) key requires (1 + key length) bytes.
- * A key with empty value requires (1 + key length + 1) bytes.
- * A key with non-empty value requires (1 + key length + 1 + value length).
- * For most applications, DNS-SD TXT records are generally
- * less than 100 bytes, so in most cases a simple fixed-sized
- * 256-byte buffer will be more than sufficient.
- * Recommended size limits for DNS-SD TXT Records are discussed in
- *
- *
- * Note: When passing parameters to and from these TXT record APIs,
- * the key name does not include the '=' character. The '=' character
- * is the separator between the key and value in the on-the-wire
- * packet format; it is not part of either the key or the value.
- *
- * txtRecord: A pointer to an uninitialized TXTRecordRef.
- *
- * bufferLen: The size of the storage provided in the "buffer" parameter.
- *
- * buffer: Optional caller-supplied storage used to hold the TXTRecord data.
- * This storage must remain valid for as long as
- * the TXTRecordRef.
- */
-
-void DNSSD_API TXTRecordCreate
- (
- TXTRecordRef *txtRecord,
- uint16_t bufferLen,
- void *buffer
- );
-
-
-/* TXTRecordDeallocate()
- *
- * Releases any resources allocated in the course of preparing a TXT Record
- * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
- * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- */
-
-void DNSSD_API TXTRecordDeallocate
- (
- TXTRecordRef *txtRecord
- );
-
-
-/* TXTRecordSetValue()
- *
- * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
- * exists in the TXTRecordRef, then the current value will be replaced with
- * the new value.
- * Keys may exist in four states with respect to a given TXT record:
- * - Absent (key does not appear at all)
- * - Present with no value ("key" appears alone)
- * - Present with empty value ("key=" appears in TXT record)
- * - Present with non-empty value ("key=value" appears in TXT record)
- * For more details refer to "Data Syntax for DNS-SD TXT Records" in
- *
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key: A null-terminated string which only contains printable ASCII
- * values (0x20-0x7E), excluding '=' (0x3D). Keys should be
- * 8 characters or less (not counting the terminating null).
- *
- * valueSize: The size of the value.
- *
- * value: Any binary value. For values that represent
- * textual data, UTF-8 is STRONGLY recommended.
- * For values that represent textual data, valueSize
- * should NOT include the terminating null (if any)
- * at the end of the string.
- * If NULL, then "key" will be added with no value.
- * If non-NULL but valueSize is zero, then "key=" will be
- * added with empty value.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_Invalid if the "key" string contains
- * illegal characters.
- * Returns kDNSServiceErr_NoMemory if adding this key would
- * exceed the available storage.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordSetValue
- (
- TXTRecordRef *txtRecord,
- const char *key,
- uint8_t valueSize, /* may be zero */
- const void *value /* may be NULL */
- );
-
-
-/* TXTRecordRemoveValue()
- *
- * Removes a key from a TXTRecordRef. The "key" must be an
- * ASCII string which exists in the TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key: A key name which exists in the TXTRecordRef.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_NoSuchKey if the "key" does not
- * exist in the TXTRecordRef.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
- (
- TXTRecordRef *txtRecord,
- const char *key
- );
-
-
-/* TXTRecordGetLength()
- *
- * Allows you to determine the length of the raw bytes within a TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value: Returns the size of the raw bytes inside a TXTRecordRef
- * which you can pass directly to DNSServiceRegister() or
- * to DNSServiceUpdateRecord().
- * Returns 0 if the TXTRecordRef is empty.
- */
-
-uint16_t DNSSD_API TXTRecordGetLength
- (
- const TXTRecordRef *txtRecord
- );
-
-
-/* TXTRecordGetBytesPtr()
- *
- * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value: Returns a pointer to the raw bytes inside the TXTRecordRef
- * which you can pass directly to DNSServiceRegister() or
- * to DNSServiceUpdateRecord().
- */
-
-const void * DNSSD_API TXTRecordGetBytesPtr
- (
- const TXTRecordRef *txtRecord
- );
-
-
-/*********************************************************************************************
- *
- * TXT Record Parsing Functions
- *
- *********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record parsing is something like:
- *
- * Receive TXT record data in DNSServiceResolve() callback
- * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
- * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
- * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
- * ...
- * bcopy(val1ptr, myval1, len1);
- * bcopy(val2ptr, myval2, len2);
- * ...
- * return;
- *
- * If you wish to retain the values after return from the DNSServiceResolve()
- * callback, then you need to copy the data to your own storage using bcopy()
- * or similar, as shown in the example above.
- *
- * If for some reason you need to parse a TXT record you built yourself
- * using the TXT record construction functions above, then you can do
- * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
- * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
- *
- * Most applications only fetch keys they know about from a TXT record and
- * ignore the rest.
- * However, some debugging tools wish to fetch and display all keys.
- * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
- */
-
-/* TXTRecordContainsKey()
- *
- * Allows you to determine if a given TXT Record contains a specified key.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * key: A null-terminated ASCII string containing the key name.
- *
- * return value: Returns 1 if the TXT Record contains the specified key.
- * Otherwise, it returns 0.
- */
-
-int DNSSD_API TXTRecordContainsKey
- (
- uint16_t txtLen,
- const void *txtRecord,
- const char *key
- );
-
-
-/* TXTRecordGetValuePtr()
- *
- * Allows you to retrieve the value for a given key from a TXT Record.
- *
- * txtLen: The size of the received TXT Record
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * key: A null-terminated ASCII string containing the key name.
- *
- * valueLen: On output, will be set to the size of the "value" data.
- *
- * return value: Returns NULL if the key does not exist in this TXT record,
- * or exists with no value (to differentiate between
- * these two cases use TXTRecordContainsKey()).
- * Returns pointer to location within TXT Record bytes
- * if the key exists with empty or non-empty value.
- * For empty value, valueLen will be zero.
- * For non-empty value, valueLen will be length of value data.
- */
-
-const void * DNSSD_API TXTRecordGetValuePtr
- (
- uint16_t txtLen,
- const void *txtRecord,
- const char *key,
- uint8_t *valueLen
- );
-
-
-/* TXTRecordGetCount()
- *
- * Returns the number of keys stored in the TXT Record. The count
- * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * return value: Returns the total number of keys in the TXT Record.
- *
- */
-
-uint16_t DNSSD_API TXTRecordGetCount
- (
- uint16_t txtLen,
- const void *txtRecord
- );
-
-
-/* TXTRecordGetItemAtIndex()
- *
- * Allows you to retrieve a key name and value pointer, given an index into
- * a TXT Record. Legal index values range from zero to TXTRecordGetCount()-1.
- * It's also possible to iterate through keys in a TXT record by simply
- * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
- * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
- *
- * On return:
- * For keys with no value, *value is set to NULL and *valueLen is zero.
- * For keys with empty value, *value is non-NULL and *valueLen is zero.
- * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * index: An index into the TXT Record.
- *
- * keyBufLen: The size of the string buffer being supplied.
- *
- * key: A string buffer used to store the key name.
- * On return, the buffer contains a null-terminated C string
- * giving the key name. DNS-SD TXT keys are usually
- * 8 characters or less. To hold the maximum possible
- * key name, the buffer should be 256 bytes long.
- *
- * valueLen: On output, will be set to the size of the "value" data.
- *
- * value: On output, *value is set to point to location within TXT
- * Record bytes that holds the value data.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
- * Returns kDNSServiceErr_Invalid if index is greater than
- * TXTRecordGetCount()-1.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
- (
- uint16_t txtLen,
- const void *txtRecord,
- uint16_t index,
- uint16_t keyBufLen,
- char *key,
- uint8_t *valueLen,
- const void **value
- );
-
-#ifdef __APPLE_API_PRIVATE
-
-/*
- * Mac OS X specific functionality
- * 3rd party clients of this API should not depend on future support or availability of this routine
- */
-
-/* DNSServiceSetDefaultDomainForUser()
- *
- * Set the default domain for the caller's UID. Future browse and registration
- * calls by this user that do not specify an explicit domain will browse and
- * register in this wide-area domain in addition to .local. In addition, this
- * domain will be returned as a Browse domain via domain enumeration calls.
- *
- *
- * Parameters:
- *
- * flags: Pass kDNSServiceFlagsAdd to add a domain for a user. Call without
- * this flag set to clear a previously added domain.
- *
- * domain: The domain to be used for the caller's UID.
- *
- * return value: Returns kDNSServiceErr_NoError on succeses, otherwise returns
- * an error code indicating the error that occurred
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
- (
- DNSServiceFlags flags,
- const char *domain
- );
-
-#endif //__APPLE_API_PRIVATE
-
-// Some C compiler cleverness. We can make the compiler check certain things for us,
-// and report errors at compile-time if anything is wrong. The usual way to do this would
-// be to use a run-time "if" statement or the conventional run-time "assert" mechanism, but
-// then you don't find out what's wrong until you run the software. This way, if the assertion
-// condition is false, the array size is negative, and the complier complains immediately.
-
-struct DNS_SD_CompileTimeAssertionChecks
- {
- char assert0[(sizeof(union _TXTRecordRef_t) == 16) ? 1 : -1];
- };
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _DNS_SD_H */
diff --git a/src/mdns/mDNS.c b/src/mdns/mDNS.c
deleted file mode 100755
index 4eb87198..00000000
--- a/src/mdns/mDNS.c
+++ /dev/null
@@ -1,7360 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This code is completely 100% portable C. It does not depend on any external header files
- * from outside the mDNS project -- all the types it expects to find are defined right here.
- *
- * The previous point is very important: This file does not depend on any external
- * header files. It should complile on *any* platform that has a C compiler, without
- * making *any* assumptions about availability of so-called "standard" C functions,
- * routines, or types (which may or may not be present on any given platform).
-
- * Formatting notes:
- * This code follows the "Whitesmiths style" C indentation rules. Plenty of discussion
- * on C indentation can be found on the web, such as ,
- * but for the sake of brevity here I will say just this: Curly braces are not syntactially
- * part of an "if" statement; they are the beginning and ending markers of a compound statement;
- * therefore common sense dictates that if they are part of a compound statement then they
- * should be indented to the same level as everything else in that compound statement.
- * Indenting curly braces at the same level as the "if" implies that curly braces are
- * part of the "if", which is false. (This is as misleading as people who write "char* x,y;"
- * thinking that variables x and y are both of type "char*" -- and anyone who doesn't
- * understand why variable y is not of type "char*" just proves the point that poor code
- * layout leads people to unfortunate misunderstandings about how the C language really works.)
-
- Change History (most recent first):
-
-$Log: mDNS.c,v $
-Revision 1.537.2.1 2006/08/29 06:24:22 cheshire
-Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
-
-Revision 1.537 2006/03/19 02:00:07 cheshire
- Improve logic for delaying packets after repeated interface transitions
-
-Revision 1.536 2006/03/08 23:29:53 cheshire
- Improve "Service Renamed" log message
-
-Revision 1.535 2006/03/02 20:41:17 cheshire
- After record update, old record sometimes remains in cache
-Minor code tidying and comments to reduce the risk of similar programming errors in future
-
-Revision 1.534 2006/03/02 03:25:46 cheshire
- After record update, old record sometimes remains in cache
-Code to harmonize RRSet TTLs was inadvertently rescuing expiring records
-
-Revision 1.533 2006/02/26 00:54:41 cheshire
-Fixes to avoid code generation warning/error on FreeBSD 7
-
-Revision 1.532 2005/12/02 20:24:36 cheshire
- Adjust cutoff time for KA list by one second
-
-Revision 1.531 2005/12/02 19:05:42 cheshire
-Tidy up constants
-
-Revision 1.530 2005/11/07 01:49:48 cheshire
-For consistency, use NonZeroTime() function instead of ?: expression
-
-Revision 1.529 2005/10/25 23:42:24 cheshire
- Error in ResolveSimultaneousProbe() when type or class don't match
-Changed switch statement to an "if"
-
-Revision 1.528 2005/10/25 23:34:22 cheshire
- RequireGoodbye state not set/respected sometimes when machine going to sleep
-
-Revision 1.527 2005/10/25 22:43:59 cheshire
-Add clarifying comments
-
-Revision 1.526 2005/10/20 00:10:33 cheshire
- Add check to avoid crashing NAT gateways that have buggy DNS relay code
-
-Revision 1.525 2005/09/24 00:47:17 cheshire
-Fix comment typos
-
-Revision 1.524 2005/09/16 21:06:49 cheshire
-Use mDNS_TimeNow_NoLock macro, instead of writing "mDNSPlatformRawTime() + m->timenow_adjust" all over the place
-
-Revision 1.523 2005/03/21 00:33:51 shersche
- Fix build warnings on Win32 platform
-
-Revision 1.522 2005/03/04 21:48:12 cheshire
- Fractional time rounded down instead of up on platforms with coarse clock granularity
-
-Revision 1.521 2005/02/25 04:21:00 cheshire
- mDNS -F returns the same domain multiple times with different casing
-
-Revision 1.520 2005/02/16 01:14:11 cheshire
-Convert RR Cache LogOperation() calls to debugf()
-
-Revision 1.519 2005/02/15 01:57:20 cheshire
-When setting "q->LastQTxTime = m->timenow", must also clear q->RecentAnswerPkts to zero
-
-Revision 1.518 2005/02/10 22:35:17 cheshire
- Update name
-
-Revision 1.517 2005/02/03 00:21:21 cheshire
-Update comments about BIND named and zero-length TXT records
-
-Revision 1.516 2005/01/28 06:06:32 cheshire
-Update comment
-
-Revision 1.515 2005/01/27 00:21:49 cheshire
- Remove mDNSResponder sleep/wake syslog message
-
-Revision 1.514 2005/01/21 01:33:45 cheshire
- Shutdown time regression: mDNSResponder not responding to SIGTERM
-
-Revision 1.513 2005/01/21 00:07:54 cheshire
- Infinite loop when the same service is registered twice, and then suffers a name conflict
-
-Revision 1.512 2005/01/20 00:37:45 cheshire
- mDNSResponder crashed in mDNSCoreReceiveResponse
-Take care not to recycle records while they are on the CacheFlushRecords list
-
-Revision 1.511 2005/01/19 22:48:53 cheshire
- Handle services with subtypes correctly when doing mDNS_RenameAndReregisterService()
-
-Revision 1.510 2005/01/19 03:12:45 cheshire
-Move LocalRecordReady() macro from mDNS.c to DNSCommon.h
-
-Revision 1.509 2005/01/19 03:08:49 cheshire
- CPU Spin in mDNSResponder
-Log messages to help catch and report CPU spins
-
-Revision 1.508 2005/01/18 18:56:32 cheshire
- QU responses not promoted to multicast responses when appropriate
-
-Revision 1.507 2005/01/18 01:12:07 cheshire
- Logging into VPN causes mDNSResponder to reissue multicast probes
-
-Revision 1.506 2005/01/17 23:28:53 cheshire
-Fix compile error
-
-Revision 1.505 2005/01/11 02:02:56 shersche
-Move variable declaration to the beginning of statement block
-
-Revision 1.504 2004/12/20 20:24:35 cheshire
- Network efficiency: Don't keep polling if we have at least one unique-type answer
-
-Revision 1.503 2004/12/20 18:41:47 cheshire
- Low memory support: Provide answers even when we don't have cache space
-
-Revision 1.502 2004/12/20 18:04:08 cheshire
- For now, don't put standard wide-area unicast responses in our main cache
-
-Revision 1.501 2004/12/19 23:50:18 cheshire
- kDNSServiceInterfaceIndexLocalOnly should return all local records
-Don't show "No active interface to send" messages for kDNSServiceInterfaceIndexLocalOnly services
-
-Revision 1.500 2004/12/18 03:13:46 cheshire
- kDNSServiceInterfaceIndexLocalOnly should return all local records
-
-Revision 1.499 2004/12/17 23:37:45 cheshire
- Guard against repeating wireless dissociation/re-association
-(and other repetitive configuration changes)
-
-Revision 1.498 2004/12/17 05:25:46 cheshire
- Shorten DNS-SD queries to avoid NAT bugs
-
-Revision 1.497 2004/12/17 03:20:58 cheshire
- Don't send unicast replies we know will be ignored
-
-Revision 1.496 2004/12/16 22:18:26 cheshire
-Make AddressIsLocalSubnet() a little more selective -- ignore point-to-point interfaces
-
-Revision 1.495 2004/12/16 21:27:37 ksekar
-Fixed build failures when compiled with verbose debugging messages
-
-Revision 1.494 2004/12/16 20:46:56 cheshire
-Fix compiler warnings
-
-Revision 1.493 2004/12/16 20:13:00 cheshire
- Cache memory management improvements
-
-Revision 1.492 2004/12/16 08:03:24 shersche
-Fix compilation error when UNICAST_DISABLED is set
-
-Revision 1.491 2004/12/11 01:52:11 cheshire
- Support kDNSServiceFlagsAllowRemoteQuery for registering services too
-
-Revision 1.490 2004/12/10 20:06:25 cheshire
- Reduce egregious stack space usage
-Reduced SendDelayedUnicastResponse() stack frame from 9K to 112 bytes
-
-Revision 1.489 2004/12/10 20:03:43 cheshire
- Reduce egregious stack space usage
-Reduced mDNSCoreReceiveQuery() stack frame from 9K to 144 bytes
-
-Revision 1.488 2004/12/10 19:50:41 cheshire
- Reduce egregious stack space usage
-Reduced SendResponses() stack frame from 9K to 176 bytes
-
-Revision 1.487 2004/12/10 19:39:13 cheshire
- Reduce egregious stack space usage
-Reduced SendQueries() stack frame from 18K to 112 bytes
-
-Revision 1.486 2004/12/10 14:16:17 cheshire
- Relax update rate limiting
-We now allow an average rate of ten updates per minute.
-Updates in excess of that are rate limited, but more gently than before.
-
-Revision 1.485 2004/12/10 02:09:24 cheshire
- Modify default TTLs
-
-Revision 1.484 2004/12/09 03:15:40 ksekar
- use _legacy instead of _default to find "empty string" browse domains
-
-Revision 1.483 2004/12/07 23:00:14 ksekar
- DNSServiceRegisterRecord() can crash on deregistration:
-Call RecordProbeFailure even if there is no record callback
-
-Revision 1.482 2004/12/07 22:49:06 cheshire
- BIND doesn't allow zero-length TXT records
-
-Revision 1.481 2004/12/07 21:26:04 ksekar
- DNSServiceRegisterRecord() can crash on deregistration
-
-Revision 1.480 2004/12/07 20:42:33 cheshire
-Add explicit context parameter to mDNS_RemoveRecordFromService()
-
-Revision 1.479 2004/12/07 17:50:49 ksekar
- BIND doesn't allow zero-length TXT records
-
-Revision 1.478 2004/12/06 21:15:22 ksekar
- mDNSResponder crashed in CheckServiceRegistrations
-
-Revision 1.477 2004/12/04 02:12:45 cheshire
- mDNSResponder puts LargeCacheRecord on the stack
-
-Revision 1.476 2004/11/29 23:34:31 cheshire
-On platforms with coarse time resolutions, ORing time values with one to ensure they are non-zero
-is crude, and effectively halves the time resolution. The more selective NonZeroTime() function
-only nudges the time value to 1 if the interval calculation happens to result in the value zero.
-
-Revision 1.475 2004/11/29 23:13:31 cheshire
- All unique records in a set should have the cache flush bit set
-Additional check: Make sure we don't unnecessarily send packets containing only additionals.
-(This could occur with multi-packet KA lists, if the answer and additionals were marked
-by the query packet, and then the answer were later suppressed in a subsequent KA packet.)
-
-Revision 1.474 2004/11/29 17:18:12 cheshire
-Remove "Unknown DNS packet type" message for update responses
-
-Revision 1.473 2004/11/25 01:57:52 cheshire
- All unique records in a set should have the cache flush bit set
-
-Revision 1.472 2004/11/25 01:28:09 cheshire
- Need to implement random delay for 'QU' unicast replies (and set cache flush bit too)
-
-Revision 1.471 2004/11/25 01:10:13 cheshire
-Move code to add additional records to a subroutine called AddAdditionalsToResponseList()
-
-Revision 1.470 2004/11/24 21:54:44 cheshire
- mDNSCore not receiving unicast responses properly
-
-Revision 1.469 2004/11/24 04:50:39 cheshire
-Minor tidying
-
-Revision 1.468 2004/11/24 01:47:07 cheshire
- DNSServiceRegisterRecord should call CallBack on success.
-
-Revision 1.467 2004/11/24 01:41:28 cheshire
-Rename CompleteProbing() to AcknowledgeRecord()
-
-Revision 1.466 2004/11/23 21:08:07 ksekar
-Don't use ID to demux multicast/unicast now that unicast uses random IDs
-
-Revision 1.465 2004/11/15 20:09:21 ksekar
- Wide Area support for Add/Remove record
-
-Revision 1.464 2004/11/03 01:44:36 cheshire
-Update debugging messages
-
-Revision 1.463 2004/10/29 02:38:48 cheshire
-Fix Windows compile errors
-
-Revision 1.462 2004/10/28 19:21:07 cheshire
-Guard against registering interface with zero InterfaceID
-
-Revision 1.461 2004/10/28 19:02:16 cheshire
-Remove \n from LogMsg() call
-
-Revision 1.460 2004/10/28 03:24:40 cheshire
-Rename m->CanReceiveUnicastOn as m->CanReceiveUnicastOn5353
-
-Revision 1.459 2004/10/26 22:34:37 cheshire
- Need to protect mDNSResponder from unbounded packet flooding
-
-Revision 1.458 2004/10/26 20:45:28 cheshire
-Show mask in "invalid mask" message
-
-Revision 1.457 2004/10/26 06:28:36 cheshire
-Now that we don't check IP TTL any more, remove associated log message
-
-Revision 1.456 2004/10/26 06:21:42 cheshire
-Adjust mask validity check to allow an all-ones mask (for IPv6 ::1 loopback address)
-
-Revision 1.455 2004/10/26 06:11:40 cheshire
-Add improved logging to aid in diagnosis of mDNSResponder crashed
-
-Revision 1.454 2004/10/23 01:16:00 cheshire
- uDNS operations not always reliable on multi-homed hosts
-
-Revision 1.453 2004/10/22 20:52:06 ksekar
- Create NAT port mappings for Long Lived Queries
-
-Revision 1.452 2004/10/20 01:50:40 cheshire
- Cannot resolve non-local registrations using the mach API
-Implemented ForceMCast mode for AuthRecords as well as for Questions
-
-Revision 1.451 2004/10/19 21:33:15 cheshire
- Cannot resolve non-local registrations using the mach API
-Added flag 'kDNSServiceFlagsForceMulticast'. Passing through an interface id for a unicast name
-doesn't force multicast unless you set this flag to indicate explicitly that this is what you want
-
-Revision 1.450 2004/10/19 17:42:59 ksekar
-Fixed compiler warnings for non-debug builds.
-
-Revision 1.449 2004/10/18 22:57:07 cheshire
- Seen in console: Ignored apparent spoof mDNS Response with TTL 1
-
-Revision 1.448 2004/10/16 00:16:59 cheshire
- Replace IP TTL 255 check with local subnet source address check
-
-Revision 1.447 2004/10/15 00:51:21 cheshire
- Seen in console: Ignored apparent spoof mDNS Response with TTL 1
-
-Revision 1.446 2004/10/14 00:43:34 cheshire
- Services continue to announce SRV and HINFO
-
-Revision 1.445 2004/10/12 21:07:09 cheshire
-Set up m->p in mDNS_Init() before calling mDNSPlatformTimeInit()
-
-Revision 1.444 2004/10/11 17:54:16 ksekar
-Changed hashtable pointer output from debugf to verbosedebugf.
-
-Revision 1.443 2004/10/10 07:05:45 cheshire
-For consistency, use symbol "localdomain" instead of literal string
-
-Revision 1.442 2004/10/08 20:25:10 cheshire
-Change of plan for -- we're not going to do that at this time
-
-Revision 1.441 2004/10/08 03:25:01 ksekar
- domain enumeration should use LLQs
-
-Revision 1.440 2004/10/06 01:44:19 cheshire
- Resolving too quickly sometimes returns stale TXT record
-
-Revision 1.439 2004/10/03 23:14:11 cheshire
-Add "mDNSEthAddr" type and "zeroEthAddr" constant
-
-Revision 1.438 2004/09/29 23:07:04 cheshire
-Patch from Pavel Repin to fix compile error on Windows
-
-Revision 1.437 2004/09/28 02:23:50 cheshire
- Deliver near-pending "remove" events before new "add" events
-Don't need to search the entire cache for nearly-expired records -- just the appropriate hash slot
-For records with the cache flush bit set, defer the decision until the end of the packet
-
-Revision 1.436 2004/09/28 01:27:04 cheshire
-Update incorrect log message
-
-Revision 1.435 2004/09/25 02:41:39 cheshire
- Deliver near-pending "remove" events before new "add" events
-
-Revision 1.434 2004/09/25 02:32:06 cheshire
-Update comments
-
-Revision 1.433 2004/09/25 02:24:27 cheshire
-Removed unused rr->UseCount
-
-Revision 1.432 2004/09/24 21:35:17 cheshire
- Browses are no longer piggybacking on other browses
-TargetPort and TargetQID are allowed to be undefined if no question->Target is set
-
-Revision 1.431 2004/09/24 21:33:12 cheshire
-Adjust comment
-
-Revision 1.430 2004/09/24 02:15:49 cheshire
- Late conflicts don't send goodbye packets on other interfaces
-
-Revision 1.429 2004/09/24 00:20:21 cheshire
- Any rrtype is a conflict for unique records
-
-Revision 1.428 2004/09/24 00:12:25 cheshire
-Get rid of unused RRUniqueOrKnownUnique(RR)
-
-Revision 1.427 2004/09/23 20:44:11 cheshire
- Reduce timeout before expiring records on failure
-
-Revision 1.426 2004/09/23 20:21:07 cheshire
- Refine "immediate answer burst; restarting exponential backoff sequence" logic
-Associate a unique sequence number with each received packet, and only increment the count of recent answer
-packets if the packet sequence number for this answer record is not one we've already seen and counted.
-
-Revision 1.425 2004/09/23 20:14:38 cheshire
-Rename "question->RecentAnswers" to "question->RecentAnswerPkts"
-
-Revision 1.424 2004/09/23 00:58:36 cheshire
- Rate limiting interferes with updating TXT records
-
-Revision 1.423 2004/09/23 00:50:53 cheshire
- Don't send a (DE) if a service is unregistered after wake from sleep
-
-Revision 1.422 2004/09/22 02:34:46 cheshire
-Move definitions of default TTL times from mDNS.c to mDNSEmbeddedAPI.h
-
-Revision 1.421 2004/09/21 23:29:49 cheshire
- DNSServiceResolve should delay sending packets
-
-Revision 1.420 2004/09/21 23:01:42 cheshire
-Update debugf messages
-
-Revision 1.419 2004/09/21 19:51:14 cheshire
-Move "Starting time value" message from mDNS.c to mDNSMacOSX/daemon.c
-
-Revision 1.418 2004/09/21 18:40:17 cheshire
- Adjust default record TTLs
-
-Revision 1.417 2004/09/21 17:32:16 cheshire
- Rate limiting imposed too soon
-
-Revision 1.416 2004/09/20 23:52:01 cheshire
-CFSocket{Puma}.c renamed to mDNSMacOSX{Puma}.c
-
-Revision 1.415 2004/09/18 01:14:09 cheshire
- Resolve() should not bother doing AAAA queries on machines with no IPv6 interfaces
-
-Revision 1.414 2004/09/18 01:06:48 cheshire
-Add comments
-
-Revision 1.413 2004/09/17 01:08:48 cheshire
-Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
- The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
- declared in that file are ONLY appropriate to single-address-space embedded applications.
- For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
-
-Revision 1.412 2004/09/17 00:46:33 cheshire
-mDNS_TimeNow should take const mDNS parameter
-
-Revision 1.411 2004/09/17 00:31:51 cheshire
-For consistency with ipv6, renamed rdata field 'ip' to 'ipv4'
-
-Revision 1.410 2004/09/17 00:19:10 cheshire
-For consistency with AllDNSLinkGroupv6, rename AllDNSLinkGroup to AllDNSLinkGroupv4
-
-Revision 1.409 2004/09/16 21:59:15 cheshire
-For consistency with zerov6Addr, rename zeroIPAddr to zerov4Addr
-
-Revision 1.408 2004/09/16 21:36:36 cheshire
- Fix unsafe use of mDNSPlatformTimeNow()
-Changes to add necessary locking calls around unicast DNS operations
-
-Revision 1.407 2004/09/16 02:29:39 cheshire
-Moved mDNS_Lock/mDNS_Unlock to DNSCommon.c; Added necessary locking around
-uDNS_ReceiveMsg, uDNS_StartQuery, uDNS_UpdateRecord, uDNS_RegisterService
-
-Revision 1.406 2004/09/16 01:58:14 cheshire
-Fix compiler warnings
-
-Revision 1.405 2004/09/16 00:24:48 cheshire
- Fix unsafe use of mDNSPlatformTimeNow()
-
-Revision 1.404 2004/09/15 21:44:11 cheshire
- Randomize initial timenow_adjust value in mDNS_Init
-Show time value in log to help diagnose errors
-
-Revision 1.403 2004/09/15 00:46:32 ksekar
-Changed debugf to verbosedebugf in CheckCacheExpiration
-
-Revision 1.402 2004/09/14 23:59:55 cheshire
- Randomize initial timenow_adjust value in mDNS_Init
-
-Revision 1.401 2004/09/14 23:27:46 cheshire
-Fix compile errors
-
-Revision 1.400 2004/09/02 03:48:47 cheshire
- Disable targeted unicast query support by default
-1. New flag kDNSServiceFlagsAllowRemoteQuery to indicate we want to allow remote queries for this record
-2. New field AllowRemoteQuery in AuthRecord structure
-3. uds_daemon.c sets AllowRemoteQuery if kDNSServiceFlagsAllowRemoteQuery is set
-4. mDNS.c only answers remote queries if AllowRemoteQuery is set
-
-Revision 1.399 2004/09/02 01:39:40 cheshire
-For better readability, follow consistent convention that QR bit comes first, followed by OP bits
-
-Revision 1.398 2004/09/01 03:59:29 ksekar
-: Conditionally compile out uDNS code on Windows
-
-Revision 1.397 2004/08/25 22:04:25 rpantos
-Fix the standard Windows compile error.
-
-Revision 1.396 2004/08/25 00:37:27 ksekar
-: Cleanup DynDNS hostname registration code
-
-Revision 1.395 2004/08/18 17:21:18 ksekar
-Removed double-call of uDNS_AdvertiseInterface from mDNS_SetFQDNs()
-
-Revision 1.394 2004/08/14 03:22:41 cheshire
- Dynamic DNS UI <-> mDNSResponder glue
-Add GetUserSpecifiedDDNSName() routine
-Convert ServiceRegDomain to domainname instead of C string
-Replace mDNS_GenerateFQDN/mDNS_GenerateGlobalFQDN with mDNS_SetFQDNs
-
-Revision 1.393 2004/08/13 23:42:52 cheshire
-Removed unused "zeroDomainNamePtr"
-
-Revision 1.392 2004/08/13 23:37:02 cheshire
-Now that we do both uDNS and mDNS, global replace "uDNS_info.hostname" with
-"uDNS_info.UnicastHostname" for clarity
-
-Revision 1.391 2004/08/13 23:25:00 cheshire
-Now that we do both uDNS and mDNS, global replace "m->hostname" with
-"m->MulticastHostname" for clarity
-
-Revision 1.390 2004/08/11 02:17:01 cheshire
- Registering service with port number 0 should create a "No Such Service" record
-
-Revision 1.389 2004/08/10 23:19:14 ksekar
-: DNS Extension daemon for Wide Area Service Discovery
-Moved routines/constants to allow extern access for garbage collection daemon
-
-Revision 1.388 2004/07/30 17:40:06 ksekar
-: TXT Record updates not available for wide-area services
-
-Revision 1.387 2004/07/26 22:49:30 ksekar
-: Feature #9516: Need support for NATPMP in client
-
-Revision 1.386 2004/07/13 21:24:24 rpantos
-Fix for .
-
-Revision 1.385 2004/06/18 19:09:59 cheshire
- Current method of doing subtypes causes name collisions
-
-Revision 1.384 2004/06/15 04:31:23 cheshire
-Make sure to clear m->CurrentRecord at the end of AnswerNewLocalOnlyQuestion()
-
-Revision 1.383 2004/06/11 00:04:59 cheshire
- TTL must be greater than zero for DNSServiceRegisterRecord
-
-Revision 1.382 2004/06/08 04:59:40 cheshire
-Tidy up wording -- log messages are already prefixed with "mDNSResponder", so don't need to repeat it
-
-Revision 1.381 2004/06/05 00:57:30 cheshire
-Remove incorrect LogMsg()
-
-Revision 1.380 2004/06/05 00:04:26 cheshire
-: wide-area domains should be returned in reg. domain enumeration
-
-Revision 1.379 2004/05/28 23:42:36 ksekar
-: Feature: DNS server->client notification on record changes (#7805)
-
-Revision 1.378 2004/05/25 17:25:25 cheshire
-Remove extraneous blank lines and white space
-
-Revision 1.377 2004/05/18 23:51:25 cheshire
-Tidy up all checkin comments to use consistent "" format for bug numbers
-
-Revision 1.376 2004/05/05 18:30:44 ksekar
-Restored surpressed Cache Tail debug messages.
-
-Revision 1.375 2004/04/26 21:36:25 cheshire
-Only send IPv4 (or v6) multicast when IPv4 (or v6) multicast send/receive
-is indicated as being available on that interface
-
-Revision 1.374 2004/04/21 02:53:26 cheshire
-Typo in debugf statement
-
-Revision 1.373 2004/04/21 02:49:11 cheshire
-To reduce future confusion, renamed 'TxAndRx' to 'McastTxRx'
-
-Revision 1.372 2004/04/21 02:38:51 cheshire
-Add debugging checks
-
-Revision 1.371 2004/04/14 23:09:28 ksekar
-Support for TSIG signed dynamic updates.
-
-Revision 1.370 2004/04/09 17:40:26 cheshire
-Remove unnecessary "Multicast" field -- it duplicates the semantics of the existing McastTxRx field
-
-Revision 1.369 2004/04/09 16:34:00 cheshire
-Debugging code for later; currently unused
-
-Revision 1.368 2004/04/02 19:19:48 cheshire
-Add code to do optional logging of multi-packet KA list time intervals
-
-Revision 1.367 2004/03/20 03:16:10 cheshire
-Minor refinement to "Excessive update rate" message
-
-Revision 1.366 2004/03/20 03:12:57 cheshire
-: UpdateCredits not granted promptly enough
-
-Revision 1.365 2004/03/19 23:51:22 cheshire
-Change to use symbolic constant kUpdateCreditRefreshInterval instead of (mDNSPlatformOneSecond * 60)
-
-Revision 1.364 2004/03/13 01:57:33 ksekar
-: DynDNS: Dynamic update of service records
-
-Revision 1.363 2004/03/12 21:00:51 cheshire
-Also show port numbers when logging "apparent spoof mDNS Response" messages
-
-Revision 1.362 2004/03/12 08:58:18 cheshire
-Guard against empty TXT records
-
-Revision 1.361 2004/03/09 03:00:46 cheshire
- Don't take lock until after mDNS_Update() has validated that the data is good.
-
-Revision 1.360 2004/03/08 02:52:41 cheshire
-Minor debugging fix: Make sure 'target' is initialized so we don't crash writing debugging log messages
-
-Revision 1.359 2004/03/02 03:21:56 cheshire
- Properly support "_services._dns-sd._udp" meta-queries
-
-Revision 1.358 2004/02/20 08:18:34 cheshire
-: mDNSResponder sometimes announces AAAA records unnecessarily
-
-Revision 1.357 2004/02/18 01:47:41 cheshire
-: Insufficient delay waiting for multi-packet KA lists causes AirPort traffic storms
-
-Revision 1.356 2004/02/06 23:04:19 ksekar
-Basic Dynamic Update support via mDNS_Register (dissabled via
-UNICAST_REGISTRATION #define)
-
-Revision 1.355 2004/02/05 09:32:33 cheshire
-Fix from Bob Bradley: When using the "%.*s" string form,
-guard against truncating in the middle of a multi-byte UTF-8 character.
-
-Revision 1.354 2004/02/05 09:30:22 cheshire
-Update comments
-
-Revision 1.353 2004/01/28 03:41:00 cheshire
-: Need ability to do targeted queries as well as multicast queries
-
-Revision 1.352 2004/01/28 02:30:07 ksekar
-Added default Search Domains to unicast browsing, controlled via
-Networking sharing prefs pane. Stopped sending unicast messages on
-every interface. Fixed unicast resolving via mach-port API.
-
-Revision 1.351 2004/01/27 20:15:22 cheshire
-: Time to prune obsolete code for listening on port 53
-
-Revision 1.350 2004/01/24 23:38:16 cheshire
-Use mDNSVal16() instead of shifting and ORing operations
-
-Revision 1.349 2004/01/23 23:23:14 ksekar
-Added TCP support for truncated unicast messages.
-
-Revision 1.348 2004/01/22 03:54:11 cheshire
-Create special meta-interface 'mDNSInterface_ForceMCast' (-2),
-which means "do this query via multicast, even if it's apparently a unicast domain"
-
-Revision 1.347 2004/01/22 03:50:49 cheshire
-If the client has specified an explicit InterfaceID, then do query by multicast, not unicast
-
-Revision 1.346 2004/01/22 03:48:41 cheshire
-Make sure uDNS client doesn't accidentally use query ID zero
-
-Revision 1.345 2004/01/22 03:43:08 cheshire
-Export constants like mDNSInterface_LocalOnly so that the client layers can use them
-
-Revision 1.344 2004/01/21 21:53:18 cheshire
-: Don't try to receive unicast responses if we're not the first to bind to the UDP port
-
-Revision 1.343 2003/12/23 00:07:47 cheshire
-Make port number in debug message be five-character field, left justified
-
-Revision 1.342 2003/12/20 01:34:28 cheshire
-: Error putting additional records into packets
-Another fix from Rampi: responseptr needs to be updated inside the "for" loop,
-after every record, not once at the end.
-
-Revision 1.341 2003/12/18 22:56:12 cheshire
-: Reduce syslog messages about ignored spoof packets
-
-Revision 1.340 2003/12/16 02:31:37 cheshire
-Minor update to comments
-
-Revision 1.339 2003/12/13 05:50:33 bradley
-Fixed crash with mDNS_Lock/Unlock being called for the initial GrowCache before the platform
-layer has been initialized. Protect mDNS_reentrancy when completing the core initialization to
-fix a race condition during async initialization. Fixed buffer overrun for 1 byte mDNS_snprintf.
-
-Revision 1.338 2003/12/13 03:05:27 ksekar
-: DynDNS: Unicast query of service records
-
-Revision 1.337 2003/12/01 21:46:05 cheshire
-mDNS_StartQuery returns mStatus_BadInterfaceErr if the specified interface does not exist
-
-Revision 1.336 2003/12/01 21:26:19 cheshire
-Guard against zero-length sbuffer in mDNS_vsnprintf()
-
-Revision 1.335 2003/12/01 20:27:48 cheshire
-Display IPv6 addresses correctly (e.g. in log messages) on little-endian processors
-
-Revision 1.334 2003/11/20 22:59:53 cheshire
-Changed runtime checks in mDNS.c to be compile-time checks in mDNSEmbeddedAPI.h
-Thanks to Bob Bradley for suggesting the ingenious compiler trick to make this work.
-
-Revision 1.333 2003/11/20 20:49:53 cheshire
-Another fix from HP: Use packedstruct macro to ensure proper packing for on-the-wire packet structures
-
-Revision 1.332 2003/11/20 05:47:37 cheshire
-: Don't exclude known answers whose expiry time is before the next query
-Now that we only include answers in the known answer list if they are less than
-halfway to expiry, the check to also see if we have another query scheduled
-before the record expires is no longer necessary (and in fact, not correct).
-
-Revision 1.331 2003/11/19 22:31:48 cheshire
-When automatically adding A records to SRVs, add them as additionals, not answers
-
-Revision 1.330 2003/11/19 22:28:50 cheshire
-Increment/Decrement mDNS_reentrancy around calls to m->MainCallback()
-to allow client to make mDNS calls (specifically the call to mDNS_GrowCache())
-
-Revision 1.329 2003/11/19 22:19:24 cheshire
-Show log message when ignoring packets with bad TTL.
-This is to help diagnose problems on Linux versions that may not report the TTL reliably.
-
-Revision 1.328 2003/11/19 22:06:38 cheshire
-Show log messages when a service or hostname is renamed
-
-Revision 1.327 2003/11/19 22:03:44 cheshire
-Move common "m->NextScheduledResponse = m->timenow" to before "if" statement
-
-Revision 1.326 2003/11/17 22:27:02 cheshire
-Another fix from ramaprasad.kr@hp.com: Improve reply delay computation
-on platforms that have native clock rates below fifty ticks per second.
-
-Revision 1.325 2003/11/17 20:41:44 cheshire
-Fix some missing mDNS_Lock(m)/mDNS_Unlock(m) calls.
-
-Revision 1.324 2003/11/17 20:36:32 cheshire
-Function rename: Remove "mDNS_" prefix from AdvertiseInterface() and
-DeadvertiseInterface() -- they're internal private routines, not API routines.
-
-Revision 1.323 2003/11/14 20:59:08 cheshire
-Clients can't use AssignDomainName macro because mDNSPlatformMemCopy is defined in mDNSPlatformFunctions.h.
-Best solution is just to combine mDNSEmbeddedAPI.h and mDNSPlatformFunctions.h into a single file.
-
-Revision 1.322 2003/11/14 19:47:52 cheshire
-Define symbol MAX_ESCAPED_DOMAIN_NAME to indicate recommended buffer size for ConvertDomainNameToCString
-
-Revision 1.321 2003/11/14 19:18:34 cheshire
-Move AssignDomainName macro to mDNSEmbeddedAPI.h to that client layers can use it too
-
-Revision 1.320 2003/11/13 06:45:04 cheshire
-Fix compiler warning on certain compilers
-
-Revision 1.319 2003/11/13 00:47:40 cheshire
- We should delay AAAA record query if A record already in cache.
-
-Revision 1.318 2003/11/13 00:33:26 cheshire
-Change macro "RRIsAddressType" to "RRTypeIsAddressType"
-
-Revision 1.317 2003/11/13 00:10:49 cheshire
-: Verify that rr data is different before updating.
-
-Revision 1.316 2003/11/08 23:37:54 cheshire
-Give explicit zero initializers to blank static structure, required by certain compilers.
-(Thanks to ramaprasad.kr@hp.com for reporting this.)
-
-Revision 1.315 2003/11/07 03:32:56 cheshire
- mDNSResponder delivers answers in inconsistent order
-This is the real fix. Checkin 1.312 was overly simplistic; Calling GetFreeCacheRR() can sometimes
-purge records from the cache, causing tail pointer *rp to be stale on return. The correct fix is
-to maintain a system-wide tail pointer for each cache slot, and then if neccesary GetFreeCacheRR()
-can update this pointer, so that mDNSCoreReceiveResponse() appends records in the right place.
-
-Revision 1.314 2003/11/07 03:19:49 cheshire
-Minor variable renaming for clarity
-
-Revision 1.313 2003/11/07 03:14:49 cheshire
-Previous checkin proved to be overly simplistic; reversing
-
-Revision 1.312 2003/11/03 23:45:15 cheshire
- mDNSResponder delivers answers in inconsistent order
-Build cache lists in FIFO order, not customary C LIFO order
-(Append new elements to tail of cache list, instead of prepending at the head.)
-
-Revision 1.311 2003/10/09 18:00:11 cheshire
-Another compiler warning fix.
-
-Revision 1.310 2003/10/07 20:27:05 cheshire
-Patch from Bob Bradley, to fix warning and compile error on Windows
-
-Revision 1.309 2003/09/26 01:06:36 cheshire
- Set kDNSClass_UniqueRRSet bit for updates too
-Made new routine HaveSentEntireRRSet() to check if flag should be set
-
-Revision 1.308 2003/09/23 01:05:01 cheshire
-Minor changes to comments and debugf() message
-
-Revision 1.307 2003/09/09 20:13:30 cheshire
- Don't send a Goodbye record if we never announced it
-Ammend checkin 1.304: Off-by-one error: By this place in the function we've already decremented
-rr->AnnounceCount, so the check needs to be for InitialAnnounceCount-1, not InitialAnnounceCount
-
-Revision 1.306 2003/09/09 03:00:03 cheshire
- Services take a long time to disappear when switching networks.
-Added two constants: kDefaultReconfirmTimeForNoAnswer and kDefaultReconfirmTimeForCableDisconnect
-
-Revision 1.305 2003/09/09 02:49:31 cheshire
- Initial probes and queries not grouped on wake-from-sleep
-
-Revision 1.304 2003/09/09 02:41:19 cheshire
- Don't send a Goodbye record if we never announced it
-
-Revision 1.303 2003/09/05 19:55:02 cheshire
- Include address records when announcing SRV records
-
-Revision 1.302 2003/09/05 00:01:36 cheshire
- Don't accelerate queries that have large KA lists
-
-Revision 1.301 2003/09/04 22:51:13 cheshire
- Group probes and goodbyes better
-
-Revision 1.300 2003/09/03 02:40:37 cheshire
- mDNSResponder complains about '_'s
-Underscores are not supposed to be legal in standard DNS names, but IANA appears
-to have allowed them in previous service name registrations, so we should too.
-
-Revision 1.299 2003/09/03 02:33:09 cheshire
- CacheRecordRmv ERROR
-Don't update m->NewQuestions until *after* CheckCacheExpiration();
-
-Revision 1.298 2003/09/03 01:47:01 cheshire
- Services always in a state of flux
-Change mDNS_Reconfirm_internal() minimum timeout from 5 seconds to 45-60 seconds
-
-Revision 1.297 2003/08/29 19:44:15 cheshire
- Traffic reduction: Eliminate synchronized QUs when a new service appears
-1. Use m->RandomQueryDelay to impose a random delay in the range 0-500ms on queries
- that already have at least one unique answer in the cache
-2. For these queries, go straight to QM, skipping QU
-
-Revision 1.296 2003/08/29 19:08:21 cheshire
- Traffic reduction: Eliminate huge KA lists after wake from sleep
-Known answers are no longer eligible to go in the KA list if they are more than half-way to their expiry time.
-
-Revision 1.295 2003/08/28 01:10:59 cheshire
- Add syslog message to report when query is reset because of immediate answer burst
-
-Revision 1.294 2003/08/27 02:30:22 cheshire
- Traffic Reduction: Inefficiencies in DNSServiceResolverResolve()
-One more change: "query->GotTXT" is now a straightforward bi-state boolean again
-
-Revision 1.293 2003/08/27 02:25:31 cheshire
- Traffic Reduction: Inefficiencies in DNSServiceResolverResolve()
-
-Revision 1.292 2003/08/21 19:27:36 cheshire
- Traffic reduction: No need to announce record for longer than TTL
-
-Revision 1.291 2003/08/21 18:57:44 cheshire
- Synchronized queries on the network
-
-Revision 1.290 2003/08/21 02:25:23 cheshire
-Minor changes to comments and debugf() messages
-
-Revision 1.289 2003/08/21 02:21:50 cheshire
- Efficiency: Reduce repeated queries
-
-Revision 1.288 2003/08/20 23:39:30 cheshire
- Review syslog messages, and remove as appropriate
-
-Revision 1.287 2003/08/20 20:47:18 cheshire
-Fix compiler warning
-
-Revision 1.286 2003/08/20 02:18:51 cheshire
- Cleanup: Review syslog messages
-
-Revision 1.285 2003/08/20 01:59:06 cheshire
- rdatahash and rdnamehash not updated after changing rdata
-Made new routine SetNewRData() to update rdlength, rdestimate, rdatahash and rdnamehash in one place
-
-Revision 1.284 2003/08/19 22:20:00 cheshire
- Don't use IPv6 on interfaces that have a routable IPv4 address configured
-More minor refinements
-
-Revision 1.283 2003/08/19 22:16:27 cheshire
-Minor fix: Add missing "mDNS_Unlock(m);" in mDNS_DeregisterInterface() error case.
-
-Revision 1.282 2003/08/19 06:48:25 cheshire
- Guard against excessive record updates
-Each record starts with 10 UpdateCredits.
-Every update consumes one UpdateCredit.
-UpdateCredits are replenished at a rate of one one per minute, up to a maximum of 10.
-As the number of UpdateCredits declines, the number of announcements is similarly scaled back.
-When fewer than 5 UpdateCredits remain, the first announcement is also delayed by an increasing amount.
-
-Revision 1.281 2003/08/19 04:49:28 cheshire
- Interaction between v4, v6 and dual-stack hosts not working quite right
-1. A dual-stack host should only suppress its own query if it sees the same query from other hosts on BOTH IPv4 and IPv6.
-2. When we see the first v4 (or first v6) member of a group, we re-trigger questions and probes on that interface.
-3. When we see the last v4 (or v6) member of a group go away, we revalidate all the records received on that interface.
-
-Revision 1.280 2003/08/19 02:33:36 cheshire
-Update comments
-
-Revision 1.279 2003/08/19 02:31:11 cheshire
- mDNSResponder overenthusiastic with final expiration queries
-Final expiration queries now only mark the question for sending on the particular interface
-pertaining to the record that's expiring.
-
-Revision 1.278 2003/08/18 22:53:37 cheshire
- mDNSResponder divide by zero in mDNSPlatformRawTime()
-
-Revision 1.277 2003/08/18 19:05:44 cheshire
- UpdateRecord not working right
-Added "newrdlength" field to hold new length of updated rdata
-
-Revision 1.276 2003/08/16 03:39:00 cheshire
- InterfaceID -1 indicates "local only"
-
-Revision 1.275 2003/08/16 02:51:27 cheshire
- mDNSResponder takes too much RPRVT
-Don't try to compute namehash etc, until *after* validating the name
-
-Revision 1.274 2003/08/16 01:12:40 cheshire
- mDNSResponder takes too much RPRVT
-Now that the minimum rdata object size has been reduced to 64 bytes, it is no longer safe to do a
-simple C structure assignment of a domainname, because that object is defined to be 256 bytes long,
-and in the process of copying it, the C compiler may run off the end of the rdata object into
-unmapped memory. All assignments of domainname objects of uncertain size are now replaced with a
-call to the macro AssignDomainName(), which is careful to copy only as many bytes as are valid.
-
-Revision 1.273 2003/08/15 20:16:02 cheshire
- mDNSResponder takes too much RPRVT
-We want to avoid touching the rdata pages, so we don't page them in.
-1. RDLength was stored with the rdata, which meant touching the page just to find the length.
- Moved this from the RData to the ResourceRecord object.
-2. To avoid unnecessarily touching the rdata just to compare it,
- compute a hash of the rdata and store the hash in the ResourceRecord object.
-
-Revision 1.272 2003/08/14 19:29:04 cheshire
- Include cache records in SIGINFO output
-Moved declarations of DNSTypeName() and GetRRDisplayString to mDNSEmbeddedAPI.h so daemon.c can use them
-
-Revision 1.271 2003/08/14 02:17:05 cheshire
- Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
-
-Revision 1.270 2003/08/13 17:07:28 ksekar
-: Extra RR linked to list even if registration fails - causes crash
-Added check to result of mDNS_Register() before linking extra record into list.
-
-Revision 1.269 2003/08/12 19:56:23 cheshire
-Update to APSL 2.0
-
-Revision 1.268 2003/08/12 15:01:10 cheshire
-Add comments
-
-Revision 1.267 2003/08/12 14:59:27 cheshire
- Rate-limiting blocks some legitimate responses
-When setting LastMCTime also record LastMCInterface. When checking LastMCTime to determine
-whether to suppress the response, also check LastMCInterface to see if it matches.
-
-Revision 1.266 2003/08/12 12:47:16 cheshire
-In mDNSCoreMachineSleep debugf message, display value of m->timenow
-
-Revision 1.265 2003/08/11 20:04:28 cheshire
- Improve efficiency by restricting cases where we have to walk the entire cache
-
-Revision 1.264 2003/08/09 00:55:02 cheshire
- mDNSResponder is taking 20-30% of the CPU
-Don't scan the whole cache after every packet.
-
-Revision 1.263 2003/08/09 00:35:29 cheshire
-Moved AnswerNewQuestion() later in the file, in preparation for next checkin
-
-Revision 1.262 2003/08/08 19:50:33 cheshire
-