summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2017-11-24 14:37:01 +0200
committerRobert Mustacchi <rm@joyent.com>2019-01-10 22:31:41 +0000
commitc65ebfc7045424bd04a6c7719a27b0ad3399ad54 (patch)
tree9ad2229fe7f2fd02d54cb8030330aa8d9b00e9a9
parentbc586359b7d9a851391f04b06254a9ead6109d47 (diff)
downloadillumos-joyent-c65ebfc7045424bd04a6c7719a27b0ad3399ad54.tar.gz
8886 mdns: update to mDNSResponder-878.1.1
Reviewed by: Gergő Mihály Doma <domag02@gmail.com> Reviewed by: Andy Fiddaman <af@citrus-it.net> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile8
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile36
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h85
-rw-r--r--usr/src/contrib/mDNSResponder/Clients/ClientCommon.c (renamed from usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c)3
-rw-r--r--usr/src/contrib/mDNSResponder/Clients/ClientCommon.h (renamed from usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/Clients/dns-sd.c (renamed from usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c)787
-rw-r--r--usr/src/contrib/mDNSResponder/LICENSE (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE)0
-rw-r--r--usr/src/contrib/mDNSResponder/LICENSE.descrip1
-rw-r--r--usr/src/contrib/mDNSResponder/README (renamed from usr/src/lib/libdns_sd/README)26
-rwxr-xr-xusr/src/contrib/mDNSResponder/copy_files.sh11
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c)165
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h)32
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c)1
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/anonymous.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c)35
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/anonymous.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/dnsproxy.h31
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/dnssec.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h)0
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c)2677
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h)4
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h)415
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSCore/nsec.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h)0
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c)969
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.h)18
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c)11
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c)185
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.h)2
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c)9
-rwxr-xr-x[-rw-r--r--]usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c)20
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.h (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.h)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h (renamed from usr/src/lib/libdns_sd/common/dns_sd.h)237
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_internal.h15
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h89
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c (renamed from usr/src/lib/libdns_sd/common/dnssd_clientlib.c)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c (renamed from usr/src/lib/libdns_sd/common/dnssd_clientstub.c)270
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.c (renamed from usr/src/lib/libdns_sd/common/dnssd_ipc.c)0
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.h (renamed from usr/src/lib/libdns_sd/common/dnssd_ipc.h)2
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c)2
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c (renamed from usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c)1265
-rw-r--r--usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.h282
-rw-r--r--usr/src/lib/libdns_sd/Makefile13
-rw-r--r--usr/src/lib/libdns_sd/Makefile.com13
-rw-r--r--usr/src/lib/libdns_sd/THIRDPARTYLICENSE13
-rw-r--r--usr/src/lib/libdns_sd/THIRDPARTYLICENSE.descrip1
-rw-r--r--usr/src/lib/libdns_sd/amd64/Makefile4
-rw-r--r--usr/src/lib/libdns_sd/common/llib-ldns_sd32
-rw-r--r--usr/src/lib/libdns_sd/i386/Makefile3
-rw-r--r--usr/src/lib/libdns_sd/java/Makefile47
-rw-r--r--usr/src/lib/libdns_sd/java/Makefile.com57
-rw-r--r--usr/src/lib/libdns_sd/java/amd64/Makefile32
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/Makefile47
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/Makefile.com31
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/BaseListener.java36
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/BrowseListener.java73
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSRecord.java52
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSD.java860
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDException.java64
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java61
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRegistration.java60
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDService.java37
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/DomainListener.java60
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/Makefile150
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/QueryListener.java59
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterListener.java49
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterRecordListener.java37
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/ResolveListener.java56
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/TXTRecord.java290
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.java420
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.manifest2
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.java333
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.manifest2
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingBrowseListener.java124
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingDomainListener.java116
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingQueryListener.java108
-rw-r--r--usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingResolveListener.java109
-rw-r--r--usr/src/lib/libdns_sd/java/common/JNISupport.c1076
-rw-r--r--usr/src/lib/libdns_sd/java/common/mapfile-vers62
-rw-r--r--usr/src/lib/libdns_sd/java/i386/Makefile35
-rw-r--r--usr/src/lib/libdns_sd/java/sparc/Makefile35
-rw-r--r--usr/src/lib/libdns_sd/java/sparcv9/Makefile32
-rw-r--r--usr/src/lib/libdns_sd/sparc/Makefile3
-rw-r--r--usr/src/lib/libdns_sd/sparcv9/Makefile3
-rw-r--r--usr/src/pkg/manifests/service-network-dns-mdns.mf104
88 files changed, 4556 insertions, 7939 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
index 24028e7f42..9640cc9a2d 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.bin/dns-sd/Makefile
@@ -10,7 +10,7 @@
#
#
-# Copyright 2016 Toomas Soome <tsoome@me.com>
+# Copyright 2017 Toomas Soome <tsoome@me.com>
#
# cmd/cmd-inet/usr.bin/dns-sd/Makefile
@@ -23,7 +23,9 @@ include ../../Makefile.cmd-inet
OBJS= ClientCommon.o dns-sd.o
SRCS= ClientCommon.c dns-sd.c
+SRCDIR= $(SRC)/contrib/mDNSResponder
CFLAGS += $(CSTD_GNU99)
+CPPFLAGS += -I$(SRCDIR)/mDNSShared
CPPFLAGS += -DMDNS_VERSIONSTR_NODTS
LDLIBS += -lsocket -ldns_sd
@@ -42,6 +44,8 @@ install: all $(ROOTPROG)
clean:
$(RM) $(OBJS)
-lint: lint_SRCS
+%.o: $(SRCDIR)/Clients/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
include ../../../Makefile.targ
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
index e110c4ef48..0aa9db8da9 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/Makefile
@@ -26,19 +26,13 @@
PROG= mdnsd
MANIFEST= multicast.xml
-CMN_DIR= $(SRC)/lib/libdns_sd/common
-CMN_OBJS= dnssd_ipc.o
-CMN_SRCS= $(CMN_OBJS:%.o=$(CMN_DIR)/%.c)
+SRCDIR= $(SRC)/contrib/mDNSResponder
-LOCAL_OBJS= DNSCommon.o DNSDigest.o GenLinkedList.o \
+OBJS= DNSCommon.o DNSDigest.o GenLinkedList.o \
PlatformCommon.o PosixDaemon.o \
mDNS.o mDNSDebug.o mDNSPosix.o mDNSUNP.o \
- uDNS.o uds_daemon.o CryptoAlg.o anonymous.o
-LOCAL_SRCS= $(LOCAL_OBJS:%.o=%.c)
-
-SRCS= $(LOCAL_SRCS) $(CMN_SRCS)
-OBJS= $(LOCAL_OBJS) $(CMN_OBJS)
-
+ uDNS.o uds_daemon.o CryptoAlg.o anonymous.o dnssd_ipc.o
+SRCS= $(OBJS:%.o=%.c)
MDNSFLAGS= -DNOT_HAVE_SA_LEN \
-DLOG_PERROR=0 -DHAVE_SOLARIS -DTARGET_OS_SOLARIS \
@@ -49,14 +43,10 @@ MDNSFLAGS= -DNOT_HAVE_SA_LEN \
include ../../../Makefile.cmd
-CERRWARN += -_gcc=-Wno-unused-variable
-CERRWARN += -_gcc=-Wno-implicit-function-declaration
-CERRWARN += -_gcc=-Wno-uninitialized
-
ROOTMANIFESTDIR= $(ROOTSVCNETWORKDNS)
$(ROOTMANIFEST) := FILEMODE= 444
-.PARALLEL: $(LOCAL_OBJS)
+.PARALLEL: $(OBJS)
.WAIT: $(PROG)
.KEEP_STATE:
@@ -69,12 +59,22 @@ $(PROG): $(OBJS)
include ../Makefile.lib
CSTD = $(CSTD_GNU99)
-CPPFLAGS += -D_REENTRANT $(MDNSFLAGS) -I$(CMN_DIR)
+CPPFLAGS += -D_REENTRANT $(MDNSFLAGS)
+CPPFLAGS += -I$(SRCDIR)/mDNSShared -I$(SRCDIR)/mDNSPosix
+CPPFLAGS += -I$(SRCDIR)/mDNSCore
LDLIBS += -lsocket -lnsl
install: all $(ROOTLIBINETPROG) $(ROOTMANIFEST)
-%.o: $(CMN_DIR)/%.c
+%.o: $(SRCDIR)/mDNSCore/%.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+ $(POST_PROCESS_O)
+
+%.o: $(SRCDIR)/mDNSShared/%.c
+ $(COMPILE.c) $(OUTPUT_OPTION) $<
+ $(POST_PROCESS_O)
+
+%.o: $(SRCDIR)/mDNSPosix/%.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POST_PROCESS_O)
@@ -83,6 +83,4 @@ check: $(CHKMANIFEST)
clean:
$(RM) $(OBJS)
-lint: lint_SRCS
-
include ../../../Makefile.targ
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE.descrip b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE.descrip
deleted file mode 100644
index beda9598bf..0000000000
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE.descrip
+++ /dev/null
@@ -1 +0,0 @@
-MDNS DAEMON
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h b/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
deleted file mode 100644
index 6cc9197d63..0000000000
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2002-2013 Apple 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.
- */
-
-#include "mDNSEmbeddedAPI.h"
-#include "dnssd_ipc.h"
-
-/* Client interface: */
-
-#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
-
-#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now)
-
-extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
-extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
-extern void udsserver_info(mDNS *const m); // print out info about current state
-extern void udsserver_handle_configchange(mDNS *const m);
-extern int udsserver_exit(void); // should be called prior to app exit
-extern void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
-#define LogMcastQ (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion
-#define LogMcastS (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService
-#define LogMcast (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg
-#define LogMcastNoIdent (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsgNoIdent
-
-/* Routines that uds_daemon expects to link against: */
-
-typedef void (*udsEventCallback)(int fd, short filter, void *context);
-extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data);
-extern int udsSupportReadFD(dnssd_sock_t fd, char* buf, int len, int flags, void *platform_data);
-extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well
-
-extern void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay);
-
-// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
-
-extern mDNS mDNSStorage;
-extern DNameListElem *AutoRegistrationDomains;
-extern DNameListElem *AutoBrowseDomains;
-
-extern mDNSs32 ChopSubTypes(char *regtype, char **AnonData);
-extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData);
-extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
-extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
-extern int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs);
-
-#if APPLE_OSX_mDNSResponder
-
-extern void machserver_automatic_browse_domain_changed(const domainname *d, mDNSBool add);
-extern void machserver_automatic_registration_domain_changed(const domainname *d, mDNSBool add);
-// D2D interface support
-extern void external_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
-extern void external_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
-extern void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
-extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
-extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
-extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
-extern void external_connection_release(const domainname *instance);
-
-#else // APPLE_OSX_mDNSResponder
-
-#define external_start_browsing_for_service(A,B,C,D) (void)(A)
-#define external_stop_browsing_for_service(A,B,C,D) (void)(A)
-#define external_start_advertising_service(A,B) (void)(A)
-#define external_stop_advertising_service(A,B) (void)(A)
-#define external_start_resolving_service(A,B,C) (void)(A)
-#define external_stop_resolving_service(A,B,C) (void)(A)
-#define external_connection_release(A) (void)(A)
-
-#endif // APPLE_OSX_mDNSResponder
-
-extern const char mDNSResponderVersionString_SCCS[];
-#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c b/usr/src/contrib/mDNSResponder/Clients/ClientCommon.c
index cb59e7b9b8..f96319cea7 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c
+++ b/usr/src/contrib/mDNSResponder/Clients/ClientCommon.c
@@ -49,8 +49,9 @@ const char *GetNextLabel(const char *cstr, char label[64])
while (*cstr && *cstr != '.') // While we have characters in the label...
{
char c = *cstr++;
- if (c == '\\' && *cstr) // If we have a backslash, and it's not the last character of the string
+ if (c == '\\') // If escape character, check next character
{
+ if (*cstr == '\0') break; // If this is the end of the string, then break
c = *cstr++;
if (isdigit(cstr[-1]) && isdigit(cstr[0]) && isdigit(cstr[1]))
{
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h b/usr/src/contrib/mDNSResponder/Clients/ClientCommon.h
index afe5b7a501..afe5b7a501 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h
+++ b/usr/src/contrib/mDNSResponder/Clients/ClientCommon.h
diff --git a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c b/usr/src/contrib/mDNSResponder/Clients/dns-sd.c
index 53619446f7..5ae5c48380 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c
+++ b/usr/src/contrib/mDNSResponder/Clients/dns-sd.c
@@ -165,6 +165,7 @@ static const char kFilePathSep = '/';
#undef _DNS_SD_LIBDISPATCH
#endif
#include "dns_sd.h"
+#include "dns_sd_internal.h"
#include "ClientCommon.h"
#if TEST_NEW_CLIENTSTUB
@@ -320,18 +321,70 @@ static char *DNSTypeName(unsigned short rr_type)
{
switch (rr_type)
{
- case kDNSServiceType_A: return("Addr");
- case kDNSServiceType_NS: return("NS");
- case kDNSServiceType_MX: return("MX");
- case kDNSServiceType_CNAME: return("CNAME");
- case kDNSServiceType_SOA: return("SOA");
- case kDNSServiceType_PTR: return("PTR");
- case kDNSServiceType_AAAA: return("AAAA");
- case kDNSServiceType_NSEC: return("NSEC");
- case kDNSServiceType_TSIG: return("TSIG");
- case kDNSServiceType_RRSIG: return("RRSIG");
- case kDNSServiceType_DNSKEY: return("DNSKEY");
- case kDNSServiceType_DS: return("DS");
+ case kDNSServiceType_A: return("Addr");
+ case kDNSServiceType_NS: return("NS");
+ case kDNSServiceType_MD: return("MD");
+ case kDNSServiceType_MF: return("MF");
+ case kDNSServiceType_CNAME: return("CNAME");
+ case kDNSServiceType_SOA: return("SOA");
+ case kDNSServiceType_MB: return("MB");
+ case kDNSServiceType_MG: return("MG");
+ case kDNSServiceType_MR: return("MR");
+ case kDNSServiceType_NULL: return("NULL");
+ case kDNSServiceType_WKS: return("WKS");
+ case kDNSServiceType_PTR: return("PTR");
+ case kDNSServiceType_HINFO: return("HINFO");
+ case kDNSServiceType_MINFO: return("MINFO");
+ case kDNSServiceType_MX: return("MX");
+ case kDNSServiceType_TXT: return("TXT");
+ case kDNSServiceType_RP: return("RP");
+ case kDNSServiceType_AFSDB: return("AFSDB");
+ case kDNSServiceType_X25: return("X25");
+ case kDNSServiceType_ISDN: return("ISDN");
+ case kDNSServiceType_RT: return("RT");
+ case kDNSServiceType_NSAP: return("NSAP");
+ case kDNSServiceType_NSAP_PTR: return("NSAP_PTR");
+ case kDNSServiceType_SIG: return("SIG");
+ case kDNSServiceType_KEY: return("KEY");
+ case kDNSServiceType_PX: return("PX");
+ case kDNSServiceType_GPOS: return("GPOS");
+ case kDNSServiceType_AAAA: return("AAAA");
+ case kDNSServiceType_LOC: return("LOC");
+ case kDNSServiceType_NXT: return("NXT");
+ case kDNSServiceType_EID: return("EID");
+ case kDNSServiceType_NIMLOC: return("NIMLOC");
+ case kDNSServiceType_SRV: return("SRV");
+ case kDNSServiceType_ATMA: return("ATMA");
+ case kDNSServiceType_NAPTR: return("NAPTR");
+ case kDNSServiceType_KX: return("KX");
+ case kDNSServiceType_CERT: return("CERT");
+ case kDNSServiceType_A6: return("A6");
+ case kDNSServiceType_DNAME: return("DNAME");
+ case kDNSServiceType_SINK: return("SINK");
+ case kDNSServiceType_OPT: return("OPT");
+ case kDNSServiceType_APL: return("APL");
+ case kDNSServiceType_DS: return("DS");
+ case kDNSServiceType_SSHFP: return("SSHFP");
+ case kDNSServiceType_IPSECKEY: return("IPSECKEY");
+ case kDNSServiceType_RRSIG: return("RRSIG");
+ case kDNSServiceType_NSEC: return("NSEC");
+ case kDNSServiceType_DNSKEY: return("DNSKEY");
+ case kDNSServiceType_DHCID: return("DHCID");
+ case kDNSServiceType_NSEC3: return("NSEC3");
+ case kDNSServiceType_NSEC3PARAM: return("NSEC3PARAM");
+ case kDNSServiceType_HIP: return("HIP");
+ case kDNSServiceType_SPF: return("SPF");
+ case kDNSServiceType_UINFO: return("UINFO");
+ case kDNSServiceType_UID: return("UID");
+ case kDNSServiceType_GID: return("GID");
+ case kDNSServiceType_UNSPEC: return("UNSPEC");
+ case kDNSServiceType_TKEY: return("TKEY");
+ case kDNSServiceType_TSIG: return("TSIG");
+ case kDNSServiceType_IXFR: return("IXFR");
+ case kDNSServiceType_AXFR: return("AXFR");
+ case kDNSServiceType_MAILB: return("MAILB");
+ case kDNSServiceType_MAILA: return("MAILA");
+ case kDNSServiceType_ANY: return("ANY");
default:
{
static char buffer[RR_TYPE_SIZE];
@@ -422,7 +475,9 @@ static DNSServiceProtocol GetProtocol(const char *s)
//*************************************************************************************************************
// Sample callback functions for each of the operation types
-static void printtimestamp(void)
+#define printtimestamp() printtimestamp_F(stdout)
+
+static void printtimestamp_F(FILE *outstream)
{
struct tm tm;
int ms;
@@ -443,10 +498,10 @@ static void printtimestamp(void)
strftime(new_date, sizeof(new_date), "%a %d %b %Y", &tm);
if (strncmp(date, new_date, sizeof(new_date)))
{
- printf("DATE: ---%s---\n", new_date); //display date only if it has changed
+ fprintf(outstream, "DATE: ---%s---\n", new_date); //display date only if it has changed
strncpy(date, new_date, sizeof(date));
}
- printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
+ fprintf(outstream, "%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms);
}
// formating time to RFC 4034 format
@@ -467,41 +522,50 @@ static void FormatTime(unsigned long te, unsigned char *buf, int bufsize)
static void print_usage(const char *arg0, int print_all)
{
+ // Print the commonly used command line options. These are listed in "the order they have been in historically".
fprintf(stderr, "%s -E (Enumerate recommended registration domains)\n", arg0);
fprintf(stderr, "%s -F (Enumerate recommended browsing domains)\n", arg0);
fprintf(stderr, "%s -R <Name> <Type> <Domain> <Port> [<TXT>...] (Register a service)\n", arg0);
- fprintf(stderr, "%s -B <Type> <Domain> (Browse for services instances)\n", arg0);
- fprintf(stderr, "%s -L <Name> <Type> <Domain> (Look up a service instance)\n", arg0);
- fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", arg0);
- fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
- fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -B <Type> <Domain> (Browse for service instances)\n", arg0);
+ fprintf(stderr, "%s -L <Name> <Type> <Domain> (Resolve a service instance)\n", arg0);
+ fprintf(stderr, "%s -Q <name> <rrtype> <rrclass> (Generic query for any record type)\n", arg0);
fprintf(stderr, "%s -Z <Type> <Domain> (Output results in Zone File format)\n", arg0);
fprintf(stderr, "%s -G v4/v6/v4v6 <name> (Get address information for hostname)\n", arg0);
- fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -H (Print usage for complete command list)\n", arg0);
fprintf(stderr, "%s -V (Get version of currently running daemon / system service)\n", arg0);
- if (print_all) //Print all available options for dns-sd tool
+ if (print_all) // Print all available options for dns-sd tool. Keep these in alphabetical order for easier maintenance.
{
- fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
- fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
+ fprintf(stderr, "\n");
fprintf(stderr, "%s -A (Test Adding/Updating/Deleting a record)\n", arg0);
- fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
+ fprintf(stderr, "%s -C <FQDN> <rrtype> <rrclass> (Query; reconfirming each result)\n", arg0);
+ fprintf(stderr, "%s -D <name> <rrtype> <rrclass>(Validate query for any record type with DNSSEC)\n", arg0);
+ fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", arg0);
fprintf(stderr, "%s -N (Test adding a large NULL record)\n", arg0);
- fprintf(stderr, "%s -T (Test creating a large TXT record)\n", arg0);
fprintf(stderr, "%s -M (Test creating a registration with multiple TXT records)\n", arg0);
- fprintf(stderr, "%s -I (Test registering and then immediately updating TXT record)\n", arg0);
+ fprintf(stderr, "%s -P <Name> <Type> <Domain> <Port> <Host> <IP> [<TXT>...] (Proxy)\n", arg0);
fprintf(stderr, "%s -S (Test multiple operations on a shared socket)\n", arg0);
+ fprintf(stderr, "%s -T (Test creating a large TXT record)\n", arg0);
+ fprintf(stderr, "%s -U (Test updating a TXT record)\n", arg0);
+ fprintf(stderr, "%s -X udp/tcp/udptcp <IntPort> <ExtPort> <TTL> (NAT Port Mapping)\n", arg0);
+ fprintf(stderr, "%s -ble (Use kDNSServiceInterfaceIndexBLE)\n", arg0);
+ fprintf(stderr, "%s -g v4/v6/v4v6 <name> (Validate address info for hostname with DNSSEC)\n", arg0);
fprintf(stderr, "%s -i <Interface> (Run dns-sd cmd on a specific interface (en0/en1)\n", arg0);
- fprintf(stderr, "%s -lo (Run dns-sd cmd using local only interface)\n", arg0);
- fprintf(stderr, "%s -p2p (Use kDNSServiceInterfaceIndexP2P)\n", arg0);
fprintf(stderr, "%s -includep2p (Set kDNSServiceFlagsIncludeP2P flag)\n", arg0);
fprintf(stderr, "%s -includeAWDL (Set kDNSServiceFlagsIncludeAWDL flag)\n", arg0);
+ fprintf(stderr, "%s -intermediates (Set kDNSServiceFlagsReturnIntermediates flag)\n", arg0);
+ fprintf(stderr, "%s -ku (Set kDNSServiceFlagsKnownUnique flag)\n", arg0);
+ fprintf(stderr, "%s -lo (Run dns-sd cmd using local only interface)\n", arg0);
fprintf(stderr, "%s -optional (Set kDNSServiceFlagsValidateOptional flag)\n", arg0);
+ fprintf(stderr, "%s -p2p (Use kDNSServiceInterfaceIndexP2P)\n", arg0);
+ fprintf(stderr, "%s -q <name> <rrtype> <rrclass> (Equivalent to -Q with kDNSServiceFlagsSuppressUnusable set)\n", arg0);
fprintf(stderr, "%s -tc (Set kDNSServiceFlagsBackgroundTrafficClass flag)\n", arg0);
- fprintf(stderr, "%s -unicastResponse (Set kDNSServiceFlagsUnicastResponse flag)\n", arg0);
+ fprintf(stderr, "%s -test (Run basic API input range tests)\n", arg0);
fprintf(stderr, "%s -t1 (Set kDNSServiceFlagsThresholdOne flag)\n", arg0);
fprintf(stderr, "%s -tFinder (Set kDNSServiceFlagsThresholdFinder flag)\n", arg0);
fprintf(stderr, "%s -timeout (Set kDNSServiceFlagsTimeout flag)\n", arg0);
+ fprintf(stderr, "%s -unicastResponse (Set kDNSServiceFlagsUnicastResponse flag)\n", arg0);
+ fprintf(stderr, "%s -autoTrigger (Set kDNSServiceFlagsAutoTrigger flag)\n", arg0);
}
}
@@ -731,17 +795,20 @@ static void DNSSD_API resolve_reply(DNSServiceRef sdref, const DNSServiceFlags f
(void)context; // Unused
EXIT_IF_LIBDISPATCH_FATAL_ERROR(errorCode);
- if (errorCode)
- printf("Error code %d\n", errorCode);
- else
- {
- printtimestamp();
- printf("%s can be reached at %s:%u (interface %d)", fullname, hosttarget, PortAsNumber, ifIndex);
- if (flags) printf(" Flags: %X", flags);
- // Don't show degenerate TXT records containing nothing but a single empty string
- if (txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
- printf("\n");
- }
+ printtimestamp();
+
+ printf("%s ", fullname);
+
+ if (errorCode == kDNSServiceErr_NoSuchRecord) printf("No Such Record");
+ else if (errorCode) printf("error code %d\n", errorCode);
+ else printf("can be reached at %s:%u (interface %d)", hosttarget, PortAsNumber, ifIndex);
+
+ if (flags) printf(" Flags: %X", flags);
+
+ // Don't show degenerate TXT records containing nothing but a single empty string
+ if (!errorCode && txtLen > 1) { printf("\n"); ShowTXTRecord(txtLen, txtRecord); }
+
+ printf("\n");
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
@@ -776,6 +843,7 @@ static void myTimerCallBack(void)
{
if (updatetest[1] != 'Z') updatetest[1]++;
else updatetest[1] = 'A';
+ // The following line toggles the string length between 1 and 2 characters.
updatetest[0] = 3 - updatetest[0];
updatetest[2] = updatetest[1];
printtimestamp();
@@ -1249,7 +1317,7 @@ static void HandleEvents(void)
DNSServiceErrorType err = kDNSServiceErr_NoError;
if (client && FD_ISSET(dns_sd_fd, &readfds)) err = DNSServiceProcessResult(client );
else if (client_pa && FD_ISSET(dns_sd_fd2, &readfds)) err = DNSServiceProcessResult(client_pa);
- if (err) { fprintf(stderr, "DNSServiceProcessResult returned %d\n", err); stopNow = 1; }
+ if (err) { printtimestamp_F(stderr); fprintf(stderr, "DNSServiceProcessResult returned %d\n", err); stopNow = 1; }
}
else if (result == 0)
myTimerCallBack();
@@ -1306,18 +1374,6 @@ static void DNSSD_API MyRegisterRecordCallback(DNSServiceRef service, DNSRecordR
default: printf("Error %d\n", errorCode); break;
}
if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
- // DNSServiceRemoveRecord(service, rec, 0); to test record removal
-
-#if 0 // To test updating of individual records registered via DNSServiceRegisterRecord
- if (!errorCode)
- {
- int x = 0x11111111;
- printf("Updating\n");
- DNSServiceUpdateRecord(service, rec, 0, sizeof(x), &x, 0);
- }
-#endif
-
- if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout);
}
static void getip(const char *const name, struct sockaddr_storage *result)
@@ -1403,131 +1459,583 @@ static char *gettype(char *buffer, char *typ)
return(typ);
}
-int main(int argc, char **argv)
+// Do some basic tests to verify API handles > 63 byte strings gracefully with
+// a returned error code.
+
+#define STRING_64_BYTES "_123456789012345678901234567890123456789012345678901234567890123"
+
+static int API_string_limit_test()
{
- DNSServiceErrorType err;
- char buffer[TypeBufferSize], *typ, *dom;
- int opi;
- DNSServiceFlags flags = 0;
- int optional = 0;
+ const char * regtype;
+ DNSServiceRef sdRef = NULL;
+ const char * longHost = STRING_64_BYTES ".local";
+ const char * longDomain = "hostname." STRING_64_BYTES;
- // Extract the program name from argv[0], which by convention contains the path to this executable.
- // Note that this is just a voluntary convention, not enforced by the kernel --
- // the process calling exec() can pass bogus data in argv[0] if it chooses to.
- const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
- if (a0 == (const char *)1) a0 = argv[0];
+ printf("Testing for error returns when various strings are > 63 bytes.\n");
-#if defined(_WIN32)
- HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
-#endif
+ printf("DNSServiceGetAddrInfo(), hostname = %s\n", longHost);
+ if (DNSServiceGetAddrInfo(&sdRef, 0, 0, 0, longHost, addrinfo_reply, 0) == 0)
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ };
-#if TEST_NEW_CLIENTSTUB
- printf("Using embedded copy of dnssd_clientstub instead of system library\n");
- if (sizeof(argv) == 8) printf("Running in 64-bit mode\n");
+ printf("DNSServiceGetAddrInfo(), hostname = %s\n", longDomain);
+ if (DNSServiceGetAddrInfo(&sdRef, 0, 0, 0, longDomain, addrinfo_reply, 0) == 0)
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceResolve(), name = %s\n", STRING_64_BYTES);
+ if (DNSServiceResolve(&sdRef, 0, 0, STRING_64_BYTES, "_test._tcp", "local", resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ regtype = STRING_64_BYTES "._tcp";
+ printf("DNSServiceResolve(), regtype = %s\n", regtype);
+ if (DNSServiceResolve(&sdRef, 0, 0, "instanceName", regtype, "local", resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ printf("DNSServiceResolve(), domain = %s\n", STRING_64_BYTES);
+ if (DNSServiceResolve(&sdRef, 0, 0, "instanceName", "_test._tcp", STRING_64_BYTES, resolve_reply, NULL) == 0)
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ };
+
+ printf("Testing for error returns when various strings are > 63 bytes: PASSED\n");
+ return 0;
+}
+
+// local prototypes for routines that don't have prototypes in dns_sd.h
+#if APPLE_OSX_mDNSResponder
+DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
+DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
#endif
- // Test code for TXTRecord functions
- //TXTRecordRef txtRecord;
- //TXTRecordCreate(&txtRecord, 0, NULL);
- //TXTRecordSetValue(&txtRecord, "aaa", 1, "b");
- //printf("%d\n", TXTRecordContainsKey(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), "Aaa"));
+static int API_NULL_input_test()
+{
+ printf("Running basic API input range tests with various pointer parameters set to NULL:\n");
+
+ // Test that API's handle NULL pointers by returning an error when appropriate.
+
+ // DNSServiceRefSockFD()
+ if (DNSServiceRefSockFD(0) != -1)
+ {
+ printf("DNSServiceRefSockFD(): expected dnssd_InvalidSocket return\n");
+ return 1;
+ }
- if (argc > 1 && !strcmp(argv[1], "-lo"))
+ // DNSServiceProcessResult()
+ if (DNSServiceProcessResult(0) == 0)
{
- argc--;
- argv++;
- opinterface = kDNSServiceInterfaceIndexLocalOnly;
- printf("Using LocalOnly\n");
+ printf("DNSServiceProcessResult(): expected error return\n");
+ return 1;
}
- if (argc > 1 && (!strcmp(argv[1], "-p2p") || !strcmp(argv[1], "-P2P")))
+ // DNSServiceRefDeallocate(): no return value, just verify it doesn't crash
+ DNSServiceRefDeallocate(0);
+
+ // DNSServiceGetProperty()
{
- argc--;
- argv++;
- opinterface = kDNSServiceInterfaceIndexP2P;
+ uint32_t result;
+ uint32_t size;
+
+ if ( (DNSServiceGetProperty( 0, &result, &size) == 0)
+ || (DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, 0, &size) == 0)
+ || (DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &result, 0) == 0)
+ )
+ {
+ printf("DNSServiceGetProperty(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
+ // DNSServiceResolve()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsIncludeP2P;
- printf("Setting kDNSServiceFlagsIncludeP2P\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *name = "name";
+ const char *regtype = "_test._tcp";
+ const char *domain = "local";
+ DNSServiceResolveReply callBack = 0;
+ void *context = 0; // can be a NULL pointer
+
+ if ( (DNSServiceResolve( 0, flags, interfaceIndex, name, regtype, domain, callBack, context) == 0)
+ || (DNSServiceResolve(&sdRef, flags, interfaceIndex, 0, regtype, domain, callBack, context) == 0)
+ || (DNSServiceResolve(&sdRef, flags, interfaceIndex, name, 0, domain, callBack, context) == 0)
+ || (DNSServiceResolve(&sdRef, flags, interfaceIndex, name, regtype, 0, callBack, context) == 0)
+ || (DNSServiceResolve(&sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context) == 0)
+ )
+ {
+ printf("DNSServiceResolve(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-includeAWDL"))
+ // DNSServiceQueryRecord()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsIncludeAWDL;
- printf("Setting kDNSServiceFlagsIncludeAWDL\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *fullname = "fullname";
+ uint16_t rrtype = 0;
+ uint16_t rrclass = 0;
+ DNSServiceQueryRecordReply callBack = 0;
+ void *context = 0; /* may be NULL */
+
+ if ( (DNSServiceQueryRecord( 0, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context) == 0)
+ || (DNSServiceQueryRecord(&sdRef, flags, interfaceIndex, 0, rrtype, rrclass, callBack, context) == 0)
+ || (DNSServiceQueryRecord(&sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, 0, context) == 0)
+ )
+ {
+ printf("DNSServiceQueryRecord(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-tc"))
+ // DNSServiceGetAddrInfo()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsBackgroundTrafficClass;
- printf("Setting kDNSServiceFlagsBackgroundTrafficClass\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ DNSServiceProtocol protocol = kDNSServiceProtocol_IPv4|kDNSServiceProtocol_IPv6;
+ const char *hostname = "host.local";
+ DNSServiceGetAddrInfoReply callBack = 0;
+ void *context = 0; // may be NULL
+
+ if ( (DNSServiceGetAddrInfo( 0, flags, interfaceIndex, protocol, hostname, callBack, context) == 0)
+ || (DNSServiceGetAddrInfo(&sdRef, flags, interfaceIndex, protocol, 0, callBack, context) == 0)
+ || (DNSServiceGetAddrInfo(&sdRef, flags, interfaceIndex, protocol, hostname, 0, context) == 0)
+ )
+ {
+ printf("DNSServiceGetAddrInfo(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-t1"))
+ // DNSServiceBrowse()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsThresholdOne;
- printf("Setting kDNSServiceFlagsThresholdOne\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *regtype = "_test._tcp";
+ const char *domain = 0; /* may be NULL */
+ DNSServiceBrowseReply callBack = 0;
+ void *context = 0; /* may be NULL */
+
+ if ( (DNSServiceBrowse( 0, flags, interfaceIndex, regtype, domain, callBack, context) == 0)
+ || (DNSServiceBrowse(&sdRef, flags, interfaceIndex, 0, domain, callBack, context) == 0)
+ || (DNSServiceBrowse(&sdRef, flags, interfaceIndex, regtype, domain, 0, context) == 0)
+ )
+ {
+ printf("DNSServiceBrowse(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-tFinder"))
+#if APPLE_OSX_mDNSResponder
+ // DNSServiceSetDefaultDomainForUser()
+ if (DNSServiceSetDefaultDomainForUser(0, 0) == 0)
+ {
+ printf("DNSServiceSetDefaultDomainForUser(): expected error return\n");
+ return 1;
+ }
+#endif
+
+ // DNSServiceRegister()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsThresholdFinder;
- printf("Setting kDNSServiceFlagsThresholdFinder\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *name = 0; /* may be NULL */
+ const char *regtype = "_test._tcp";
+ const char *domain = 0; /* may be NULL */
+ const char *host = 0; /* may be NULL */
+ uint16_t port = 0x2211; /* In network byte order */
+ uint16_t txtLen = 1;
+ const void *txtRecord = "\0"; /* may be NULL */
+ DNSServiceRegisterReply callBack = 0; /* may be NULL */
+ void *context = 0; /* may be NULL */
+
+ if ( (DNSServiceRegister( 0, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context) == 0)
+ || (DNSServiceRegister(&sdRef, flags, interfaceIndex, name, 0, domain, host, port, txtLen, txtRecord, callBack, context) == 0)
+ )
+ {
+ printf("DNSServiceRegister(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-wo"))
+ // DNSServiceEnumerateDomains()
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsWakeOnlyService;
- printf("Setting kDNSServiceFlagsWakeOnlyService\n");
+ DNSServiceRef sdRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ DNSServiceDomainEnumReply callBack = 0;
+ void *context = 0; /* may be NULL */
+
+ if ( (DNSServiceEnumerateDomains( 0, flags, interfaceIndex, callBack, context) == 0)
+ || (DNSServiceEnumerateDomains(&sdRef, flags, interfaceIndex, 0, context) == 0)
+ )
+ {
+ printf("DNSServiceEnumerateDomains(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 1 && !strcasecmp(argv[1], "-unicastResponse"))
+ // DNSServiceCreateConnection()
+ if (DNSServiceCreateConnection(0) == 0)
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsUnicastResponse;
- printf("Setting kDNSServiceFlagsUnicastResponse\n");
+ printf("DNSServiceCreateConnection(): expected error return\n");
+ return 1;
}
- if (argc > 1 && !strcasecmp(argv[1], "-timeout"))
+
+#if APPLE_OSX_mDNSResponder
+ // DNSServiceCreateDelegateConnection()
+ if (DNSServiceCreateDelegateConnection(0, 0, 0) == 0)
{
- argc--;
- argv++;
- flags |= kDNSServiceFlagsTimeout;
- printf("Setting kDNSServiceFlagsTimeout\n");
+ printf("DNSServiceCreateDelegateConnection(): expected error return\n");
+ return 1;
}
- if (argc > 1 && !strcasecmp(argv[1], "-optional"))
+#endif
+
+ // DNSServiceRegisterRecord()
{
- argc--;
- argv++;
- optional = 1;
- printf("Setting DNSSEC optional flag\n");
+ DNSServiceRef sdRef;
+ DNSRecordRef RecordRef;
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *fullname = "test1._test._tcp.local";
+ uint16_t rrtype = kDNSServiceType_TXT;
+ uint16_t rrclass = kDNSServiceClass_IN;
+ uint16_t rdlen = 1;
+ const void *rdata = "\0";
+ uint32_t ttl = 0;
+ DNSServiceRegisterRecordReply callBack = 0;
+ void *context = 0; /* may be NULL */
+
+ // Need an initialize sdRef
+ if (DNSServiceCreateConnection(&sdRef))
+ {
+ printf("DNSServiceCreateConnection(): failed\n");
+ return 1;
+ }
+
+ if ( (DNSServiceRegisterRecord( 0, &RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, callBack, context) == 0)
+ || (DNSServiceRegisterRecord(sdRef, &RecordRef, flags, interfaceIndex, 0, rrtype, rrclass, rdlen, rdata, ttl, callBack, context) == 0)
+ || (DNSServiceRegisterRecord(sdRef, &RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, 0, ttl, callBack, context) == 0)
+ || (DNSServiceRegisterRecord(sdRef, &RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, 0, context) == 0)
+ )
+ {
+ printf("DNSServiceRegisterRecord(): expected error return\n");
+ return 1;
+ }
}
- if (argc > 2 && !strcmp(argv[1], "-i"))
+ // DNSServiceAddRecord(), DNSServiceUpdateRecord(), and DNSServiceRemoveRecord() verify that they
+ // get a valid DNSServiceRef returned from DNSServiceRegister()
+ {
+ DNSServiceErrorType err;
+ Opaque16 registerPort = { { 0x12, 0x34 } };
+ static const char TXT[] = "\xC" "First String";
+ DNSServiceRef sdRef;
+
+ DNSRecordRef RecordRef;
+ DNSServiceFlags flags = 0;
+ uint16_t rrtype = kDNSServiceType_TXT;
+ uint16_t rdlen = 1;
+ const void *rdata = "\0";
+ uint32_t ttl = 100;
+
+ err = DNSServiceRegister(&sdRef, 0, 0, "Test", "_test._tcp.", "", NULL, registerPort.NotAnInteger, sizeof(TXT)-1, TXT, reg_reply, NULL);
+ if (err)
+ {
+ printf("DNSServiceRegister() failed with: %d\n", err);
+ return 1;
+ }
+
+ // DNSServiceAddRecord()
+ if ( (DNSServiceAddRecord( 0, &RecordRef, flags, rrtype, rdlen, rdata, ttl) == 0)
+ || (DNSServiceAddRecord(sdRef, 0, flags, rrtype, rdlen, rdata, ttl) == 0)
+ || (DNSServiceAddRecord(sdRef, &RecordRef, flags, rrtype, rdlen, 0, ttl) == 0)
+ )
+
+ {
+ printf("DNSServiceAddRecord(): expected error return\n");
+ return 1;
+ }
+
+ // (rdlen == 0 && rdata == 0) should indicate a TXT with rdata containing only a 0 length byte.
+ if (DNSServiceAddRecord(sdRef, &RecordRef, flags, rrtype, 0, 0, ttl) == kDNSServiceErr_BadParam)
+ {
+ printf("DNSServiceAddRecord(): with (rdlen == 0 && rdata == 0) returned kDNSServiceErr_BadParam\n");
+ return 1;
+ }
+
+ // DNSServiceUpdateRecord()
+ // Note, RecordRef can be NULL per explanation with declaration in dns_sd.h
+ if ( (DNSServiceUpdateRecord( 0, RecordRef, flags, rdlen, rdata, ttl) == 0)
+ || (DNSServiceUpdateRecord(sdRef, RecordRef, flags, rdlen, 0, ttl) == 0)
+ )
+ {
+ printf("DNSServiceUpdateRecord(): expected error return\n");
+ return 1;
+ }
+
+ // (rdlen == 0 && rdata == 0) should indicate a TXT with rdata containing only a 0 length byte.
+ if (DNSServiceUpdateRecord(sdRef, RecordRef, flags, 0, 0, ttl) == kDNSServiceErr_BadParam)
+ {
+ printf("DNSServiceUpdateRecord(): with (rdlen == 0 && rdata == 0) returned kDNSServiceErr_BadParam\n");
+ return 1;
+ }
+
+ // DNSServiceRemoveRecord()
+ if ( (DNSServiceRemoveRecord( 0, RecordRef, flags) == 0)
+ || (DNSServiceRemoveRecord(sdRef, 0, flags) == 0)
+ )
+ {
+ printf("DNSServiceRemoveRecord(): expected error return\n");
+ return 1;
+ }
+
+ DNSServiceRefDeallocate(sdRef);
+ }
+
+ // DNSServiceReconfirmRecord()
+ {
+ DNSServiceFlags flags = 0;
+ uint32_t interfaceIndex = 0;
+ const char *fullname = "aaa._test._tcp.local";
+ uint16_t rrtype = kDNSServiceType_TXT;
+ uint16_t rrclass = kDNSServiceClass_IN;
+ uint16_t rdlen = 1;
+ const void *rdata = "\0";
+
+ if ( (DNSServiceReconfirmRecord(flags, interfaceIndex, 0, rrtype, rrclass, rdlen, rdata) == 0)
+ || (DNSServiceReconfirmRecord(flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, 0) == 0)
+ )
+ {
+ printf("DNSServiceReconfirmRecord(): expected error return\n");
+ return 1;
+ }
+ // (rdlen == 0 && rdata == 0) should indicate a TXT with rdata containing only a 0 length byte.
+ if (DNSServiceReconfirmRecord(flags, interfaceIndex, fullname, rrtype, rrclass, 0, 0) == kDNSServiceErr_BadParam)
+ {
+ printf("DNSServiceReconfirmRecord(): with (rdlen == 0 && rdata == 0) returned kDNSServiceErr_BadParam\n");
+ return 1;
+ }
+ }
+
+
+ printf("Basic API input range tests: PASSED\n");
+ return 0;
+}
+
+static int API_input_range_test()
+{
+
+ if (API_string_limit_test())
+ return 1;
+
+ if (API_NULL_input_test())
+ return 1;
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ DNSServiceErrorType err;
+ char buffer[TypeBufferSize], *typ, *dom;
+ int opi;
+ DNSServiceFlags flags = 0;
+ int optional = 0;
+
+ // Extract the program name from argv[0], which by convention contains the path to this executable.
+ // Note that this is just a voluntary convention, not enforced by the kernel --
+ // the process calling exec() can pass bogus data in argv[0] if it chooses to.
+ const char *a0 = strrchr(argv[0], kFilePathSep) + 1;
+ if (a0 == (const char *)1) a0 = argv[0];
+
+#if defined(_WIN32)
+ HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
+#endif
+
+#if TEST_NEW_CLIENTSTUB
+ printf("Using embedded copy of dnssd_clientstub instead of system library\n");
+ if (sizeof(argv) == 8) printf("Running in 64-bit mode\n");
+#endif
+
+ // Test code for TXTRecord functions
+ //TXTRecordRef txtRecord;
+ //TXTRecordCreate(&txtRecord, 0, NULL);
+ //TXTRecordSetValue(&txtRecord, "aaa", 1, "b");
+ //printf("%d\n", TXTRecordContainsKey(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), "Aaa"));
+
+ while (argc > 1)
{
- opinterface = if_nametoindex(argv[2]);
- if (!opinterface) opinterface = atoi(argv[2]);
- if (!opinterface) { fprintf(stderr, "Unknown interface %s\n", argv[2]); goto Fail; }
- argc -= 2;
- argv += 2;
+ int entryCount;
+
+ // record current argc to see if we process an argument in this pass
+ entryCount = argc;
+
+ if (argc > 1 && !strcmp(argv[1], "-test"))
+ {
+ argc--;
+ argv++;
+ return API_input_range_test();
+ }
+
+ if (argc > 1 && !strcmp(argv[1], "-lo"))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexLocalOnly;
+ printf("Using LocalOnly\n");
+ }
+
+ if (argc > 1 && (!strcasecmp(argv[1], "-p2p")))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexP2P;
+ }
+
+ if (argc > 1 && (!strcasecmp(argv[1], "-ble")))
+ {
+ argc--;
+ argv++;
+ opinterface = kDNSServiceInterfaceIndexBLE;
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-includep2p"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsIncludeP2P;
+ printf("Setting kDNSServiceFlagsIncludeP2P\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-fmc"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsForceMulticast;
+ printf("Setting kDNSServiceFlagsForceMulticast flag for this request\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-includeAWDL"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsIncludeAWDL;
+ printf("Setting kDNSServiceFlagsIncludeAWDL\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-intermediates"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsReturnIntermediates;
+ printf("Setting kDNSServiceFlagsReturnIntermediates\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-tc"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsBackgroundTrafficClass;
+ printf("Setting kDNSServiceFlagsBackgroundTrafficClass\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-t1"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsThresholdOne;
+ printf("Setting kDNSServiceFlagsThresholdOne\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-tFinder"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsThresholdFinder;
+ printf("Setting kDNSServiceFlagsThresholdFinder\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-wo"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsWakeOnlyService;
+ printf("Setting kDNSServiceFlagsWakeOnlyService\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-ku"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsKnownUnique;
+ printf("Setting kDNSServiceFlagsKnownUnique\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-unicastResponse"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsUnicastResponse;
+ printf("Setting kDNSServiceFlagsUnicastResponse\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-timeout"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsTimeout;
+ printf("Setting kDNSServiceFlagsTimeout\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-autoTrigger"))
+ {
+ argc--;
+ argv++;
+ flags |= kDNSServiceFlagsAutoTrigger;
+ printf("Setting kDNSServiceFlagsAutoTrigger\n");
+ }
+
+ if (argc > 1 && !strcasecmp(argv[1], "-optional"))
+ {
+ argc--;
+ argv++;
+ optional = 1;
+ printf("Setting DNSSEC optional flag\n");
+ }
+
+ if (argc > 2 && !strcmp(argv[1], "-i"))
+ {
+ opinterface = if_nametoindex(argv[2]);
+ if (!opinterface) opinterface = atoi(argv[2]);
+ if (!opinterface) { fprintf(stderr, "Unknown interface %s\n", argv[2]); goto Fail; }
+ argc -= 2;
+ argv += 2;
+ }
+
+ // Exit loop if if we didn't match one of the multi character options.
+ if (argc == entryCount)
+ break;
}
if (argc < 2) goto Fail; // Minimum command line is the command name and one argument
- operation = getfirstoption(argc, argv, "EFBZLlRPQqCAUNTMISVHhD"
+ operation = getfirstoption(argc, argv, "ABCDEFHILMNPQRSTUVZhlq"
"X"
"Gg"
, &opi);
@@ -1686,6 +2194,7 @@ int main(int argc, char **argv)
case 'g':
case 'G': {
flags |= kDNSServiceFlagsReturnIntermediates;
+
if (operation == 'g')
{
flags |= kDNSServiceFlagsSuppressUnusable;
@@ -1779,11 +2288,7 @@ Fail:
// NOT static -- otherwise the compiler may optimize it out
// The "@(#) " pattern is a special prefix the "what" command looks for
-#ifndef MDNS_VERSIONSTR_NODTS
const char VersionString_SCCS[] = "@(#) dns-sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
-#else
-const char VersionString_SCCS[] = "@(#) dns-sd " STRINGIFY(mDNSResponderVersion);
-#endif
#if _BUILDING_XCODE_PROJECT_
// If the process crashes, then this string will be magically included in the automatically-generated crash log
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE b/usr/src/contrib/mDNSResponder/LICENSE
index f4589044ee..f4589044ee 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE
+++ b/usr/src/contrib/mDNSResponder/LICENSE
diff --git a/usr/src/contrib/mDNSResponder/LICENSE.descrip b/usr/src/contrib/mDNSResponder/LICENSE.descrip
new file mode 100644
index 0000000000..73f70154ad
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/LICENSE.descrip
@@ -0,0 +1 @@
+mDNSResponder
diff --git a/usr/src/lib/libdns_sd/README b/usr/src/contrib/mDNSResponder/README
index 9bae6c7404..ea5d4d4740 100644
--- a/usr/src/lib/libdns_sd/README
+++ b/usr/src/contrib/mDNSResponder/README
@@ -21,22 +21,24 @@
#
# CDDL HEADER END
#
+
+The mdns vendor source repository is at https://github.com/illumos/mdns/.
+
+Updated from upstream version mDNSResponder-878.1.1
Updated from upstream version mDNSResponder-625.41.2
Updated from upstream version mDNSResponder-576.30.4
Multicast DNS and Service Discovery support in Solaris using the
-Apple Bonjour source code (v107.6). Apple Bonjour source can be
-downloaded from:
- http://developer.apple.com/networking/bonjour/download/
+Apple Bonjour source code (v107.6). Apple Bonjour source can be
+downloaded from:
+ http://developer.apple.com/networking/bonjour/download/
The following components are integrated from the Apple Bonjour
source in Solaris:
- libdns_sd: usr/src/lib/libdns_sd <dns_sd.h>
- libjdns_sd: usr/src/lib/libdns_sd/java/common
- dnssd.jar: usr/src/lib/libdns_sd/java/com (incl. examples)
+ libdns_sd: usr/src/lib/libdns_sd <dns_sd.h>
mdnsd: usr/src/cmd/cmd-inet/usr.lib/mdnsd
- dns-sd: usr/src/cmd/cmd-inet/usr.bin/dns-sd.c
+ dns-sd: usr/src/cmd/cmd-inet/usr.bin/dns-sd
-Following fixes have been made to the Apple Bonjour source
+Following fixes have been made to the Apple Bonjour source
integrated in Solaris:
* 64-bit support by adding pad bytes in ipc_msg_hdr_struct
* 64-bit support in libjdns_sd, dnssd.jar (JNISupport.c, DNSSD.java)
@@ -44,13 +46,13 @@ integrated in Solaris:
* Fixes to support IPv6 (mDNSPosix.c, mDNSUNP.c)
* Fix error raised when uDNS.c is compiled with Sun Studio compiler
* Fix in dnssd_clientstub.c to not check errno when recvmsg returns 0
-* mDNSDebug.c modified to not send msgs directly to console when
+* mDNSDebug.c modified to not send msgs directly to console when
syslog call returns an error. Logs the messages at LOG_INFO level
and not LOG_ERR
In addition the project introduces the following changes:
-* A new nss_mdns module is introduced to use Multicast DNS (mdns)
- for resolving link-local hostnames and is located at:
+* A new nss_mdns module is introduced to use Multicast DNS (mdns)
+ for resolving link-local hostnames and is located at:
usr/src/lib/nsswitch/mdns
* snoop updated to decode mDNS packets
* updated /etc/services to include mdns
@@ -61,5 +63,5 @@ In addition the project introduces the following changes:
Both authorizations added in network management execution profile.
* Default nsswitch.dns includes mdns as source for hosts & ipnodes
* nscd daemon updated to support mdns
-* SUNWdsdu and SUNWdsdr packages deliver all the new mDNS
+* SUNWdsdu and SUNWdsdr packages deliver all the new mDNS
service discovery components.
diff --git a/usr/src/contrib/mDNSResponder/copy_files.sh b/usr/src/contrib/mDNSResponder/copy_files.sh
new file mode 100755
index 0000000000..a7f3662a8f
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/copy_files.sh
@@ -0,0 +1,11 @@
+#!/bin/ksh
+
+if [ ! -d "$1" ]; then
+ echo "\"$1\" should be source repository root directory"
+ exit 1
+fi
+
+for f in LICENSE */*
+do
+ cp $1/$f $f
+done
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c b/usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.c
index 0008405ddd..0008405ddd 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.c
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h b/usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.h
index c21507e4b1..c21507e4b1 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/CryptoAlg.h
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c
index e75f734e22..323974cb45 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.c
@@ -21,6 +21,10 @@
#include "CryptoAlg.h"
#include "anonymous.h"
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
+
// Disable certain benign warnings with Microsoft compilers
#if (defined(_MSC_VER))
// Disable "conditional expression is constant" warning for debug macros.
@@ -43,6 +47,7 @@ mDNSexport const mDNSInterfaceID mDNSInterface_LocalOnly = (mDNSInterfaceID)-2;
mDNSexport const mDNSInterfaceID mDNSInterface_Unicast = (mDNSInterfaceID)-3;
mDNSexport const mDNSInterfaceID mDNSInterface_P2P = (mDNSInterfaceID)-4;
mDNSexport const mDNSInterfaceID uDNSInterfaceMark = (mDNSInterfaceID)-5;
+mDNSexport const mDNSInterfaceID mDNSInterface_BLE = (mDNSInterfaceID)-6;
// Note: Microsoft's proposed "Link Local Multicast Name Resolution Protocol" (LLMNR) is essentially a limited version of
// Multicast DNS, using the same packet formats, naming syntax, and record types as Multicast DNS, but on a different UDP
@@ -107,8 +112,11 @@ mDNSexport const mDNSOpaque16 DNSSecQFlags = { { kDNSFlag0_QR_Query | kDNS
mDNSexport const mDNSOpaque16 ResponseFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery | kDNSFlag0_AA, 0 } };
mDNSexport const mDNSOpaque16 UpdateReqFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Update, 0 } };
mDNSexport const mDNSOpaque16 UpdateRespFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, 0 } };
+mDNSexport const mDNSOpaque16 SubscribeFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Subscribe, 0 } };
+mDNSexport const mDNSOpaque16 UnSubscribeFlags= { { kDNSFlag0_QR_Query | kDNSFlag0_OP_UnSubscribe, 0 } };
-mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque128 zeroOpaque128 = { { 0 } };
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
@@ -462,9 +470,9 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
const mDNSu8 *p = (mDNSu8 *)&nsec3->salt;
int hashLength, bitmaplen, i;
- length += mDNS_snprintf(buffer+length, RemSpc, "\t%s %d %d ",
+ length += mDNS_snprintf(buffer+length, RemSpc, "\t%s %d %d ",
DNSSECDigestName(nsec3->alg), nsec3->flags, swap16(nsec3->iterations));
-
+
if (!nsec3->saltLength)
{
length += mDNS_snprintf(buffer+length, RemSpc, "-");
@@ -483,7 +491,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
p += nsec3->saltLength;
// p is pointing at hashLength
hashLength = (int)*p++;
-
+
length += baseEncode(buffer + length, RemSpc, p, hashLength, ENC_BASE32);
// put a space at the end
@@ -510,7 +518,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
length += mDNS_snprintf(buffer+length, RemSpc, "\t%s %s %d %d %s %s %d %##s ",
DNSTypeName(swap16(rrsig->typeCovered)), DNSSECAlgName(rrsig->alg), rrsig->labels, swap32(rrsig->origTTL),
- expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), ((domainname *)(&rrsig->signerName))->c);
+ expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag), rrsig->signerName);
len = DomainNameLength((domainname *)&rrsig->signerName);
baseEncode(buffer + length, RemSpc, (const mDNSu8 *)(rd->data + len + RRSIG_FIXED_SIZE),
@@ -541,7 +549,7 @@ mDNSexport char *GetRRDisplayString_rdb(const ResourceRecord *const rr, const RD
}
break;
- default: mDNS_snprintf(buffer+length, RemSpc, "RDLen %d: %s", rr->rdlength, rd->data);
+ default: mDNS_snprintf(buffer+length, RemSpc, "RDLen %d: %.*s", rr->rdlength, rr->rdlength, rd->data);
// Really should scan buffer to check if text is valid UTF-8 and only replace with dots if not
for (ptr = buffer; *ptr; ptr++) if (*ptr < ' ') *ptr = '.';
break;
@@ -619,6 +627,8 @@ mDNSexport mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
#pragma mark - Domain Name Utility Functions
#endif
+#if !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
{
int i;
@@ -639,6 +649,8 @@ mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
return(mDNStrue);
}
+#endif // !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2)
{
const mDNSu8 * a = d1->c;
@@ -803,6 +815,7 @@ mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstri
mDNSu8 c = (mDNSu8)*cstr++; // Read the character
if (c == '\\') // If escape character, check next character
{
+ if (*cstr == '\0') break; // If this is the end of the string, then break
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,
@@ -815,7 +828,7 @@ mDNSexport mDNSu8 *AppendDNSNameString(domainname *const name, const char *cstri
}
*ptr++ = c; // Write the character
}
- if (*cstr) cstr++; // Skip over the trailing dot (if present)
+ 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
@@ -967,10 +980,6 @@ mDNSexport void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], do
hostlabel->c[0] = (mDNSu8)(ptr - &hostlabel->c[1]);
}
-#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
- ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
- ((X)[4] | 0x20) == 'p')
-
mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
const domainlabel *name, const domainname *type, const domainname *const domain)
{
@@ -1029,10 +1038,6 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
{
LogMsg("Bad service type in %#s.%##s%##s Application protocol name must be underscore plus 1-15 characters. "
"See <http://www.dns-sd.org/ServiceTypes.html>", name->c, type->c, domain->c);
-#if APPLE_OSX_mDNSResponder
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameTooLong", "noop", typeBuf, "");
-#endif
}
if (len < 2 || len >= 0x40 || (len > 16 && !SameDomainName(domain, &localdomain))) return(mDNSNULL);
if (src[1] != '_') { errormsg = "Application protocol name must begin with underscore"; goto fail; }
@@ -1049,19 +1054,13 @@ mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
if (src[i] == '_' && loggedUnderscore == mDNSfalse)
{
ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithUnderscore", "noop", typeBuf, "");
+ LogInfo("ConstructServiceName: Service type with non-leading underscore %s", typeBuf);
loggedUnderscore = mDNStrue;
}
#endif
continue;
}
errormsg = "Application protocol name must contain only letters, digits, and hyphens";
-#if APPLE_OSX_mDNSResponder
- {
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithIllegalCharacters", "noop", typeBuf, "");
- }
-#endif
goto fail;
}
for (i=0; i<=len; i++) *dst++ = *src++;
@@ -1165,7 +1164,8 @@ mDNSexport const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3
const mDNSu8 hash[NSEC3_MAX_HASH_LEN], int *dlen)
{
AlgContext *ctx;
- int i;
+ unsigned int i;
+ unsigned int iterations;
domainname lname;
mDNSu8 *p = (mDNSu8 *)&nsec3->salt;
const mDNSu8 *digest;
@@ -1183,7 +1183,8 @@ mDNSexport const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3
// Note that it is "i <=". The first iteration is for digesting the name and salt.
// The iteration count does not include that.
- for (i = 0; i <= swap16(nsec3->iterations); i++)
+ iterations = swap16(nsec3->iterations);
+ for (i = 0; i <= iterations; i++)
{
ctx = AlgCreate(DIGEST_ALG, nsec3->alg);
if (!ctx)
@@ -1367,17 +1368,14 @@ mDNSexport void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mD
if (InterfaceID == mDNSInterface_LocalOnly && artype != AuthRecordLocalOnly)
{
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch LocalOnly record InterfaceID %p called with artype %d", InterfaceID, artype);
- return;
}
else if (InterfaceID == mDNSInterface_P2P && artype != AuthRecordP2P)
{
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch P2P record InterfaceID %p called with artype %d", InterfaceID, artype);
- return;
}
else if (!InterfaceID && (artype == AuthRecordP2P || artype == AuthRecordLocalOnly))
{
LogMsg("mDNS_SetupResourceRecord: ERROR!! Mismatch InterfaceAny record InterfaceID %p called with artype %d", InterfaceID, artype);
- return;
}
// Don't try to store a TTL bigger than we can represent in platform time units
@@ -1467,8 +1465,6 @@ mDNSexport void mDNS_SetupQuestion(DNSQuestion *const q, const mDNSInterfaceID I
q->ForceMCast = mDNSfalse;
q->ReturnIntermed = mDNSfalse;
q->SuppressUnusable = mDNSfalse;
- q->DenyOnCellInterface = mDNSfalse;
- q->DenyOnExpInterface = mDNSfalse;
q->SearchListIndex = 0;
q->AppendSearchDomains = 0;
q->RetryWithSearchDomains = mDNSfalse;
@@ -1779,7 +1775,7 @@ mDNSexport mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr
// LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
// are handled in LocalOnlyRecordAnswersQuestion
- if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
+ if (LocalOnlyOrP2PInterface(rr->InterfaceID))
{
LogMsg("SameNameRecordAnswersQuestion: ERROR!! called with LocalOnly ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
return mDNSfalse;
@@ -1914,7 +1910,7 @@ mDNSexport mDNSBool AnyTypeRecordAnswersQuestion(const ResourceRecord *const rr,
{
// LocalOnly/P2P questions can be answered with AuthRecordAny in this function. LocalOnly/P2P records
// are handled in LocalOnlyRecordAnswersQuestion
- if ((rr->InterfaceID == mDNSInterface_LocalOnly) || (rr->InterfaceID == mDNSInterface_P2P))
+ if (LocalOnlyOrP2PInterface(rr->InterfaceID))
{
LogMsg("AnyTypeRecordAnswersQuestion: ERROR!! called with LocalOnly ResourceRecord %p, Question %p", rr->InterfaceID, q->InterfaceID);
return mDNSfalse;
@@ -2142,7 +2138,6 @@ mDNSexport const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const
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
@@ -2305,12 +2300,12 @@ mDNSexport mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNS
int len = 0;
const rdataOPT *opt;
const rdataOPT *const end = (const rdataOPT *)&rr->rdata->u.data[rr->rdlength];
- for (opt = &rr->rdata->u.opt[0]; opt < end; opt++)
+ for (opt = &rr->rdata->u.opt[0]; opt < end; opt++)
len += DNSOpt_Data_Space(opt);
- if (ptr + len > limit)
- {
- LogMsg("ERROR: putOptRData - out of space");
- return mDNSNULL;
+ if (ptr + len > limit)
+ {
+ LogMsg("ERROR: putOptRData - out of space");
+ return mDNSNULL;
}
for (opt = &rr->rdata->u.opt[0]; opt < end; opt++)
{
@@ -2754,12 +2749,12 @@ mDNSexport const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8
while (1) // Read sequence of labels
{
+ int i;
+ mDNSu16 offset;
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); }
@@ -2843,7 +2838,7 @@ mDNSlocal mDNSu8 *SanityCheckBitMap(const mDNSu8 *bmap, const mDNSu8 *end, int l
// (domainnames are expanded to 255 bytes) when stored in memory.
//
// This function can also be called with "NULL" msg to parse a single resource record pointed to by ptr.
-// The caller can do this only if the names in the resource records are compressed and validity of the
+// The caller can do this only if the names in the resource records are not compressed and validity of the
// resource record has already been done before. DNSSEC currently uses it this way.
mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *end,
LargeCacheRecord *const largecr, mDNSu16 rdlength)
@@ -3293,7 +3288,7 @@ mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, con
{
LogInfo("SetRData: nsec3 iteration count %d too big", swap16(nsec3->iterations));
goto fail;
- }
+ }
p += nsec3->saltLength;
// There should at least be one byte beyond saltLength
if (p >= end)
@@ -3348,6 +3343,12 @@ mDNSexport mDNSBool SetRData(const DNSMessage *const msg, const mDNSu8 *ptr, con
dlen = DomainNameLength(&name);
rlen = end - ptr;
rr->resrec.rdlength = dlen + rlen;
+ if (rr->resrec.rdlength > MaximumRDSize)
+ {
+ LogInfo("SetRData: Malformed TSIG/TKEY rdlength %d, rr->resrec.rdlength %d, "
+ "bmaplen %d, name %##s", rdlength, rr->resrec.rdlength, name.c);
+ goto fail;
+ }
AssignDomainName((domainname *)rdb->data, &name);
mDNSPlatformMemCopy(rdb->data + dlen, ptr, rlen);
break;
@@ -3451,12 +3452,6 @@ mDNSexport const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage
rr->CRActiveQuestion = mDNSNULL;
rr->UnansweredQueries = 0;
rr->LastUnansweredTime= 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- rr->MPUnansweredQ = 0;
- rr->MPLastUnansweredQT= 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
-#endif
rr->NextInCFList = mDNSNULL;
rr->resrec.InterfaceID = InterfaceID;
@@ -3611,22 +3606,33 @@ mDNSexport const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const
}
// Get the lease life of records in a dynamic update
-// returns 0 on error or if no lease present
-mDNSexport mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end)
+mDNSexport mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease)
{
- mDNSu32 result = 0;
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
- if (ptr) ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr && m->rec.r.resrec.rdlength >= DNSOpt_LeaseData_Space && m->rec.r.resrec.rdata->u.opt[0].opt == kDNSOpt_Lease)
- result = m->rec.r.resrec.rdata->u.opt[0].u.updatelease;
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- return(result);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
+ if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *o;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
+ if (o->opt == kDNSOpt_Lease)
+ {
+ *lease = o->u.updatelease;
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ return mDNStrue;
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+ return mDNSfalse;
}
mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end, int count, char *label)
{
int i;
- LogMsg("%2d %s", count, label);
+ LogInfo("%2d %s", count, label);
for (i = 0; i < count && ptr; i++)
{
// This puts a LargeCacheRecord on the stack instead of using the shared m->rec storage,
@@ -3634,9 +3640,11 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg,
// embedded systems) putting a 9kB object on the stack isn't a big problem.
LargeCacheRecord largecr;
ptr = GetLargeResourceRecord(m, msg, ptr, end, mDNSInterface_Any, kDNSRecordTypePacketAns, &largecr);
- if (ptr) LogMsg("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
+ if (ptr)
+ LogInfo("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
}
- if (!ptr) LogMsg("DumpRecords: ERROR: Premature end of packet data");
+ if (!ptr)
+ LogInfo("DumpRecords: ERROR: Premature end of packet data");
return(ptr);
}
@@ -3646,7 +3654,9 @@ mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg,
(X) == kDNSFlag0_OP_Status ? "Status " : \
(X) == kDNSFlag0_OP_Unused3 ? "Unused3 " : \
(X) == kDNSFlag0_OP_Notify ? "Notify " : \
- (X) == kDNSFlag0_OP_Update ? "Update " : "?? " )
+ (X) == kDNSFlag0_OP_Update ? "Update " : \
+ (X) == kDNSFlag0_OP_Subscribe? "Subscribe": \
+ (X) == kDNSFlag0_OP_UnSubscribe? "UnSubscribe" : "?? " )
#define DNS_RC_Name(X) ( \
(X) == kDNSFlag1_RC_NoErr ? "NoErr" : \
@@ -3678,7 +3688,7 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
if (dstaddr || !mDNSIPPortIsZero(dstport))
dbuffer[mDNS_snprintf(dbuffer, sizeof(dbuffer), " to %#a:%d", dstaddr, mDNSVal16(dstport))] = 0;
- LogMsg("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
+ LogInfo("-- %s %s DNS %s%s (flags %02X%02X) RCODE: %s (%d) %s%s%s%s%s%sID: %d %d bytes from %s%d%s%s --",
tbuffer, transport,
DNS_OP_Name(msg->h.flags.b[0] & kDNSFlag0_OP_Mask),
msg->h.flags.b[0] & kDNSFlag0_QR_Response ? "Response" : "Query",
@@ -3697,16 +3707,16 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
(msg->h.flags.b[0] & kDNSFlag0_TC) ? " (truncated)" : ""
);
- LogMsg("%2d %s", msg->h.numQuestions, IsUpdate ? "Zone" : "Questions");
+ LogInfo("%2d %s", msg->h.numQuestions, IsUpdate ? "Zone" : "Questions");
for (i = 0; i < msg->h.numQuestions && ptr; i++)
{
ptr = getQuestion(msg, ptr, end, mDNSInterface_Any, &q);
- if (ptr) LogMsg("%2d %##s %s", i, q.qname.c, DNSTypeName(q.qtype));
+ if (ptr) LogInfo("%2d %##s %s", i, q.qname.c, DNSTypeName(q.qtype));
}
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAnswers, IsUpdate ? "Prerequisites" : "Answers");
ptr = DumpRecords(m, msg, ptr, end, msg->h.numAuthorities, IsUpdate ? "Updates" : "Authorities");
DumpRecords(m, msg, ptr, end, msg->h.numAdditionals, "Additionals");
- LogMsg("--------------");
+ LogInfo("--------------");
}
// ***************************************************************************
@@ -3715,6 +3725,10 @@ mDNSexport void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *t
#pragma mark - Packet Sending Functions
#endif
+#ifdef UNIT_TEST
+// Run the unit test of mDNSSendDNSMessage
+UNITTEST_SENDDNSMESSAGE
+#else
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
@@ -3723,7 +3737,7 @@ struct UDPSocket_struct { mDNSIPPort port; /* ... */ };
// Note: When we sign a DNS message using DNSDigest_SignMessage(), the current real-time clock value is used, which
// is why we generally defer signing until we send the message, to ensure the signature is as fresh as possible.
mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
- mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
+ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo,
mDNSBool useBackgroundTrafficClass)
{
@@ -3808,19 +3822,15 @@ mDNSexport mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNS
SwapDNSHeaderBytes(msg);
// Dump the packet with the HINFO and TSIG
- if (mDNS_PacketLoggingEnabled && !mDNSOpaque16IsZero(msg->h.id)) {
- mDNSIPPort port = MulticastDNSPort;
- DumpPacket(m, status, mDNStrue,
- sock && (sock->flags & kTCPSocketFlags_UseTLS) ?
- "TLS" : sock ? "TCP" : "UDP", mDNSNULL,
- src ? src->port : port, dst, dstport, msg, end);
- }
+ if (mDNS_PacketLoggingEnabled && !mDNSOpaque16IsZero(msg->h.id))
+ DumpPacket(m, status, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", mDNSNULL, src ? src->port : MulticastDNSPort, dst, dstport, msg, end);
// put the number of additionals back the way it was
msg->h.numAdditionals = numAdditionals;
return(status);
}
+#endif // UNIT_TEST
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
@@ -3878,7 +3888,7 @@ mDNSlocal AuthRecord *AnyLocalRecordReady(const mDNS *const m)
mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
{
- mDNSs32 e = m->timenow + 0x78000000;
+ mDNSs32 e = m->timenow + FutureTime;
if (m->mDNSPlatformStatus != mStatus_NoError) return(e);
if (m->NewQuestions)
{
@@ -3901,6 +3911,10 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
if (e - m->NextScheduledSPS > 0) e = m->NextScheduledSPS;
if (e - m->NextScheduledKA > 0) e = m->NextScheduledKA;
+#if BONJOUR_ON_DEMAND
+ if (m->NextBonjourDisableTime && (e - m->NextBonjourDisableTime > 0)) e = m->NextBonjourDisableTime;
+#endif // BONJOUR_ON_DEMAND
+
// NextScheduledSPRetry only valid when DelaySleep not set
if (!m->DelaySleep && m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry;
if (m->DelaySleep && e - m->DelaySleep > 0) e = m->DelaySleep;
@@ -3916,6 +3930,9 @@ mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
if (e - m->NextScheduledResponse > 0) e = m->NextScheduledResponse;
}
if (e - m->NextScheduledStopTime > 0) e = m->NextScheduledStopTime;
+
+ if (m->NextBLEServiceTime && (e - m->NextBLEServiceTime > 0)) e = m->NextBLEServiceTime;
+
return(e);
}
@@ -4045,7 +4062,8 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
for (c = *fmt; c != 0; c = *++fmt)
{
- if (c != '%')
+ unsigned long n;
+ if (c != '%')
{
*sbuffer++ = (char)c;
if (++nwritten >= buflen) goto exit;
@@ -4101,7 +4119,6 @@ mDNSexport mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt
conv:
switch (c) // perform appropriate conversion
{
- unsigned long n;
case 'h': F.hSize = 1; c = *++fmt; goto conv;
case 'l': // fall through
case 'L': F.lSize = 1; c = *++fmt; goto conv;
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h
index e51b06dd7a..1e0e09abe1 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSCommon.h
@@ -40,17 +40,19 @@ extern "C" {
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_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_Subscribe = 0x06,
+ kDNSFlag0_OP_UnSubscribe = 0x07,
+ 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,
@@ -84,6 +86,7 @@ typedef enum
TSIG_ErrBadTime = 18
} TSIG_ErrorCode;
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
@@ -237,8 +240,7 @@ extern const mDNSu8 *NSEC3HashName(const domainname *name, rdataNSEC3 *nsec3, co
#pragma mark - DNS Message Parsing Functions
#endif
-#define AuthHashSlot(X) (DomainNameHashValue(X) % AUTH_HASH_SLOTS)
-#define HashSlot(X) (DomainNameHashValue(X) % CACHE_HASH_SLOTS)
+#define HashSlotFromNameHash(X) ((X) % CACHE_HASH_SLOTS)
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);
@@ -257,7 +259,7 @@ extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8
extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
extern const mDNSu8 *LocateOptRR(const DNSMessage *const msg, const mDNSu8 *const end, int minsize);
extern const rdataOPT *GetLLQOptData(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end);
-extern mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end);
+extern mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease);
extern void DumpPacket(mDNS *const m, mStatus status, mDNSBool sent, char *transport,
const mDNSAddr *srcaddr, mDNSIPPort srcport,
const mDNSAddr *dstaddr, mDNSIPPort dstport, const DNSMessage *const msg, const mDNSu8 *const end);
@@ -275,7 +277,7 @@ extern mDNSu32 swap32(mDNSu32 x);
#endif
extern mStatus mDNSSendDNSMessage(mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
- mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
+ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo,
mDNSBool useBackgroundTrafficClass);
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c b/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c
index 6520ac6f6e..0f8b32b082 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSDigest.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/DNSDigest.c
@@ -1,7 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2011 Apple Inc. All rights reserved.
- * Copyright (c) 2016 by Delphix. 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.
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c b/usr/src/contrib/mDNSResponder/mDNSCore/anonymous.c
index 184de13788..107dc177ac 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/anonymous.c
@@ -25,7 +25,7 @@
#ifndef ANONYMOUS_DISABLED
-#define ANON_NSEC3_ITERATIONS 1
+#define ANON_NSEC3_ITERATIONS 1
struct AnonInfoResourceRecord_struct
{
@@ -71,7 +71,7 @@ mDNSlocal mDNSBool InitializeNSEC3Record(ResourceRecord *rr, const mDNSu8 *AnonD
// Hash the base service name + salt + AnonData
if (!NSEC3HashName(rr->name, nsec3, AnonData, len, hashName, &hlen))
{
- LogMsg("InitializeNSEC3Record: NSEC3HashName failed for ##s", rr->name->c);
+ LogMsg("InitializeNSEC3Record: NSEC3HashName failed for %##s", rr->name->c);
return mDNSfalse;
}
if (hlen != SHA1_HASH_LENGTH)
@@ -98,8 +98,8 @@ mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const
}
dlen = DomainNameLength(service);
-
- // Allocate space for the name and RData.
+
+ // Allocate space for the name and RData.
rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + dlen + sizeof(RData));
if (!rr)
return mDNSNULL;
@@ -236,10 +236,16 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
LogMsg("SetAnonData: question %##s(%p), rr %##s(%p), NULL", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
return;
}
-
+
debugf("SetAnonData: question %##s(%p), rr %##s(%p)", q->qname.c, q->AnonInfo, rr->name->c, rr->AnonInfo);
if (ForQuestion)
{
+ if (q->AnonInfo->AnonDataLen < rr->AnonInfo->AnonDataLen)
+ {
+ mDNSPlatformMemFree(q->AnonInfo->AnonData);
+ q->AnonInfo->AnonData = mDNSNULL;
+ }
+
if (!q->AnonInfo->AnonData)
{
q->AnonInfo->AnonData = mDNSPlatformMemAllocate(rr->AnonInfo->AnonDataLen);
@@ -251,6 +257,12 @@ mDNSexport void SetAnonData(DNSQuestion *q, ResourceRecord *rr, mDNSBool ForQues
}
else
{
+ if (rr->AnonInfo->AnonDataLen < q->AnonInfo->AnonDataLen)
+ {
+ mDNSPlatformMemFree(rr->AnonInfo->AnonData);
+ rr->AnonInfo->AnonData = mDNSNULL;
+ }
+
if (!rr->AnonInfo->AnonData)
{
rr->AnonInfo->AnonData = mDNSPlatformMemAllocate(q->AnonInfo->AnonDataLen);
@@ -275,9 +287,10 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
int AnonDataLen;
rdataNSEC3 *nsec3;
int hlen;
- const mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
int nxtLength;
mDNSu8 *nxtName;
+ mDNSu8 hashName[NSEC3_MAX_HASH_LEN];
+ mDNSPlatformMemZero(hashName, sizeof(hashName));
debugf("AnonInfoAnswersQuestion: question qname %##s", q->qname.c);
@@ -289,7 +302,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
// We allow anonymous questions to be answered by both normal services (without the
// anonymous information) and anonymous services that are part of the same set. And
- // normal questions discover normal services and all anonymous services.
+ // normal questions discover normal services and all anonymous services.
//
// The three cases have been enumerated clearly even though they all behave the
// same way.
@@ -341,7 +354,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
//
// It is also possible that a local question is matched against the local AuthRecord
// as that is also the case for which the AnonData would be non-NULL for both.
- // We match questions against AuthRecords (rather than the cache) for LocalOnly case and
+ // We match questions against AuthRecords (rather than the cache) for LocalOnly case and
// to see whether a .local query should be suppressed or not. The latter never happens
// because PTR queries are never suppressed.
@@ -368,7 +381,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
// If there is AnonData, then this is a local question. The
// NSEC3 RR comes from the resource record which could be part
// of the cache or local auth record. The cache entry could
- // be from a remote host or created when we heard our own
+ // be from a remote host or created when we heard our own
// announcements. In any case, we use that to see if it matches
// the question.
AnonData = qai->AnonData;
@@ -398,7 +411,7 @@ mDNSexport int AnonInfoAnswersQuestion(const ResourceRecord *const rr, const DNS
if (!NSEC3HashName(nsec3RR->name, nsec3, AnonData, AnonDataLen, hashName, &hlen))
{
- LogMsg("AnonInfoAnswersQuestion: NSEC3HashName failed for ##s", nsec3RR->name->c);
+ LogMsg("AnonInfoAnswersQuestion: NSEC3HashName failed for %##s", nsec3RR->name->c);
return mDNSfalse;
}
if (hlen != SHA1_HASH_LENGTH)
@@ -434,7 +447,7 @@ mDNSlocal CacheRecord *FindMatchingNSEC3ForName(mDNS *const m, CacheRecord **nse
{
CacheRecord *cr;
CacheRecord **prev = nsec3;
-
+
(void) m;
for (cr = *nsec3; cr; cr = cr->next)
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h b/usr/src/contrib/mDNSResponder/mDNSCore/anonymous.h
index b60812ea0d..b60812ea0d 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/anonymous.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/anonymous.h
diff --git a/usr/src/contrib/mDNSResponder/mDNSCore/dnsproxy.h b/usr/src/contrib/mDNSResponder/mDNSCore/dnsproxy.h
new file mode 100644
index 0000000000..7008c058da
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/dnsproxy.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2011-2013 Apple 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.
+ */
+
+#ifndef __DNS_PROXY_H
+#define __DNS_PROXY_H
+
+#include "mDNSEmbeddedAPI.h"
+#include "DNSCommon.h"
+
+extern void ProxyUDPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+ const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
+extern void ProxyTCPCallback(void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+ const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
+extern void DNSProxyInit(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf);
+extern void DNSProxyTerminate(void);
+
+#endif // __DNS_PROXY_H
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h b/usr/src/contrib/mDNSResponder/mDNSCore/dnssec.h
index b770af8de0..b770af8de0 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/dnssec.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/dnssec.h
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c b/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c
index 69236e0b88..f51c22b287 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNS.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNS.c
@@ -45,10 +45,14 @@
#endif
#include "dns_sd.h" // for kDNSServiceFlags* definitions
+#include "dns_sd_internal.h"
#if APPLE_OSX_mDNSResponder
#include <WebFilterDNS/WebFilterDNS.h>
+// Delay in seconds before disabling multicast after there are no active queries or registrations.
+#define BONJOUR_DISABLE_DELAY 60
+
#if !NO_WCF
WCFConnection *WCFConnectionNew(void) __attribute__((weak_import));
void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
@@ -62,15 +66,22 @@ void WCFConnectionDealloc(WCFConnection* c) __attribute__((weak_import));
#define NO_WCF 1
#endif // APPLE_OSX_mDNSResponder
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
#include "Metrics.h"
#endif
+#if USE_DNS64
+#include "DNS64.h"
+#endif
+
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
+
// Forward declarations
mDNSlocal void BeginSleepProcessing(mDNS *const m);
mDNSlocal void RetrySPSRegistrations(mDNS *const m);
-mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password);
-mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
+mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password, mDNSBool unicastOnly);
mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q);
mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q);
@@ -106,16 +117,43 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
#define NR_AnswerMulticast (mDNSu8*)~0
#define NR_AnswerUnicast (mDNSu8*)~1
-// Defined to set the kDNSQClass_UnicastResponse bit in the first four query packets.
-// else, it's just set it the first query.
-#define mDNS_REQUEST_UNICAST_RESPONSE 0
+// Question default timeout values
+#define DEFAULT_MCAST_TIMEOUT 5
+#define DEFAULT_LO_OR_P2P_TIMEOUT 5
// The code (see SendQueries() and BuildQuestion()) needs to have the
// RequestUnicast value set to a value one greater than the number of times you want the query
// sent with the "request unicast response" (QU) bit set.
#define SET_QU_IN_FIRST_QUERY 2
-#define SET_QU_IN_FIRST_FOUR_QUERIES 5
+#define kDefaultRequestUnicastCount SET_QU_IN_FIRST_QUERY
+
+// The time needed to offload records to a sleep proxy after powerd sends the kIOMessageSystemWillSleep notification
+#define DARK_WAKE_DELAY_SLEEP 5
+#define kDarkWakeDelaySleep (mDNSPlatformOneSecond * DARK_WAKE_DELAY_SLEEP)
+
+// The maximum number of times we delay probing to prevent spurious conflicts due to stale packets
+#define MAX_CONFLICT_PROCESSING_DELAYS 3
+
+// RFC 6762 defines Passive Observation Of Failures (POOF)
+//
+// A host observes the multicast queries issued by the other hosts on
+// the network. One of the major benefits of also sending responses
+// using multicast is that it allows all hosts to see the responses
+// (or lack thereof) to those queries.
+//
+// If a host sees queries, for which a record in its cache would be
+// expected to be given as an answer in a multicast response, but no
+// such answer is seen, then the host may take this as an indication
+// that the record may no longer be valid.
+//
+// After seeing two or more of these queries, and seeing no multicast
+// response containing the expected answer within ten seconds, then even
+// though its TTL may indicate that it is not yet due to expire, that
+// record SHOULD be flushed from the cache.
+//
+// <https://tools.ietf.org/html/rfc6762#section-10.5>
+#define POOF_ENABLED 1
mDNSexport const char *const mDNS_DomainTypeNames[] =
{
@@ -136,8 +174,8 @@ mDNSexport const char *const mDNS_DomainTypeNames[] =
#pragma mark - General Utility Functions
#endif
-// Returns true if this is a unique, authoritative LocalOnly record that answers questions of type
-// A, AAAA , CNAME, or PTR. The caller should answer the question with this record and not send out
+// Returns true if this is a unique, authoritative LocalOnly record that answers questions of type
+// A, AAAA , CNAME, or PTR. The caller should answer the question with this record and not send out
// the question on the wire if LocalOnlyRecordAnswersQuestion() also returns true.
// Main use is to handle /etc/hosts records and the LocalOnly PTR records created for localhost.
#define UniqueLocalOnlyRecord(rr) ((rr)->ARType == AuthRecordLocalOnly && \
@@ -248,24 +286,27 @@ mDNSlocal AuthEntity *GetAuthEntity(AuthHash *r, const AuthGroup *const Preserve
return(e);
}
-mDNSexport AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
+mDNSexport AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name)
{
AuthGroup *ag;
+ const mDNSu32 slot = namehash % AUTH_HASH_SLOTS;
+
for (ag = r->rrauth_hash[slot]; ag; ag=ag->next)
if (ag->namehash == namehash && SameDomainName(ag->name, name))
break;
return(ag);
}
-mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSexport AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr)
{
- return(AuthGroupForName(r, slot, rr->namehash, rr->name));
+ return(AuthGroupForName(r, rr->namehash, rr->name));
}
-mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const ResourceRecord *const rr)
{
mDNSu16 namelen = DomainNameLength(rr->name);
AuthGroup *ag = (AuthGroup*)GetAuthEntity(r, mDNSNULL);
+ const mDNSu32 slot = rr->namehash % AUTH_HASH_SLOTS;
if (!ag) { LogMsg("GetAuthGroup: Failed to allocate memory for %##s", rr->name->c); return(mDNSNULL); }
ag->next = r->rrauth_hash[slot];
ag->namehash = rr->namehash;
@@ -284,9 +325,9 @@ mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const Resourc
}
AssignDomainName(ag->name, rr->name);
- if (AuthGroupForRecord(r, slot, rr)) LogMsg("GetAuthGroup: Already have AuthGroup for %##s", rr->name->c);
+ if (AuthGroupForRecord(r, rr)) LogMsg("GetAuthGroup: Already have AuthGroup for %##s", rr->name->c);
r->rrauth_hash[slot] = ag;
- if (AuthGroupForRecord(r, slot, rr) != ag) LogMsg("GetAuthGroup: Not finding AuthGroup for %##s", rr->name->c);
+ if (AuthGroupForRecord(r, rr) != ag) LogMsg("GetAuthGroup: Not finding AuthGroup for %##s", rr->name->c);
return(ag);
}
@@ -295,12 +336,12 @@ mDNSlocal AuthGroup *GetAuthGroup(AuthHash *r, const mDNSu32 slot, const Resourc
mDNSexport AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr)
{
AuthGroup *ag;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- ag = AuthGroupForRecord(r, slot, &rr->resrec);
- if (!ag) ag = GetAuthGroup(r, slot, &rr->resrec); // If we don't have a AuthGroup for this name, make one now
+
+ (void)m;
+ ag = AuthGroupForRecord(r, &rr->resrec);
+ if (!ag) ag = GetAuthGroup(r, &rr->resrec); // If we don't have a AuthGroup for this name, make one now
if (ag)
{
- LogInfo("InsertAuthRecord: inserting auth record %s from table", ARDisplayString(m, rr));
*(ag->rrauth_tail) = rr; // Append this record to tail of cache slot list
ag->rrauth_tail = &(rr->next); // Advance tail pointer
}
@@ -310,13 +351,11 @@ mDNSexport AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *r
mDNSexport AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr)
{
AuthGroup *a;
- AuthGroup **ag = &a;
AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) { LogMsg("RemoveAuthRecord: ERROR!! AuthGroup not found for %s", ARDisplayString(m, rr)); return mDNSNULL; }
- rp = &(*ag)->members;
+ rp = &a->members;
while (*rp)
{
if (*rp != rr)
@@ -330,22 +369,23 @@ mDNSexport AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *r
}
}
// TBD: If there are no more members, release authgroup ?
- (*ag)->rrauth_tail = rp;
+ a->rrauth_tail = rp;
return a;
}
-mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name)
+mDNSexport CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name)
{
CacheGroup *cg;
+ mDNSu32 slot = HashSlotFromNameHash(namehash);
for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
if (cg->namehash == namehash && SameDomainName(cg->name, name))
break;
return(cg);
}
-mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const mDNSu32 slot, const ResourceRecord *const rr)
+mDNSlocal CacheGroup *CacheGroupForRecord(const mDNS *const m, const ResourceRecord *const rr)
{
- return(CacheGroupForName(m, slot, rr->namehash, rr->name));
+ return(CacheGroupForName(m, rr->namehash, rr->name));
}
mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
@@ -391,7 +431,7 @@ mDNSlocal NetworkInterfaceInfo *FirstIPv4LLInterfaceForID(mDNS *const m, const m
if (!InterfaceID)
return mDNSNULL;
- // Note: We don't check for InterfaceActive, as the active interface could be IPv6 and
+ // Note: We don't check for InterfaceActive, as the active interface could be IPv6 and
// we still want to find the first IPv4 Link-Local interface
for (intf = m->HostInterfaces; intf; intf = intf->next)
{
@@ -412,14 +452,15 @@ mDNSexport char *InterfaceNameForID(mDNS *const m, const mDNSInterfaceID Interfa
}
// Caller should hold the lock
-mDNSlocal void GenerateNegativeResponse(mDNS *const m, QC_result qc)
+mDNSlocal void GenerateNegativeResponse(mDNS *const m, mDNSInterfaceID InterfaceID, QC_result qc)
{
DNSQuestion *q;
if (!m->CurrentQuestion) { LogMsg("GenerateNegativeResponse: ERROR!! CurrentQuestion not set"); return; }
q = m->CurrentQuestion;
LogInfo("GenerateNegativeResponse: Generating negative response for question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, mDNSInterface_Any, mDNSNULL);
+ MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, 60, InterfaceID, mDNSNULL);
+
// We need to force the response through in the following cases
//
// a) SuppressUnusable questions that are suppressed
@@ -446,29 +487,11 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
const mDNSu32 c = q->CNAMEReferrals + 1; // Stash a copy of the new q->CNAMEReferrals value
UDPSocket *sock = q->LocalSocket;
mDNSOpaque16 id = q->TargetQID;
-#if TARGET_OS_EMBEDDED
- domainname *originalQName;
+#if AWD_METRICS
+ uDNSMetrics metrics;
#endif
- // if there is a message waiting at the socket, we want to process that instead
- // of throwing it away. If we have a CNAME response that answers
- // both A and AAAA question and while answering it we don't want to throw
- // away the response where the actual addresses are present.
- // This is a stupid hack and we should get rid of it.
- // The chance of there being a second unicast UDP packet already waiting in the kernel before we’ve
- // finished processing the previous one is virtually nil, and will only happen by luck on very rare
- // occasions when running on a machine with a fast network connection and a slow or busy processor.
- // The idea that we’d rely for correctness on this random chance event occurring is ridiculous.
- // -- SC
- if (mDNSPlatformPeekUDP(m, q->LocalSocket))
- {
- LogInfo("AnswerQuestionByFollowingCNAME: Preserving UDP socket for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- q->LocalSocket = mDNSNULL;
- }
- else
- {
- sock = mDNSNULL;
- }
+ q->LocalSocket = mDNSNULL;
// The SameDomainName check above is to ignore bogus CNAME records that point right back at
// themselves. Without that check we can get into a case where we have two duplicate questions,
@@ -488,30 +511,25 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
LogInfo("AnswerQuestionByFollowingCNAME: %p %##s (%s) following CNAME referral %d for %s",
q, q->qname.c, DNSTypeName(q->qtype), q->CNAMEReferrals, RRDisplayString(m, rr));
-#if TARGET_OS_EMBEDDED
- if (q->metrics.originalQName)
+#if AWD_METRICS
+ if ((q->CNAMEReferrals == 0) && !q->metrics.originalQName)
{
- originalQName = q->metrics.originalQName;
- q->metrics.originalQName = mDNSNULL;
- }
- else
- {
- mDNSu16 qNameLen;
+ domainname * qName;
+ mDNSu16 qNameLen;
qNameLen = DomainNameLength(&q->qname);
if ((qNameLen > 0) && (qNameLen <= MAX_DOMAIN_NAME))
{
- originalQName = mDNSPlatformMemAllocate(qNameLen);
- if (originalQName)
+ qName = mDNSPlatformMemAllocate(qNameLen);
+ if (qName)
{
- mDNSPlatformMemCopy(originalQName->c, q->qname.c, qNameLen);
+ mDNSPlatformMemCopy(qName->c, q->qname.c, qNameLen);
+ q->metrics.originalQName = qName;
}
}
- else
- {
- originalQName = mDNSNULL;
- }
}
+ metrics = q->metrics;
+ mDNSPlatformMemZero(&q->metrics, sizeof(q->metrics));
#endif
mDNS_StopQuery_internal(m, q); // Stop old query
AssignDomainName(&q->qname, &rr->rdata->u.name); // Update qname
@@ -529,20 +547,97 @@ mDNSexport void AnswerQuestionByFollowingCNAME(mDNS *const m, DNSQuestion *q, Re
// Record how many times we've done this. We need to do this *after* mDNS_StartQuery_internal,
// because mDNS_StartQuery_internal re-initializes CNAMEReferrals to zero
q->CNAMEReferrals = c;
-#if TARGET_OS_EMBEDDED
- q->metrics.originalQName = originalQName;
+#if AWD_METRICS
+ q->metrics = metrics;
#endif
if (sock)
{
- // We have a message waiting and that should answer this question.
- if (q->LocalSocket)
- mDNSPlatformUDPClose(q->LocalSocket);
- q->LocalSocket = sock;
- q->TargetQID = id;
+ // If our new query is a duplicate, then it can't have a socket of its own, so we have to close the one we saved.
+ if (q->DuplicateOf) mDNSPlatformUDPClose(sock);
+ else
+ {
+ // Transplant the old socket into the new question, and copy the query ID across too.
+ // No need to close the old q->LocalSocket value because it won't have been created yet (they're made lazily on-demand).
+ q->LocalSocket = sock;
+ q->TargetQID = id;
+ }
}
}
}
+#ifdef USE_LIBIDN
+
+#include <unicode/uidna.h>
+
+// #define DEBUG_PUNYCODE 1
+
+mDNSlocal mDNSu8 *PunycodeConvert(const mDNSu8 *const src, mDNSu8 *const dst, const mDNSu8 *const end)
+{
+ UErrorCode errorCode = U_ZERO_ERROR;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UIDNA *uts46 = uidna_openUTS46(UIDNA_USE_STD3_RULES|UIDNA_NONTRANSITIONAL_TO_UNICODE, &errorCode);
+ int32_t len = uidna_nameToASCII_UTF8(uts46, (const char *)src+1, src[0], (char *)dst+1, end-(dst+1), &info, &errorCode);
+ uidna_close(uts46);
+ #if DEBUG_PUNYCODE
+ if (errorCode) LogMsg("uidna_nameToASCII_UTF8(%##s) failed errorCode %d", src, errorCode);
+ if (info.errors) LogMsg("uidna_nameToASCII_UTF8(%##s) failed info.errors 0x%08X", src, info.errors);
+ if (len > MAX_DOMAIN_LABEL) LogMsg("uidna_nameToASCII_UTF8(%##s) result too long %d", src, len);
+ #endif
+ if (errorCode || info.errors || len > MAX_DOMAIN_LABEL) return mDNSNULL;
+ *dst = len;
+ return(dst + 1 + len);
+}
+
+mDNSlocal mDNSBool IsHighASCIILabel(const mDNSu8 *d)
+{
+ int i;
+ for (i=1; i<=d[0]; i++) if (d[i] & 0x80) return mDNStrue;
+ return mDNSfalse;
+}
+
+mDNSlocal const mDNSu8 *FindLastHighASCIILabel(const domainname *const d)
+{
+ const mDNSu8 *ptr = d->c;
+ const mDNSu8 *ans = mDNSNULL;
+ while (ptr[0])
+ {
+ const mDNSu8 *const next = ptr + 1 + ptr[0];
+ if (ptr[0] > MAX_DOMAIN_LABEL || next >= d->c + MAX_DOMAIN_NAME) return mDNSNULL;
+ if (IsHighASCIILabel(ptr)) ans = ptr;
+ ptr = next;
+ }
+ return ans;
+}
+
+mDNSlocal mDNSBool PerformNextPunycodeConversion(const DNSQuestion *const q, domainname *const newname)
+{
+ const mDNSu8 *h = FindLastHighASCIILabel(&q->qname);
+ #if DEBUG_PUNYCODE
+ LogMsg("PerformNextPunycodeConversion: %##s (%s) Last High-ASCII Label %##s", q->qname.c, DNSTypeName(q->qtype), h);
+ #endif
+ if (!h) return mDNSfalse; // There are no high-ascii labels to convert
+
+ mDNSu8 *const dst = PunycodeConvert(h, newname->c + (h - q->qname.c), newname->c + MAX_DOMAIN_NAME);
+ if (!dst)
+ return mDNSfalse; // The label was not convertible to Punycode
+ else
+ {
+ // If Punycode conversion of final eligible label was successful, copy the rest of the domainname
+ const mDNSu8 *const src = h + 1 + h[0];
+ const mDNSu8 remainder = DomainNameLength((domainname*)src);
+ if (dst + remainder > newname->c + MAX_DOMAIN_NAME) return mDNSfalse; // Name too long -- cannot be converted to Punycode
+
+ mDNSPlatformMemCopy(newname->c, q->qname.c, h - q->qname.c); // Fill in the leading part
+ mDNSPlatformMemCopy(dst, src, remainder); // Fill in the trailing part
+ #if DEBUG_PUNYCODE
+ LogMsg("PerformNextPunycodeConversion: %##s converted to %##s", q->qname.c, newname->c);
+ #endif
+ return mDNStrue;
+ }
+}
+
+#endif // USE_LIBIDN
+
// For a single given DNSQuestion pointed to by CurrentQuestion, deliver an add/remove result for the single given AuthRecord
// Note: All the callers should use the m->CurrentQuestion to see if the question is still valid or not
mDNSlocal void AnswerLocalQuestionWithLocalAuthRecord(mDNS *const m, AuthRecord *rr, QC_result AddRecord)
@@ -707,7 +802,6 @@ mDNSlocal void AnswerAllLocalQuestionsWithLocalAuthRecord(mDNS *const m, AuthRec
(X) &kDNSRecordTypeActiveUniqueMask ? DefaultAnnounceIntervalForTypeUnique : 0)
#define TimeToAnnounceThisRecord(RR,time) ((RR)->AnnounceCount && (time) - ((RR)->LastAPTime + (RR)->ThisAPInterval) >= 0)
-#define TimeToSendThisRecord(RR,time) ((TimeToAnnounceThisRecord(RR,time) || (RR)->ImmedAnswer) && ResourceRecordIsValidAnswer(RR))
#define TicksTTL(RR) ((mDNSs32)(RR)->resrec.rroriginalttl * mDNSPlatformOneSecond)
#define RRExpireTime(RR) ((RR)->TimeRcvd + TicksTTL(RR))
@@ -766,6 +860,8 @@ mDNSlocal mDNSBool PacketRRMatchesSignature(const CacheRecord *const pktrr, cons
pktrr->resrec.InterfaceID != authrr->resrec.InterfaceID) return(mDNSfalse);
if (!(authrr->resrec.RecordType & kDNSRecordTypeUniqueMask) || authrr->WakeUp.HMAC.l[0])
if (pktrr->resrec.rrtype != authrr->resrec.rrtype) return(mDNSfalse);
+ if ((authrr->resrec.InterfaceID == mDNSInterface_Any) &&
+ !mDNSPlatformValidRecordForInterface(authrr, pktrr->resrec.InterfaceID)) return(mDNSfalse);
return (mDNSBool)(
pktrr->resrec.rrclass == authrr->resrec.rrclass &&
pktrr->resrec.namehash == authrr->resrec.namehash &&
@@ -843,11 +939,12 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
if (m->SuppressProbes == 0 || m->SuppressProbes - m->timenow < 0)
{
// To allow us to aggregate probes when a group of services are registered together,
- // the first probe is delayed 1/4 second. This means the common-case behaviour is:
- // 1/4 second wait; probe
+ // the first probe is delayed by a random delay in the range 1/8 to 1/4 second.
+ // This means the common-case behaviour is:
+ // randomized wait; probe
// 1/4 second wait; probe
// 1/4 second wait; probe
- // 1/4 second wait; announce (i.e. service is normally announced exactly one second after being registered)
+ // 1/4 second wait; announce (i.e. service is normally announced 7/8 to 1 second after being registered)
m->SuppressProbes = NonZeroTime(m->timenow + DefaultProbeIntervalForTypeUnique/2 + mDNSRandom(DefaultProbeIntervalForTypeUnique/2));
// If we already have a *probe* scheduled to go out sooner, then use that time to get better aggregation
@@ -879,7 +976,9 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
}
rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval;
}
- else if (m->SuppressProbes && m->SuppressProbes - m->timenow >= 0)
+ // Skip kDNSRecordTypeKnownUnique and kDNSRecordTypeShared records here and set their LastAPTime in the "else" block below so
+ // that they get announced immediately, otherwise, their announcement would be delayed until the based on the SuppressProbes value.
+ else if ((rr->resrec.RecordType != kDNSRecordTypeKnownUnique) && (rr->resrec.RecordType != kDNSRecordTypeShared) && m->SuppressProbes && (m->SuppressProbes - m->timenow >= 0))
rr->LastAPTime = m->SuppressProbes - rr->ThisAPInterval + DefaultProbeIntervalForTypeUnique * DefaultProbeCountForTypeUnique + rr->ThisAPInterval / 2;
else
rr->LastAPTime = m->timenow - rr->ThisAPInterval;
@@ -890,7 +989,7 @@ mDNSlocal void InitializeLastAPTime(mDNS *const m, AuthRecord *const rr)
// and we can begin broadcasting our announcements to take over ownership of that IP address.
// If we don't wait for the client to go to sleep, then when the client sees our ARP Announcements there's a risk
// (depending on the OS and networking stack it's using) that it might interpret it as a conflict and change its IP address.
- if (rr->AddressProxy.type)
+ if (rr->AddressProxy.type)
rr->LastAPTime = m->timenow;
// Set LastMCTime to now, to inhibit multicast responses
@@ -1068,26 +1167,24 @@ mDNSexport void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr)
mDNSlocal AuthRecord *CheckAuthIdenticalRecord(AuthHash *r, AuthRecord *rr)
{
- AuthGroup *a;
- AuthGroup **ag = &a;
- AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
+ const AuthGroup *a;
+ AuthRecord *rp;
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSNULL;
- rp = &(*ag)->members;
- while (*rp)
+ rp = a->members;
+ while (rp)
{
- if (!RecordIsLocalDuplicate(*rp, rr))
- rp=&(*rp)->next;
+ if (!RecordIsLocalDuplicate(rp, rr))
+ rp = rp->next;
else
{
- if ((*rp)->resrec.RecordType == kDNSRecordTypeDeregistering)
+ if (rp->resrec.RecordType == kDNSRecordTypeDeregistering)
{
- (*rp)->AnnounceCount = 0;
- rp=&(*rp)->next;
+ rp->AnnounceCount = 0;
+ rp = rp->next;
}
- else return *rp;
+ else return rp;
}
}
return (mDNSNULL);
@@ -1095,22 +1192,20 @@ mDNSlocal AuthRecord *CheckAuthIdenticalRecord(AuthHash *r, AuthRecord *rr)
mDNSlocal mDNSBool CheckAuthRecordConflict(AuthHash *r, AuthRecord *rr)
{
- AuthGroup *a;
- AuthGroup **ag = &a;
- AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
+ const AuthGroup *a;
+ const AuthRecord *rp;
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSfalse;
- rp = &(*ag)->members;
- while (*rp)
+ rp = a->members;
+ while (rp)
{
const AuthRecord *s1 = rr->RRSet ? rr->RRSet : rr;
- const AuthRecord *s2 = (*rp)->RRSet ? (*rp)->RRSet : *rp;
- if (s1 != s2 && SameResourceRecordSignature((*rp), rr) && !IdenticalSameNameRecord(&(*rp)->resrec, &rr->resrec))
+ const AuthRecord *s2 = rp->RRSet ? rp->RRSet : rp;
+ if (s1 != s2 && SameResourceRecordSignature(rp, rr) && !IdenticalSameNameRecord(&rp->resrec, &rr->resrec))
return mDNStrue;
else
- rp=&(*rp)->next;
+ rp = rp->next;
}
return (mDNSfalse);
}
@@ -1118,21 +1213,19 @@ mDNSlocal mDNSBool CheckAuthRecordConflict(AuthHash *r, AuthRecord *rr)
// checks to see if "rr" is already present
mDNSlocal AuthRecord *CheckAuthSameRecord(AuthHash *r, AuthRecord *rr)
{
- AuthGroup *a;
- AuthGroup **ag = &a;
- AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
+ const AuthGroup *a;
+ AuthRecord *rp;
- a = AuthGroupForRecord(r, slot, &rr->resrec);
+ a = AuthGroupForRecord(r, &rr->resrec);
if (!a) return mDNSNULL;
- rp = &(*ag)->members;
- while (*rp)
+ rp = a->members;
+ while (rp)
{
- if (*rp != rr)
- rp=&(*rp)->next;
+ if (rp != rr)
+ rp = rp->next;
else
{
- return *rp;
+ return rp;
}
}
return (mDNSNULL);
@@ -1158,20 +1251,22 @@ mDNSlocal void DecrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
LogInfo("DecrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
}
-#if TARGET_OS_WATCH
+#if BONJOUR_ON_DEMAND
if (!AuthRecord_uDNS(rr))
{
if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
- m->NetworkChanged = m->timenow;
+ m->NextBonjourDisableTime = NonZeroTime(m->timenow + (BONJOUR_DISABLE_DELAY * mDNSPlatformOneSecond));
m->NumAllInterfaceRecords--;
LogInfo("DecrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
}
-#endif
+#endif // BONJOUR_ON_DEMAND
}
mDNSlocal void IncrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
{
+ mDNSBool enablingBonjour = 0;
+
if (RRLocalOnly(rr))
{
// A sanity check, this should be prevented in calling code.
@@ -1179,34 +1274,51 @@ mDNSlocal void IncrementAutoTargetServices(mDNS *const m, AuthRecord *const rr)
return;
}
-#if TARGET_OS_WATCH
+#if BONJOUR_ON_DEMAND
if (!AuthRecord_uDNS(rr))
{
m->NumAllInterfaceRecords++;
LogInfo("IncrementAutoTargetServices: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %s",
m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, ARDisplayString(m, rr));
if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
- m->NetworkChanged = m->timenow;
+ {
+ m->NextBonjourDisableTime = 0;
+ if (m->BonjourEnabled == 0)
+ {
+ // Enable Bonjour immediately by scheduling network changed processing where
+ // we will join the multicast group on each active interface.
+ m->BonjourEnabled = 1;
+ enablingBonjour = 1;
+ m->NetworkChanged = m->timenow;
+ }
+ }
}
-#endif
+#endif // BONJOUR_ON_DEMAND
if (!AuthRecord_uDNS(rr) && rr->resrec.rrtype == kDNSType_SRV && rr->AutoTarget == Target_AutoHost)
{
m->AutoTargetServices++;
LogInfo("IncrementAutoTargetServices: AutoTargetServices %d Record %s", m->AutoTargetServices, ARDisplayString(m, rr));
- // If this is the first advertised service
- if (m->AutoTargetServices == 1)
+
+ // If this is the first advertised service and we did not just enable Bonjour above, then
+ // advertise all the interface records. If we did enable Bonjour above, the interface records will
+ // be advertised during the network changed processing scheduled above, so no need
+ // to do it here.
+ if ((m->AutoTargetServices == 1) && (enablingBonjour == 0))
AdvertiseAllInterfaceRecords(m);
}
}
mDNSlocal void getKeepaliveRaddr(mDNS *const m, AuthRecord *rr, mDNSAddr *raddr)
{
- mDNSAddr laddr;
- mDNSEthAddr eth;
- mDNSIPPort lport, rport;
- mDNSu32 timeout, seq, ack;
- mDNSu16 win;
+ mDNSAddr laddr = zeroAddr;
+ mDNSEthAddr eth = zeroEthAddr;
+ mDNSIPPort lport = zeroIPPort;
+ mDNSIPPort rport = zeroIPPort;
+ mDNSu32 timeout = 0;
+ mDNSu32 seq = 0;
+ mDNSu32 ack = 0;
+ mDNSu16 win = 0;
if (mDNS_KeepaliveRecord(&rr->resrec))
{
@@ -1285,9 +1397,9 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
{
if (rr->resrec.RecordType == kDNSRecordTypeUnique)
rr->resrec.RecordType = kDNSRecordTypeVerified;
- else
+ else if (rr->resrec.RecordType != kDNSRecordTypeKnownUnique)
{
- LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique",
+ LogMsg("mDNS_Register_internal: ERROR! %##s (%s): rr->DependentOn && RecordType != kDNSRecordTypeUnique or kDNSRecordTypeKnownUnique",
rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
return(mStatus_Invalid);
}
@@ -1305,15 +1417,15 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
// Set up by client prior to call
// Field Group 2: Persistent metadata for Authoritative Records
-// rr->Additional1 = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
-// rr->Additional2 = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
-// rr->DependentOn = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
-// rr->RRSet = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
-// rr->Callback = already set in mDNS_SetupResourceRecord
-// rr->Context = already set in mDNS_SetupResourceRecord
-// rr->RecordType = already set in mDNS_SetupResourceRecord
-// rr->HostTarget = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
-// rr->AllowRemoteQuery = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
+// rr->Additional1 = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
+// rr->Additional2 = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
+// rr->DependentOn = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
+// rr->RRSet = set to mDNSNULL in mDNS_SetupResourceRecord; may be overridden by client
+// rr->Callback = already set in mDNS_SetupResourceRecord
+// rr->Context = already set in mDNS_SetupResourceRecord
+// rr->RecordType = already set in mDNS_SetupResourceRecord
+// rr->HostTarget = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
+// rr->AllowRemoteQuery = set to mDNSfalse in mDNS_SetupResourceRecord; may be overridden by client
// Make sure target is not uninitialized data, or we may crash writing debugging log messages
if (rr->AutoTarget && target) target->c[0] = 0;
@@ -1336,9 +1448,9 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
rr->NR_AnswerTo = mDNSNULL;
rr->NR_AdditionalTo = mDNSNULL;
if (!rr->AutoTarget) InitializeLastAPTime(m, rr);
-// rr->LastAPTime = Set for us in InitializeLastAPTime()
-// rr->LastMCTime = Set for us in InitializeLastAPTime()
-// rr->LastMCInterface = Set for us in InitializeLastAPTime()
+// rr->LastAPTime = Set for us in InitializeLastAPTime()
+// rr->LastMCTime = Set for us in InitializeLastAPTime()
+// rr->LastMCInterface = Set for us in InitializeLastAPTime()
rr->NewRData = mDNSNULL;
rr->newrdlength = 0;
rr->UpdateCallback = mDNSNULL;
@@ -1371,12 +1483,12 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
// times with different values if the external NAT port changes during the lifetime of the service registration.
//if (rr->resrec.rrtype == kDNSType_SRV) rr->NATinfo.IntPort = rr->resrec.rdata->u.srv.port;
-// rr->resrec.interface = already set in mDNS_SetupResourceRecord
-// rr->resrec.name->c = MUST be set by client
-// rr->resrec.rrtype = already set in mDNS_SetupResourceRecord
-// rr->resrec.rrclass = already set in mDNS_SetupResourceRecord
-// rr->resrec.rroriginalttl = already set in mDNS_SetupResourceRecord
-// rr->resrec.rdata = MUST be set by client, unless record type is CNAME or PTR and rr->HostTarget is set
+// rr->resrec.interface = already set in mDNS_SetupResourceRecord
+// rr->resrec.name->c = MUST be set by client
+// rr->resrec.rrtype = already set in mDNS_SetupResourceRecord
+// rr->resrec.rrclass = already set in mDNS_SetupResourceRecord
+// rr->resrec.rroriginalttl = already set in mDNS_SetupResourceRecord
+// rr->resrec.rdata = MUST be set by client, unless record type is CNAME or PTR and rr->HostTarget is set
// BIND named (name daemon) doesn't allow TXT records with zero-length rdata. This is strictly speaking correct,
// since RFC 1035 specifies a TXT record as "One or more <character-string>s", not "Zero or more <character-string>s".
@@ -1471,7 +1583,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
if (r)
{
- debugf("mDNS_Register_internal:Adding to duplicate list %s", ARDisplayString(m,rr));
+ LogInfo("mDNS_Register_internal: Adding to duplicate list %s", ARDisplayString(m,rr));
*d = rr;
// If the previous copy of this record is already verified unique,
// then indicate that we should move this record promptly to kDNSRecordTypeUnique state.
@@ -1482,7 +1594,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
}
else
{
- debugf("mDNS_Register_internal: Adding to active record list %s", ARDisplayString(m,rr));
+ LogInfo("mDNS_Register_internal: Adding to active record list %s", ARDisplayString(m,rr));
if (RRLocalOnly(rr))
{
AuthGroup *ag;
@@ -1504,6 +1616,19 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
}
}
+ if (!AuthRecord_uDNS(rr)) // This check is superfluous, given that for unicast records we (currently) bail out above
+ {
+ // We have inserted the record in the list. See if we have to advertise the A/AAAA, HINFO, PTR records.
+ IncrementAutoTargetServices(m, rr);
+
+ // For records that are not going to probe, acknowledge them right away
+ if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
+ AcknowledgeRecord(m, rr);
+
+ // Adding a record may affect whether or not we should sleep
+ mDNS_UpdateAllowSleep(m);
+ }
+
// If this is a non-sleep proxy keepalive record, fetch the MAC address of the remote host.
// This is used by the in-NIC proxy to send the keepalive packets.
if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
@@ -1516,20 +1641,7 @@ mDNSexport mStatus mDNS_Register_internal(mDNS *const m, AuthRecord *const rr)
getKeepaliveRaddr(m, rr, &raddr);
// This is an asynchronous call. Once the remote MAC address is available, helper will schedule an
// asynchronous task to update the resource record
- mDNSPlatformGetRemoteMacAddr(m, &raddr);
- }
-
- if (!AuthRecord_uDNS(rr)) // This check is superfluous, given that for unicast records we (currently) bail out above
- {
- // We have inserted the record in the list. See if we have to advertise the A/AAAA, HINFO, PTR records.
- IncrementAutoTargetServices(m, rr);
-
- // For records that are not going to probe, acknowledge them right away
- if (rr->resrec.RecordType != kDNSRecordTypeUnique && rr->resrec.RecordType != kDNSRecordTypeDeregistering)
- AcknowledgeRecord(m, rr);
-
- // Adding a record may affect whether or not we should sleep
- mDNS_UpdateAllowSleep(m);
+ mDNSPlatformGetRemoteMacAddr(&raddr);
}
return(mStatus_NoError);
@@ -1577,13 +1689,11 @@ mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr,
if (RRLocalOnly(rr))
{
AuthGroup *a;
- AuthGroup **ag = &a;
AuthRecord **rp;
- const mDNSu32 slot = AuthHashSlot(rr->resrec.name);
- a = AuthGroupForRecord(&m->rrauth, slot, &rr->resrec);
+ a = AuthGroupForRecord(&m->rrauth, &rr->resrec);
if (!a) return mDNSfalse;
- rp = &(*ag)->members;
+ rp = &a->members;
while (*rp && *rp != rr) rp=&(*rp)->next;
p = rp;
}
@@ -1793,7 +1903,7 @@ mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr,
if (drt != mDNS_Dereg_conflict)
{
mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
- LogInfo("mDNS_Deregister_internal: mStatus_MemFree for %s", ARDisplayString(m, rr));
+ LogInfo("mDNS_Deregister_internal: callback with mStatus_MemFree for %s", ARDisplayString(m, rr));
if (rr->RecordCallback)
rr->RecordCallback(m, rr, mStatus_MemFree); // MUST NOT touch rr after this
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
@@ -1817,6 +1927,10 @@ mDNSexport mStatus mDNS_Deregister_internal(mDNS *const m, AuthRecord *const rr,
}
else
{
+#if APPLE_OSX_mDNSResponder
+ // See if this record was also registered with any D2D plugins.
+ D2D_stop_advertising_record(r2);
+#endif
mDNS_Deregister_internal(m, r2, mDNS_Dereg_conflict);
// As this is a duplicate record, it will be unlinked from the list
// immediately
@@ -1850,6 +1964,27 @@ mDNSlocal void AddRecordToResponseList(AuthRecord ***nrpp, AuthRecord *rr, AuthR
debugf("AddRecordToResponseList: %##s (%s) already in list", rr->resrec.name->c, DNSTypeName(rr->resrec.rrtype));
}
+mDNSlocal void AddRRSetAdditionalsToResponseList(mDNS *const m, AuthRecord ***nrpp, AuthRecord *rr, AuthRecord *additional, const mDNSInterfaceID InterfaceID)
+{
+ AuthRecord *rr2;
+ if (additional->resrec.RecordType & kDNSRecordTypeUniqueMask)
+ {
+ for (rr2 = m->ResourceRecords; rr2; rr2 = rr2->next)
+ {
+ if ((rr2->resrec.namehash == additional->resrec.namehash) &&
+ (rr2->resrec.rrtype == additional->resrec.rrtype) &&
+ (rr2 != additional) &&
+ (rr2->resrec.RecordType & kDNSRecordTypeUniqueMask) &&
+ (rr2->resrec.rrclass == additional->resrec.rrclass) &&
+ ResourceRecordIsValidInterfaceAnswer(rr2, InterfaceID) &&
+ SameDomainName(rr2->resrec.name, additional->resrec.name))
+ {
+ AddRecordToResponseList(nrpp, rr2, rr);
+ }
+ }
+ }
+}
+
mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseRecords, AuthRecord ***nrpp, const mDNSInterfaceID InterfaceID)
{
AuthRecord *rr, *rr2;
@@ -1858,10 +1993,16 @@ mDNSlocal void AddAdditionalsToResponseList(mDNS *const m, AuthRecord *ResponseR
// (Note: This is an "if", not a "while". If we add a record, we'll find it again
// later in the "for" loop, and we will follow further "additional" links then.)
if (rr->Additional1 && ResourceRecordIsValidInterfaceAnswer(rr->Additional1, InterfaceID))
+ {
AddRecordToResponseList(nrpp, rr->Additional1, rr);
+ AddRRSetAdditionalsToResponseList(m, nrpp, rr, rr->Additional1, InterfaceID);
+ }
if (rr->Additional2 && ResourceRecordIsValidInterfaceAnswer(rr->Additional2, InterfaceID))
+ {
AddRecordToResponseList(nrpp, rr->Additional2, rr);
+ AddRRSetAdditionalsToResponseList(m, nrpp, rr, rr->Additional2, InterfaceID);
+ }
// For SRV records, automatically add the Address record(s) for the target host
if (rr->resrec.rrtype == kDNSType_SRV)
@@ -1927,9 +2068,8 @@ mDNSlocal void SendDelayedUnicastResponse(mDNS *const m, const mDNSAddr *const d
rr->v6Requester = zerov6Addr;
// Only sent records registered for P2P over P2P interfaces
- if (intf && !mDNSPlatformValidRecordForInterface(rr, intf))
+ if (intf && !mDNSPlatformValidRecordForInterface(rr, intf->InterfaceID))
{
- LogInfo("SendDelayedUnicastResponse: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, InterfaceID));
continue;
}
@@ -2036,7 +2176,7 @@ mDNSexport void CompleteDeregistration(mDNS *const m, AuthRecord *rr)
rr->resrec.RecordType = kDNSRecordTypeShared;
rr->RequireGoodbye = mDNSfalse;
rr->WakeUp.HMAC = zeroEthAddr;
- if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_rmv); rr->AnsweredLocalQ = mDNSfalse; }
+ if (rr->AnsweredLocalQ) { AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse); rr->AnsweredLocalQ = mDNSfalse; }
mDNS_Deregister_internal(m, rr, mDNS_Dereg_normal); // Don't touch rr after this
}
@@ -2224,11 +2364,7 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
// *ptr++ = tpa->b[0xF];
// 0x06 Source address (Note: Since we don't currently set the BIOCSHDRCMPLT option, BPF will fill in the real interface address for us)
- for (i=0; i<6; i++)
- if (tha)
- *ptr++ = tha->b[i];
- else
- *ptr++ = intf->MAC.b[i];
+ for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
// 0x0C IPv6 Ethertype (0x86DD)
*ptr++ = 0x86; *ptr++ = 0xDD;
@@ -2265,11 +2401,7 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
{
*ptr++ = NDP_SrcLL; // Option Type 1 == Source Link-layer Address
*ptr++ = 0x01; // Option length 1 (in units of 8 octets)
- for (i=0; i<6; i++)
- if (tha)
- *ptr++ = tha->b[i];
- else
- *ptr++ = intf->MAC.b[i];
+ for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
}
}
else // Neighbor Advertisement. The NDP "target" is the address we're giving information about.
@@ -2279,11 +2411,7 @@ mDNSlocal void SendNDP(mDNS *const m, const mDNSu8 op, const mDNSu8 flags, const
// 0x4E Target Link-layer Address
*ptr++ = NDP_TgtLL; // Option Type 2 == Target Link-layer Address
*ptr++ = 0x01; // Option length 1 (in units of 8 octets)
- for (i=0; i<6; i++)
- if (tha)
- *ptr++ = tha->b[i];
- else
- *ptr++ = intf->MAC.b[i];
+ for (i=0; i<6; i++) *ptr++ = (tha ? *tha : intf->MAC).b[i];
}
// 0x4E or 0x56 Total NDP Packet length 78 or 86 bytes
@@ -2355,6 +2483,22 @@ mDNSlocal mDNSBool ShouldSendGoodbyesBeforeSleep(mDNS *const m, const NetworkInt
}
}
+mDNSlocal mDNSBool IsInterfaceValidForAuthRecord(const AuthRecord *ar, mDNSInterfaceID InterfaceID)
+{
+ mDNSBool result;
+
+ if (ar->resrec.InterfaceID == mDNSInterface_Any)
+ {
+ result = mDNSPlatformValidRecordForInterface(ar, InterfaceID);
+ }
+ else
+ {
+ result = (ar->resrec.InterfaceID == InterfaceID);
+ }
+
+ return(result);
+}
+
// Note about acceleration of announcements to facilitate automatic coalescing of
// multiple independent threads of announcements into a single synchronized thread:
// The announcements in the packet may be at different stages of maturity;
@@ -2378,7 +2522,7 @@ mDNSlocal void SendResponses(mDNS *const m)
mDNSs32 maxExistingAnnounceInterval = 0;
const NetworkInterfaceInfo *intf = GetFirstActiveInterface(m->HostInterfaces);
- m->NextScheduledResponse = m->timenow + 0x78000000;
+ m->NextScheduledResponse = m->timenow + FutureTime;
if (m->SleepState == SleepState_Transferring) RetrySPSRegistrations(m);
@@ -2416,8 +2560,10 @@ mDNSlocal void SendResponses(mDNS *const m)
}
else
{
+ mDNSBool unicastOnly;
LogSPS("SendResponses: Sending wakeup %2d for %.6a %s", rr->AnnounceCount-3, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
- SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password);
+ unicastOnly = ((rr->AnnounceCount == WakeupCount) || (rr->AnnounceCount == WakeupCount - 1)) ? mDNStrue : mDNSfalse;
+ SendWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.IMAC, &rr->WakeUp.password, unicastOnly);
for (r2 = rr; r2; r2=r2->next)
if ((r2->resrec.RecordType == kDNSRecordTypeDeregistering) && r2->AnnounceCount && (r2->resrec.InterfaceID == rr->resrec.InterfaceID) &&
mDNSSameEthAddress(&r2->WakeUp.IMAC, &rr->WakeUp.IMAC) && !mDNSSameEthAddress(&zeroEthAddr, &r2->WakeUp.HMAC))
@@ -2518,17 +2664,28 @@ mDNSlocal void SendResponses(mDNS *const m)
if (rr->ImmedAnswer) // If we're sending this as answer, see that its whole RRSet is similarly marked
{
for (r2 = m->ResourceRecords; r2; r2=r2->next)
- if (ResourceRecordIsValidAnswer(r2))
- if (r2->ImmedAnswer != mDNSInterfaceMark &&
- r2->ImmedAnswer != rr->ImmedAnswer && SameResourceRecordSignature(r2, rr))
- r2->ImmedAnswer = !r2->ImmedAnswer ? rr->ImmedAnswer : mDNSInterfaceMark;
+ {
+ if ((r2->resrec.RecordType & kDNSRecordTypeUniqueMask) && ResourceRecordIsValidAnswer(r2) &&
+ (r2->ImmedAnswer != mDNSInterfaceMark) && (r2->ImmedAnswer != rr->ImmedAnswer) &&
+ SameResourceRecordSignature(r2, rr) &&
+ ((rr->ImmedAnswer == mDNSInterfaceMark) || IsInterfaceValidForAuthRecord(r2, rr->ImmedAnswer)))
+ {
+ r2->ImmedAnswer = !r2->ImmedAnswer ? rr->ImmedAnswer : mDNSInterfaceMark;
+ }
+ }
}
else if (rr->ImmedAdditional) // If we're sending this as additional, see that its whole RRSet is similarly marked
{
for (r2 = m->ResourceRecords; r2; r2=r2->next)
- if (ResourceRecordIsValidAnswer(r2))
- if (r2->ImmedAdditional != rr->ImmedAdditional && SameResourceRecordSignature(r2, rr))
- r2->ImmedAdditional = rr->ImmedAdditional;
+ {
+ if ((r2->resrec.RecordType & kDNSRecordTypeUniqueMask) && ResourceRecordIsValidAnswer(r2) &&
+ (r2->ImmedAdditional != rr->ImmedAdditional) &&
+ SameResourceRecordSignature(r2, rr) &&
+ IsInterfaceValidForAuthRecord(r2, rr->ImmedAdditional))
+ {
+ r2->ImmedAdditional = rr->ImmedAdditional;
+ }
+ }
}
}
@@ -2541,6 +2698,7 @@ mDNSlocal void SendResponses(mDNS *const m)
rr->ImmedAdditional = mDNSNULL; // No need to send as additional if sending as answer
rr->LastMCTime = m->timenow;
rr->LastMCInterface = rr->ImmedAnswer;
+ rr->ProbeRestartCount = 0; // Reset the probe restart count
// If we're announcing this record, and it's at least half-way to its ordained time, then consider this announcement done
if (TimeToAnnounceThisRecord(rr, m->timenow + rr->ThisAPInterval/2))
{
@@ -2588,9 +2746,8 @@ mDNSlocal void SendResponses(mDNS *const m)
// Skip this interface if the record InterfaceID is *Any and the record is not
// appropriate for the interface type.
if ((rr->SendRNow == intf->InterfaceID) &&
- ((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf)))
+ ((rr->resrec.InterfaceID == mDNSInterface_Any) && !mDNSPlatformValidRecordForInterface(rr, intf->InterfaceID)))
{
- // LogInfo("SendResponses: Not sending %s, on %s", ARDisplayString(m, rr), InterfaceNameForID(m, rr->SendRNow));
rr->SendRNow = GetNextActiveInterfaceID(intf);
}
else if (rr->SendRNow == intf->InterfaceID)
@@ -2663,7 +2820,7 @@ mDNSlocal void SendResponses(mDNS *const m)
// Get the reserved space back
OwnerRecordSpace -= AnoninfoSpace;
- TraceRecordSpace -= AnoninfoSpace;
+ TraceRecordSpace -= AnoninfoSpace;
newptr = responseptr;
for (rr = m->ResourceRecords; rr; rr=rr->next)
{
@@ -2812,10 +2969,9 @@ mDNSlocal void SendResponses(mDNS *const m)
SetupTracerOpt(m, &opt.resrec.rdata->u.opt[0]);
}
newptr = PutResourceRecord(&m->omsg, responseptr, &m->omsg.h.numAdditionals, &opt.resrec);
- if (newptr)
- {
- responseptr = newptr;
- LogInfo("SendResponses put %s %s: %s %s", OwnerRecordSpace ? "OWNER" : "", TraceRecordSpace ? "TRACER" : "", intf->ifname, ARDisplayString(m, &opt));
+ if (newptr)
+ {
+ responseptr = newptr;
}
else if (m->omsg.h.numAnswers + m->omsg.h.numAuthorities + m->omsg.h.numAdditionals == 1)
{
@@ -2828,7 +2984,7 @@ mDNSlocal void SendResponses(mDNS *const m)
m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
}
}
-
+
debugf("SendResponses: Sending %d Deregistration%s, %d Announcement%s, %d Answer%s, %d Additional%s on %p",
numDereg, numDereg == 1 ? "" : "s",
numAnnounce, numAnnounce == 1 ? "" : "s",
@@ -2940,13 +3096,18 @@ mDNSexport void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const
verbosedebugf("SetNextCacheCheckTimeForRecord: NextRequiredQuery in %ld sec CacheCheckGracePeriod %d ticks for %s",
(rr->NextRequiredQuery - m->timenow) / mDNSPlatformOneSecond, CacheCheckGracePeriod(rr), CRDisplayString(m,rr));
}
- ScheduleNextCacheCheckTime(m, HashSlot(rr->resrec.name), NextCacheCheckEvent(rr));
+ ScheduleNextCacheCheckTime(m, HashSlotFromNameHash(rr->resrec.namehash), NextCacheCheckEvent(rr));
}
#define kMinimumReconfirmTime ((mDNSu32)mDNSPlatformOneSecond * 5)
#define kDefaultReconfirmTimeForWake ((mDNSu32)mDNSPlatformOneSecond * 5)
#define kDefaultReconfirmTimeForNoAnswer ((mDNSu32)mDNSPlatformOneSecond * 5)
-#define kDefaultReconfirmTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 5)
+
+// Delay before restarting questions on a flapping interface.
+#define kDefaultQueryDelayTimeForFlappingInterface ((mDNSu32)mDNSPlatformOneSecond * 3)
+// After kDefaultQueryDelayTimeForFlappingInterface seconds, allow enough time for up to three queries (0, 1, and 4 seconds)
+// plus three seconds for "response delay" before removing the reconfirmed records from the cache.
+#define kDefaultReconfirmTimeForFlappingInterface (kDefaultQueryDelayTimeForFlappingInterface + ((mDNSu32)mDNSPlatformOneSecond * 7))
mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr, mDNSu32 interval)
{
@@ -2961,7 +3122,7 @@ mDNSexport mStatus mDNS_Reconfirm_internal(mDNS *const m, CacheRecord *const rr,
// Add a 33% random amount to the interval, to avoid synchronization between multiple hosts
// For all the reconfirmations in a given batch, we want to use the same random value
// so that the reconfirmation questions can be grouped into a single query packet
- if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(0x3FFFFFFF);
+ if (!m->RandomReconfirmDelay) m->RandomReconfirmDelay = 1 + mDNSRandom(FutureTime);
interval += m->RandomReconfirmDelay % ((interval/3) + 1);
rr->TimeRcvd = m->timenow - (mDNSs32)interval * 3;
rr->resrec.rroriginalttl = (interval * 4 + mDNSPlatformOneSecond - 1) / mDNSPlatformOneSecond;
@@ -2991,8 +3152,7 @@ mDNSlocal mDNSBool BuildQuestion(mDNS *const m, const NetworkInterfaceInfo *intf
else
{
mDNSu32 forecast = *answerforecast + anoninfo_space;
- const mDNSu32 slot = HashSlot(&q->qname);
- const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rr;
CacheRecord **ka = *kalistptrptr; // Make a working copy of the pointer we're going to update
@@ -3085,7 +3245,7 @@ mDNSlocal void ReconfirmAntecedents(mDNS *const m, const domainname *const name,
// to get a AAAA response is not grounds to doubt the PTR/SRV chain that lead us to that name.
mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const domainname *const name, const mDNSu32 namehash)
{
- CacheGroup *const cg = CacheGroupForName(m, HashSlot(name), namehash, name);
+ CacheGroup *const cg = CacheGroupForName(m, namehash, name);
const CacheRecord *cr = cg ? cg->members : mDNSNULL;
while (cr && !RRTypeIsAddressType(cr->resrec.rrtype)) cr=cr->next;
return(cr);
@@ -3095,7 +3255,7 @@ mDNSlocal const CacheRecord *CacheHasAddressTypeForName(mDNS *const m, const dom
mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *const q, const CacheRecord *const c0, const CacheRecord *const c1)
{
#ifndef SPC_DISABLED
- CacheGroup *const cg = CacheGroupForName(m, HashSlot(&q->qname), q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
const CacheRecord *cr, *bestcr = mDNSNULL;
mDNSu32 bestmetric = 1000000;
for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
@@ -3109,11 +3269,11 @@ mDNSlocal const CacheRecord *FindSPSInCache1(mDNS *const m, const DNSQuestion *c
}
return(bestcr);
#else // SPC_DISABLED
- (void) m;
- (void) q;
- (void) c0;
- (void) c1;
- (void) c1;
+ (void) m;
+ (void) q;
+ (void) c0;
+ (void) c1;
+ (void) c1;
return mDNSNULL;
#endif // SPC_DISABLED
}
@@ -3211,7 +3371,7 @@ mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
domainname *d = &q->qname;
// We can't send magic packets without knowing which interface to send it on.
- if (InterfaceID == mDNSInterface_Any || InterfaceID == mDNSInterface_LocalOnly || InterfaceID == mDNSInterface_P2P)
+ if (InterfaceID == mDNSInterface_Any || LocalOnlyOrP2PInterface(InterfaceID))
{
LogMsg("mDNSSendWakeOnResolve: ERROR!! Invalid InterfaceID %p for question %##s", InterfaceID, q->qname.c);
return;
@@ -3246,7 +3406,7 @@ mDNSlocal void mDNSSendWakeOnResolve(mDNS *const m, DNSQuestion *q)
mDNSPlatformMemCopy(IPAddr, &d->c[i + 1], len - i);
IPAddr[len - i] = 0;
m->mDNSStats.WakeOnResolves++;
- mDNSPlatformSendWakeupPacket(m, InterfaceID, EthAddr, IPAddr, InitialWakeOnResolveCount - q->WakeOnResolveCount);
+ mDNSPlatformSendWakeupPacket(InterfaceID, EthAddr, IPAddr, InitialWakeOnResolveCount - q->WakeOnResolveCount);
return;
}
else if (d->c[i] == ':')
@@ -3267,8 +3427,7 @@ mDNSlocal mDNSBool AccelerateThisQuery(mDNS *const m, DNSQuestion *q)
{
// We forecast: qname (n) type (2) class (2)
mDNSu32 forecast = (mDNSu32)DomainNameLength(&q->qname) + 4;
- const mDNSu32 slot = HashSlot(&q->qname);
- const CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
const CacheRecord *rr;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next) // If we have a resource record in our cache,
if (rr->resrec.rdlength <= SmallRecordLimit && // which is small enough to sensibly fit in the packet
@@ -3371,7 +3530,7 @@ mDNSlocal void SendQueries(mDNS *const m)
const mDNSu8 *const limit = m->omsg.data + sizeof(m->omsg.data);
// If we fail to get a new on-demand socket (should only happen cases of the most extreme resource exhaustion), we'll try again next time
- if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ if (!q->LocalSocket) q->LocalSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (q->LocalSocket)
{
InitializeDNSMessage(&m->omsg.h, q->TargetQID, QueryFlags);
@@ -3412,7 +3571,7 @@ mDNSlocal void SendQueries(mDNS *const m)
// Note: Don't set NextScheduledQuery until here, because uDNS_CheckCurrentQuestion in the loop above can add new questions to the list,
// which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
// next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
- m->NextScheduledQuery = m->timenow + 0x78000000;
+ m->NextScheduledQuery = m->timenow + FutureTime;
for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
{
if (mDNSOpaque16IsZero(q->TargetQID)
@@ -3423,11 +3582,11 @@ mDNSlocal void SendQueries(mDNS *const m)
// treat this as logically a repeat of the last transmission, without advancing the interval
if (m->timenow - (q->LastQTime + (q->ThisQInterval/2)) >= 0)
{
- // If we have reached the answer threshold for this question,
+ // If we have reached the answer threshold for this question,
// don't send it again until MaxQuestionInterval unless:
// one of its cached answers needs to be refreshed,
// or it's the initial query for a kDNSServiceFlagsThresholdFinder mode browse.
- if (q->BrowseThreshold
+ if (q->BrowseThreshold
&& (q->CurrentAnswers >= q->BrowseThreshold)
&& (q->CachedAnswerNeedsUpdate == mDNSfalse)
&& !((q->flags & kDNSServiceFlagsThresholdFinder) && (q->ThisQInterval == InitialQuestionInterval)))
@@ -3449,7 +3608,7 @@ mDNSlocal void SendQueries(mDNS *const m)
debugf("SendQueries: %##s (%s) next interval %d seconds RequestUnicast = %d",
q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval / InitialQuestionInterval, q->RequestUnicast);
- if (q->ThisQInterval >= QuestionIntervalThreshold)
+ if (q->ThisQInterval > MaxQuestionInterval)
{
q->ThisQInterval = MaxQuestionInterval;
}
@@ -3491,7 +3650,7 @@ mDNSlocal void SendQueries(mDNS *const m)
// 2. Scan our authoritative RR list to see what probes we might need to send
- m->NextScheduledProbe = m->timenow + 0x78000000;
+ m->NextScheduledProbe = m->timenow + FutureTime;
if (m->CurrentRecord)
LogMsg("SendQueries ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
@@ -3512,11 +3671,11 @@ mDNSlocal void SendQueries(mDNS *const m)
{
if (ar->AddressProxy.type == mDNSAddrType_IPv4)
{
- // There's a problem here. If a host is waking up, and we probe to see if it responds, then
- // it will see those ARP probes as signalling intent to use the address, so it picks a different one.
- // A more benign way to find out if a host is responding to ARPs might be send a standard ARP *request*
- // (using our sender IP address) instead of an ARP *probe* (using all-zero sender IP address).
- // A similar concern may apply to the NDP Probe too. -- SC
+ // There's a problem here. If a host is waking up, and we probe to see if it responds, then
+ // it will see those ARP probes as signalling intent to use the address, so it picks a different one.
+ // A more benign way to find out if a host is responding to ARPs might be send a standard ARP *request*
+ // (using our sender IP address) instead of an ARP *probe* (using all-zero sender IP address).
+ // A similar concern may apply to the NDP Probe too. -- SC
LogSPS("SendQueries ARP Probe %d %s %s", ar->ProbeCount, InterfaceNameForID(m, ar->resrec.InterfaceID), ARDisplayString(m,ar));
SendARP(m, 1, ar, &zerov4Addr, &zeroEthAddr, &ar->AddressProxy.ip.v4, &ar->WakeUp.IMAC);
}
@@ -3608,7 +3767,6 @@ mDNSlocal void SendQueries(mDNS *const m)
// If interface is P2P type, verify that query should be sent over it.
if (!mDNSPlatformValidQuestionForInterface(q, intf))
{
- LogInfo("SendQueries: Not sending (%s) %##s on %s", DNSTypeName(q->qtype), q->qname.c, InterfaceNameForID(m, intf->InterfaceID));
q->SendQNow = (q->InterfaceID || !q->SendOnAll) ? mDNSNULL : GetNextActiveInterfaceID(intf);
}
// If we're suppressing this question, or we successfully put it, update its SendQNow state
@@ -3648,24 +3806,62 @@ mDNSlocal void SendQueries(mDNS *const m)
// Put probe questions in this packet
for (ar = m->ResourceRecords; ar; ar=ar->next)
- if (ar->SendRNow == intf->InterfaceID)
+ {
+ if (ar->SendRNow != intf->InterfaceID)
+ continue;
+
+ // If interface is a P2P variant, verify that the probe should be sent over it.
+ if (!mDNSPlatformValidRecordForInterface(ar, intf->InterfaceID))
+ {
+ ar->SendRNow = (ar->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
+ ar->IncludeInProbe = mDNSfalse;
+ }
+ else
{
mDNSBool ucast = (ar->ProbeCount >= DefaultProbeCountForTypeUnique-1) && m->CanReceiveUnicastOn5353 && intf->SupportsUnicastMDNSResponse;
mDNSu16 ucbit = (mDNSu16)(ucast ? kDNSQClass_UnicastResponse : 0);
const mDNSu8 *const limit = m->omsg.data + (m->omsg.h.numQuestions ? NormalMaxDNSMessageData : AbsoluteMaxDNSMessageData);
// We forecast: compressed name (2) type (2) class (2) TTL (4) rdlength (2) rdata (n)
mDNSu32 forecast = answerforecast + 12 + ar->resrec.rdestimate;
- mDNSu8 *newptr = putQuestion(&m->omsg, queryptr, limit - forecast, ar->resrec.name, kDNSQType_ANY, (mDNSu16)(ar->resrec.rrclass | ucbit));
- if (newptr)
+ mDNSBool putProbe = mDNStrue;
+ mDNSu16 qclass = ar->resrec.rrclass | ucbit;
+
+ {// Determine if this probe question is already in packet's dns message
+ const mDNSu8 *questionptr = m->omsg.data;
+ DNSQuestion question;
+ mDNSu16 n;
+ for (n = 0; n < m->omsg.h.numQuestions && questionptr; n++)
+ {
+ questionptr = getQuestion(&m->omsg, questionptr, limit, mDNSInterface_Any, &question);
+ if (questionptr && (question.qtype == kDNSQType_ANY) && (question.qclass == qclass) &&
+ (question.qnamehash == ar->resrec.namehash) && SameDomainName(&question.qname, ar->resrec.name))
+ {
+ putProbe = mDNSfalse; // set to false if already in message
+ break;
+ }
+ }
+ }
+
+ if (putProbe)
+ {
+ mDNSu8 *newptr = putQuestion(&m->omsg, queryptr, limit - forecast, ar->resrec.name, kDNSQType_ANY, qclass);
+ if (newptr)
+ {
+ queryptr = newptr;
+ answerforecast = forecast;
+ ar->SendRNow = (ar->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
+ ar->IncludeInProbe = mDNStrue;
+ verbosedebugf("SendQueries: Put Question %##s (%s) probecount %d InterfaceID= %d %d %d",
+ ar->resrec.name->c, DNSTypeName(ar->resrec.rrtype), ar->ProbeCount, ar->resrec.InterfaceID, ar->resrec.rdestimate, answerforecast);
+ }
+ }
+ else
{
- queryptr = newptr;
- answerforecast = forecast;
ar->SendRNow = (ar->resrec.InterfaceID) ? mDNSNULL : GetNextActiveInterfaceID(intf);
ar->IncludeInProbe = mDNStrue;
- verbosedebugf("SendQueries: Put Question %##s (%s) probecount %d",
- ar->resrec.name->c, DNSTypeName(ar->resrec.rrtype), ar->ProbeCount);
}
}
+ }
}
// Put our known answer list (either new one from this question or questions, or remainder of old one from last time)
@@ -3731,7 +3927,7 @@ mDNSlocal void SendQueries(mDNS *const m)
AuthRecord opt;
mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
opt.resrec.rrclass = NormalMaxDNSMessageData;
- opt.resrec.rdlength = sizeof(rdataOPT);
+ opt.resrec.rdlength = sizeof(rdataOPT);
opt.resrec.rdestimate = sizeof(rdataOPT);
if (OwnerRecordSpace && TraceRecordSpace)
{
@@ -3748,19 +3944,18 @@ mDNSlocal void SendQueries(mDNS *const m)
{
SetupTracerOpt(m, &opt.resrec.rdata->u.opt[0]);
}
- LogInfo("SendQueries putting %s %s: %s %s", OwnerRecordSpace ? "OWNER" : "", TraceRecordSpace ? "TRACER" : "", intf->ifname, ARDisplayString(m, &opt));
queryptr = PutResourceRecordTTLWithLimit(&m->omsg, queryptr, &m->omsg.h.numAdditionals,
&opt.resrec, opt.resrec.rroriginalttl, m->omsg.data + AbsoluteMaxDNSMessageData);
if (!queryptr)
- {
+ {
LogMsg("SendQueries: How did we fail to have space for %s %s OPT record (%d/%d/%d/%d) %s", OwnerRecordSpace ? "OWNER" : "", TraceRecordSpace ? "TRACER" : "",
m->omsg.h.numQuestions, m->omsg.h.numAnswers, m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
}
if (queryptr > m->omsg.data + NormalMaxDNSMessageData)
{
if (m->omsg.h.numQuestions != 1 || m->omsg.h.numAnswers != 0 || m->omsg.h.numAuthorities != 1 || m->omsg.h.numAdditionals != 1)
- LogMsg("SendQueries: Why did we generate oversized packet with %s %s OPT record %p %p %p (%d/%d/%d/%d) %s", OwnerRecordSpace ? "OWNER" : "",
- TraceRecordSpace ? "TRACER" : "", m->omsg.data, m->omsg.data + NormalMaxDNSMessageData, queryptr, m->omsg.h.numQuestions, m->omsg.h.numAnswers,
+ LogMsg("SendQueries: Why did we generate oversized packet with %s %s OPT record %p %p %p (%d/%d/%d/%d) %s", OwnerRecordSpace ? "OWNER" : "",
+ TraceRecordSpace ? "TRACER" : "", m->omsg.data, m->omsg.data + NormalMaxDNSMessageData, queryptr, m->omsg.h.numQuestions, m->omsg.h.numAnswers,
m->omsg.h.numAuthorities, m->omsg.h.numAdditionals, ARDisplayString(m, &opt));
}
}
@@ -3829,17 +4024,21 @@ mDNSlocal void SendQueries(mDNS *const m)
{
DNSQuestion *x;
for (x = m->NewQuestions; x; x=x->next) if (x == q) break; // Check if this question is a NewQuestion
- LogInfo("SendQueries: No active interface %d to send %s question: %d %##s (%s)",
- (uint32_t)q->SendQNow, x ? "new" : "old", (uint32_t)q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ // There will not be an active interface for questions applied to mDNSInterface_BLE
+ // so don't log the warning in that case.
+ if (q->InterfaceID != mDNSInterface_BLE)
+ LogInfo("SendQueries: No active interface %d to send %s question: %d %##s (%s)",
+ (uint32_t)q->SendQNow, x ? "new" : "old", (uint32_t)q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
q->SendQNow = mDNSNULL;
}
q->CachedAnswerNeedsUpdate = mDNSfalse;
}
}
-mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password)
+mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAddr *EthAddr, mDNSOpaque48 *password, mDNSBool unicastOnly)
{
int i, j;
+
mDNSu8 *ptr = m->omsg.data;
NetworkInterfaceInfo *intf = FirstInterfaceForID(m, InterfaceID);
if (!intf) { LogMsg("SendARP: No interface with InterfaceID %p found", InterfaceID); return; }
@@ -3865,13 +4064,16 @@ mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAdd
mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
- // For Ethernet switches that don't flood-foward packets with unknown unicast destination MAC addresses,
- // broadcast is the only reliable way to get a wakeup packet to the intended target machine.
- // For 802.11 WPA networks, where a sleeping target machine may have missed a broadcast/multicast
- // key rotation, unicast is the only way to get a wakeup packet to the intended target machine.
- // So, we send one of each, unicast first, then broadcast second.
- for (i=0; i<6; i++) m->omsg.data[i] = 0xFF;
- mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
+ if (!unicastOnly)
+ {
+ // For Ethernet switches that don't flood-foward packets with unknown unicast destination MAC addresses,
+ // broadcast is the only reliable way to get a wakeup packet to the intended target machine.
+ // For 802.11 WPA networks, where a sleeping target machine may have missed a broadcast/multicast
+ // key rotation, unicast is the only way to get a wakeup packet to the intended target machine.
+ // So, we send one of each, unicast first, then broadcast second.
+ for (i=0; i<6; i++) m->omsg.data[i] = 0xFF;
+ mDNSPlatformSendRawPacket(m->omsg.data, ptr, InterfaceID);
+ }
}
// ***************************************************************************
@@ -3903,7 +4105,7 @@ mDNSlocal void ResetQuestionState(mDNS *const m, DNSQuestion *q)
mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheRecord *const rr, const QC_result AddRecord)
{
DNSQuestion *const q = m->CurrentQuestion;
- mDNSBool followcname = FollowCNAME(q, &rr->resrec, AddRecord);
+ const mDNSBool followcname = FollowCNAME(q, &rr->resrec, AddRecord);
verbosedebugf("AnswerCurrentQuestionWithResourceRecord:%4lu %s TTL %d %s",
q->CurrentAnswers, AddRecord ? "Add" : "Rmv", rr->resrec.rroriginalttl, CRDisplayString(m, rr));
@@ -3919,7 +4121,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
// to do it on the next ADD of a negative cache record. This ADD could be the result of a timeout, no DNS servers
// etc. in which case we need to reset the state to make sure we don't deliver them as secure. If this is
// a real negative response, we would reset the state here and validate the results at the end of this function.
- // or the real response again if we purge the cache.
+ // or the real response again if we purge the cache.
if (q->ValidationRequired && ((AddRecord == QC_rmv) ||
(rr->resrec.RecordType == kDNSRecordTypePacketNegative && (AddRecord == QC_add))))
{
@@ -3948,29 +4150,33 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
return;
}
-#if TARGET_OS_EMBEDDED
- if ((AddRecord == QC_add) && Question_uDNS(q) && (!q->metrics.answered || (q->metrics.querySendCount > 0)))
+#if AWD_METRICS
+ if ((AddRecord == QC_add) && Question_uDNS(q) && !followcname)
{
- uDNSMetrics * metrics;
const domainname * queryName;
mDNSu32 responseLatencyMs;
mDNSBool isForCellular;
- metrics = &q->metrics;
- queryName = metrics->originalQName ? metrics->originalQName : &q->qname;
- if (metrics->querySendCount > 0)
+ queryName = q->metrics.originalQName ? q->metrics.originalQName : &q->qname;
+ isForCellular = (q->qDNSServer && q->qDNSServer->cellIntf);
+ if (!q->metrics.answered)
{
- responseLatencyMs = ((m->timenow - metrics->firstQueryTime) * 1000) / mDNSPlatformOneSecond;
+ if (q->metrics.querySendCount > 0)
+ {
+ responseLatencyMs = ((m->timenow - q->metrics.firstQueryTime) * 1000) / mDNSPlatformOneSecond;
+ }
+ else
+ {
+ responseLatencyMs = 0;
+ }
+
+ MetricsUpdateUDNSQueryStats(queryName, q->qtype, &rr->resrec, q->metrics.querySendCount, responseLatencyMs, isForCellular);
+ q->metrics.answered = mDNStrue;
}
- else
+ if (q->metrics.querySendCount > 0)
{
- responseLatencyMs = 0;
+ MetricsUpdateUDNSResolveStats(queryName, &rr->resrec, isForCellular);
}
- isForCellular = (q->qDNSServer && q->qDNSServer->cellIntf);
-
- MetricsUpdateUDNSStats(queryName, mDNStrue, metrics->querySendCount, responseLatencyMs, isForCellular);
- metrics->answered = mDNStrue;
- metrics->querySendCount = 0;
}
#endif
// Note: Use caution here. In the case of records with rr->DelayDelivery set, AnswerCurrentQuestionWithResourceRecord(... mDNStrue)
@@ -4003,6 +4209,35 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
if (rr->DelayDelivery) return; // We'll come back later when CacheRecordDeferredAdd() calls us
+#if USE_DNS64
+ // If DNS64StateMachine() returns true, then the question was restarted as a different question, so return.
+ if (!mDNSOpaque16IsZero(q->TargetQID) && DNS64StateMachine(m, q, &rr->resrec, AddRecord)) return;
+#endif
+
+#ifdef USE_LIBIDN
+ if (rr->resrec.RecordType == kDNSRecordTypePacketNegative) // If negative answer, check if we need to try Punycode conversion
+ {
+ domainname newname;
+ if (PerformNextPunycodeConversion(q, &newname)) // Itertative Punycode conversion succeeded, so reissue question with new name
+ {
+ UDPSocket *const sock = q->LocalSocket; // Save old socket and transaction ID
+ const mDNSOpaque16 id = q->TargetQID;
+ q->LocalSocket = mDNSNULL;
+ mDNS_StopQuery_internal(m, q); // Stop old query
+ AssignDomainName(&q->qname, &newname); // Update qname
+ q->qnamehash = DomainNameHashValue(&q->qname); // and namehash
+ mDNS_StartQuery_internal(m, q); // Start new query
+
+ if (sock) // Transplant saved socket, if appropriate
+ {
+ if (q->DuplicateOf) mDNSPlatformUDPClose(sock);
+ else { q->LocalSocket = sock; q->TargetQID = id; }
+ }
+ return; // All done for now; wait until we get the next answer
+ }
+ }
+#endif // USE_LIBIDN
+
// Only deliver negative answers if client has explicitly requested them except when we are forcing a negative response
// for the purpose of retrying search domains/timeout OR the question is suppressed
if (rr->resrec.RecordType == kDNSRecordTypePacketNegative || (q->qtype != kDNSType_NSEC && RRAssertsNonexistence(&rr->resrec, q->qtype)))
@@ -4019,7 +4254,18 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
q->QuestionCallback(m, q, &neg.resrec, AddRecord);
}
else
- q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ {
+#if USE_DNS64
+ if (DNS64ShouldAnswerQuestion(q, &rr->resrec))
+ {
+ DNS64AnswerQuestion(m, q, &rr->resrec, AddRecord);
+ }
+ else
+#endif
+ {
+ q->QuestionCallback(m, q, &rr->resrec, AddRecord);
+ }
+ }
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
// If this is an "Add" operation and this question needs validation, validate the response.
@@ -4053,7 +4299,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
// If we get a CNAME back while we are validating the response (i.e., CNAME for DS, DNSKEY, RRSIG),
// don't follow them. If it is a ValidationRequired question, wait for the CNAME to be validated
// first before following it
- if (!ValidatingQuestion(q) && followcname && m->CurrentQuestion == q)
+ if ((m->CurrentQuestion == q) && followcname && !ValidatingQuestion(q))
AnswerQuestionByFollowingCNAME(m, q, &rr->resrec);
}
@@ -4075,12 +4321,12 @@ mDNSlocal void CacheRecordDeferredAdd(mDNS *const m, CacheRecord *rr)
m->CurrentQuestion = mDNSNULL;
}
-mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, const mDNSu32 slot, mDNSBool *purge)
+mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *const name, const mDNSu32 namehash, mDNSBool *purge)
{
const mDNSs32 threshhold = m->timenow + mDNSPlatformOneSecond; // See if there are any records expiring within one second
const mDNSs32 start = m->timenow - 0x10000000;
mDNSs32 delay = start;
- CacheGroup *cg = CacheGroupForName(m, slot, namehash, name);
+ CacheGroup *cg = CacheGroupForName(m, namehash, name);
const CacheRecord *rr;
if (purge)
@@ -4094,7 +4340,7 @@ mDNSlocal mDNSs32 CheckForSoonToExpireRecords(mDNS *const m, const domainname *c
// deliver a RMV (for the current old entry) followed by ADD (for the new entry).
// It needs to schedule the timer for the next cache expiry (ScheduleNextCacheCheckTime),
// so that the cache entry can be purged (purging causes the RMV followed by ADD)
- //
+ //
// 2) A new question is about to be answered and the caller needs to know whether it's
// scheduling should be delayed so that the question is not answered with this record.
// Instead of delivering an ADD (old entry) followed by RMV (old entry) and another ADD
@@ -4154,7 +4400,6 @@ mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
{
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
- mDNSIPPort zp = zeroIPPort;
// If this question is one that's actively sending queries, and it's received ten answers within one
// second of sending the last query packet, then that indicates some radical network topology change,
// so reset its exponential backoff back to the start. We must be at least at the eight-second interval
@@ -4177,7 +4422,7 @@ mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
verbosedebugf("CacheRecordAdd %p %##s (%s) %lu %#a:%d question %p", rr, rr->resrec.name->c,
DNSTypeName(rr->resrec.rrtype), rr->resrec.rroriginalttl, rr->resrec.rDNSServer ?
&rr->resrec.rDNSServer->addr : mDNSNULL, mDNSVal16(rr->resrec.rDNSServer ?
- rr->resrec.rDNSServer->port : zp), q);
+ rr->resrec.rDNSServer->port : zeroIPPort), q);
q->CurrentAnswers++;
q->unansweredQueries = 0;
@@ -4274,12 +4519,10 @@ mDNSlocal void CacheRecordRmv(mDNS *const m, CacheRecord *rr)
q->FlappingInterface1 = mDNSNULL;
q->FlappingInterface2 = mDNSNULL;
- if (q->CurrentAnswers == 0) {
- mDNSIPPort zp = zeroIPPort;
+ if (q->CurrentAnswers == 0)
LogMsg("CacheRecordRmv ERROR!!: How can CurrentAnswers already be zero for %p %##s (%s) DNSServer %#a:%d",
q, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL,
- mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp));
- }
+ mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort));
else
{
q->CurrentAnswers--;
@@ -4332,7 +4575,7 @@ mDNSlocal void ReleaseCacheGroup(mDNS *const m, CacheGroup **cp)
if ((*cp)->rrcache_tail != &(*cp)->members)
LogMsg("ERROR: (*cp)->members == mDNSNULL but (*cp)->rrcache_tail != &(*cp)->members)");
//if ((*cp)->name != (domainname*)((*cp)->namestorage))
- // LogMsg("ReleaseCacheGroup: %##s, %p %p", (*cp)->name->c, (*cp)->name, (domainname*)((*cp)->namestorage));
+ // LogMsg("ReleaseCacheGroup: %##s, %p %p", (*cp)->name->c, (*cp)->name, (domainname*)((*cp)->namestorage));
if ((*cp)->name != (domainname*)((*cp)->namestorage)) mDNSPlatformMemFree((*cp)->name);
(*cp)->name = mDNSNULL;
*cp = (*cp)->next; // Cut record from list
@@ -4372,14 +4615,13 @@ mDNSlocal void ReleaseAdditionalCacheRecords(mDNS *const m, CacheRecord **rp)
mDNSexport void ReleaseCacheRecord(mDNS *const m, CacheRecord *r)
{
CacheGroup *cg;
- const mDNSu32 slot = HashSlot(r->resrec.name);
//LogMsg("ReleaseCacheRecord: Releasing %s", CRDisplayString(m, r));
if (r->resrec.rdata && r->resrec.rdata != (RData*)&r->smallrdatastorage) mDNSPlatformMemFree(r->resrec.rdata);
r->resrec.rdata = mDNSNULL;
- cg = CacheGroupForRecord(m, slot, &r->resrec);
-
+ cg = CacheGroupForRecord(m, &r->resrec);
+
if (!cg)
{
// It is okay to have this printed for NSEC/NSEC3s
@@ -4432,7 +4674,7 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
if (m->timenow - event >= 0) // If expired, delete it
{
*rp = rr->next; // Cut it from the list
-
+
verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s",
m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
if (rr->CRActiveQuestion) // If this record has one or more active questions, tell them it's going away
@@ -4475,7 +4717,7 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
m->NextScheduledQuery = m->timenow;
// After sending the query we'll increment UnansweredQueries and call SetNextCacheCheckTimeForRecord(),
// which will correctly update m->NextCacheCheck for us.
- event = m->timenow + 0x3FFFFFFF;
+ event = m->timenow + FutureTime;
}
}
}
@@ -4496,19 +4738,17 @@ mDNSlocal void CheckCacheExpiration(mDNS *const m, const mDNSu32 slot, CacheGrou
// If "CheckOnly" is set to "true", the question won't be answered but just check to see if there is an answer and
// returns true if there is an answer.
//
-// If "CheckOnly" is set to "false", the question will be answered if there is a LocalOnly/P2P record and
+// If "CheckOnly" is set to "false", the question will be answered if there is a LocalOnly/P2P record and
// returns true to indicate the same.
mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDNSBool checkOnly)
{
- mDNSu32 slot;
AuthRecord *lr;
AuthGroup *ag;
if (m->CurrentRecord)
LogMsg("AnswerQuestionWithLORecord ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
m->CurrentRecord = ag->members;
@@ -4524,7 +4764,7 @@ mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDN
// details on how we handle this case. For P2P we just handle "Interface_Any" questions. For LocalOnly
// we handle both mDNSInterface_Any and scoped questions.
- if (rr->ARType == AuthRecordLocalOnly || (rr->ARType == AuthRecordP2P && q->InterfaceID == mDNSInterface_Any))
+ if (rr->ARType == AuthRecordLocalOnly || (rr->ARType == AuthRecordP2P && (q->InterfaceID == mDNSInterface_Any || q->InterfaceID == mDNSInterface_BLE)))
if (LocalOnlyRecordAnswersQuestion(rr, q))
{
if (checkOnly)
@@ -4534,7 +4774,7 @@ mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDN
m->CurrentRecord = mDNSNULL;
return mDNStrue;
}
- AnswerLocalQuestionWithLocalAuthRecord(m, rr, QC_add);
+ AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
if (m->CurrentQuestion != q)
break; // If callback deleted q, then we're finished here
}
@@ -4585,14 +4825,25 @@ mDNSlocal mDNSBool AnswerQuestionWithLORecord(mDNS *const m, DNSQuestion *q, mDN
// reasons for suppressing the query, this function should be updated.
mDNSlocal void AnswerSuppressedQuestion(mDNS *const m, DNSQuestion *q)
{
- mDNSBool SuppressQuery = q->SuppressQuery;
- mDNSBool DisallowPID = q->DisallowPID;
+ mDNSBool SuppressQuery;
+ mDNSBool DisallowPID;
+
+ // If the client did not set the kDNSServiceFlagsReturnIntermediates flag, then don't generate a negative response, just
+ // deactivate the DNSQuestion.
+ if (!q->ReturnIntermed)
+ {
+ q->ThisQInterval = 0;
+ return;
+ }
+
+ SuppressQuery = q->SuppressQuery;
+ DisallowPID = q->DisallowPID;
// make sure that QuerySuppressed() returns false
q->SuppressQuery = mDNSfalse;
q->DisallowPID = mDNSfalse;
- GenerateNegativeResponse(m, QC_suppressed);
+ GenerateNegativeResponse(m, mDNSInterface_Any, QC_suppressed);
q->SuppressQuery = SuppressQuery;
q->DisallowPID = DisallowPID;
@@ -4602,13 +4853,15 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
{
mDNSBool ShouldQueryImmediately = mDNStrue;
DNSQuestion *const q = m->NewQuestions; // Grab the question we're going to answer
- mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+#if USE_DNS64
+ if (!mDNSOpaque16IsZero(q->TargetQID)) DNS64HandleNewQuestion(m, q);
+#endif
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
mDNSBool AnsweredFromCache = mDNSfalse;
verbosedebugf("AnswerNewQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- if (cg) CheckCacheExpiration(m, slot, cg);
+ if (cg) CheckCacheExpiration(m, HashSlotFromNameHash(q->qnamehash), cg);
if (m->NewQuestions != q) { LogInfo("AnswerNewQuestion: Question deleted while doing CheckCacheExpiration"); goto exit; }
m->NewQuestions = q->next;
// Advance NewQuestions to the next *after* calling CheckCacheExpiration, because if we advance it first
@@ -4697,7 +4950,7 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
AnswerCurrentQuestionWithResourceRecord(m, rr, QC_add);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
- else if (RRTypeIsAddressType(rr->resrec.rrtype) && RRTypeIsAddressType(q->qtype))
+ else if (mDNSOpaque16IsZero(q->TargetQID) && RRTypeIsAddressType(rr->resrec.rrtype) && RRTypeIsAddressType(q->qtype))
ShouldQueryImmediately = mDNSfalse;
}
// We don't use LogInfo for this "Question deleted" message because it happens so routinely that
@@ -4711,7 +4964,7 @@ mDNSlocal void AnswerNewQuestion(mDNS *const m)
if (!QuerySuppressed(q) && !AnsweredFromCache && q->RetryWithSearchDomains)
{
LogInfo("AnswerNewQuestion: Generating response for retrying with search domains %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
- GenerateNegativeResponse(m, QC_forceresponse);
+ GenerateNegativeResponse(m, mDNSInterface_Any, QC_forceresponse);
}
if (m->CurrentQuestion != q) { debugf("AnswerNewQuestion: Question deleted while giving negative answer"); goto exit; }
@@ -4748,9 +5001,9 @@ exit:
// appropriate answers, stopping if it reaches a NewLocalOnlyRecord -- these will be handled by AnswerAllLocalQuestionsWithLocalAuthRecord
mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
{
- mDNSu32 slot;
AuthGroup *ag;
DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
+ mDNSBool retEv = mDNSfalse;
m->NewLocalOnlyQuestions = q->next; // Advance NewLocalOnlyQuestions to the next (if any)
debugf("AnswerNewLocalOnlyQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -4766,8 +5019,7 @@ mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
// 1. First walk the LocalOnly records answering the LocalOnly question
// 2. As LocalOnly questions should also be answered by any other Auth records local to the machine,
// walk the ResourceRecords list delivering the answers
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
m->CurrentRecord = ag->members;
@@ -4777,7 +5029,8 @@ mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
m->CurrentRecord = rr->next;
if (LocalOnlyRecordAnswersQuestion(rr, q))
{
- AnswerLocalQuestionWithLocalAuthRecord(m, rr, QC_add);
+ retEv = mDNStrue;
+ AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
}
@@ -4793,12 +5046,18 @@ mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
m->CurrentRecord = rr->next;
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
- AnswerLocalQuestionWithLocalAuthRecord(m, rr, QC_add);
+ retEv = mDNStrue;
+ AnswerLocalQuestionWithLocalAuthRecord(m, rr, mDNStrue);
if (m->CurrentQuestion != q) break; // If callback deleted q, then we're finished here
}
}
}
+ // The local host is the authoritative source for LocalOnly questions
+ // so if no records exist and client requested intermediates, then generate a negative response
+ if (!retEv && (m->CurrentQuestion == q) && q->ReturnIntermed)
+ GenerateNegativeResponse(m, mDNSInterface_LocalOnly, QC_forceresponse);
+
m->CurrentQuestion = mDNSNULL;
m->CurrentRecord = mDNSNULL;
}
@@ -4913,7 +5172,7 @@ mDNSlocal CacheGroup *GetCacheGroup(mDNS *const m, const mDNSu32 slot, const Res
cg->namehash = rr->namehash;
cg->members = mDNSNULL;
cg->rrcache_tail = &cg->members;
- if (namelen > sizeof(cg->namestorage))
+ if (namelen > sizeof(cg->namestorage))
cg->name = mDNSPlatformMemAllocate(namelen);
else
cg->name = (domainname*)cg->namestorage;
@@ -4925,9 +5184,9 @@ mDNSlocal CacheGroup *GetCacheGroup(mDNS *const m, const mDNSu32 slot, const Res
}
AssignDomainName(cg->name, rr->name);
- if (CacheGroupForRecord(m, slot, rr)) LogMsg("GetCacheGroup: Already have CacheGroup for %##s", rr->name->c);
+ if (CacheGroupForRecord(m, rr)) LogMsg("GetCacheGroup: Already have CacheGroup for %##s", rr->name->c);
m->rrcache_hash[slot] = cg;
- if (CacheGroupForRecord(m, slot, rr) != cg) LogMsg("GetCacheGroup: Not finding CacheGroup for %##s", rr->name->c);
+ if (CacheGroupForRecord(m, rr) != cg) LogMsg("GetCacheGroup: Not finding CacheGroup for %##s", rr->name->c);
return(cg);
}
@@ -4967,7 +5226,7 @@ mDNSexport mDNSs32 mDNS_TimeNow(const mDNS *const m)
// had its Sleep Proxy client list change, and defer to actual BPF reconfiguration to mDNS_Execute().
// (GetNextScheduledEvent() returns "now" when m->SPSProxyListChanged is set)
#define SetSPSProxyListChanged(X) do { \
- if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m, m->SPSProxyListChanged); \
+ if (m->SPSProxyListChanged && m->SPSProxyListChanged != (X)) mDNSPlatformUpdateProxyList(m->SPSProxyListChanged); \
m->SPSProxyListChanged = (X); } while(0)
// Called from mDNS_Execute() to expire stale proxy records
@@ -5011,7 +5270,7 @@ mDNSlocal void CheckRmvEventsForLocalRecords(mDNS *const m)
{
debugf("CheckRmvEventsForLocalRecords: Generating local RMV events for %s", ARDisplayString(m, rr));
rr->resrec.RecordType = kDNSRecordTypeShared;
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_rmv);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNSfalse);
if (m->CurrentRecord == rr) // If rr still exists in list, restore its state now
{
rr->resrec.RecordType = kDNSRecordTypeDeregistering;
@@ -5026,13 +5285,12 @@ mDNSlocal void CheckRmvEventsForLocalRecords(mDNS *const m)
}
}
-mDNSlocal void TimeoutQuestions(mDNS *const m)
+mDNSlocal void TimeoutQuestions_internal(mDNS *const m, DNSQuestion* questions, mDNSInterfaceID InterfaceID)
{
- m->NextScheduledStopTime = m->timenow + 0x3FFFFFFF;
if (m->CurrentQuestion)
LogMsg("TimeoutQuestions ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c,
DNSTypeName(m->CurrentQuestion->qtype));
- m->CurrentQuestion = m->Questions;
+ m->CurrentQuestion = questions;
while (m->CurrentQuestion)
{
DNSQuestion *const q = m->CurrentQuestion;
@@ -5044,7 +5302,8 @@ mDNSlocal void TimeoutQuestions(mDNS *const m)
if (m->timenow - q->StopTime >= 0)
{
LogInfo("TimeoutQuestions: question %p %##s timed out, time %d", q, q->qname.c, m->timenow - q->StopTime);
- GenerateNegativeResponse(m, QC_forceresponse);
+ q->LOAddressAnswers = 0; // unset since timing out the question
+ GenerateNegativeResponse(m, InterfaceID, QC_forceresponse);
if (m->CurrentQuestion == q) q->StopTime = 0;
}
else
@@ -5062,6 +5321,13 @@ mDNSlocal void TimeoutQuestions(mDNS *const m)
m->CurrentQuestion = mDNSNULL;
}
+mDNSlocal void TimeoutQuestions(mDNS *const m)
+{
+ m->NextScheduledStopTime = m->timenow + FutureTime; // push reschedule of TimeoutQuestions to way off into the future
+ TimeoutQuestions_internal(m, m->Questions, mDNSInterface_Any);
+ TimeoutQuestions_internal(m, m->LocalOnlyQuestions, mDNSInterface_LocalOnly);
+}
+
mDNSlocal void mDNSCoreFreeProxyRR(mDNS *const m)
{
AuthRecord *rrPtr = m->SPSRRSet, *rrNext = mDNSNULL;
@@ -5079,10 +5345,6 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
{
mDNS_Lock(m); // Must grab lock before trying to read m->timenow
-#if APPLE_OSX_mDNSResponder
- mDNSLogStatistics(m);
-#endif // APPLE_OSX_mDNSResponder
-
if (m->timenow - m->NextScheduledEvent >= 0)
{
int i;
@@ -5109,13 +5371,13 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (m->rrcache_size && m->timenow - m->NextCacheCheck >= 0)
{
mDNSu32 numchecked = 0;
- m->NextCacheCheck = m->timenow + 0x3FFFFFFF;
+ m->NextCacheCheck = m->timenow + FutureTime;
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
if (m->timenow - m->rrcache_nextcheck[slot] >= 0)
{
CacheGroup **cp = &m->rrcache_hash[slot];
- m->rrcache_nextcheck[slot] = m->timenow + 0x3FFFFFFF;
+ m->rrcache_nextcheck[slot] = m->timenow + FutureTime;
while (*cp)
{
debugf("m->NextCacheCheck %4d Slot %3d %##s", numchecked, slot, *cp ? (*cp)->name : (domainname*)"\x04NULL");
@@ -5135,7 +5397,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (m->timenow - m->NextScheduledSPS >= 0)
{
- m->NextScheduledSPS = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledSPS = m->timenow + FutureTime;
CheckProxyRecords(m, m->DuplicateRecords); // Clear m->DuplicateRecords first, then m->ResourceRecords
CheckProxyRecords(m, m->ResourceRecords);
}
@@ -5146,14 +5408,30 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
// as records could have expired during that check
if (m->timenow - m->NextScheduledKA >= 0)
{
- m->NextScheduledKA = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledKA = m->timenow + FutureTime;
mDNS_SendKeepalives(m);
}
+#if BONJOUR_ON_DEMAND
+ if (m->NextBonjourDisableTime && (m->timenow - m->NextBonjourDisableTime >= 0))
+ {
+ // Schedule immediate network change processing to leave the multicast group
+ // since the delay time has expired since the previous active registration or query.
+ m->NetworkChanged = m->timenow;
+ m->NextBonjourDisableTime = 0;
+ m->BonjourEnabled = 0;
+
+ LogInfo("mDNS_Execute: Scheduled network changed processing to leave multicast group.");
+ }
+#endif // BONJOUR_ON_DEMAND
+
// Clear AnnounceOwner if necessary. (Do this *before* SendQueries() and SendResponses().)
if (m->AnnounceOwner && m->timenow - m->AnnounceOwner >= 0)
{
m->AnnounceOwner = 0;
+
+ // This is a good time to reset the delay counter used to prevent spurious conflicts
+ m->DelayConflictProcessing = 0;
}
if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
@@ -5203,7 +5481,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (LocalRecordReady(rr))
{
debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_add);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
}
else if (!rr->next)
{
@@ -5260,7 +5538,7 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
if (LocalRecordReady(rr))
{
debugf("mDNS_Execute: Delivering Add event with LocalAuthRecord %s", ARDisplayString(m, rr));
- AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, QC_add);
+ AnswerAllLocalQuestionsWithLocalAuthRecord(m, rr, mDNStrue);
}
else LogMsg("mDNS_Execute: LocalOnlyRecord %s not ready", ARDisplayString(m, rr));
}
@@ -5314,12 +5592,17 @@ mDNSexport mDNSs32 mDNS_Execute(mDNS *const m)
m->RandomQueryDelay = 0;
m->RandomReconfirmDelay = 0;
+ // See if any questions (or local-only questions) have timed out
if (m->NextScheduledStopTime && m->timenow - m->NextScheduledStopTime >= 0) TimeoutQuestions(m);
#ifndef UNICAST_DISABLED
if (m->NextSRVUpdate && m->timenow - m->NextSRVUpdate >= 0) UpdateAllSRVRecords(m);
if (m->timenow - m->NextScheduledNATOp >= 0) CheckNATMappings(m);
if (m->timenow - m->NextuDNSEvent >= 0) uDNS_Tasks(m);
#endif
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ extern void serviceBLE();
+ if (m->NextBLEServiceTime && (m->timenow - m->NextBLEServiceTime >= 0)) serviceBLE();
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
}
// Note about multi-threaded systems:
@@ -5359,11 +5642,9 @@ mDNSlocal void SuspendLLQs(mDNS *m)
mDNSlocal mDNSBool QuestionHasLocalAnswers(mDNS *const m, DNSQuestion *q)
{
AuthRecord *rr;
- mDNSu32 slot;
AuthGroup *ag;
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
for (rr = ag->members; rr; rr=rr->next)
@@ -5399,7 +5680,7 @@ mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question,
!SameDomainLabel(question->qname.c, (const mDNSu8 *)"\x0c_autotunnel6")&& question->QuestionCallback != AutoTunnelCallback)
{
question->NoAnswer = NoAnswer_Suspended;
- AddNewClientTunnel(m, question);
+ AddNewClientTunnel(question);
return;
}
#endif // APPLE_OSX_mDNSResponder
@@ -5565,11 +5846,7 @@ mDNSexport void mDNSCoreRestartQuestion(mDNS *const m, DNSQuestion *q)
if (mDNSOpaque16IsZero(q->TargetQID) && ActiveQuestion(q))
{
q->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
-#if mDNS_REQUEST_UNICAST_RESPONSE
- q->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
-#else // mDNS_REQUEST_UNICAST_RESPONSE
- q->RequestUnicast = SET_QU_IN_FIRST_QUERY;
-#endif // mDNS_REQUEST_UNICAST_RESPONSE
+ q->RequestUnicast = kDefaultRequestUnicastCount;
q->LastQTime = m->timenow - q->ThisQInterval;
q->RecentAnswerPkts = 0;
ExpireDupSuppressInfo(q->DupSuppress, m->timenow);
@@ -5578,23 +5855,26 @@ mDNSexport void mDNSCoreRestartQuestion(mDNS *const m, DNSQuestion *q)
}
// restart the probe/announce cycle for multicast record
-mDNSexport void mDNSCoreRestartRegistration(mDNS *const m, AuthRecord *rr, int announceCount)
+mDNSexport void mDNSCoreRestartRegistration(mDNS *const m, AuthRecord *rr, int announceCount)
{
if (!AuthRecord_uDNS(rr))
{
if (rr->resrec.RecordType == kDNSRecordTypeVerified && !rr->DependentOn) rr->resrec.RecordType = kDNSRecordTypeUnique;
rr->ProbeCount = DefaultProbeCountForRecordType(rr->resrec.RecordType);
- // announceCount < 0 indicates default announce count should be used
- if (announceCount < 0)
- announceCount = InitialAnnounceCount;
- if (rr->AnnounceCount < announceCount)
- rr->AnnounceCount = announceCount;
-
if (mDNS_KeepaliveRecord(&rr->resrec))
- rr->AnnounceCount = 0; // Do not announce keepalive records
+ {
+ rr->AnnounceCount = 0; // Do not announce keepalive records
+ }
else
- rr->AnnounceCount = InitialAnnounceCount;
+ {
+ // announceCount < 0 indicates default announce count should be used
+ if (announceCount < 0)
+ announceCount = InitialAnnounceCount;
+ if (rr->AnnounceCount < (mDNSu8)announceCount)
+ rr->AnnounceCount = (mDNSu8)announceCount;
+ }
+
rr->SendNSECNow = mDNSNULL;
InitializeLastAPTime(m, rr);
}
@@ -5676,7 +5956,7 @@ mDNSexport void mDNS_UpdateAllowSleep(mDNS *const m)
}
// Call the platform code to enable/disable sleep
- mDNSPlatformSetAllowSleep(m, allowSleep, reason);
+ mDNSPlatformSetAllowSleep(allowSleep, reason);
#else
(void) m;
#endif /* !defined(IDLESLEEPCONTROL_DISABLED) */
@@ -5687,7 +5967,7 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
// If it is not a uDNS record, check to see if the updateid is zero. "updateid" is cleared when we have
// sent the resource record on all the interfaces. If the update id is not zero, check to see if it is time
// to send.
- if (AuthRecord_uDNS(rr) || (rr->AuthFlags & AuthFlagsWakeOnly) || mDNSOpaque16IsZero(rr->updateid) ||
+ if (AuthRecord_uDNS(rr) || (rr->AuthFlags & AuthFlagsWakeOnly) || mDNSOpaque16IsZero(rr->updateid) ||
m->timenow - (rr->LastAPTime + rr->ThisAPInterval) < 0)
{
return mDNSfalse;
@@ -5708,53 +5988,56 @@ mDNSlocal mDNSBool mDNSUpdateOkToSend(mDNS *const m, AuthRecord *rr, NetworkInte
return mDNSfalse;
}
-mDNSexport void UpdateRMACCallback(mDNS *const m, void *context)
-{
- IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
- m->CurrentRecord = m->ResourceRecords;
-
- if (!addrmap)
- {
- LogMsg("UpdateRMACCallback: Address mapping is NULL");
- return;
- }
-
- while (m->CurrentRecord)
- {
- AuthRecord *rr = m->CurrentRecord;
- // If this is a non-sleep proxy keepalive record and the remote IP address matches, update the RData
- if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
- {
- mDNSAddr raddr;
- getKeepaliveRaddr(m, rr, &raddr);
- if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
- {
- // Update the MAC address only if it is not a zero MAC address
- mDNSEthAddr macAddr;
- mDNSu8 *ptr = GetValueForMACAddr((mDNSu8 *)(addrmap->ethaddr), (mDNSu8 *) (addrmap->ethaddr + sizeof(addrmap->ethaddr)), &macAddr);
- if (ptr != mDNSNULL && !mDNSEthAddressIsZero(macAddr))
- {
- UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
- }
- }
- }
- m->CurrentRecord = rr->next;
- }
-
- if (addrmap)
- {
- mDNSPlatformMemFree(addrmap);
- }
+mDNSexport void UpdateRMAC(mDNS *const m, void *context)
+{
+ IPAddressMACMapping *addrmap = (IPAddressMACMapping *)context ;
+ m->CurrentRecord = m->ResourceRecords;
+
+ if (!addrmap)
+ {
+ LogMsg("UpdateRMAC: Address mapping is NULL");
+ return;
+ }
+
+ while (m->CurrentRecord)
+ {
+ AuthRecord *rr = m->CurrentRecord;
+ // If this is a non-sleep proxy keepalive record and the remote IP address matches, update the RData
+ if (!rr->WakeUp.HMAC.l[0] && mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ mDNSAddr raddr;
+ getKeepaliveRaddr(m, rr, &raddr);
+ if (mDNSSameAddress(&raddr, &addrmap->ipaddr))
+ {
+ // Update the MAC address only if it is not a zero MAC address
+ mDNSEthAddr macAddr;
+ mDNSu8 *ptr = GetValueForMACAddr((mDNSu8 *)(addrmap->ethaddr), (mDNSu8 *) (addrmap->ethaddr + sizeof(addrmap->ethaddr)), &macAddr);
+ if (ptr != mDNSNULL && !mDNSEthAddressIsZero(macAddr))
+ {
+ UpdateKeepaliveRData(m, rr, mDNSNULL, mDNStrue, (char *)(addrmap->ethaddr));
+ }
+ }
+ }
+ m->CurrentRecord = rr->next;
+ }
+
+ if (addrmap)
+ mDNSPlatformMemFree(addrmap);
+
}
mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr)
{
mDNSu16 newrdlength;
- mDNSAddr laddr, raddr;
- mDNSEthAddr eth;
- mDNSIPPort lport, rport;
- mDNSu32 timeout, seq, ack;
- mDNSu16 win;
+ mDNSAddr laddr = zeroAddr;
+ mDNSAddr raddr = zeroAddr;
+ mDNSEthAddr eth = zeroEthAddr;
+ mDNSIPPort lport = zeroIPPort;
+ mDNSIPPort rport = zeroIPPort;
+ mDNSu32 timeout = 0;
+ mDNSu32 seq = 0;
+ mDNSu32 ack = 0;
+ mDNSu16 win = 0;
UTF8str255 txt;
int rdsize;
RData *newrd;
@@ -5764,8 +6047,7 @@ mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkIn
// Note: If we fail to update the DNS NULL record with additional information in this function, it will be registered
// with the SPS like any other record. SPS will not send keepalives if it does not have additional information.
mDNS_ExtractKeepaliveInfo(rr, &timeout, &laddr, &raddr, &eth, &seq, &ack, &lport, &rport, &win);
- if (!timeout || mDNSAddressIsZero(&laddr) || mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(lport) ||
- mDNSIPPortIsZero(rport))
+ if (!timeout || mDNSAddressIsZero(&laddr) || mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(lport) || mDNSIPPortIsZero(rport))
{
LogMsg("UpdateKeepaliveRData: not a valid record %s for keepalive %#a:%d %#a:%d", ARDisplayString(m, rr), &laddr, lport.NotAnInteger, &raddr, rport.NotAnInteger);
return mStatus_UnknownErr;
@@ -5785,7 +6067,7 @@ mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkIn
// now, then we don't update the DNS NULL record. But we do not prevent it from registering with the SPS. When SPS sees
// this DNS NULL record, it does not send any keepalives as it does not have all the information
mDNSPlatformMemZero(&mti, sizeof (mDNSTCPInfo));
- ret = mDNSPlatformRetrieveTCPInfo(m, &laddr, &lport, &raddr, &rport, &mti);
+ ret = mDNSPlatformRetrieveTCPInfo(&laddr, &lport, &raddr, &rport, &mti);
if (ret != mStatus_NoError)
{
LogMsg("mDNSPlatformRetrieveTCPInfo: mDNSPlatformRetrieveTCPInfo failed %d", ret);
@@ -5828,8 +6110,8 @@ mDNSexport mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkIn
// free that memory here before copying in the new data.
if ( rr->resrec.rdata != &rr->rdatastorage)
{
- mDNSPlatformMemFree(rr->resrec.rdata);
LogSPS("UpdateKeepaliveRData: Freed allocated memory for keep alive packet: %s ", ARDisplayString(m, rr));
+ mDNSPlatformMemFree(rr->resrec.rdata);
}
SetNewRData(&rr->resrec, newrd, newrdlength); // Update our rdata
@@ -5969,7 +6251,7 @@ mDNSlocal void SendSPSRegistrationForOwner(mDNS *const m, NetworkInterfaceInfo *
LogSPS("SendSPSRegistration: Sending Update %s %d (%d) id %5d with %d records %d bytes to %#a:%d", intf->ifname, intf->NextSPSAttempt, sps,
mDNSVal16(m->omsg.h.id), m->omsg.h.mDNS_numUpdates, p - m->omsg.data, &intf->SPSAddr[sps], mDNSVal16(intf->SPSPort[sps]));
- // if (intf->NextSPSAttempt < 5) m->omsg.h.flags = zeroID; // For simulating packet loss
+ // if (intf->NextSPSAttempt < 5) m->omsg.h.flags = zeroID; // For simulating packet loss
err = mDNSSendDNSMessage(m, &m->omsg, p, intf->InterfaceID, mDNSNULL, &intf->SPSAddr[sps], intf->SPSPort[sps], mDNSNULL, mDNSNULL, mDNSfalse);
if (err) LogSPS("SendSPSRegistration: mDNSSendDNSMessage err %d", err);
if (err && intf->SPSAddr[sps].type == mDNSAddrType_IPv4 && intf->NetWakeResolve[sps].ThisQInterval == -1)
@@ -6042,7 +6324,7 @@ mDNSlocal void SPSInitRecordsBeforeUpdate(mDNS *const m, mDNSOpaque64 updateIntI
{
AuthRecord *ar;
LogSPS("SPSInitRecordsBeforeUpdate: UpdateIntID 0x%x 0x%x", updateIntID.l[1], updateIntID.l[0]);
-
+
*WakeOnlyService = mDNSfalse;
// Before we store the A and AAAA records that we are going to register with the sleep proxy,
@@ -6159,7 +6441,7 @@ mDNSlocal void NetWakeResolve(mDNS *const m, DNSQuestion *question, const Resour
if (!AddRecord) return; // Don't care about REMOVE events
if (answer->rrtype != question->qtype) return; // Don't care about CNAMEs
- // if (answer->rrtype == kDNSType_AAAA && sps == 0) return; // To test failing to resolve sleep proxy's address
+ // if (answer->rrtype == kDNSType_AAAA && sps == 0) return; // To test failing to resolve sleep proxy's address
if (answer->rrtype == kDNSType_SRV)
{
@@ -6245,14 +6527,8 @@ mDNSlocal void SendGoodbyesForWakeOnlyService(mDNS *const m, mDNSBool *WakeOnlyS
{
return SendGoodbyesForSelectServices(m, WakeOnlyService, WAKE_ONLY_SERVICE);
}
-#endif // APPLE_OSx_mDNSResponder
+#endif // APPLE_OSX_mDNSResponder
-#ifdef APPLE_OSX_mDNSResponder
-mDNSlocal void SendGoodbyesForACOnlyServices(mDNS *const m, mDNSBool *acOnlyService)
-{
- return SendGoodbyesForSelectServices(m, acOnlyService, AC_ONLY_SERVICE);
-}
-#endif
mDNSlocal void SendSleepGoodbyes(mDNS *const m, mDNSBool AllInterfaces, mDNSBool unicast)
{
@@ -6349,25 +6625,23 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
{
mDNSBool SendGoodbyes = mDNStrue;
mDNSBool WakeOnlyService = mDNSfalse;
- mDNSBool ACOnlyService = mDNSfalse;
mDNSBool invokeKACallback = mDNStrue;
const CacheRecord *sps[3] = { mDNSNULL };
mDNSOpaque64 updateIntID = zeroOpaque64;
- mDNSInterfaceID registeredIntfIDS[128];
+ mDNSInterfaceID registeredIntfIDS[128] = { 0 };
mDNSu32 registeredCount = 0;
int skippedRegistrations = 0;
m->NextScheduledSPRetry = m->timenow;
+ // Clear out the SCDynamic entry that stores the external SPS information
+ mDNSPlatformClearSPSData();
+
if (!m->SystemWakeOnLANEnabled) LogSPS("BeginSleepProcessing: m->SystemWakeOnLANEnabled is false");
else if (!mDNSCoreHaveAdvertisedMulticastServices(m)) LogSPS("BeginSleepProcessing: No advertised services");
else // If we have at least one advertised service
{
NetworkInterfaceInfo *intf;
-
- // Clear out the SCDynamic entry that stores the external SPS information
- mDNSPlatformClearSPSMACAddr();
-
for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
{
// Intialize it to false. These values make sense only when SleepState is set to Sleeping.
@@ -6407,18 +6681,21 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
else if (SupportsInNICProxy(intf))
{
mDNSBool keepaliveOnly = mDNSfalse;
- if (ActivateLocalProxy(m, intf, &keepaliveOnly) == mStatus_NoError)
+ if (ActivateLocalProxy(intf, &keepaliveOnly) == mStatus_NoError)
{
SendGoodbyesForWakeOnlyService(m, &WakeOnlyService);
- if (keepaliveOnly)
- SendGoodbyesForACOnlyServices(m, &ACOnlyService);
- SendGoodbyes = mDNSfalse;
- invokeKACallback = mDNSfalse;
+
+ // Send goodbyes for all advertised services if the only record offloaded was the keepalive record.
+ SendGoodbyes = (keepaliveOnly) ? mDNStrue: mDNSfalse;
+ invokeKACallback = mDNSfalse;
LogSPS("BeginSleepProcessing: %-6s using local proxy", intf->ifname);
// This will leave m->SleepState set to SleepState_Transferring,
// which is okay because with no outstanding resolves, or updates in flight,
// mDNSCoreReadyForSleep() will conclude correctly that all the updates have already completed
+ // Setting this flag activates the SleepLimit which delays sleep by 5 seconds and
+ // will allow the system to deregister any BTMM records.
+ m->NextScheduledSPRetry = m->timenow + (5 * mDNSPlatformOneSecond);
registeredIntfIDS[registeredCount] = intf->InterfaceID;
registeredCount++;
}
@@ -6497,7 +6774,7 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
//
// - If there are no sleep proxy servers, then send goodbyes on all interfaces
// for both multicast and unicast.
- //
+ //
// - If we skipped registrations on some interfaces, then we have already marked
// them appropriately above. We don't need to send goodbyes for unicast as
// we have registered with at least one sleep proxy.
@@ -6517,10 +6794,10 @@ mDNSlocal void BeginSleepProcessing(mDNS *const m)
LogSPS("BeginSleepProcessing: Not registering with Sleep Proxy Server on all interfaces");
SendSleepGoodbyes(m, mDNSfalse, mDNSfalse);
}
- else if (WakeOnlyService || ACOnlyService)
+ else if (WakeOnlyService)
{
// If we saw WakeOnly service above, send the goodbyes now.
- LogSPS("BeginSleepProcessing: Sending goodbyes for %s", WakeOnlyService? "WakeOnlyService" : "AC Only Service");
+ LogSPS("BeginSleepProcessing: Sending goodbyes for WakeOnlyService");
SendResponses(m);
}
}
@@ -6546,7 +6823,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
#ifndef SPC_DISABLED
if (oldstate == 1) mDNS_DeregisterService(m, &m->SPSRecords);
#else
- (void)oldstate;
+ (void)oldstate;
#endif
mDNS_ReclaimLockAfterCallback();
}
@@ -6594,7 +6871,11 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
{
m->SleepState = SleepState_Awake;
m->SleepSeqNum++;
- m->DelaySleep = 0;
+ // If the machine wakes and then immediately tries to sleep again (e.g. a maintenance wake)
+ // then we enforce a minimum delay of five seconds before we begin sleep processing.
+ // This is to allow time for the Ethernet link to come up, DHCP to get an address, mDNS to issue queries, etc.,
+ // before we make our determination of whether there's a Sleep Proxy out there we should register with.
+ m->DelaySleep = NonZeroTime(m->timenow + kDarkWakeDelaySleep);
}
if (m->SPSState == 3)
@@ -6603,7 +6884,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
mDNSCoreBeSleepProxyServer_internal(m, m->SPSType, m->SPSPortability, m->SPSMarginalPower, m->SPSTotalPower, m->SPSFeatureFlags);
}
m->mDNSStats.Wakes++;
-
+ m->DelayConflictProcessing = MAX_CONFLICT_PROCESSING_DELAYS;
// ... and the same for NextSPSAttempt
for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next)) intf->NextSPSAttempt = -1;
@@ -6617,11 +6898,6 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
// 2. Re-validate our cache records
currtime = mDNSPlatformUTC();
-#if APPLE_OSX_mDNSResponder
- // start time of this statistics gathering interval
- m->StatStartTime = currtime;
-#endif // APPLE_OSX_mDNSResponder
-
diff = currtime - m->TimeSlept;
FORALL_CACHERECORDS(slot, cg, cr)
{
@@ -6644,7 +6920,7 @@ mDNSexport void mDNSCoreMachineSleep(mDNS *const m, mDNSBool sleep)
mDNSu32 uTTL = RRUnadjustedTTL(cr->resrec.rroriginalttl);
const mDNSs32 remain = uTTL - (m->timenow - cr->TimeRcvd) / mDNSPlatformOneSecond;
- // -if we have slept longer than the remaining TTL, purge and start fresh.
+ // -if we have slept longer than the remaining TTL, purge and start fresh.
// -if we have been sleeping for a long time, we could reduce TimeRcvd below by
// a sufficiently big value which could cause the value to go into the future
// because of the signed comparison of time. For this to happen, we should have been
@@ -6768,7 +7044,7 @@ mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now)
if (rr->state == regState_Refresh && rr->tcp)
{ LogSPS("mDNSCoreReadyForSleep: waiting for Record updateIntID 0x%x 0x%x (updateid %d) %s", rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; }
#if APPLE_OSX_mDNSResponder
- if (!RecordReadyForSleep(m, rr)) { LogSPS("mDNSCoreReadyForSleep: waiting for %s", ARDisplayString(m, rr)); goto notready; }
+ if (!RecordReadyForSleep(rr)) { LogSPS("mDNSCoreReadyForSleep: waiting for %s", ARDisplayString(m, rr)); goto notready; }
#endif
}
@@ -7099,8 +7375,7 @@ exit:
mDNSlocal CacheRecord *FindIdenticalRecordInCache(const mDNS *const m, const ResourceRecord *const pktrr)
{
- mDNSu32 slot = HashSlot(pktrr->name);
- CacheGroup *cg = CacheGroupForRecord(m, slot, pktrr);
+ CacheGroup *cg = CacheGroupForRecord(m, pktrr);
CacheRecord *rr;
mDNSBool match;
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
@@ -7128,7 +7403,7 @@ mDNSlocal void DeregisterProxyRecord(mDNS *const m, AuthRecord *const rr)
mDNSlocal void ClearKeepaliveProxyRecords(mDNS *const m, const OwnerOptData *const owner, AuthRecord *const thelist, const mDNSInterfaceID InterfaceID)
{
if (m->CurrentRecord)
- LogMsg("ClearIdenticalProxyRecords ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
+ LogMsg("ClearKeepaliveProxyRecords ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
m->CurrentRecord = thelist;
// Normally, the RDATA of the keepalive record will be different each time and hence we always
@@ -7262,9 +7537,9 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
}
- //
+ //
// Look in Authority Section for NSEC3 record
- //
+ //
mDNSParseNSEC3Records(m, query, end, InterfaceID, &McastNSEC3Records);
@@ -7328,7 +7603,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
// As we have verified this question to be part of the same subset,
// set the anonymous data which is needed below when walk the cache
// records to see what answers we should be expecting. The cache records
- // may cache only the nsec3RR and not the anonymous data itself.
+ // may cache only the nsec3RR and not the anonymous data itself.
if (pktq.AnonInfo && rr->resrec.AnonInfo)
SetAnonData(&pktq, &rr->resrec, mDNStrue);
@@ -7347,7 +7622,7 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
// We only mark this question for sending if it is at least one second since the last time we multicast it
// on this interface. If it is more than a second, or LastMCInterface is different, then we may multicast it.
// This is to guard against the case where someone blasts us with queries as fast as they can.
- if (m->timenow - (rr->LastMCTime + mDNSPlatformOneSecond) >= 0 ||
+ if ((mDNSu32)(m->timenow - rr->LastMCTime) >= (mDNSu32)mDNSPlatformOneSecond ||
(rr->LastMCInterface != mDNSInterfaceMark && rr->LastMCInterface != InterfaceID))
rr->NR_AnswerTo = NR_AnswerMulticast;
}
@@ -7376,44 +7651,25 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
if (query->h.flags.b[0] & kDNSFlag0_TC)
m->mDNSStats.KnownAnswerMultiplePkts++;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (QuestionNeedsMulticastResponse)
-#else
// We only do the following accelerated cache expiration and duplicate question suppression processing
// for non-truncated multicast queries with multicast responses.
// For any query generating a unicast response we don't do this because we can't assume we will see the response.
// For truncated queries we don't do this because a response we're expecting might be suppressed by a subsequent
// known-answer packet, and when there's packet loss we can't safely assume we'll receive *all* known-answer packets.
if (QuestionNeedsMulticastResponse && !(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif
{
#if POOF_ENABLED
- const mDNSu32 slot = HashSlot(&pktq.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, pktq.qnamehash, &pktq.qname);
+ CacheGroup *cg = CacheGroupForName(m, pktq.qnamehash, &pktq.qname);
CacheRecord *cr;
// Make a list indicating which of our own cache records we expect to see updated as a result of this query
// Note: Records larger than 1K are not habitually multicast, so don't expect those to be updated
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (!(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
for (cr = cg ? cg->members : mDNSNULL; cr; cr=cr->next)
if (SameNameRecordAnswersQuestion(&cr->resrec, &pktq) && cr->resrec.rdlength <= SmallRecordLimit)
if (!cr->NextInKAList && eap != &cr->NextInKAList)
{
*eap = cr;
eap = &cr->NextInKAList;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (cr->MPUnansweredQ == 0 || m->timenow - cr->MPLastUnansweredQT >= mDNSPlatformOneSecond)
- {
- // Although MPUnansweredQ is only really used for multi-packet query processing,
- // we increment it for both single-packet and multi-packet queries, so that it stays in sync
- // with the MPUnansweredKA value, which by necessity is incremented for both query types.
- cr->MPUnansweredQ++;
- cr->MPLastUnansweredQT = m->timenow;
- cr->MPExpectingKA = mDNStrue;
- }
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
}
#endif // POOF_ENABLED
@@ -7421,9 +7677,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
// We only do this for non-truncated queries. Right now it would be too complicated to try
// to keep track of duplicate suppression state between multiple packets, especially when we
// can't guarantee to receive all of the Known Answer packets that go with a particular query.
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- if (!(query->h.flags.b[0] & kDNSFlag0_TC))
-#endif
// For anonymous question, the duplicate suppressesion should happen if the
// question belongs in the same group. As the group is expected to be
// small, we don't do the optimization for now.
@@ -7507,16 +7760,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
ourcacherr = FindIdenticalRecordInCache(m, &m->rec.r.resrec);
- #if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- // See if this Known-Answer suppresses any answers we were expecting for our cache records. We do this always,
- // even if the TC bit is not set (the TC bit will *not* be set in the *last* packet of a multi-packet KA list).
- if (ourcacherr && ourcacherr->MPExpectingKA && m->timenow - ourcacherr->MPLastUnansweredQT < mDNSPlatformOneSecond)
- {
- ourcacherr->MPUnansweredKA++;
- ourcacherr->MPExpectingKA = mDNSfalse;
- }
- #endif
-
#if POOF_ENABLED
// Having built our ExpectedAnswers list from the questions in this packet, we then remove
// any records that are suppressed by the Known Answer list in this packet.
@@ -7563,13 +7806,9 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
mDNSBool SendMulticastResponse = mDNSfalse; // Send modern multicast response
mDNSBool SendUnicastResponse = mDNSfalse; // Send modern unicast response (not legacy unicast response)
-#if !TARGET_OS_EMBEDDED
- // always honor kDNSQClass_UnicastResponse in embedded environment to increase reliability
- // in high multicast packet loss environments.
-
- // If it's been one TTL/4 since we multicast this, then send a multicast response
+ // If it's been one TTL/4 since we multicast this, then send a multicast response
// for conflict detection, etc.
- if (m->timenow - (rr->LastMCTime + TicksTTL(rr)/4) >= 0)
+ if ((mDNSu32)(m->timenow - rr->LastMCTime) >= (mDNSu32)TicksTTL(rr)/4)
{
SendMulticastResponse = mDNStrue;
// If this record was marked for modern (delayed) unicast response, then mark it as promoted to
@@ -7581,7 +7820,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
rr->NR_AnswerTo = NR_AnswerMulticast;
}
}
-#endif // !TARGET_OS_EMBEDDED
// If the client insists on a multicast response, then we'd better send one
if (rr->NR_AnswerTo == NR_AnswerMulticast)
@@ -7598,7 +7836,6 @@ mDNSlocal mDNSu8 *ProcessQuery(mDNS *const m, const DNSMessage *const query, con
{
SendLegacyResponse = mDNStrue;
}
-
if (SendMulticastResponse || SendUnicastResponse)
{
@@ -7705,15 +7942,12 @@ exit:
// For non-truncated queries, we can definitively say that we should expect
// to be seeing a response for any records still left in the ExpectedAnswers list
if (!(query->h.flags.b[0] & kDNSFlag0_TC))
- if (cr->UnansweredQueries == 0 || m->timenow - cr->LastUnansweredTime >= mDNSPlatformOneSecond)
+ if (cr->UnansweredQueries == 0 || m->timenow - cr->LastUnansweredTime >= mDNSPlatformOneSecond * 3/4)
{
cr->UnansweredQueries++;
cr->LastUnansweredTime = m->timenow;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
if (cr->UnansweredQueries > 1)
- debugf("ProcessQuery: (!TC) UAQ %lu MPQ %lu MPKA %lu %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ debugf("ProcessQuery: UnansweredQueries %lu %s", cr->UnansweredQueries, CRDisplayString(m, cr));
SetNextCacheCheckTimeForRecord(m, cr);
}
@@ -7721,47 +7955,14 @@ exit:
// then mark it to expire in five seconds if we don't get a response by then.
if (cr->UnansweredQueries >= MaxUnansweredQueries)
{
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
// Only show debugging message if this record was not about to expire anyway
- if (RRExpireTime(cr) - m->timenow > 4 * mDNSPlatformOneSecond)
- debugf("ProcessQuery: (Max) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
+ if (RRExpireTime(cr) - m->timenow > (mDNSs32) kDefaultReconfirmTimeForNoAnswer * 4 / 3 + mDNSPlatformOneSecond)
+ LogInfo("ProcessQuery: UnansweredQueries %lu interface %lu TTL %lu mDNS_Reconfirm() for %s",
+ cr->UnansweredQueries, InterfaceID, (RRExpireTime(cr) - m->timenow + mDNSPlatformOneSecond-1) / mDNSPlatformOneSecond, CRDisplayString(m, cr));
+
m->mDNSStats.PoofCacheDeletions++;
mDNS_Reconfirm_internal(m, cr, kDefaultReconfirmTimeForNoAnswer);
}
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- // Make a guess, based on the multi-packet query / known answer counts, whether we think we
- // should have seen an answer for this. (We multiply MPQ by 4 and MPKA by 5, to allow for
- // possible packet loss of up to 20% of the additional KA packets.)
- else if (cr->MPUnansweredQ * 4 > cr->MPUnansweredKA * 5 + 8)
- {
- // We want to do this conservatively.
- // If there are so many machines on the network that they have to use multi-packet known-answer lists,
- // then we don't want them to all hit the network simultaneously with their final expiration queries.
- // By setting the record to expire in four minutes, we achieve two things:
- // (a) the 90-95% final expiration queries will be less bunched together
- // (b) we allow some time for us to witness enough other failed queries that we don't have to do our own
- mDNSu32 remain = (mDNSu32)(RRExpireTime(cr) - m->timenow) / 4;
- if (remain > 240 * (mDNSu32)mDNSPlatformOneSecond)
- remain = 240 * (mDNSu32)mDNSPlatformOneSecond;
-
- // Only show debugging message if this record was not about to expire anyway
- if (RRExpireTime(cr) - m->timenow > 4 * mDNSPlatformOneSecond)
- debugf("ProcessQuery: (MPQ) UAQ %lu MPQ %lu MPKA %lu mDNS_Reconfirm() for %s",
- cr->UnansweredQueries, cr->MPUnansweredQ, cr->MPUnansweredKA, CRDisplayString(m, cr));
-
- if (remain <= 60 * (mDNSu32)mDNSPlatformOneSecond)
- cr->UnansweredQueries++; // Treat this as equivalent to one definite unanswered query
- cr->MPUnansweredQ = 0; // Clear MPQ/MPKA statistics
- cr->MPUnansweredKA = 0;
- cr->MPExpectingKA = mDNSfalse;
-
- if (remain < kDefaultReconfirmTimeForNoAnswer)
- remain = kDefaultReconfirmTimeForNoAnswer;
- mDNS_Reconfirm_internal(m, cr, remain);
- }
-#endif // ENABLE_MULTI_PACKET_QUERY_SNOOPING
}
#endif // POOF_ENABLED
@@ -7792,15 +7993,16 @@ mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg,
mDNSBool QueryWasLocalUnicast = srcaddr && dstaddr &&
!mDNSAddrIsDNSMulticast(dstaddr) && mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr);
- if (!InterfaceID && dstaddr && mDNSAddrIsDNSMulticast(dstaddr))
+ if (!dstaddr || (!InterfaceID && mDNSAddrIsDNSMulticast(dstaddr)))
{
+ const char *const reason = !dstaddr ? "Received over TCP connection" : "Multicast, but no InterfaceID";
LogMsg("Ignoring Query from %#-15a:%-5d to %#-15a:%-5d on 0x%p with "
- "%2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s %d bytes (Multicast, but no InterfaceID)",
+ "%2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s %d bytes (%s)",
srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), InterfaceID,
msg->h.numQuestions, msg->h.numQuestions == 1 ? ", " : "s,",
msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
- msg->h.numAdditionals, msg->h.numAdditionals == 1 ? " " : "s", end - msg->data);
+ msg->h.numAdditionals, msg->h.numAdditionals == 1 ? " " : "s", end - msg->data, reason);
return;
}
@@ -7882,10 +8084,7 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
mDNSIPPort srcp;
if (!tcp)
{
- if (q->LocalSocket)
- srcp = q->LocalSocket->port;
- else
- srcp = zeroIPPort;
+ srcp = q->LocalSocket ? q->LocalSocket->port : zeroIPPort;
}
else
{
@@ -7893,9 +8092,9 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
}
if (mDNSSameIPPort(srcp, port)) return(q);
- // if (mDNSSameAddress(srcaddr, &q->Target)) return(mDNStrue);
- // if (q->LongLived && mDNSSameAddress(srcaddr, &q->servAddr)) return(mDNStrue); Shouldn't need this now that we have LLQType checking
- // if (TrustedSource(m, srcaddr)) return(mDNStrue);
+ // if (mDNSSameAddress(srcaddr, &q->Target)) return(mDNStrue);
+ // if (q->LongLived && mDNSSameAddress(srcaddr, &q->servAddr)) return(mDNStrue); Shouldn't need this now that we have LLQType checking
+ // if (TrustedSource(m, srcaddr)) return(mDNStrue);
LogInfo("WARNING: Ignoring suspect uDNS response for %##s (%s) [q->Target %#a:%d] from %#a:%d %s",
q->qname.c, DNSTypeName(q->qtype), &q->Target, mDNSVal16(srcp), srcaddr, mDNSVal16(port), CRDisplayString(m, rr));
return(mDNSNULL);
@@ -7933,7 +8132,7 @@ mDNSexport CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, C
if (!m->rec.r.resrec.InterfaceID) debugf("CreateNewCacheEntry %s", CRDisplayString(m, &m->rec.r));
//if (RDLength > InlineCacheRDSize)
- // LogInfo("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
+ // LogInfo("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
if (!cg) cg = GetCacheGroup(m, slot, &m->rec.r.resrec); // If we don't have a CacheGroup for this name, make one now
if (cg) rr = GetCacheRecord(m, cg, RDLength); // Make a cache record, being careful not to recycle cg
@@ -8010,19 +8209,13 @@ mDNSlocal void RefreshCacheRecord(mDNS *const m, CacheRecord *rr, mDNSu32 ttl)
rr->TimeRcvd = m->timenow;
rr->resrec.rroriginalttl = ttl;
rr->UnansweredQueries = 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- rr->MPUnansweredQ = 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
-#endif
SetNextCacheCheckTimeForRecord(m, rr);
}
mDNSexport void GrantCacheExtensions(mDNS *const m, DNSQuestion *q, mDNSu32 lease)
{
CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *cg = CacheGroupForName(m, q->qnamehash, &q->qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->CRActiveQuestion == q)
{
@@ -8197,7 +8390,7 @@ mDNSlocal void mDNSCoreReceiveNoDNSSECAnswers(mDNS *const m, const DNSMessage *c
LogMsg("mDNSCoreReceiveNoDNSSECAnswers: ERROR!! qptr %##s (%s) Duplicate question matching response", qptr->qname.c, DNSTypeName(qptr->qtype));
// Be careful to call the callback for duplicate questions first and then the original
- // question. If we called the callback on the original question, it could stop and
+ // question. If we called the callback on the original question, it could stop and
// a duplicate question would become the original question.
mDNS_DropLockBeforeCallback(); // Allow client (and us) to legally make mDNS API calls
for (q = qptr->next ; q && q != m->NewQuestions; q = next)
@@ -8235,8 +8428,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
if (ptr && (qptr = ExpectingUnicastResponseForQuestion(m, dstport, response->h.id, &q, !dstaddr)))
{
CacheRecord *rr, *neg = mDNSNULL;
- mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (SameNameRecordAnswersQuestion(&rr->resrec, qptr))
{
@@ -8272,7 +8464,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
// the application
if (qptr->ProxyQuestion)
qptr->responseFlags = response->h.flags;
- GenerateNegativeResponse(m, QC_forceresponse);
+ GenerateNegativeResponse(m, mDNSInterface_Any, QC_forceresponse);
m->CurrentQuestion = mDNSNULL;
}
else
@@ -8305,8 +8497,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_SOA)
{
- const mDNSu32 s = HashSlot(m->rec.r.resrec.name);
- CacheGroup *cgSOA = CacheGroupForRecord(m, s, &m->rec.r.resrec);
+ CacheGroup *cgSOA = CacheGroupForRecord(m, &m->rec.r.resrec);
const rdataSOA *const soa = (const rdataSOA *)m->rec.r.resrec.rdata->u.data;
mDNSu32 ttl_s = soa->min;
// We use the lesser of the SOA.MIN field and the SOA record's TTL, *except*
@@ -8318,7 +8509,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
// Create the SOA record as we may have to return this to the questions
// that we are acting as a proxy for currently or in the future.
- SOARecord = CreateNewCacheEntry(m, s, cgSOA, 1, mDNSfalse, mDNSNULL);
+ SOARecord = CreateNewCacheEntry(m, HashSlotFromNameHash(m->rec.r.resrec.namehash), cgSOA, 1, mDNSfalse, mDNSNULL);
// Special check for SOA queries: If we queried for a.b.c.d.com, and got no answer,
// with an Authority Section SOA record for d.com, then this is a hint that the authority
@@ -8401,12 +8592,12 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
// been NULL. If we pass NULL cg to new cache entries that we create below,
// it will create additional cache groups for the same name. To avoid that,
// look up the cache group again to re-initialize cg again.
- cg = CacheGroupForName(m, slot, hash, name);
+ cg = CacheGroupForName(m, hash, name);
if (NSECRecords && DNSSECQuestion(qptr))
{
// Create the cache entry with delay and then add the NSEC records
// to it and add it immediately.
- negcr = CreateNewCacheEntry(m, slot, cg, 1, mDNStrue, mDNSNULL);
+ negcr = CreateNewCacheEntry(m, HashSlotFromNameHash(hash), cg, 1, mDNStrue, mDNSNULL);
if (negcr)
{
negcr->CRDNSSECQuestion = 0;
@@ -8431,7 +8622,7 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
else
{
// Need to add with a delay so that we can tag the SOA record
- negcr = CreateNewCacheEntry(m, slot, cg, 1, mDNStrue, mDNSNULL);
+ negcr = CreateNewCacheEntry(m, HashSlotFromNameHash(hash), cg, 1, mDNStrue, mDNSNULL);
if (negcr)
{
negcr->CRDNSSECQuestion = 0;
@@ -8455,9 +8646,6 @@ mDNSlocal void mDNSCoreReceiveNoUnicastAnswers(mDNS *const m, const DNSMessage *
repeat--;
name = (const domainname *)(name->c + 1 + name->c[0]);
hash = DomainNameHashValue(name);
- slot = HashSlot(name);
- // For now, we don't need to update cg here, because we'll do it again immediately, back up at the start of this loop
- //cg = CacheGroupForName(m, slot, hash, name);
}
}
}
@@ -8632,7 +8820,6 @@ mDNSlocal CacheRecord* mDNSCoreReceiveCacheCheck(mDNS *const m, const DNSMessage
}
else
{
-
// If the packet TTL is zero, that means we're deleting this record.
// To give other hosts on the network a chance to protest, we push the deletion
// out one second into the future. Also, we set UnansweredQueries to MaxUnansweredQueries.
@@ -8673,7 +8860,6 @@ mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const resp
}
for (i = 0; i < response->h.numAuthorities && ptr && ptr < end; i++)
{
- mDNSu32 slot;
CacheGroup *cg;
ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &m->rec);
@@ -8683,11 +8869,10 @@ mDNSlocal void mDNSParseNSEC3Records(mDNS *const m, const DNSMessage *const resp
m->rec.r.resrec.RecordType = 0;
continue;
}
- slot = HashSlot(m->rec.r.resrec.name);
- cg = CacheGroupForRecord(m, slot, &m->rec.r.resrec);
+ cg = CacheGroupForRecord(m, &m->rec.r.resrec);
// Create the cache entry but don't add it to the cache it. We need
// to cache this along with the main cache record.
- rr = CreateNewCacheEntry(m, slot, cg, 0, mDNSfalse, mDNSNULL);
+ rr = CreateNewCacheEntry(m, HashSlotFromNameHash(m->rec.r.resrec.namehash), cg, 0, mDNSfalse, mDNSNULL);
if (rr)
{
debugf("mDNSParseNSEC3Records: %s", CRDisplayString(m, rr));
@@ -8703,7 +8888,7 @@ mDNSlocal void mDNSCoreResetRecord(mDNS *const m)
m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
if (m->rec.r.resrec.AnonInfo)
{
- FreeAnonInfo(m->rec.r.resrec.AnonInfo);
+ FreeAnonInfo(m->rec.r.resrec.AnonInfo);
m->rec.r.resrec.AnonInfo = mDNSNULL;
}
}
@@ -8740,6 +8925,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
mDNSBool rrsigsCreated = mDNSfalse;
mDNSBool DNSSECQuestion = mDNSfalse;
NetworkInterfaceInfo *llintf = FirstIPv4LLInterfaceForID(m, InterfaceID);
+ mDNSBool recordAcceptedInResponse = mDNSfalse; // Set if a record is accepted from a unicast mDNS response that answers an existing question.
// All records in a DNS response packet are treated as equally valid statements of truth. If we want
// to guard against spoof responses, then the only credible protection against that is cryptographic
@@ -8808,8 +8994,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
CacheRecord *rr;
// Remember the unicast question that we found, which we use to make caching
// decisions later on in this function
- const mDNSu32 slot = HashSlot(&q.qname);
- CacheGroup *cg = CacheGroupForName(m, slot, q.qnamehash, &q.qname);
+ CacheGroup *cg = CacheGroupForName(m, q.qnamehash, &q.qname);
if (!mDNSOpaque16IsZero(response->h.id))
{
unicastQuestion = qptr;
@@ -8850,14 +9035,14 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// and hence retransmit without the EDNS0/DOK option.
if (DNSSECOptionalQuestion(qptr) && qptr->qDNSServer && !qptr->qDNSServer->DNSSECAware)
{
- LogInfo("mDNSCoreReceiveResponse: Server %p responded with code %d to DNSSEC Query %##s (%s), clear DO flag",
+ LogInfo("mDNSCoreReceiveResponse: Server %p responded with code %d to DNSSEC Query %##s (%s), clear DO flag",
qptr->qDNSServer, rcode, q.qname.c, DNSTypeName(q.qtype));
- qptr->qDNSServer->req_DO = mDNSfalse;
+ qptr->qDNSServer->req_DO = mDNSfalse;
}
// For Unicast DNS Queries, penalize the DNSServer
else
{
- LogInfo("mDNSCoreReceiveResponse: Server %p responded with code %d to query %##s (%s)",
+ LogInfo("mDNSCoreReceiveResponse: Server %p responded with code %d to query %##s (%s)",
qptr->qDNSServer, rcode, q.qname.c, DNSTypeName(q.qtype));
PenalizeDNSServer(m, qptr, response->h.flags);
}
@@ -8892,7 +9077,9 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
{
// All responses sent via LL multicast are acceptable for caching
// All responses received over our outbound TCP connections are acceptable for caching
- mDNSBool AcceptableResponse = ResponseMCast || !dstaddr || LLQType;
+ // We accept all records in a unicast response to a multicast query once we find one that
+ // answers an active question.
+ mDNSBool AcceptableResponse = ResponseMCast || !dstaddr || LLQType || recordAcceptedInResponse;
// (Note that just because we are willing to cache something, that doesn't necessarily make it a trustworthy answer
// to any specific question -- any code reading records from the cache needs to make that determination for itself.)
@@ -8979,38 +9166,42 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// Even though it is AcceptableResponse, we still need a DNSServer pointer for the resource records that
// we create.
- DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
-
- // Initialize the DNS server on the resource record which will now filter what questions we answer with
- // this record.
- //
- // We could potentially lookup the DNS server based on the source address, but that may not work always
- // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
- // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
- // on the "id" and "source port", then this response answers the question and assume the response
- // came from the same DNS server that we sent the query to.
-
- if (q != mDNSNULL)
- {
- AcceptableResponse = mDNStrue;
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
- }
- else
- LogInfo("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
- }
- else
- {
- // If we can't find a matching question, we need to see whether we have seen records earlier that matched
- // the question. The code below does that. So, make this record unacceptable for now
- if (!InterfaceID)
- {
- debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
- AcceptableResponse = mDNSfalse;
- }
- }
+ DNSQuestion *q = ExpectingUnicastResponseForRecord(m, srcaddr, ResponseSrcLocal, dstport, response->h.id, &m->rec.r, !dstaddr);
+
+ // Initialize the DNS server on the resource record which will now filter what questions we answer with
+ // this record.
+ //
+ // We could potentially lookup the DNS server based on the source address, but that may not work always
+ // and that's why ExpectingUnicastResponseForRecord does not try to verify whether the response came
+ // from the DNS server that queried. We follow the same logic here. If we can find a matching quetion based
+ // on the "id" and "source port", then this response answers the question and assume the response
+ // came from the same DNS server that we sent the query to.
+
+ if (q != mDNSNULL)
+ {
+ AcceptableResponse = mDNStrue;
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: InterfaceID %p %##s (%s)", q->InterfaceID, q->qname.c, DNSTypeName(q->qtype));
+ m->rec.r.resrec.rDNSServer = uDNSServer = q->qDNSServer;
+ }
+ else
+ {
+ // Accept all remaining records in this unicast response to an mDNS query.
+ recordAcceptedInResponse = mDNStrue;
+ LogInfo("mDNSCoreReceiveResponse: Accepting response for query: %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ }
+ }
+ else
+ {
+ // If we can't find a matching question, we need to see whether we have seen records earlier that matched
+ // the question. The code below does that. So, make this record unacceptable for now
+ if (!InterfaceID)
+ {
+ debugf("mDNSCoreReceiveResponse: Can't find question for record name %##s", m->rec.r.resrec.name->c);
+ AcceptableResponse = mDNSfalse;
+ }
+ }
}
}
else if (llintf && llintf->IgnoreIPv4LL && m->rec.r.resrec.rrtype == kDNSType_A)
@@ -9121,13 +9312,36 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// If we're probing for this record, we just failed
else if (rr->resrec.RecordType == kDNSRecordTypeUnique)
{
+ // At this point in the code, we're probing for uniqueness.
+ // We've sent at least one probe (rr->ProbeCount < DefaultProbeCountForTypeUnique)
+ // but we haven't completed probing yet (rr->resrec.RecordType == kDNSRecordTypeUnique).
// Before we call deregister, check if this is a packet we registered with the sleep proxy.
if (!mDNSCoreRegisteredProxyRecord(m, rr))
{
- LogMsg("mDNSCoreReceiveResponse: ProbeCount %d; will deregister %s", rr->ProbeCount, ARDisplayString(m, rr));
-
- m->mDNSStats.NameConflicts++;
- mDNS_Deregister_internal(m, rr, mDNS_Dereg_conflict);
+ // This may be a conflict due to stale packets on the network. Delay probing by a second.
+ // If there are conflicts after 3 such attempts, then it is a true conflict.
+ if (m->DelayConflictProcessing)
+ {
+ m->DelayConflictProcessing--;
+ LogMsg("Possible spurious conflict for %s. Attempt %d at suppressing probes for one second",
+ ARDisplayString(m, rr), (MAX_CONFLICT_PROCESSING_DELAYS - m->DelayConflictProcessing));
+ rr->ProbeCount = DefaultProbeCountForTypeUnique + 1;
+ rr->AnnounceCount = InitialAnnounceCount;
+ m->SuppressProbes = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
+ InitializeLastAPTime(m, rr);
+ RecordProbeFailure(m, rr); // Repeated late conflicts also cause us to back off to the slower probing rate
+ }
+ else
+ {
+ LogMsg("mDNSCoreReceiveResponse: ProbeCount %d; will deregister %s", rr->ProbeCount, ARDisplayString(m, rr));
+ m->mDNSStats.NameConflicts++;
+#if APPLE_OSX_mDNSResponder
+ // See if this record was also registered with any D2D plugins.
+ D2D_stop_advertising_record(rr);
+#endif
+ mDNS_Deregister_internal(m, rr, mDNS_Dereg_conflict);
+ }
+
}
}
// We assumed this record must be unique, but we were wrong. (e.g. There are two mDNSResponders on the
@@ -9139,6 +9353,9 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
{
LogMsg("mDNSCoreReceiveResponse: Unexpected conflict discarding %s", ARDisplayString(m, rr));
m->mDNSStats.KnownUniqueNameConflicts++;
+#if APPLE_OSX_mDNSResponder
+ D2D_stop_advertising_record(rr);
+#endif
mDNS_Deregister_internal(m, rr, mDNS_Dereg_conflict);
}
else
@@ -9150,7 +9367,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
// have any record(s) of the same type that we should re-assert to rescue them
// (see note about "multi-homing and bridged networks" at the end of this function).
else if (m->rec.r.resrec.rrtype == rr->resrec.rrtype)
- if ((m->rec.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) && m->timenow - rr->LastMCTime > mDNSPlatformOneSecond/2)
+ if ((m->rec.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) && (mDNSu32)(m->timenow - rr->LastMCTime) > (mDNSu32)mDNSPlatformOneSecond/2)
{ rr->ImmedAnswer = mDNSInterfaceMark; m->NextScheduledResponse = m->timenow; }
}
}
@@ -9169,8 +9386,8 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (!AcceptableResponse) LogInfo("mDNSCoreReceiveResponse ignoring %s", CRDisplayString(m, &m->rec.r));
if (m->rrcache_size && AcceptableResponse)
{
- const mDNSu32 slot = HashSlot(m->rec.r.resrec.name);
- CacheGroup *cg = CacheGroupForRecord(m, slot, &m->rec.r.resrec);
+ const mDNSu32 slot = HashSlotFromNameHash(m->rec.r.resrec.namehash);
+ CacheGroup *cg = CacheGroupForRecord(m, &m->rec.r.resrec);
CacheRecord *rr = mDNSNULL;
if (McastNSEC3Records)
@@ -9180,7 +9397,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
//
// If this record should go in the nseclist, don't look in the cache for updating it.
// They are supposed to be cached under the "nsec" field of the cache record for
- // validation. Just create the cache record.
+ // validation. Just create the cache record.
if (!nseclist)
{
rr = mDNSCoreReceiveCacheCheck(m, response, LLQType, slot, cg, unicastQuestion, &cfp, &NSECCachePtr, InterfaceID);
@@ -9196,7 +9413,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
if (AddToCFList)
delay = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
else
- delay = CheckForSoonToExpireRecords(m, m->rec.r.resrec.name, m->rec.r.resrec.namehash, slot, mDNSNULL);
+ delay = CheckForSoonToExpireRecords(m, m->rec.r.resrec.name, m->rec.r.resrec.namehash, mDNSNULL);
// If unique, assume we may have to delay delivery of this 'add' event.
// Below, where we walk the CacheFlushRecords list, we either call CacheRecordDeferredAdd()
@@ -9262,8 +9479,8 @@ exit:
while (CacheFlushRecords != (CacheRecord*)1)
{
CacheRecord *r1 = CacheFlushRecords, *r2;
- const mDNSu32 slot = HashSlot(r1->resrec.name);
- const CacheGroup *cg = CacheGroupForRecord(m, slot, &r1->resrec);
+ const mDNSu32 slot = HashSlotFromNameHash(r1->resrec.namehash);
+ const CacheGroup *cg = CacheGroupForRecord(m, &r1->resrec);
CacheFlushRecords = CacheFlushRecords->NextInCFList;
r1->NextInCFList = mDNSNULL;
@@ -9307,7 +9524,7 @@ exit:
continue;
}
}
-
+
// For Unicast (null InterfaceID) the resolver IDs should also match
if ((r1->resrec.InterfaceID == r2->resrec.InterfaceID) &&
(r1->resrec.InterfaceID || (id1 == id2)) &&
@@ -9331,7 +9548,7 @@ exit:
// to give us an aged TTL to correct for how long it has held the record,
// so our received TTLs are expected to vary in that case
- // We also suppress log message in the case of SRV records that are recieved
+ // We also suppress log message in the case of SRV records that are received
// with a TTL of 4500 that are already cached with a TTL of 120 seconds, since
// this behavior was observed for a number of discoveryd based AppleTV's in iOS 8
// GM builds.
@@ -9406,14 +9623,14 @@ exit:
// Note: We need to do this before we call CacheRecordDeferredAdd as this
// might start the verification process which needs these NSEC records
if (!AddNSECSForCacheRecord(m, NSECRecords, NSECCachePtr, rcode))
- {
+ {
LogInfo("mDNSCoreReceiveResponse: AddNSECSForCacheRecord failed to add NSEC for %s", CRDisplayString(m, NSECCachePtr));
FreeNSECRecords(m, NSECRecords);
}
NSECRecords = mDNSNULL;
NSECCachePtr = mDNSNULL;
}
- r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash, slot, mDNSNULL);
+ r1->DelayDelivery = CheckForSoonToExpireRecords(m, r1->resrec.name, r1->resrec.namehash, mDNSNULL);
// If no longer delaying, deliver answer now, else schedule delivery for the appropriate time
if (!r1->DelayDelivery) CacheRecordDeferredAdd(m, r1);
else ScheduleNextCacheCheckTime(m, slot, r1->DelayDelivery);
@@ -9426,7 +9643,7 @@ exit:
{
LogInfo("mDNSCoreReceieveResponse: Updating NSEC records in %s", CRDisplayString(m, NSECCachePtr));
if (!AddNSECSForCacheRecord(m, NSECRecords, NSECCachePtr, rcode))
- {
+ {
LogInfo("mDNSCoreReceiveResponse: AddNSECSForCacheRecord failed to add NSEC for %s", CRDisplayString(m, NSECCachePtr));
FreeNSECRecords(m, NSECRecords);
}
@@ -9506,8 +9723,8 @@ mDNSlocal void SPSRecordCallback(mDNS *const m, AuthRecord *const ar, mStatus re
LogMsg("%-7s Conflicting mDNS -- waking %.6a %s", InterfaceNameForID(m, ar->resrec.InterfaceID), &ar->WakeUp.HMAC, ARDisplayString(m, ar));
if (ar->WakeUp.HMAC.l[0])
{
- SendWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.IMAC, &ar->WakeUp.password); // Send one wakeup magic packet
- ScheduleWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.HMAC); // Schedule all other records with the same owner to be woken
+ SendWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.IMAC, &ar->WakeUp.password, mDNSfalse); // Send one wakeup magic packet
+ ScheduleWakeup(m, ar->resrec.InterfaceID, &ar->WakeUp.HMAC); // Schedule all other records with the same owner to be woken
}
mDNS_Unlock(m);
}
@@ -9525,7 +9742,7 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
int i;
mDNSs8 hval = 0;
int colons = 0;
- mDNSu16 val = 0; /* need to use 16 bit int to detect overflow */
+ mDNSu8 val = 0;
for (i = 0; ptr < limit && *ptr != ' ' && i < 17; i++, ptr++)
{
@@ -9537,12 +9754,12 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
}
else if (*ptr == ':')
{
- if (colons >=5 || val > 255)
+ if (colons >=5)
{
LogMsg("GetValueForMACAddr: Address malformed colons %d val %d", colons, val);
return mDNSNULL;
}
- eth->b[colons] = (mDNSs8)val;
+ eth->b[colons] = val;
colons++;
val = 0;
}
@@ -9552,7 +9769,7 @@ mDNSlocal mDNSu8 *GetValueForMACAddr(mDNSu8 *ptr, mDNSu8 *limit, mDNSEthAddr *et
LogMsg("GetValueForMACAddr: Address malformed colons %d", colons);
return mDNSNULL;
}
- eth->b[colons] = (mDNSs8)val;
+ eth->b[colons] = val;
return ptr;
}
@@ -9722,32 +9939,33 @@ mDNSlocal mDNSu8 *GetValueForKeepalive(mDNSu8 *ptr, mDNSu8 *limit, mDNSu32 *valu
mDNSexport mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr)
{
- mDNSAddr laddr, raddr;
- mDNSEthAddr eth;
- mDNSIPPort lport, rport;
- mDNSu32 timeout, seq, ack;
- mDNSu16 win;
+ mDNSAddr laddr, raddr;
+ mDNSEthAddr eth;
+ mDNSIPPort lport, rport;
+ mDNSu32 timeout, seq, ack;
+ mDNSu16 win;
- if (!mDNS_KeepaliveRecord(&rr->resrec))
- {
- return mDNSfalse;
- }
+ if (!mDNS_KeepaliveRecord(&rr->resrec))
+ {
+ return mDNSfalse;
+ }
- timeout = seq = ack = 0;
- win = 0;
- laddr = raddr = zeroAddr;
- lport = rport = zeroIPPort;
+ timeout = seq = ack = 0;
+ win = 0;
+ laddr = raddr = zeroAddr;
+ lport = rport = zeroIPPort;
+ eth = zeroEthAddr;
- mDNS_ExtractKeepaliveInfo(rr, &timeout, &laddr, &raddr, &eth, &seq, &ack, &lport, &rport, &win);
+ mDNS_ExtractKeepaliveInfo(rr, &timeout, &laddr, &raddr, &eth, &seq, &ack, &lport, &rport, &win);
- if (mDNSAddressIsZero(&laddr) || mDNSIPPortIsZero(lport) ||
- mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(rport) ||
- mDNSEthAddressIsZero(eth))
- {
- return mDNSfalse;
- }
+ if (mDNSAddressIsZero(&laddr) || mDNSIPPortIsZero(lport) ||
+ mDNSAddressIsZero(&raddr) || mDNSIPPortIsZero(rport) ||
+ mDNSEthAddressIsZero(eth))
+ {
+ return mDNSfalse;
+ }
- return mDNStrue;
+ return mDNStrue;
}
@@ -9778,7 +9996,7 @@ mDNSlocal void mDNS_ExtractKeepaliveInfo(AuthRecord *ar, mDNSu32 *timeout, mDNSA
raddr->type = mDNSAddrType_IPv4;
ptr = GetValueForIPv4Addr(ptr, limit, &raddr->ip.v4);
}
- if (param == 'H')
+ else if (param == 'H')
{
laddr->type = mDNSAddrType_IPv6;
ptr = GetValueForIPv6Addr(ptr, limit, &laddr->ip.v6);
@@ -10124,30 +10342,48 @@ mDNSlocal void mDNSCoreReceiveUpdate(mDNS *const m,
mDNS_SendKeepalives(m);
}
+mDNSlocal mDNSu32 mDNSGenerateOwnerOptForInterface(mDNS *const m, const mDNSInterfaceID InterfaceID, DNSMessage *msg)
+{
+ mDNSu8 *ptr = msg->data;
+ mDNSu8 *end = mDNSNULL;
+ mDNSu32 length = 0;
+ AuthRecord opt;
+ NetworkInterfaceInfo *intf;
+
+ mDNS_SetupResourceRecord(&opt, mDNSNULL, mDNSInterface_Any, kDNSType_OPT, kStandardTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
+ opt.resrec.rrclass = NormalMaxDNSMessageData;
+ opt.resrec.rdlength = sizeof(rdataOPT);
+ opt.resrec.rdestimate = sizeof(rdataOPT);
+
+ intf = FirstInterfaceForID(m, InterfaceID);
+ SetupOwnerOpt(m, intf, &opt.resrec.rdata->u.opt[0]);
+
+ LogSPS("Generated OPT record : %s", ARDisplayString(m, &opt));
+ end = PutResourceRecord(msg, ptr, &msg->h.numAdditionals, &opt.resrec);
+ if (end != mDNSNULL)
+ {
+ // Put all the integer values in IETF byte-order (MSB first, LSB second)
+ SwapDNSHeaderBytes(msg);
+ length = (end - msg->data);
+ }
+ else
+ LogSPS("mDNSGenerateOwnerOptForInterface: Failed to generate owner OPT record");
+
+ return length;
+}
+
+// Note that this routine is called both for Sleep Proxy Registrations, and for Standard Dynamic
+// DNS registrations, but (currently) only has to handle the Sleep Proxy Registration reply case,
+// and should ignore Standard Dynamic DNS registration replies, because those are handled elsewhere.
+// Really, both should be unified and handled in one place.
mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *end, const mDNSAddr *srcaddr, const mDNSInterfaceID InterfaceID)
{
if (InterfaceID)
{
- mDNSu32 updatelease = 60 * 60; // If SPS fails to indicate lease time, assume one hour
- const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
- mDNSAddr spsaddr;
- char *ifname;
- if (ptr)
- {
- ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
- {
- const rdataOPT *o;
- const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
- for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
- if (o->opt == kDNSOpt_Lease)
- {
- updatelease = o->u.updatelease;
- LogSPS("Sleep Proxy granted lease time %4d seconds, updateid %d, InterfaceID %p", updatelease, mDNSVal16(msg->h.id), InterfaceID);
- }
- }
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- }
+ mDNSu32 pktlease = 0, spsupdates = 0;
+ const mDNSBool gotlease = GetPktLease(m, msg, end, &pktlease);
+ const mDNSu32 updatelease = gotlease ? pktlease : 60 * 60; // If SPS fails to indicate lease time, assume one hour
+ if (gotlease) LogSPS("DNS Update response contains lease option granting %4d seconds, updateid %d, InterfaceID %p", updatelease, mDNSVal16(msg->h.id), InterfaceID);
if (m->CurrentRecord)
LogMsg("mDNSCoreReceiveUpdateR ERROR m->CurrentRecord already set %s", ARDisplayString(m, m->CurrentRecord));
@@ -10166,7 +10402,8 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
if (mDNSOpaque64IsZero(&rr->updateIntID))
rr->updateid = zeroID;
rr->expire = NonZeroTime(m->timenow + updatelease * mDNSPlatformOneSecond);
- LogSPS("Sleep Proxy %s record %5d 0x%x 0x%x (%d) %s", rr->WakeUp.HMAC.l[0] ? "transferred" : "registered", updatelease, rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr));
+ spsupdates++;
+ LogSPS("Sleep Proxy %s record %2d %5d 0x%x 0x%x (%d) %s", rr->WakeUp.HMAC.l[0] ? "transferred" : "registered", spsupdates, updatelease, rr->updateIntID.l[1], rr->updateIntID.l[0], mDNSVal16(rr->updateid), ARDisplayString(m,rr));
if (rr->WakeUp.HMAC.l[0])
{
rr->WakeUp.HMAC = zeroEthAddr; // Clear HMAC so that mDNS_Deregister_internal doesn't waste packets trying to wake this host
@@ -10179,11 +10416,27 @@ mDNSlocal void mDNSCoreReceiveUpdateR(mDNS *const m, const DNSMessage *const msg
if (m->CurrentRecord == rr) // If m->CurrentRecord was not advanced for us, do it now
m->CurrentRecord = rr->next;
}
+ if (spsupdates) // Only do this dynamic store stuff if this was, in fact, a Sleep Proxy Update response
+ {
+ char *ifname;
+ mDNSAddr spsaddr;
+ DNSMessage optMsg;
+ int length;
+ // Update the dynamic store with the IP Address and MAC address of the sleep proxy
+ ifname = InterfaceNameForID(m, InterfaceID);
+ mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
+ mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
- // Update the dynamic store with the IP Address and MAC address of the sleep proxy
- ifname = InterfaceNameForID(m, InterfaceID);
- mDNSPlatformMemCopy(&spsaddr, srcaddr, sizeof (mDNSAddr));
- mDNSPlatformStoreSPSMACAddr(&spsaddr, ifname);
+ // Store the Owner OPT record for this interface.
+ // Configd may use the OPT record if it detects a conflict with the BSP when the system wakes up
+ InitializeDNSMessage(&optMsg.h, zeroID, ResponseFlags);
+ length = mDNSGenerateOwnerOptForInterface(m, InterfaceID, &optMsg);
+ if (length != 0)
+ {
+ length += sizeof(DNSMessageHeader);
+ mDNSPlatformStoreOwnerOptRecord(ifname, &optMsg, length);
+ }
+ }
}
// If we were waiting to go to sleep, then this SPS registration or wide-area record deletion
// may have been the thing we were waiting for, so schedule another check to see if we can sleep now.
@@ -10219,12 +10472,6 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
cr->CRActiveQuestion = mDNSNULL;
cr->UnansweredQueries = 0;
cr->LastUnansweredTime = 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- cr->MPUnansweredQ = 0;
- cr->MPLastUnansweredQT = 0;
- cr->MPUnansweredKA = 0;
- cr->MPExpectingKA = mDNSfalse;
-#endif
cr->NextInCFList = mDNSNULL;
cr->nsec = mDNSNULL;
cr->soa = mDNSNULL;
@@ -10234,12 +10481,12 @@ mDNSexport void MakeNegativeCacheRecord(mDNS *const m, CacheRecord *const cr,
cr->responseFlags = ResponseFlags;
}
-mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *const end,
+mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport,
const mDNSInterfaceID InterfaceID)
{
mDNSInterfaceID ifid = InterfaceID;
- DNSMessage *msg = (DNSMessage *)pkt;
+ const mDNSu8 *const pkt = (mDNSu8 *)msg;
const mDNSu8 StdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery;
const mDNSu8 StdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery;
const mDNSu8 UpdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_Update;
@@ -10256,7 +10503,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
if (mDNSSameIPPort(srcport, SSDPPort) || (m->SSDPSocket && mDNSSameIPPort(dstport, m->SSDPSocket->port)))
{
mDNS_Lock(m);
- LNT_ConfigureRouterInfo(m, InterfaceID, pkt, (mDNSu16)(end - (mDNSu8 *)pkt));
+ LNT_ConfigureRouterInfo(m, InterfaceID, (mDNSu8 *)msg, (mDNSu16)(end - pkt));
mDNS_Unlock(m);
return;
}
@@ -10264,7 +10511,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
if (mDNSSameIPPort(srcport, NATPMPPort))
{
mDNS_Lock(m);
- uDNS_ReceiveNATPacket(m, InterfaceID, pkt, (mDNSu16)(end - (mDNSu8 *)pkt));
+ uDNS_ReceiveNATPacket(m, InterfaceID, (mDNSu8 *)msg, (mDNSu16)(end - pkt));
mDNS_Unlock(m);
return;
}
@@ -10274,9 +10521,9 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
#endif
#endif
- if ((unsigned)(end - (mDNSu8 *)pkt) < sizeof(DNSMessageHeader))
+ if ((unsigned)(end - pkt) < sizeof(DNSMessageHeader))
{
- LogMsg("DNS Message from %#a:%d to %#a:%d length %d too short", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end - (mDNSu8 *)pkt);
+ LogMsg("DNS Message from %#a:%d to %#a:%d length %d too short", srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - pkt));
return;
}
QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
@@ -10302,7 +10549,7 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
// Track the number of multicast packets received from a source outside our subnet.
// Check the destination address to avoid accounting for spurious packets that
// comes in with message id zero.
- if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr) &&
+ if (!mDNS_AddressIsLocalSubnet(m, InterfaceID, srcaddr) && dstaddr &&
mDNSAddressIsAllDNSLinkGroup(dstaddr))
{
m->RemoteSubnet++;
@@ -10327,17 +10574,21 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
else if (QR_OP == UpdR) mDNSCoreReceiveUpdateR (m, msg, end, srcaddr, InterfaceID);
else
{
- LogMsg("Unknown DNS packet type %02X%02X from %#-15a:%-5d to %#-15a:%-5d length %d on %p (ignored)",
- msg->h.flags.b[0], msg->h.flags.b[1], srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), end - (mDNSu8 *)pkt, InterfaceID);
if (mDNS_LoggingEnabled)
{
- int i = 0;
- while (i<end - (mDNSu8 *)pkt)
- {
- char buffer[128];
- char *p = buffer + mDNS_snprintf(buffer, sizeof(buffer), "%04X", i);
- do if (i<end - (mDNSu8 *)pkt) p += mDNS_snprintf(p, sizeof(buffer), " %02X", ((mDNSu8 *)pkt)[i]);while (++i & 15);
- LogInfo("%s", buffer);
+ static int msgCount = 0;
+ if (msgCount < 1000) {
+ int i = 0;
+ msgCount++;
+ LogInfo("Unknown DNS packet type %02X%02X from %#-15a:%-5d to %#-15a:%-5d length %d on %p (ignored)",
+ msg->h.flags.b[0], msg->h.flags.b[1], srcaddr, mDNSVal16(srcport), dstaddr, mDNSVal16(dstport), (int)(end - pkt), InterfaceID);
+ while (i < (int)(end - pkt))
+ {
+ char buffer[128];
+ char *p = buffer + mDNS_snprintf(buffer, sizeof(buffer), "%04X", i);
+ do if (i < (int)(end - pkt)) p += mDNS_snprintf(p, sizeof(buffer), " %02X", pkt[i]);while (++i & 15);
+ LogInfo("%s", buffer);
+ }
}
}
}
@@ -10361,6 +10612,11 @@ mDNSexport void mDNSCoreReceive(mDNS *const m, void *const pkt, const mDNSu8 *co
#define SameQTarget(A,B) (((A)->Target.type == mDNSAddrType_None && (B)->Target.type == mDNSAddrType_None) || \
(mDNSSameAddress(& (A)->Target, & (B)->Target) && mDNSSameIPPort((A)->TargetPort, (B)->TargetPort)))
+// SameQuestionKind is true if *both* questions are either multicast or unicast
+// TargetQID is used for this determination.
+#define SameQuestionKind(A,B) ((mDNSOpaque16IsZero(A) && mDNSOpaque16IsZero(B)) || \
+ ((!mDNSOpaque16IsZero(A)) && (!mDNSOpaque16IsZero(B))))
+
// Note: We explicitly disallow making a public query be a duplicate of a private one. This is to avoid the
// circular deadlock where a client does a query for something like "dns-sd -Q _dns-query-tls._tcp.company.com SRV"
// and we have a key for company.com, so we try to locate the private query server for company.com, which necessarily entails
@@ -10404,8 +10660,9 @@ mDNSlocal DNSQuestion *FindDuplicateQuestion(const mDNS *const m, const DNSQuest
(q->DisallowPID == question->DisallowPID) && // Disallowing a PID should not affect a PID that is allowed
(q->BrowseThreshold == question->BrowseThreshold) && // browse thresholds must match
q->qnamehash == question->qnamehash &&
- (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
- SameDomainName(&q->qname, &question->qname)) // and name
+ (IsAWDLIncluded(q) == IsAWDLIncluded(question)) && // Inclusion of AWDL interface must match
+ SameQuestionKind(q->TargetQID, question->TargetQID) && // mDNS or uDNS must match
+ SameDomainName(&q->qname, &question->qname)) // and name
return(q);
return(mDNSNULL);
}
@@ -10453,15 +10710,11 @@ mDNSlocal void UpdateQuestionDuplicates(mDNS *const m, DNSQuestion *const questi
q->triedAllServersOnce = question->triedAllServersOnce;
q->TargetQID = question->TargetQID;
- if (q->LocalSocket)
- {
- mDNSPlatformUDPClose(q->LocalSocket);
- }
-
q->LocalSocket = question->LocalSocket;
+ // No need to close old q->LocalSocket first -- duplicate questions can't have their own sockets
q->state = question->state;
- // q->tcp = question->tcp;
+ // q->tcp = question->tcp;
q->ReqLease = question->ReqLease;
q->expire = question->expire;
q->ntries = question->ntries;
@@ -10469,7 +10722,7 @@ mDNSlocal void UpdateQuestionDuplicates(mDNS *const m, DNSQuestion *const questi
question->LocalSocket = mDNSNULL;
question->nta = mDNSNULL; // If we've got a GetZoneData in progress, transfer it to the newly active question
- // question->tcp = mDNSNULL;
+ // question->tcp = mDNSNULL;
if (q->LocalSocket)
debugf("UpdateQuestionDuplicates transferred LocalSocket pointer for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
@@ -10675,7 +10928,7 @@ mDNSlocal mDNSBool DNSServerMatch(DNSServer *d, mDNSInterfaceID InterfaceID, mDN
//
// 3) Scoped questions (non-zero ServiceID) should consider *only* scoped DNSServers (DNSServer
// with "scoped" set to kScopeServiceID) and their ServiceIDs should match.
- //
+ //
// The first condition in the "if" statement checks to see if both the question and the DNSServer are
// unscoped. The question is unscoped only if InterfaceID is zero and ServiceID is -1.
//
@@ -10714,7 +10967,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
mDNSu32 timeout = 0;
mDNSBool DEQuery;
- question->validDNSServers = zeroOpaque64;
+ question->validDNSServers = zeroOpaque128;
DEQuery = DomainEnumQuery(&question->qname);
for (curr = m->DNSServers; curr; curr = curr->next)
{
@@ -10742,7 +10995,9 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
}
currcount = CountLabels(&curr->domain);
- if ((!DEQuery || !curr->cellIntf) && DNSServerMatch(curr, question->InterfaceID, question->ServiceID))
+ if ((!curr->cellIntf || (!DEQuery && !(question->flags & kDNSServiceFlagsDenyCellular))) &&
+ (!curr->isExpensive || !(question->flags & kDNSServiceFlagsDenyExpensive)) &&
+ DNSServerMatch(curr, question->InterfaceID, question->ServiceID))
{
bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
@@ -10756,7 +11011,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
if (bettermatch)
{
debugf("SetValidDNSServers: Resetting all the bits");
- question->validDNSServers = zeroOpaque64;
+ question->validDNSServers = zeroOpaque128;
timeout = 0;
}
debugf("SetValidDNSServers: question %##s Setting the bit for DNS server Address %#a (Domain %##s), Scoped:%d index %d,"
@@ -10765,15 +11020,15 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
timeout += curr->timeout;
if (DEQuery)
debugf("DomainEnumQuery: Question %##s, DNSServer %#a, cell %d", question->qname.c, &curr->addr, curr->cellIntf);
- bit_set_opaque64(question->validDNSServers, index);
+ bit_set_opaque128(question->validDNSServers, index);
}
}
index++;
}
question->noServerResponse = 0;
- debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x for question %p %##s (%s)",
- question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
+ debugf("SetValidDNSServers: ValidDNSServer bits 0x%x%x%x%x for question %p %##s (%s)",
+ question->validDNSServers.l[3], question->validDNSServers.l[2], question->validDNSServers.l[1], question->validDNSServers.l[0], question, question->qname.c, DNSTypeName(question->qtype));
// If there are no matching resolvers, then use the default timeout value.
// For ProxyQuestion, shorten the timeout so that dig does not timeout on us in case of no response.
return ((question->ProxyQuestion || question->ValidatingResponse) ? DEFAULT_UDNSSEC_TIMEOUT : timeout ? timeout : DEFAULT_UDNS_TIMEOUT);
@@ -10781,7 +11036,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
// Get the Best server that matches a name. If you find penalized servers, look for the one
// that will come out of the penalty box soon
-mDNSlocal DNSServer *GetBestServer(mDNS *m, const domainname *name, mDNSInterfaceID InterfaceID, mDNSs32 ServiceID, mDNSOpaque64 validBits,
+mDNSlocal DNSServer *GetBestServer(mDNS *m, const domainname *name, mDNSInterfaceID InterfaceID, mDNSs32 ServiceID, mDNSOpaque128 validBits,
int *selected, mDNSBool nameMatch)
{
DNSServer *curmatch = mDNSNULL;
@@ -10860,7 +11115,7 @@ mDNSlocal DNSServer *GetServerForName(mDNS *m, const domainname *name, mDNSInter
{
DNSServer *curmatch = mDNSNULL;
char *ifname = mDNSNULL; // for logging purposes only
- mDNSOpaque64 allValid;
+ mDNSOpaque128 allValid;
if ((InterfaceID == mDNSInterface_Unicast) || (InterfaceID == mDNSInterface_LocalOnly))
InterfaceID = mDNSNULL;
@@ -10868,7 +11123,7 @@ mDNSlocal DNSServer *GetServerForName(mDNS *m, const domainname *name, mDNSInter
if (InterfaceID) ifname = InterfaceNameForID(m, InterfaceID);
// By passing in all ones, we make sure that every DNS server is considered
- allValid.l[0] = allValid.l[1] = 0xFFFFFFFF;
+ allValid.l[0] = allValid.l[1] = allValid.l[2] = allValid.l[3] = 0xFFFFFFFF;
curmatch = GetBestServer(m, name, InterfaceID, ServiceID, allValid, mDNSNULL, mDNStrue);
@@ -10897,11 +11152,11 @@ mDNSexport DNSServer *GetServerForQuestion(mDNS *m, DNSQuestion *question)
if (InterfaceID)
ifname = InterfaceNameForID(m, InterfaceID);
- if (!mDNSOpaque64IsZero(&question->validDNSServers))
+ if (!mDNSOpaque128IsZero(&question->validDNSServers))
{
curmatch = GetBestServer(m, name, InterfaceID, question->ServiceID, question->validDNSServers, &currindex, mDNSfalse);
if (currindex != -1)
- bit_clr_opaque64(question->validDNSServers, currindex);
+ bit_clr_opaque128(question->validDNSServers, currindex);
}
if (curmatch != mDNSNULL)
@@ -10981,7 +11236,7 @@ mDNSlocal mDNSBool ShouldSuppressUnicastQuery(mDNS *const m, DNSQuestion *q, DNS
LogInfo("ShouldSuppressUnicastQuery: Query suppressed for %##s, qtype %s, as the DNS server is NULL", q->qname.c, DNSTypeName(q->qtype));
return mDNStrue;
}
-
+
// Check if the DNS Configuration allows A/AAAA queries to be sent
if ((q->qtype == kDNSType_A) && (d->req_A))
{
@@ -10995,6 +11250,13 @@ mDNSlocal mDNSBool ShouldSuppressUnicastQuery(mDNS *const m, DNSQuestion *q, DNS
DNSTypeName(q->qtype), d->domain.c, &d->addr, mDNSVal16(d->port));
return mDNSfalse;
}
+#if USE_DNS64
+ if (DNS64IsQueryingARecord(q->dns64.state))
+ {
+ LogInfo("ShouldSuppressUnicastQuery: DNS64 query not suppressed for %##s, qtype %s", q->qname.c, DNSTypeName(q->qtype));
+ return mDNSfalse;
+ }
+#endif
LogInfo("ShouldSuppressUnicastQuery: Query suppressed for %##s, qtype %s, since DNS Configuration does not allow (req_A is %s and req_AAAA is %s)",
q->qname.c, DNSTypeName(q->qtype), d->req_A ? "true" : "false", d->req_AAAA ? "true" : "false");
@@ -11011,12 +11273,12 @@ mDNSlocal mDNSBool ShouldSuppressDotLocalQuery(mDNS *const m, DNSQuestion *q)
// Check to see if there is at least one interface other than loopback and don't suppress
// .local questions if you find one. If we have at least one interface, it means that
// we can send unicast queries for the .local name and we don't want to suppress
- // multicast in that case as upper layers don't know how to handle if we return a
+ // multicast in that case as upper layers don't know how to handle if we return a
// negative response for multicast followed by a positive response for unicast.
//
// Note: we used to check for multicast capable interfaces instead of just any interface
// present. That did not work in the case where we have a valid interface for unicast
- // but not multicast capable e.g., cellular, as we ended up delivering a negative response
+ // but not multicast capable e.g., cellular, as we ended up delivering a negative response
// first and the upper layer did not wait for the positive response that came later.
for (intf = m->HostInterfaces; intf; intf = intf->next)
{
@@ -11040,7 +11302,7 @@ mDNSlocal mDNSBool ShouldSuppressDotLocalQuery(mDNS *const m, DNSQuestion *q)
return mDNSfalse;
}
- // 2. If we find a local AuthRecord answering this question, then don't suppress it.
+ // 2. If we find a local AuthRecord answering this question, then don't suppress it.
for (rr = m->ResourceRecords; rr; rr = rr->next)
{
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
@@ -11055,6 +11317,12 @@ mDNSlocal mDNSBool ShouldSuppressDotLocalQuery(mDNS *const m, DNSQuestion *q)
mDNSlocal mDNSBool ShouldSuppressQuery(mDNS *const m, DNSQuestion *q)
{
+ if (q->InterfaceID == mDNSInterface_LocalOnly)
+ {
+ LogInfo("ShouldSuppressQuery: LocalOnly query not suppressed for %##s, qtype %s", q->qname.c, DNSTypeName(q->qtype));
+ return mDNSfalse;
+ }
+
if (q->qtype != kDNSType_A && q->qtype != kDNSType_AAAA)
{
LogInfo("ShouldSuppressQuery: Query not suppressed for %##s, qtype %s, not A/AAAA type", q->qname.c, DNSTypeName(q->qtype));
@@ -11084,11 +11352,9 @@ mDNSlocal mDNSBool ShouldSuppressQuery(mDNS *const m, DNSQuestion *q)
mDNSlocal void CacheRecordRmvEventsForCurrentQuestion(mDNS *const m, DNSQuestion *q)
{
CacheRecord *rr;
- mDNSu32 slot;
CacheGroup *cg;
- slot = HashSlot(&q->qname);
- cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ cg = CacheGroupForName(m, q->qnamehash, &q->qname);
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
{
// Don't deliver RMV events for negative records
@@ -11145,7 +11411,6 @@ mDNSlocal mDNSBool IsQuestionNew(mDNS *const m, DNSQuestion *question)
mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
{
AuthRecord *rr;
- mDNSu32 slot;
AuthGroup *ag;
if (m->CurrentQuestion)
@@ -11158,8 +11423,7 @@ mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q
return mDNStrue;
}
m->CurrentQuestion = q;
- slot = AuthHashSlot(&q->qname);
- ag = AuthGroupForName(&m->rrauth, slot, q->qnamehash, &q->qname);
+ ag = AuthGroupForName(&m->rrauth, q->qnamehash, &q->qname);
if (ag)
{
for (rr = ag->members; rr; rr=rr->next)
@@ -11185,7 +11449,7 @@ mDNSlocal mDNSBool LocalRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q
// Returns false if the question got deleted while delivering the RMV events
// The caller should handle the case
-mDNSlocal mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
+mDNSexport mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q)
{
if (m->CurrentQuestion)
LogMsg("CacheRecordRmvEventsForQuestion: ERROR m->CurrentQuestion already set: %##s (%s)",
@@ -11328,7 +11592,7 @@ mDNSlocal void RestartUnicastQuestions(mDNS *const m)
{
if (mDNSOpaque16IsZero(q->TargetQID))
LogMsg("RestartUnicastQuestions: ERROR!! Restart set for multicast question %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
-
+
q->Restart = 0;
SuppressStatusChanged(m, q, &restart);
}
@@ -11344,8 +11608,8 @@ mDNSlocal void RestartUnicastQuestions(mDNS *const m)
}
-// ValidateParameters() is called by mDNS_StartQuery_internal() to check the client parameters of
-// DNS Question that are already set by the client before calling mDNS_StartQuery()
+// ValidateParameters() is called by mDNS_StartQuery_internal() to check the client parameters of
+// DNS Question that are already set by the client before calling mDNS_StartQuery()
mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
{
@@ -11357,7 +11621,7 @@ mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
}
// If no question->Target specified, clear TargetPort
- if (!question->Target.type)
+ if (!question->Target.type)
question->TargetPort = zeroIPPort;
if (!ValidateDomainName(&question->qname))
@@ -11366,71 +11630,71 @@ mDNSlocal mStatus ValidateParameters(mDNS *const m, DNSQuestion *const question)
return(mStatus_Invalid);
}
- // If this question is referencing a specific interface, verify it exists
- if (question->InterfaceID && question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_Unicast && question->InterfaceID != mDNSInterface_P2P)
+ // If this question is referencing a specific interface, verify it exists
+ if (question->InterfaceID && !LocalOnlyOrP2PInterface(question->InterfaceID) && question->InterfaceID != mDNSInterface_Unicast)
{
NetworkInterfaceInfo *intf = FirstInterfaceForID(m, question->InterfaceID);
if (!intf)
LogInfo("ValidateParameters: Note: InterfaceID %d for question %##s (%s) not currently found in active interface list",
(uint32_t)question->InterfaceID, question->qname.c, DNSTypeName(question->qtype));
}
-
+
return(mStatus_NoError);
}
-// InitDNSConfig() is called by InitCommonState() to initialize the DNS configuration of the Question.
+// InitDNSConfig() is called by InitCommonState() to initialize the DNS configuration of the Question.
// These are a subset of the internal uDNS fields. Must be done before ShouldSuppressQuery() & mDNS_PurgeForQuestion()
mDNSlocal void InitDNSConfig(mDNS *const m, DNSQuestion *const question)
{
// First reset all DNS Configuration
question->qDNSServer = mDNSNULL;
- question->validDNSServers = zeroOpaque64;
- question->triedAllServersOnce = 0;
- question->noServerResponse = 0;
- question->StopTime = 0;
-#if TARGET_OS_EMBEDDED
+ question->validDNSServers = zeroOpaque128;
+ question->triedAllServersOnce = 0;
+ question->noServerResponse = 0;
+ question->StopTime = (question->TimeoutQuestion) ? question->StopTime : 0;
+#if AWD_METRICS
mDNSPlatformMemZero(&question->metrics, sizeof(question->metrics));
#endif
- // Need not initialize the DNS Configuration for Local Only OR P2P Questions
- if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
+ // Need not initialize the DNS Configuration for Local Only OR P2P Questions when timeout not specified
+ if (LocalOnlyOrP2PInterface(question->InterfaceID) && !question->TimeoutQuestion)
return;
// Proceed to initialize DNS Configuration (some are set in SetValidDNSServers())
if (!mDNSOpaque16IsZero(question->TargetQID))
- {
+ {
mDNSu32 timeout = SetValidDNSServers(m, question);
- mDNSIPPort zp = zeroIPPort;
- // We set the timeout whenever mDNS_StartQuery_internal is called. This means if we have
- // a networking change/search domain change that calls this function again we keep
- // reinitializing the timeout value which means it may never timeout. If this becomes
- // a common case in the future, we can easily fix this by adding extra state that
- // indicates that we have already set the StopTime.
- //
- // Note that we set the timeout for all questions. If this turns out to be a duplicate,
+ // We set the timeout value the first time mDNS_StartQuery_internal is called for a question.
+ // So if a question is restarted when a network change occurs, the StopTime is not reset.
+ // Note that we set the timeout for all questions. If this turns out to be a duplicate,
// it gets a full timeout value even if the original question times out earlier.
- if (question->TimeoutQuestion)
+ if (question->TimeoutQuestion && !question->StopTime)
{
question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
- LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
+ LogInfo("InitDNSConfig: Setting StopTime on the uDNS question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
}
question->qDNSServer = GetServerForQuestion(m, question);
LogInfo("InitDNSConfig: question %p %##s (%s) Timeout %d, DNS Server %#a:%d",
question, question->qname.c, DNSTypeName(question->qtype), timeout,
question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
- mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
+ mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
}
- else
- {
- if (question->TimeoutQuestion)
- question->StopTime = NonZeroTime(m->timenow + GetTimeoutForMcastQuestion(m, question) * mDNSPlatformOneSecond);
+ else if (question->TimeoutQuestion && !question->StopTime)
+ {
+ // If the question is to be timed out and its a multicast, local-only or P2P case,
+ // then set it's stop time.
+ mDNSu32 timeout = LocalOnlyOrP2PInterface(question->InterfaceID) ?
+ DEFAULT_LO_OR_P2P_TIMEOUT : GetTimeoutForMcastQuestion(m, question);
+ question->StopTime = NonZeroTime(m->timenow + timeout * mDNSPlatformOneSecond);
+ LogInfo("InitDNSConfig: Setting StopTime on question %p %##s (%s)", question, question->qname.c, DNSTypeName(question->qtype));
}
- // Set StopTime here since it is a part of DNS Configuration
+ // Set StopTime here since it is a part of DNS Configuration
if (question->StopTime)
SetNextQueryStopTime(m, question);
- // SetNextQueryTime() need not be initialized for LocalOnly OR P2P Questions since those questions
- // will never be transmitted on the wire. Hence we call SetNextQueryTime() here.
- SetNextQueryTime(m,question);
+ // Don't call SetNextQueryTime() if a LocalOnly OR P2P Question since those questions
+ // will never be transmitted on the wire.
+ if (!(LocalOnlyOrP2PInterface(question->InterfaceID)))
+ SetNextQueryTime(m,question);
}
// InitCommonState() is called by mDNS_StartQuery_internal() to initialize the common(uDNS/mDNS) internal
@@ -11439,7 +11703,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
{
mDNSBool purge;
int i;
- mDNSBool isCellBlocked = mDNSfalse;
+ mDNSBool isBlocked = mDNSfalse;
// Note: In the case where we already have the answer to this question in our cache, that may be all the client
// wanted, and they may immediately cancel their question. In this case, sending an actual query on the wire would
@@ -11456,7 +11720,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
// turned ON which can allocate memory e.g., base64 encoding, in the case of DNSSEC.
question->ThisQInterval = InitialQuestionInterval; // MUST be > zero for an active question
question->qnamehash = DomainNameHashValue(&question->qname);
- question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, HashSlot(&question->qname), &purge);
+ question->DelayAnswering = CheckForSoonToExpireRecords(m, &question->qname, question->qnamehash, &purge);
question->LastQTime = m->timenow;
question->ExpectUnicastResp = 0;
question->LastAnswerPktNum = m->PktNum;
@@ -11487,13 +11751,19 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
question->LOAddressAnswers = 0;
question->FlappingInterface1 = mDNSNULL;
question->FlappingInterface2 = mDNSNULL;
-
- // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetDNSRoutePolicy()
- // since we would already have the question->ServiceID in that case.
- if (!(question->flags & kDNSServiceFlagsServiceIndex))
- mDNSPlatformGetDNSRoutePolicy(m, question, &isCellBlocked);
- else
- LogInfo("InitCommonState: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] is already set by client", question->qname.c,
+
+ // if kDNSServiceFlagsServiceIndex flag is SET by the client, then do NOT call mDNSPlatformGetDNSRoutePolicy()
+ // since we would already have the question->ServiceID in that case.
+ if (!(question->flags & kDNSServiceFlagsServiceIndex))
+ {
+#if APPLE_OSX_mDNSResponder
+ mDNSPlatformGetDNSRoutePolicy(question, &isBlocked);
+#else
+ question->ServiceID = -1;
+#endif
+ }
+ else
+ LogInfo("InitCommonState: Query for %##s (%s), PID[%d], EUID[%d], ServiceID[%d] is already set by client", question->qname.c,
DNSTypeName(question->qtype), question->pid, question->euid, question->ServiceID);
InitDNSConfig(m, question);
@@ -11505,7 +11775,7 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
// If ServiceID is 0 or the policy disallows making DNS requests,
// set DisallowPID
- question->DisallowPID = (question->ServiceID == 0 || (isCellBlocked && question->qDNSServer && question->qDNSServer->cellIntf));
+ question->DisallowPID = (question->ServiceID == 0 || isBlocked);
if (question->DisallowPID)
LogInfo("InitCommonState: Query suppressed for %##s (%s), PID %d/ServiceID %d not allowed", question->qname.c,
DNSTypeName(question->qtype), question->pid, question->ServiceID);
@@ -11513,47 +11783,27 @@ mDNSlocal mDNSBool InitCommonState(mDNS *const m, DNSQuestion *const question)
question->NextInDQList = mDNSNULL;
question->SendQNow = mDNSNULL;
question->SendOnAll = mDNSfalse;
-
-#if mDNS_REQUEST_UNICAST_RESPONSE
- question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
-#else // mDNS_REQUEST_UNICAST_RESPONSE
- question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
-#endif // mDNS_REQUEST_UNICAST_RESPONSE
+ question->RequestUnicast = kDefaultRequestUnicastCount;
#if APPLE_OSX_mDNSResponder
- // Request unicast response for first 4 queries to increase
- // reliability in an environment with high multicast packet loss.
- // Must set to one more than the number of unicast queries you want, since SendQueries()
- // decrements it before calling BuildQuestion() which acts on it.
- if (question->flags & kDNSServiceFlagsUnicastResponse)
+ // Set the QU bit in the first query for the following options.
+ if ((question->flags & kDNSServiceFlagsUnicastResponse) || (question->flags & kDNSServiceFlagsThresholdFinder))
{
- question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
+ question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
LogInfo("InitCommonState: setting RequestUnicast = %d for %##s (%s)", question->RequestUnicast, question->qname.c,
DNSTypeName(question->qtype));
- }
- else if (question->flags & kDNSServiceFlagsThresholdFinder)
- {
- // always send one request with QU bit set when kDNSServiceFlagsThresholdFinder is set
-#if mDNS_REQUEST_UNICAST_RESPONSE
- question->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
-#else // mDNS_REQUEST_UNICAST_RESPONSE
- question->RequestUnicast = SET_QU_IN_FIRST_QUERY;
-#endif // mDNS_REQUEST_UNICAST_RESPONSE
-
- LogInfo("InitCommonState: kDNSServiceFlagsThresholdFinder set, setting RequestUnicast = %d for %##s (%s)",
- question->RequestUnicast, question->qname.c, DNSTypeName(question->qtype));
}
#endif // APPLE_OSX_mDNSResponder
question->LastQTxTime = m->timenow;
- question->CNAMEReferrals = 0;
+ question->CNAMEReferrals = 0;
question->WakeOnResolveCount = 0;
if (question->WakeOnResolve)
- {
+ {
question->WakeOnResolveCount = InitialWakeOnResolveCount;
purge = mDNStrue;
- }
+ }
for (i=0; i<DupSuppressInfoSize; i++)
question->DupSuppress[i].InterfaceID = mDNSNULL;
@@ -11580,7 +11830,7 @@ mDNSlocal void InitWABState(DNSQuestion *const question)
// We won't need one for duplicate questions, or from questions answered immediately out of the cache.
// We also don't need one for LLQs because (when we're using NAT) we want them all to share a single
// NAT mapping for receiving inbound add/remove events.
- question->LocalSocket = mDNSNULL;
+ question->LocalSocket = mDNSNULL;
question->unansweredQueries = 0;
question->nta = mDNSNULL;
question->servAddr = zeroAddr;
@@ -11612,8 +11862,15 @@ mDNSlocal void InitLLQState(DNSQuestion *const question)
question->id = zeroOpaque64;
}
+#ifdef DNS_PUSH_ENABLED
+mDNSlocal void InitDNSPNState(DNSQuestion *const question)
+{
+ question->dnsPushState = DNSPUSH_INIT;
+}
+#endif // DNS_PUSH_ENABLED
+
// InitDNSSECProxyState() is called by mDNS_StartQuery_internal() to initialize
-// DNSSEC & DNS Proxy fields of the DNS Question.
+// DNSSEC & DNS Proxy fields of the DNS Question.
mDNSlocal void InitDNSSECProxyState(mDNS *const m, DNSQuestion *const question)
{
(void) m;
@@ -11650,13 +11907,22 @@ mDNSlocal void FinalizeUnicastQuestion(mDNS *const m, DNSQuestion *question, mDN
// Ensure DNS related info of duplicate question is same as the orig question
if (question->DuplicateOf)
{
- mDNSIPPort zp = zeroIPPort;
question->validDNSServers = question->DuplicateOf->validDNSServers;
+ // If current(dup) question has DNS Server assigned but the original question has no DNS Server assigned to it,
+ // then we log a line as it could indicate an issue
+ if (question->DuplicateOf->qDNSServer == mDNSNULL)
+ {
+ if (question->qDNSServer)
+ LogInfo("FinalizeUnicastQuestion: Current(dup) question %p has DNSServer(%#a:%d) but original question(%p) has no DNS Server! %##s (%s)",
+ question, question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
+ mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort),
+ question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype));
+ }
question->qDNSServer = question->DuplicateOf->qDNSServer;
LogInfo("FinalizeUnicastQuestion: Duplicate question %p (%p) %##s (%s), DNS Server %#a:%d",
question, question->DuplicateOf, question->qname.c, DNSTypeName(question->qtype),
question->qDNSServer ? &question->qDNSServer->addr : mDNSNULL,
- mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zp));
+ mDNSVal16(question->qDNSServer ? question->qDNSServer->port : zeroIPPort));
}
ActivateUnicastQuery(m, question, mDNSfalse);
@@ -11692,7 +11958,6 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
DNSQuestion **q;
mStatus vStatus;
mDNSBool purge;
- mDNSOpaque16 zqid = zeroID;
// First check for cache space (can't do queries if there is no cache space allocated)
if (m->rrcache_size == 0)
@@ -11701,19 +11966,30 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
vStatus = ValidateParameters(m, question);
if (vStatus)
return(vStatus);
-
+
+#ifdef USE_LIBIDN
+ // If the TLD includes high-ascii bytes, assume it will need to be converted to Punycode.
+ // (In the future the root name servers may answer UTF-8 queries directly, but for now they do not.)
+ if (IsHighASCIILabel(LastLabel(&question->qname)))
+ {
+ domainname newname;
+ if (PerformNextPunycodeConversion(question, &newname))
+ AssignDomainName(&question->qname, &newname);
+ }
+#endif // USE_LIBIDN
+
question->TargetQID =
#ifndef UNICAST_DISABLED
(question->Target.type || Question_uDNS(question)) ? mDNS_NewMessageID(m) :
#endif // UNICAST_DISABLED
- zqid;
- debugf("mDNS_StartQuery_internal: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
-
+ zeroID;
+ debugf("mDNS_StartQuery_internal: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+
// Note: It important that new questions are appended at the *end* of the list, not prepended at the start
q = &m->Questions;
- if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
+ if (LocalOnlyOrP2PInterface(question->InterfaceID))
q = &m->LocalOnlyQuestions;
- while (*q && *q != question)
+ while (*q && *q != question)
q=&(*q)->next;
if (*q)
@@ -11723,7 +11999,6 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
return(mStatus_AlreadyRegistered);
}
*q = question;
-
// Intialize the question. The only ordering constraint we have today is that
// InitDNSSECProxyState should be called after the DNS server is selected (in
@@ -11733,23 +12008,26 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
purge = InitCommonState(m, question);
InitWABState(question);
InitLLQState(question);
+#ifdef DNS_PUSH_ENABLED
+ InitDNSPNState(question);
+#endif // DNS_PUSH_ENABLED
InitDNSSECProxyState(m, question);
// FindDuplicateQuestion should be called last after all the intialization
// as the duplicate logic could be potentially based on any field in the
// question.
question->DuplicateOf = FindDuplicateQuestion(m, question);
- if (question->DuplicateOf)
- question->AuthInfo = question->DuplicateOf->AuthInfo;
+ if (question->DuplicateOf)
+ question->AuthInfo = question->DuplicateOf->AuthInfo;
- if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P)
+ if (LocalOnlyOrP2PInterface(question->InterfaceID))
{
- if (!m->NewLocalOnlyQuestions)
+ if (!m->NewLocalOnlyQuestions)
m->NewLocalOnlyQuestions = question;
}
else
{
- if (!m->NewQuestions)
+ if (!m->NewQuestions)
m->NewQuestions = question;
// If the question's id is non-zero, then it's Wide Area
@@ -11764,13 +12042,22 @@ mDNSexport mStatus mDNS_StartQuery_internal(mDNS *const m, DNSQuestion *const qu
}
else
{
-#if TARGET_OS_WATCH
- m->NumAllInterfaceQuestions++;
- LogInfo("mDNS_StartQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
- m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
- if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
- m->NetworkChanged = m->timenow;
-#endif
+#if BONJOUR_ON_DEMAND
+ m->NumAllInterfaceQuestions++;
+ LogInfo("mDNS_StartQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ {
+ m->NextBonjourDisableTime = 0;
+ if (m->BonjourEnabled == 0)
+ {
+ // Enable Bonjour immediately by scheduling network changed processing where
+ // we will join the multicast group on each active interface.
+ m->BonjourEnabled = 1;
+ m->NetworkChanged = m->timenow;
+ }
+ }
+#endif // BONJOUR_ON_DEMAND
if (purge)
{
LogInfo("mDNS_StartQuery_internal: Purging for %##s", question->qname.c);
@@ -11800,14 +12087,14 @@ mDNSexport void CancelGetZoneData(mDNS *const m, ZoneData *nta)
mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const question)
{
- const mDNSu32 slot = HashSlot(&question->qname);
- CacheGroup *cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
+ CacheGroup *cg = CacheGroupForName(m, question->qnamehash, &question->qname);
CacheRecord *rr;
DNSQuestion **qp = &m->Questions;
//LogInfo("mDNS_StopQuery_internal %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
- if (question->InterfaceID == mDNSInterface_LocalOnly || question->InterfaceID == mDNSInterface_P2P) qp = &m->LocalOnlyQuestions;
+ if (LocalOnlyOrP2PInterface(question->InterfaceID))
+ qp = &m->LocalOnlyQuestions;
while (*qp && *qp != question) qp=&(*qp)->next;
if (*qp) *qp = (*qp)->next;
else
@@ -11819,29 +12106,28 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
return(mStatus_BadReferenceErr);
}
-#if TARGET_OS_WATCH
- if (question->InterfaceID != mDNSInterface_LocalOnly && question->InterfaceID != mDNSInterface_P2P && mDNSOpaque16IsZero(question->TargetQID))
+#if BONJOUR_ON_DEMAND
+ if (!LocalOnlyOrP2PInterface(question->InterfaceID) && mDNSOpaque16IsZero(question->TargetQID))
{
- if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
- m->NetworkChanged = m->timenow;
- m->NumAllInterfaceQuestions--;
- LogInfo("mDNS_StopQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
- m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
+ if (m->NumAllInterfaceRecords + m->NumAllInterfaceQuestions == 1)
+ m->NextBonjourDisableTime = NonZeroTime(m->timenow + (BONJOUR_DISABLE_DELAY * mDNSPlatformOneSecond));
+ m->NumAllInterfaceQuestions--;
+ LogInfo("mDNS_StopQuery_internal: NumAllInterfaceRecords %d NumAllInterfaceQuestions %d %##s (%s)",
+ m->NumAllInterfaceRecords, m->NumAllInterfaceQuestions, question->qname.c, DNSTypeName(question->qtype));
}
-#endif
+#endif // BONJOUR_ON_DEMAND
-#if TARGET_OS_EMBEDDED
- if (Question_uDNS(question) && !question->metrics.answered)
+#if AWD_METRICS
+ if (Question_uDNS(question) && !question->metrics.answered && (question->metrics.querySendCount > 0))
{
- uDNSMetrics * metrics;
const domainname * queryName;
- mDNSBool isForCellular;
-
- metrics = &question->metrics;
- queryName = metrics->originalQName ? metrics->originalQName : &question->qname;
- isForCellular = (question->qDNSServer && question->qDNSServer->cellIntf);
+ mDNSBool isForCell;
+ mDNSu32 durationMs;
- MetricsUpdateUDNSStats(queryName, mDNSfalse, metrics->querySendCount, 0, isForCellular);
+ queryName = question->metrics.originalQName ? question->metrics.originalQName : &question->qname;
+ isForCell = (question->qDNSServer && question->qDNSServer->cellIntf);
+ durationMs = ((m->timenow - question->metrics.firstQueryTime) * 1000) / mDNSPlatformOneSecond;
+ MetricsUpdateUDNSQueryStats(queryName, question->qtype, mDNSNULL, question->metrics.querySendCount, durationMs, isForCell);
}
#endif
// Take care to cut question from list *before* calling UpdateQuestionDuplicates
@@ -11856,16 +12142,31 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
if (rr->CRActiveQuestion == question)
{
DNSQuestion *q;
- // Checking for ActiveQuestion filters questions that are suppressed also
- // as suppressed questions are not active
- for (q = m->Questions; q; q=q->next) // Scan our list of questions
- if (ActiveQuestion(q) && ResourceRecordAnswersQuestion(&rr->resrec, q))
- break;
- if (q)
+ DNSQuestion *replacement = mDNSNULL;
+ // If we find an active question that is answered by this cached record, use it as the cache record's
+ // CRActiveQuestion replacement. If there are no such questions, but there's at least one unsuppressed inactive
+ // question that is answered by this cache record, then use an inactive one to not forgo generating RMV events
+ // via CacheRecordRmv() when the cache record expires.
+ for (q = m->Questions; q && (q != m->NewQuestions); q = q->next)
+ {
+ if (!q->DuplicateOf && !QuerySuppressed(q) && ResourceRecordAnswersQuestion(&rr->resrec, q))
+ {
+ if (q->ThisQInterval > 0)
+ {
+ replacement = q;
+ break;
+ }
+ else if (!replacement)
+ {
+ replacement = q;
+ }
+ }
+ }
+ if (replacement)
debugf("mDNS_StopQuery_internal: Updating CRActiveQuestion to %p for cache record %s, Original question CurrentAnswers %d, new question "
- "CurrentAnswers %d, SuppressQuery %d", q, CRDisplayString(m,rr), question->CurrentAnswers, q->CurrentAnswers, q->SuppressQuery);
- rr->CRActiveQuestion = q; // Question used to be active; new value may or may not be null
- if (!q) m->rrcache_active--; // If no longer active, decrement rrcache_active count
+ "CurrentAnswers %d, SuppressQuery %d", replacement, CRDisplayString(m,rr), question->CurrentAnswers, replacement->CurrentAnswers, replacement->SuppressQuery);
+ rr->CRActiveQuestion = replacement; // Question used to be active; new value may or may not be null
+ if (!replacement) m->rrcache_active--; // If no longer active, decrement rrcache_active count
}
}
@@ -11948,6 +12249,17 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
question->tcp = mDNSNULL;
}
}
+#ifdef DNS_PUSH_ENABLED
+ else if (question->dnsPushState == DNSPUSH_ESTABLISHED)
+ {
+ if (question->tcp)
+ {
+ UnSubscribeToDNSPushNotificationServer(m, q);
+ question->tcp->question = mDNSNULL;
+ question->tcp = mDNSNULL;
+ }
+ }
+#endif // DNS_PUSH_ENABLED
#if APPLE_OSX_mDNSResponder
UpdateAutoTunnelDomainStatuses(m);
#endif
@@ -11966,7 +12278,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
FreeAnonInfo(question->AnonInfo);
question->AnonInfo = mDNSNULL;
}
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if (question->metrics.originalQName)
{
mDNSPlatformMemFree(question->metrics.originalQName);
@@ -11974,6 +12286,10 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
}
#endif
+#if USE_DNS64
+ DNS64ResetState(question);
+#endif
+
return(mStatus_NoError);
}
@@ -12012,15 +12328,14 @@ mDNSexport mStatus mDNS_StopQueryWithRemoves(mDNS *const m, DNSQuestion *const q
if (status == mStatus_NoError && !qq)
{
const CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&question->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, question->qnamehash, &question->qname);
+ CacheGroup *const cg = CacheGroupForName(m, question->qnamehash, &question->qname);
LogInfo("Generating terminal removes for %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
for (rr = cg ? cg->members : mDNSNULL; rr; rr=rr->next)
if (rr->resrec.RecordType != kDNSRecordTypePacketNegative && SameNameRecordAnswersQuestion(&rr->resrec, question))
{
// Don't use mDNS_DropLockBeforeCallback() here, since we don't allow API calls
if (question->QuestionCallback)
- question->QuestionCallback(m, question, &rr->resrec, QC_rmv);
+ question->QuestionCallback(m, question, &rr->resrec, mDNSfalse);
}
}
mDNS_Unlock(m);
@@ -12064,10 +12379,8 @@ mDNSlocal mStatus mDNS_StartBrowse_internal(mDNS *const m, DNSQuestion *const qu
question->LongLived = mDNStrue;
question->ExpectUnique = mDNSfalse;
question->ForceMCast = ForceMCast;
- question->ReturnIntermed = mDNSfalse;
+ question->ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
question->SuppressUnusable = mDNSfalse;
- question->DenyOnCellInterface = mDNSfalse;
- question->DenyOnExpInterface = mDNSfalse;
question->SearchListIndex = 0;
question->AppendSearchDomains = 0;
question->RetryWithSearchDomains = mDNSfalse;
@@ -12108,295 +12421,6 @@ mDNSexport mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
return(status);
}
-mDNSlocal mDNSBool MachineHasActiveIPv6(mDNS *const m)
-{
- NetworkInterfaceInfo *intf;
- for (intf = m->HostInterfaces; intf; intf = intf->next)
- if (intf->ip.type == mDNSAddrType_IPv6) return(mDNStrue);
- return(mDNSfalse);
-}
-
-mDNSlocal void FoundServiceInfoSRV(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
-{
- ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
- mDNSBool PortChanged = !mDNSSameIPPort(query->info->port, answer->rdata->u.srv.port);
- if (!AddRecord) return;
- if (answer->rrtype != kDNSType_SRV) return;
-
- query->info->port = answer->rdata->u.srv.port;
-
- // If this is our first answer, then set the GotSRV flag and start the address query
- if (!query->GotSRV)
- {
- query->GotSRV = mDNStrue;
- query->qAv4.InterfaceID = answer->InterfaceID;
- AssignDomainName(&query->qAv4.qname, &answer->rdata->u.srv.target);
- query->qAv6.InterfaceID = answer->InterfaceID;
- AssignDomainName(&query->qAv6.qname, &answer->rdata->u.srv.target);
- mDNS_StartQuery(m, &query->qAv4);
- // Only do the AAAA query if this machine actually has IPv6 active
- if (MachineHasActiveIPv6(m)) mDNS_StartQuery(m, &query->qAv6);
- }
- // If this is not our first answer, only re-issue the address query if the target host name has changed
- else if ((query->qAv4.InterfaceID != query->qSRV.InterfaceID && query->qAv4.InterfaceID != answer->InterfaceID) ||
- !SameDomainName(&query->qAv4.qname, &answer->rdata->u.srv.target))
- {
- mDNS_StopQuery(m, &query->qAv4);
- if (query->qAv6.ThisQInterval >= 0) mDNS_StopQuery(m, &query->qAv6);
- if (SameDomainName(&query->qAv4.qname, &answer->rdata->u.srv.target) && !PortChanged)
- {
- // If we get here, it means:
- // 1. This is not our first SRV answer
- // 2. The interface ID is different, but the target host and port are the same
- // This implies that we're seeing the exact same SRV record on more than one interface, so we should
- // make our address queries at least as broad as the original SRV query so that we catch all the answers.
- query->qAv4.InterfaceID = query->qSRV.InterfaceID; // Will be mDNSInterface_Any, or a specific interface
- query->qAv6.InterfaceID = query->qSRV.InterfaceID;
- }
- else
- {
- query->qAv4.InterfaceID = answer->InterfaceID;
- AssignDomainName(&query->qAv4.qname, &answer->rdata->u.srv.target);
- query->qAv6.InterfaceID = answer->InterfaceID;
- AssignDomainName(&query->qAv6.qname, &answer->rdata->u.srv.target);
- }
- debugf("FoundServiceInfoSRV: Restarting address queries for %##s (%s)", query->qAv4.qname.c, DNSTypeName(query->qAv4.qtype));
- mDNS_StartQuery(m, &query->qAv4);
- // Only do the AAAA query if this machine actually has IPv6 active
- if (MachineHasActiveIPv6(m)) mDNS_StartQuery(m, &query->qAv6);
- }
- else if (query->ServiceInfoQueryCallback && query->GotADD && query->GotTXT && PortChanged)
- {
- if (++query->Answers >= 100)
- debugf("**** WARNING **** Have given %lu answers for %##s (SRV) %##s %u",
- query->Answers, query->qSRV.qname.c, answer->rdata->u.srv.target.c,
- mDNSVal16(answer->rdata->u.srv.port));
- query->ServiceInfoQueryCallback(m, query);
- }
- // CAUTION: MUST NOT do anything more with query after calling query->Callback(), because the client's
- // callback function is allowed to do anything, including deleting this query and freeing its memory.
-}
-
-mDNSlocal void FoundServiceInfoTXT(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
-{
- ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
- if (!AddRecord) return;
- if (answer->rrtype != kDNSType_TXT) return;
- if (answer->rdlength > sizeof(query->info->TXTinfo)) return;
-
- query->GotTXT = mDNStrue;
- query->info->TXTlen = answer->rdlength;
- query->info->TXTinfo[0] = 0; // In case answer->rdlength is zero
- mDNSPlatformMemCopy(query->info->TXTinfo, answer->rdata->u.txt.c, answer->rdlength);
-
- verbosedebugf("FoundServiceInfoTXT: %##s GotADD=%d", query->info->name.c, query->GotADD);
-
- // CAUTION: MUST NOT do anything more with query after calling query->Callback(), because the client's
- // callback function is allowed to do anything, including deleting this query and freeing its memory.
- if (query->ServiceInfoQueryCallback && query->GotADD)
- {
- if (++query->Answers >= 100)
- debugf("**** WARNING **** have given %lu answers for %##s (TXT) %#s...",
- query->Answers, query->qSRV.qname.c, answer->rdata->u.txt.c);
- query->ServiceInfoQueryCallback(m, query);
- }
-}
-
-mDNSlocal void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
-{
- ServiceInfoQuery *query = (ServiceInfoQuery *)question->QuestionContext;
- //LogInfo("FoundServiceInfo %d %s", AddRecord, RRDisplayString(m, answer));
- if (!AddRecord) return;
-
- if (answer->rrtype == kDNSType_A)
- {
- query->info->ip.type = mDNSAddrType_IPv4;
- query->info->ip.ip.v4 = answer->rdata->u.ipv4;
- }
- else if (answer->rrtype == kDNSType_AAAA)
- {
- query->info->ip.type = mDNSAddrType_IPv6;
- query->info->ip.ip.v6 = answer->rdata->u.ipv6;
- }
- else
- {
- debugf("FoundServiceInfo: answer %##s type %d (%s) unexpected", answer->name->c, answer->rrtype, DNSTypeName(answer->rrtype));
- return;
- }
-
- query->GotADD = mDNStrue;
- query->info->InterfaceID = answer->InterfaceID;
-
- verbosedebugf("FoundServiceInfo v%ld: %##s GotTXT=%d", query->info->ip.type, query->info->name.c, query->GotTXT);
-
- // CAUTION: MUST NOT do anything more with query after calling query->Callback(), because the client's
- // callback function is allowed to do anything, including deleting this query and freeing its memory.
- if (query->ServiceInfoQueryCallback && query->GotTXT)
- {
- if (++query->Answers >= 100)
- debugf(answer->rrtype == kDNSType_A ?
- "**** WARNING **** have given %lu answers for %##s (A) %.4a" :
- "**** WARNING **** have given %lu answers for %##s (AAAA) %.16a",
- query->Answers, query->qSRV.qname.c, &answer->rdata->u.data);
- query->ServiceInfoQueryCallback(m, query);
- }
-}
-
-// On entry, the client must have set the name and InterfaceID fields of the ServiceInfo structure
-// If the query is not interface-specific, then InterfaceID may be zero
-// Each time the Callback is invoked, the remainder of the fields will have been filled in
-// In addition, InterfaceID will be updated to give the interface identifier corresponding to that response
-mDNSexport mStatus mDNS_StartResolveService(mDNS *const m,
- ServiceInfoQuery *query, ServiceInfo *info, mDNSServiceInfoQueryCallback *Callback, void *Context)
-{
- mStatus status;
- mDNS_Lock(m);
-
- query->qSRV.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
- query->qSRV.InterfaceID = info->InterfaceID;
- query->qSRV.flags = 0;
- query->qSRV.Target = zeroAddr;
- AssignDomainName(&query->qSRV.qname, &info->name);
- query->qSRV.qtype = kDNSType_SRV;
- query->qSRV.qclass = kDNSClass_IN;
- query->qSRV.LongLived = mDNSfalse;
- query->qSRV.ExpectUnique = mDNStrue;
- query->qSRV.ForceMCast = mDNSfalse;
- query->qSRV.ReturnIntermed = mDNSfalse;
- query->qSRV.SuppressUnusable = mDNSfalse;
- query->qSRV.DenyOnCellInterface = mDNSfalse;
- query->qSRV.DenyOnExpInterface = mDNSfalse;
- query->qSRV.SearchListIndex = 0;
- query->qSRV.AppendSearchDomains = 0;
- query->qSRV.RetryWithSearchDomains = mDNSfalse;
- query->qSRV.TimeoutQuestion = 0;
- query->qSRV.WakeOnResolve = 0;
- query->qSRV.UseBackgroundTrafficClass = mDNSfalse;
- query->qSRV.ValidationRequired = 0;
- query->qSRV.ValidatingResponse = 0;
- query->qSRV.ProxyQuestion = 0;
- query->qSRV.qnameOrig = mDNSNULL;
- query->qSRV.AnonInfo = mDNSNULL;
- query->qSRV.QuestionCallback = FoundServiceInfoSRV;
- query->qSRV.QuestionContext = query;
-
- query->qTXT.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
- query->qTXT.InterfaceID = info->InterfaceID;
- query->qTXT.flags = 0;
- query->qTXT.Target = zeroAddr;
- AssignDomainName(&query->qTXT.qname, &info->name);
- query->qTXT.qtype = kDNSType_TXT;
- query->qTXT.qclass = kDNSClass_IN;
- query->qTXT.LongLived = mDNSfalse;
- query->qTXT.ExpectUnique = mDNStrue;
- query->qTXT.ForceMCast = mDNSfalse;
- query->qTXT.ReturnIntermed = mDNSfalse;
- query->qTXT.SuppressUnusable = mDNSfalse;
- query->qTXT.DenyOnCellInterface = mDNSfalse;
- query->qTXT.DenyOnExpInterface = mDNSfalse;
- query->qTXT.SearchListIndex = 0;
- query->qTXT.AppendSearchDomains = 0;
- query->qTXT.RetryWithSearchDomains = mDNSfalse;
- query->qTXT.TimeoutQuestion = 0;
- query->qTXT.WakeOnResolve = 0;
- query->qTXT.UseBackgroundTrafficClass = mDNSfalse;
- query->qTXT.ValidationRequired = 0;
- query->qTXT.ValidatingResponse = 0;
- query->qTXT.ProxyQuestion = 0;
- query->qTXT.qnameOrig = mDNSNULL;
- query->qTXT.AnonInfo = mDNSNULL;
- query->qTXT.QuestionCallback = FoundServiceInfoTXT;
- query->qTXT.QuestionContext = query;
-
- query->qAv4.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
- query->qAv4.InterfaceID = info->InterfaceID;
- query->qAv4.flags = 0;
- query->qAv4.Target = zeroAddr;
- query->qAv4.qname.c[0] = 0;
- query->qAv4.qtype = kDNSType_A;
- query->qAv4.qclass = kDNSClass_IN;
- query->qAv4.LongLived = mDNSfalse;
- query->qAv4.ExpectUnique = mDNStrue;
- query->qAv4.ForceMCast = mDNSfalse;
- query->qAv4.ReturnIntermed = mDNSfalse;
- query->qAv4.SuppressUnusable = mDNSfalse;
- query->qAv4.DenyOnCellInterface = mDNSfalse;
- query->qAv4.DenyOnExpInterface = mDNSfalse;
- query->qAv4.SearchListIndex = 0;
- query->qAv4.AppendSearchDomains = 0;
- query->qAv4.RetryWithSearchDomains = mDNSfalse;
- query->qAv4.TimeoutQuestion = 0;
- query->qAv4.WakeOnResolve = 0;
- query->qAv4.UseBackgroundTrafficClass = mDNSfalse;
- query->qAv4.ValidationRequired = 0;
- query->qAv4.ValidatingResponse = 0;
- query->qAv4.ProxyQuestion = 0;
- query->qAv4.qnameOrig = mDNSNULL;
- query->qAv4.AnonInfo = mDNSNULL;
- query->qAv4.QuestionCallback = FoundServiceInfo;
- query->qAv4.QuestionContext = query;
-
- query->qAv6.ThisQInterval = -1; // So that mDNS_StopResolveService() knows whether to cancel this question
- query->qAv6.InterfaceID = info->InterfaceID;
- query->qAv6.flags = 0;
- query->qAv6.Target = zeroAddr;
- query->qAv6.qname.c[0] = 0;
- query->qAv6.qtype = kDNSType_AAAA;
- query->qAv6.qclass = kDNSClass_IN;
- query->qAv6.LongLived = mDNSfalse;
- query->qAv6.ExpectUnique = mDNStrue;
- query->qAv6.ForceMCast = mDNSfalse;
- query->qAv6.ReturnIntermed = mDNSfalse;
- query->qAv6.SuppressUnusable = mDNSfalse;
- query->qAv6.DenyOnCellInterface = mDNSfalse;
- query->qAv6.DenyOnExpInterface = mDNSfalse;
- query->qAv6.SearchListIndex = 0;
- query->qAv6.AppendSearchDomains = 0;
- query->qAv6.RetryWithSearchDomains = mDNSfalse;
- query->qAv6.TimeoutQuestion = 0;
- query->qAv6.UseBackgroundTrafficClass = mDNSfalse;
- query->qAv6.ValidationRequired = 0;
- query->qAv6.ValidatingResponse = 0;
- query->qAv6.ProxyQuestion = 0;
- query->qAv6.qnameOrig = mDNSNULL;
- query->qAv6.AnonInfo = mDNSNULL;
- query->qAv6.QuestionCallback = FoundServiceInfo;
- query->qAv6.QuestionContext = query;
-
- query->GotSRV = mDNSfalse;
- query->GotTXT = mDNSfalse;
- query->GotADD = mDNSfalse;
- query->Answers = 0;
-
- query->info = info;
- query->ServiceInfoQueryCallback = Callback;
- query->ServiceInfoQueryContext = Context;
-
-// info->name = Must already be set up by client
-// info->interface = Must already be set up by client
- info->ip = zeroAddr;
- info->port = zeroIPPort;
- info->TXTlen = 0;
-
- // We use mDNS_StartQuery_internal here because we're already holding the lock
- status = mDNS_StartQuery_internal(m, &query->qSRV);
- if (status == mStatus_NoError) status = mDNS_StartQuery_internal(m, &query->qTXT);
- if (status != mStatus_NoError) mDNS_StopResolveService(m, query);
-
- mDNS_Unlock(m);
- return(status);
-}
-
-mDNSexport void mDNS_StopResolveService (mDNS *const m, ServiceInfoQuery *q)
-{
- mDNS_Lock(m);
- // We use mDNS_StopQuery_internal here because we're already holding the lock
- if (q->qSRV.ThisQInterval >= 0) mDNS_StopQuery_internal(m, &q->qSRV);
- if (q->qTXT.ThisQInterval >= 0) mDNS_StopQuery_internal(m, &q->qTXT);
- if (q->qAv4.ThisQInterval >= 0) mDNS_StopQuery_internal(m, &q->qAv4);
- if (q->qAv6.ThisQInterval >= 0) mDNS_StopQuery_internal(m, &q->qAv6);
- mDNS_Unlock(m);
-}
mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom,
const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context)
@@ -12411,8 +12435,6 @@ mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, m
question->ForceMCast = mDNSfalse;
question->ReturnIntermed = mDNSfalse;
question->SuppressUnusable = mDNSfalse;
- question->DenyOnCellInterface = mDNSfalse;
- question->DenyOnExpInterface = mDNSfalse;
question->SearchListIndex = 0;
question->AppendSearchDomains = 0;
question->RetryWithSearchDomains = mDNSfalse;
@@ -12425,7 +12447,7 @@ mDNSexport mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, m
question->qnameOrig = mDNSNULL;
question->AnonInfo = mDNSNULL;
question->pid = mDNSPlatformGetPID();
- question->euid = 0;
+ question->euid = 0;
question->QuestionCallback = Callback;
question->QuestionContext = Context;
if (DomainType > mDNS_DomainTypeMax) return(mStatus_BadParamErr);
@@ -12538,6 +12560,8 @@ mDNSlocal NetworkInterfaceInfo *FindFirstAdvertisedInterface(mDNS *const m)
return(intf);
}
+// The parameter "set" here refers to the set of AuthRecords used to advertise this interface.
+// (It's a set of records, not a set of interfaces.)
mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
{
char buffer[MAX_REVERSE_MAPPING_NAME];
@@ -12552,6 +12576,8 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
primary = FindFirstAdvertisedInterface(m);
if (!primary) primary = set; // If no existing advertised interface, this new NetworkInterfaceInfo becomes our new primary
+ // We should never have primary be NULL, because even if there is
+ // no other interface yet, we should always find ourself in the list.
// If interface is marked as a direct link, we can assume the address record is unique
// and does not need to go through the probe phase of the probe/announce packet sequence.
@@ -12561,9 +12587,9 @@ mDNSlocal void AdvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
LogInfo("AdvertiseInterface: Marking address record as kDNSRecordTypeKnownUnique for %s", set->ifname);
// Send dynamic update for non-linklocal IPv4 Addresses
- mDNS_SetupResourceRecord(&set->RR_A, mDNSNULL, set->InterfaceID, kDNSType_A, kHostNameTTL, recordType, AuthRecordAny, mDNS_HostNameCallback, set);
- mDNS_SetupResourceRecord(&set->RR_PTR, mDNSNULL, set->InterfaceID, kDNSType_PTR, kHostNameTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
- mDNS_SetupResourceRecord(&set->RR_HINFO, mDNSNULL, set->InterfaceID, kDNSType_HINFO, kHostNameTTL, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
+ mDNS_SetupResourceRecord(&set->RR_A, mDNSNULL, set->InterfaceID, kDNSType_A, kHostNameTTL, recordType, AuthRecordAny, mDNS_HostNameCallback, set);
+ mDNS_SetupResourceRecord(&set->RR_PTR, mDNSNULL, set->InterfaceID, kDNSType_PTR, kHostNameTTL, kDNSRecordTypeKnownUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
+ mDNS_SetupResourceRecord(&set->RR_HINFO, mDNSNULL, set->InterfaceID, kDNSType_HINFO, kHostNameTTL, kDNSRecordTypeUnique, AuthRecordAny, mDNSNULL, mDNSNULL);
#if ANSWER_REMOTE_HOSTNAME_QUERIES
set->RR_A.AllowRemoteQuery = mDNStrue;
@@ -12636,6 +12662,10 @@ mDNSlocal void DeadvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
return;
}
+#if APPLE_OSX_mDNSResponder
+ D2D_stop_advertising_interface(set);
+#endif // APPLE_OSX_mDNSResponder
+
// Unregister these records.
// When doing the mDNS_Exit processing, we first call DeadvertiseInterface for each interface, so by the time the platform
// support layer gets to call mDNS_DeregisterInterface, the address and PTR records have already been deregistered for it.
@@ -12644,11 +12674,6 @@ mDNSlocal void DeadvertiseInterface(mDNS *const m, NetworkInterfaceInfo *set)
if (set->RR_A .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_A, mDNS_Dereg_normal);
if (set->RR_PTR .resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_PTR, mDNS_Dereg_normal);
if (set->RR_HINFO.resrec.RecordType) mDNS_Deregister_internal(m, &set->RR_HINFO, mDNS_Dereg_normal);
-
-#if APPLE_OSX_mDNSResponder
- D2D_stop_advertising_interface(set);
-#endif // APPLE_OSX_mDNSResponder
-
}
mDNSlocal void AdvertiseAllInterfaceRecords(mDNS *const m)
@@ -12677,6 +12702,23 @@ mDNSlocal void DeadvertiseAllInterfaceRecords(mDNS *const m)
}
}
+// Change target host name for record.
+mDNSlocal void UpdateTargetHostName(mDNS *const m, AuthRecord *const rr)
+{
+#if APPLE_OSX_mDNSResponder
+ // If this record was also registered with any D2D plugins, stop advertising
+ // the version with the old host name.
+ D2D_stop_advertising_record(rr);
+#endif
+
+ SetTargetToHostName(m, rr);
+
+#if APPLE_OSX_mDNSResponder
+ // Advertise the record with the updated host name with the D2D plugins if appropriate.
+ D2D_start_advertising_record(rr);
+#endif
+}
+
mDNSexport void mDNS_SetFQDN(mDNS *const m)
{
domainname newmname;
@@ -12697,8 +12739,8 @@ mDNSexport void mDNS_SetFQDN(mDNS *const m)
}
// 3. Make sure that any AutoTarget SRV records (and the like) get updated
- for (rr = m->ResourceRecords; rr; rr=rr->next) if (rr->AutoTarget) SetTargetToHostName(m, rr);
- for (rr = m->DuplicateRecords; rr; rr=rr->next) if (rr->AutoTarget) SetTargetToHostName(m, rr);
+ for (rr = m->ResourceRecords; rr; rr=rr->next) if (rr->AutoTarget) UpdateTargetHostName(m, rr);
+ for (rr = m->DuplicateRecords; rr; rr=rr->next) if (rr->AutoTarget) UpdateTargetHostName(m, rr);
mDNS_Unlock(m);
}
@@ -12787,7 +12829,7 @@ mDNSlocal void InitializeNetWakeState(mDNS *const m, NetworkInterfaceInfo *set)
// be stopped during interface deregistration. We can't sanity check to see if the
// question has been stopped or not before initializing it to -1 because we need to
// initialize it to -1 the very first time.
-
+
set->NetWakeBrowse.ThisQInterval = -1;
for (i=0; i<3; i++)
{
@@ -12834,7 +12876,7 @@ mDNSexport void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceI
if (m->SPSBrowseCallback)
{
mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
- m->SPSBrowseCallback(m, &set->NetWakeBrowse, mDNSNULL, QC_rmv);
+ m->SPSBrowseCallback(m, &set->NetWakeBrowse, mDNSNULL, mDNSfalse);
mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
}
@@ -12844,7 +12886,7 @@ mDNSexport void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceI
}
}
-mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed)
{
AuthRecord *rr;
mDNSBool FirstOfType = mDNStrue;
@@ -12915,31 +12957,56 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
// We don't want to do a probe, and then see a stale echo of an announcement we ourselves sent,
// and think it's a conflicting answer to our probe.
// In the case of a flapping interface, we pause for five seconds, and reduce the announcement count to one packet.
- const mDNSs32 probedelay = flapping ? mDNSPlatformOneSecond * 5 : mDNSPlatformOneSecond / 2;
- const mDNSu8 numannounce = flapping ? (mDNSu8)1 : InitialAnnounceCount;
+ mDNSs32 probedelay;
+ mDNSu8 numannounce;
+ switch (activationSpeed)
+ {
+ case FastActivation:
+ probedelay = (mDNSs32)0;
+ numannounce = InitialAnnounceCount;
+ LogMsg("mDNS_RegisterInterface: Using fast activation for DirectLink interface %s (%#a)", set->ifname, &set->ip);
+ break;
- // Use a small amount of randomness:
- // In the case of a network administrator turning on an Ethernet hub so that all the
- // connected machines establish link at exactly the same time, we don't want them all
- // to go and hit the network with identical queries at exactly the same moment.
- // We set a random delay of up to InitialQuestionInterval (1/3 second).
- // We must *never* set m->SuppressSending to more than that (or set it repeatedly in a way
- // that causes mDNSResponder to remain in a prolonged state of SuppressSending, because
- // suppressing packet sending for more than about 1/3 second can cause protocol correctness
- // to start to break down (e.g. we don't answer probes fast enough, and get name conflicts).
- // See <rdar://problem/4073853> mDNS: m->SuppressSending set too enthusiastically
- if (!m->SuppressSending) m->SuppressSending = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+ case SlowActivation:
+ probedelay = mDNSPlatformOneSecond * 5;
+ numannounce = (mDNSu8)1;
+ LogMsg("mDNS_RegisterInterface: Frequent transitions for interface %s (%#a), doing slow activation", set->ifname, &set->ip);
+ m->mDNSStats.InterfaceUpFlap++;
+ break;
- if (flapping)
- {
- LogMsg("mDNS_RegisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
- m->mDNSStats.InterfaceUpFlap++;
+ case NormalActivation:
+ default:
+ probedelay = mDNSPlatformOneSecond / 2;
+ numannounce = InitialAnnounceCount;
+ break;
}
LogInfo("mDNS_RegisterInterface: %s (%#a) probedelay %d", set->ifname, &set->ip, probedelay);
- if (m->SuppressProbes == 0 ||
- m->SuppressProbes - NonZeroTime(m->timenow + probedelay) < 0)
- m->SuppressProbes = NonZeroTime(m->timenow + probedelay);
+
+ // No probe or sending suppression on DirectLink type interfaces.
+ if (activationSpeed == FastActivation)
+ {
+ m->SuppressSending = 0;
+ m->SuppressProbes = 0;
+ }
+ else
+ {
+ // Use a small amount of randomness:
+ // In the case of a network administrator turning on an Ethernet hub so that all the
+ // connected machines establish link at exactly the same time, we don't want them all
+ // to go and hit the network with identical queries at exactly the same moment.
+ // We set a random delay of up to InitialQuestionInterval (1/3 second).
+ // We must *never* set m->SuppressSending to more than that (or set it repeatedly in a way
+ // that causes mDNSResponder to remain in a prolonged state of SuppressSending, because
+ // suppressing packet sending for more than about 1/3 second can cause protocol correctness
+ // to start to break down (e.g. we don't answer probes fast enough, and get name conflicts).
+ // See <rdar://problem/4073853> mDNS: m->SuppressSending set too enthusiastically
+ if (!m->SuppressSending) m->SuppressSending = m->timenow + (mDNSs32)mDNSRandom((mDNSu32)InitialQuestionInterval);
+
+ if (m->SuppressProbes == 0 ||
+ m->SuppressProbes - NonZeroTime(m->timenow + probedelay) < 0)
+ m->SuppressProbes = NonZeroTime(m->timenow + probedelay);
+ }
// Include OWNER option in packets for 60 seconds after connecting to the network. Setting
// it here also handles the wake up case as the network link comes UP after waking causing
@@ -12956,21 +13023,15 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
if (!q->InterfaceID || q->InterfaceID == set->InterfaceID) // If non-specific Q, or Q on this specific interface,
{ // then reactivate this question
// If flapping, delay between first and second queries is nine seconds instead of one second
- mDNSBool dodelay = flapping && (q->FlappingInterface1 == set->InterfaceID || q->FlappingInterface2 == set->InterfaceID);
+ mDNSBool dodelay = (activationSpeed == SlowActivation) && (q->FlappingInterface1 == set->InterfaceID || q->FlappingInterface2 == set->InterfaceID);
mDNSs32 initial = dodelay ? InitialQuestionInterval * QuestionIntervalStep2 : InitialQuestionInterval;
- mDNSs32 qdelay = dodelay ? mDNSPlatformOneSecond * 5 : 0;
- if (dodelay) LogInfo("No cache records expired for %##s (%s); okay to delay questions a little", q->qname.c, DNSTypeName(q->qtype));
+ mDNSs32 qdelay = dodelay ? kDefaultQueryDelayTimeForFlappingInterface : 0;
+ if (dodelay) LogInfo("No cache records expired for %##s (%s); delaying questions by %d seconds", q->qname.c, DNSTypeName(q->qtype), qdelay);
if (!q->ThisQInterval || q->ThisQInterval > initial)
{
- q->ThisQInterval = initial;
-
-#if mDNS_REQUEST_UNICAST_RESPONSE
- q->RequestUnicast = SET_QU_IN_FIRST_FOUR_QUERIES;
-#else // mDNS_REQUEST_UNICAST_RESPONSE
- q->RequestUnicast = SET_QU_IN_FIRST_QUERY;
-#endif // mDNS_REQUEST_UNICAST_RESPONSE
-
+ q->ThisQInterval = initial;
+ q->RequestUnicast = kDefaultRequestUnicastCount;
}
q->LastQTime = m->timenow - q->ThisQInterval + qdelay;
q->RecentAnswerPkts = 0;
@@ -13008,7 +13069,7 @@ mDNSexport mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *s
// Note: mDNS_DeregisterInterface calls mDNS_Deregister_internal which can call a user callback, which may change
// the record list and/or question list.
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
-mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping)
+mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed)
{
NetworkInterfaceInfo **p = &m->HostInterfaces;
mDNSBool revalidate = mDNSfalse;
@@ -13068,7 +13129,7 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
m->mDNSStats.InterfaceDown++;
- if (set->McastTxRx && flapping)
+ if (set->McastTxRx && (activationSpeed == SlowActivation))
{
LogMsg("mDNS_DeregisterInterface: Frequent transitions for interface %s (%#a)", set->ifname, &set->ip);
m->mDNSStats.InterfaceDownFlap++;
@@ -13094,9 +13155,10 @@ mDNSexport void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *se
{
// If this interface is deemed flapping,
// postpone deleting the cache records in case the interface comes back again
- if (set->McastTxRx && flapping)
+ if (set->McastTxRx && (activationSpeed == SlowActivation))
{
- // For a flapping interface we want these record to go away after 30 seconds
+ // For a flapping interface we want these records to go away after
+ // kDefaultReconfirmTimeForFlappingInterface seconds if they are not reconfirmed.
mDNS_Reconfirm_internal(m, rr, kDefaultReconfirmTimeForFlappingInterface);
// We set UnansweredQueries = MaxUnansweredQueries so we don't waste time doing any queries for them --
// if the interface does come back, any relevant questions will be reactivated anyway
@@ -13256,20 +13318,21 @@ mDNSlocal void NSSCallback(mDNS *const m, AuthRecord *const rr, mStatus result)
}
+// Derive AuthRecType from the kDNSServiceFlags* values.
mDNSlocal AuthRecType setAuthRecType(mDNSInterfaceID InterfaceID, mDNSu32 flags)
{
AuthRecType artype;
if (InterfaceID == mDNSInterface_LocalOnly)
artype = AuthRecordLocalOnly;
- else if (InterfaceID == mDNSInterface_P2P)
+ else if (InterfaceID == mDNSInterface_P2P || InterfaceID == mDNSInterface_BLE)
artype = AuthRecordP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeP2P)
- && (flags & coreFlagIncludeAWDL))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P)
+ && (flags & kDNSServiceFlagsIncludeAWDL))
artype = AuthRecordAnyIncludeAWDLandP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeP2P))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P))
artype = AuthRecordAnyIncludeP2P;
- else if ((InterfaceID == mDNSInterface_Any) && (flags & coreFlagIncludeAWDL))
+ else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeAWDL))
artype = AuthRecordAnyIncludeAWDL;
else
artype = AuthRecordAny;
@@ -13277,6 +13340,18 @@ mDNSlocal AuthRecType setAuthRecType(mDNSInterfaceID InterfaceID, mDNSu32 flags)
return artype;
}
+// Used to derive the original D2D specific flags specified by the client in the registration
+// when we don't have access to the original flag (kDNSServiceFlags*) values.
+mDNSexport mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType)
+{
+ mDNSu32 flags = 0;
+ if ((authRecType == AuthRecordAnyIncludeP2P) || (authRecType == AuthRecordAnyIncludeAWDLandP2P))
+ flags |= kDNSServiceFlagsIncludeP2P;
+ else if ((authRecType == AuthRecordAnyIncludeAWDL) || (authRecType == AuthRecordAnyIncludeAWDLandP2P))
+ flags |= kDNSServiceFlagsIncludeAWDL;
+ return flags;
+}
+
// Note:
// Name is first label of domain name (any dots in the name are actual dots, not label separators)
// Type is service type (e.g. "_ipp._tcp.")
@@ -13296,7 +13371,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
mDNSu32 i;
mDNSu32 hostTTL;
AuthRecType artype;
- mDNSu8 recordType = (flags & coreFlagKnownUnique) ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique;
+ mDNSu8 recordType = (flags & kDNSServiceFlagsKnownUnique) ? kDNSRecordTypeKnownUnique : kDNSRecordTypeUnique;
sr->ServiceCallback = Callback;
sr->ServiceContext = Context;
@@ -13314,7 +13389,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
mDNS_SetupResourceRecord(&sr->RR_ADV, mDNSNULL, InterfaceID, kDNSType_PTR, kStandardTTL, kDNSRecordTypeAdvisory, artype, ServiceCallback, sr);
mDNS_SetupResourceRecord(&sr->RR_PTR, mDNSNULL, InterfaceID, kDNSType_PTR, kStandardTTL, kDNSRecordTypeShared, artype, ServiceCallback, sr);
- if (flags & coreFlagWakeOnly)
+ if (flags & kDNSServiceFlagsWakeOnlyService)
{
sr->RR_PTR.AuthFlags = AuthFlagsWakeOnly;
}
@@ -13325,14 +13400,14 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
hostTTL = kHostNameTTL;
mDNS_SetupResourceRecord(&sr->RR_SRV, mDNSNULL, InterfaceID, kDNSType_SRV, hostTTL, recordType, artype, ServiceCallback, sr);
- mDNS_SetupResourceRecord(&sr->RR_TXT, mDNSNULL, InterfaceID, kDNSType_TXT, kStandardTTL, kDNSRecordTypeUnique, artype, ServiceCallback, sr);
+ mDNS_SetupResourceRecord(&sr->RR_TXT, mDNSNULL, InterfaceID, kDNSType_TXT, kStandardTTL, recordType, artype, ServiceCallback, sr);
// If port number is zero, that means the client is really trying to do a RegisterNoSuchService
if (mDNSIPPortIsZero(port))
return(mDNS_RegisterNoSuchService(m, &sr->RR_SRV, name, type, domain, mDNSNULL, InterfaceID, NSSCallback, sr, flags));
- // If the client is registering an oversized TXT record,
- // it is the client's responsibility to alloate a ServiceRecordSet structure that is large enough for it
+ // If the caller is registering an oversized TXT record,
+ // it is the caller's responsibility to allocate a ServiceRecordSet structure that is large enough for it
if (sr->RR_TXT.resrec.rdata->MaxRDLength < txtlen)
sr->RR_TXT.resrec.rdata->MaxRDLength = txtlen;
@@ -13370,7 +13445,7 @@ mDNSexport mStatus mDNS_RegisterService(mDNS *const m, ServiceRecordSet *sr,
sr->SubTypes[i].Additional1 = &sr->RR_SRV;
sr->SubTypes[i].Additional2 = &sr->RR_TXT;
}
-
+
SetAnonInfoSRS(sr, NumSubTypes);
// 3. Set up the SRV record rdata.
@@ -13430,6 +13505,7 @@ mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
mStatus status;
AuthRecType artype;
mDNSInterfaceID InterfaceID = sr->RR_PTR.resrec.InterfaceID;
+ ResourceRecord *rr;
artype = setAuthRecType(InterfaceID, flags);
@@ -13439,6 +13515,37 @@ mDNSexport mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr,
AssignDomainName(&extra->r.namestorage, sr->RR_SRV.resrec.name);
mDNS_Lock(m);
+ rr = mDNSNULL;
+ if (extra->r.resrec.rrtype == kDNSType_TXT)
+ {
+ if (sr->RR_TXT.resrec.RecordType & kDNSRecordTypeUniqueMask) rr = &sr->RR_TXT.resrec;
+ }
+ else if (extra->r.resrec.rrtype == kDNSType_SRV)
+ {
+ if (sr->RR_SRV.resrec.RecordType & kDNSRecordTypeUniqueMask) rr = &sr->RR_SRV.resrec;
+ }
+
+ if (!rr)
+ {
+ ExtraResourceRecord *srExtra;
+
+ for (srExtra = sr->Extras; srExtra; srExtra = srExtra->next)
+ {
+ if ((srExtra->r.resrec.rrtype == extra->r.resrec.rrtype) && (srExtra->r.resrec.RecordType & kDNSRecordTypeUniqueMask))
+ {
+ rr = &srExtra->r.resrec;
+ break;
+ }
+ }
+ }
+
+ if (rr && (extra->r.resrec.rroriginalttl != rr->rroriginalttl))
+ {
+ LogMsg("mDNS_AddRecordToService: Correcting TTL from %4d to %4d for %s",
+ extra->r.resrec.rroriginalttl, rr->rroriginalttl, RRDisplayString(m, &extra->r.resrec));
+ extra->r.resrec.rroriginalttl = rr->rroriginalttl;
+ }
+
e = &sr->Extras;
while (*e) e = &(*e)->next;
@@ -13614,7 +13721,7 @@ mDNSexport mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr,
if (InterfaceID == mDNSInterface_LocalOnly)
artype = AuthRecordLocalOnly;
- else if (InterfaceID == mDNSInterface_P2P)
+ else if (InterfaceID == mDNSInterface_P2P || InterfaceID == mDNSInterface_BLE)
artype = AuthRecordP2P;
else
artype = AuthRecordAny;
@@ -13723,8 +13830,9 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
const char *const msg = mDNSSameEthAddress(&arp->sha, &rr->WakeUp.IMAC) ? msg1 :
(rr->AnnounceCount == InitialAnnounceCount) ? msg2 :
mDNSSameEthAddress(&arp->sha, &intf->MAC) ? msg3 : msg4;
- LogSPS("%-7s %s %.6a %.4a for %.4a -- H-MAC %.6a I-MAC %.6a %s",
- intf->ifname, msg, &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+ LogMsg("Arp %-7s %s %.6a %.4a for %.4a -- H-MAC %.6a I-MAC %.6a %s",
+ intf->ifname, msg, arp->sha.b, arp->spa.b, arp->tpa.b,
+ &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
if (msg == msg1)
{
if ( rr->ProbeRestartCount < MAX_PROBE_RESTARTS)
@@ -13734,11 +13842,11 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
}
else if (msg == msg3)
{
- mDNSPlatformSetLocalAddressCacheEntry(m, &rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
+ mDNSPlatformSetLocalAddressCacheEntry(&rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
}
else if (msg == msg4)
{
- SendARP(m, 2, rr, &arp->tpa, &arp->sha, &arp->spa, &arp->sha);
+ SendARP(m, 2, rr, (mDNSv4Addr *)arp->tpa.b, &arp->sha, (mDNSv4Addr *)arp->spa.b, &arp->sha);
}
}
}
@@ -13752,7 +13860,7 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
// If the sender hardware address is the original owner this is benign, so we just suppress our own proxy answering for a while longer.
// If the sender hardware address is *not* the original owner, then this is a conflict, and we need to wake the sleeping machine to handle it.
if (mDNSSameEthAddress(&arp->sha, &intf->MAC))
- debugf("ARP from self for %.4a", &arp->tpa);
+ debugf("ARP from self for %.4a", arp->tpa.b);
else
{
if (!mDNSSameIPv4Address(arp->spa, zerov4Addr))
@@ -13762,22 +13870,22 @@ mDNSlocal void mDNSCoreReceiveRawARP(mDNS *const m, const ARP_EthIP *const arp,
{
if (mDNSSameEthAddress(&zeroEthAddr, &rr->WakeUp.HMAC))
{
- LogSPS("%-7s ARP from %.6a %.4a for %.4a -- Invalid H-MAC %.6a I-MAC %.6a %s", intf->ifname,
- &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+ LogMsg("%-7s ARP from %.6a %.4a for %.4a -- Invalid H-MAC %.6a I-MAC %.6a %s", intf->ifname,
+ arp->sha.b, arp->spa.b, arp->tpa.b, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
}
else
{
RestartARPProbing(m, rr);
if (mDNSSameEthAddress(&arp->sha, &rr->WakeUp.IMAC))
{
- LogSPS("%-7s ARP %s from owner %.6a %.4a for %-15.4a -- re-starting probing for %s", intf->ifname,
+ LogMsg("%-7s ARP %s from owner %.6a %.4a for %-15.4a -- re-starting probing for %s", intf->ifname,
mDNSSameIPv4Address(arp->spa, arp->tpa) ? "Announcement " : mDNSSameOpaque16(arp->op, ARP_op_request) ? "Request " : "Response ",
- &arp->sha, &arp->spa, &arp->tpa, ARDisplayString(m, rr));
+ arp->sha.b, arp->spa.b, arp->tpa.b, ARDisplayString(m, rr));
}
else
{
LogMsg("%-7s Conflicting ARP from %.6a %.4a for %.4a -- waking H-MAC %.6a I-MAC %.6a %s", intf->ifname,
- &arp->sha, &arp->spa, &arp->tpa, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
+ arp->sha.b, arp->spa.b, arp->tpa.b, &rr->WakeUp.HMAC, &rr->WakeUp.IMAC, ARDisplayString(m, rr));
ScheduleWakeup(m, rr->resrec.InterfaceID, &rr->WakeUp.HMAC);
}
}
@@ -13840,10 +13948,10 @@ mDNSlocal void mDNSCoreReceiveRawND(mDNS *const m, const mDNSEthAddr *const sha,
LogSPS("Reached maximum number of restarts for probing - %s", ARDisplayString(m,rr));
}
else if (msg == msg3)
- mDNSPlatformSetLocalAddressCacheEntry(m, &rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
- else if (msg == msg4)
+ mDNSPlatformSetLocalAddressCacheEntry(&rr->AddressProxy, &rr->WakeUp.IMAC, InterfaceID);
+ else if (msg == msg4)
SendNDP(m, NDP_Adv, NDP_Solicited, rr, &ndp->target, mDNSNULL, spa, sha);
- else if (msg == msg5)
+ else if (msg == msg5)
SendNDP(m, NDP_Adv, 0, rr, &ndp->target, mDNSNULL, &AllHosts_v6, &AllHosts_v6_Eth);
}
}
@@ -14179,7 +14287,7 @@ mDNSexport void mDNSCoreBeSleepProxyServer_internal(mDNS *const m, mDNSu8 sps, m
{
if (!m->SPSSocket)
{
- m->SPSSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ m->SPSSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (!m->SPSSocket) { LogMsg("mDNSCoreBeSleepProxyServer: Failed to allocate SPSSocket"); goto fail; }
}
#ifndef SPC_DISABLED
@@ -14221,9 +14329,9 @@ mDNSexport void mDNS_GrowCache(mDNS *const m, CacheEntity *storage, mDNSu32 numr
mDNS_Unlock(m);
}
-mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
- CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
- mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
+mDNSlocal mStatus mDNS_InitStorage(mDNS *const m, mDNS_PlatformSupport *const p,
+ CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
+ mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
{
mDNSu32 slot;
mDNSs32 timenow;
@@ -14263,14 +14371,22 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->timenow_last = timenow;
m->NextScheduledEvent = timenow;
m->SuppressSending = timenow;
- m->NextCacheCheck = timenow + 0x78000000;
- m->NextScheduledQuery = timenow + 0x78000000;
- m->NextScheduledProbe = timenow + 0x78000000;
- m->NextScheduledResponse = timenow + 0x78000000;
- m->NextScheduledNATOp = timenow + 0x78000000;
- m->NextScheduledSPS = timenow + 0x78000000;
- m->NextScheduledKA = timenow + 0x78000000;
- m->NextScheduledStopTime = timenow + 0x78000000;
+ m->NextCacheCheck = timenow + FutureTime;
+ m->NextScheduledQuery = timenow + FutureTime;
+ m->NextScheduledProbe = timenow + FutureTime;
+ m->NextScheduledResponse = timenow + FutureTime;
+ m->NextScheduledNATOp = timenow + FutureTime;
+ m->NextScheduledSPS = timenow + FutureTime;
+ m->NextScheduledKA = timenow + FutureTime;
+ m->NextScheduledStopTime = timenow + FutureTime;
+ m->NextBLEServiceTime = 0; // zero indicates inactive
+
+#if BONJOUR_ON_DEMAND
+ m->NextBonjourDisableTime = 0; // Timer active when non zero.
+ m->BonjourEnabled = 0; // Set when Bonjour on Demand is enabled and Bonjour is currently enabled.
+#endif // BONJOUR_ON_DEMAND
+
+ m->DelayConflictProcessing = MAX_CONFLICT_PROCESSING_DELAYS;
m->RandomQueryDelay = 0;
m->RandomReconfirmDelay = 0;
m->PktNum = 0;
@@ -14284,9 +14400,6 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->SleepLimit = 0;
#if APPLE_OSX_mDNSResponder
- m->StatStartTime = mDNSPlatformUTC();
- m->NextStatLogTime = m->StatStartTime + kDefaultNextStatsticsLogTime;
- m->ActiveStatTime = 0;
m->UnicastPacketsSent = 0;
m->MulticastPacketsSent = 0;
m->RemoteSubnet = 0;
@@ -14309,7 +14422,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
{
m->rrcache_hash[slot] = mDNSNULL;
- m->rrcache_nextcheck[slot] = timenow + 0x78000000;;
+ m->rrcache_nextcheck[slot] = timenow + FutureTime;;
}
mDNS_GrowCache_internal(m, rrcachestorage, rrcachesize);
@@ -14335,8 +14448,8 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->SuppressProbes = 0;
#ifndef UNICAST_DISABLED
- m->NextuDNSEvent = timenow + 0x78000000;
- m->NextSRVUpdate = timenow + 0x78000000;
+ m->NextuDNSEvent = timenow + FutureTime;
+ m->NextSRVUpdate = timenow + FutureTime;
m->DNSServers = mDNSNULL;
@@ -14355,19 +14468,11 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->WABBrowseQueriesCount = 0;
m->WABLBrowseQueriesCount = 0;
m->WABRegQueriesCount = 0;
-#if TARGET_OS_EMBEDDED || TARGET_OS_WATCH
- m->AutoTargetServices = 0;
-#else
m->AutoTargetServices = 1;
-#endif
-#if TARGET_OS_WATCH
+
+#if BONJOUR_ON_DEMAND
m->NumAllInterfaceRecords = 0;
m->NumAllInterfaceQuestions = 0;
-#else
- // Initialize to 1 for these targets to prevent not joining multicast group for interfaces when
- // both of these values are zero.
- m->NumAllInterfaceRecords = 1;
- m->NumAllInterfaceQuestions = 1;
#endif
// NAT traversal fields
m->LLQNAT.clientCallback = mDNSNULL;
@@ -14375,7 +14480,7 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->NATTraversals = mDNSNULL;
m->CurrentNATTraversal = mDNSNULL;
m->retryIntervalGetAddr = 0; // delta between time sent and retry
- m->retryGetAddr = timenow + 0x78000000; // absolute time when we retry
+ m->retryGetAddr = timenow + FutureTime; // absolute time when we retry
m->ExtAddress = zerov4Addr;
m->PCPNonce[0] = mDNSRandom(-1);
m->PCPNonce[1] = mDNSRandom(-1);
@@ -14407,6 +14512,8 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
m->SPSBrowseCallback = mDNSNULL;
m->ProxyRecords = 0;
+ m->DNSPushServers = mDNSNULL;
+ m->DNSPushZones = mDNSNULL;
#endif
#if APPLE_OSX_mDNSResponder
@@ -14422,6 +14529,17 @@ mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
#endif
+ return(result);
+}
+
+mDNSexport mStatus mDNS_Init(mDNS *const m, mDNS_PlatformSupport *const p,
+ CacheEntity *rrcachestorage, mDNSu32 rrcachesize,
+ mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
+{
+ mStatus result = mDNS_InitStorage(m, p, rrcachestorage, rrcachesize, AdvertiseLocalAddresses, Callback, Context);
+ if (result != mStatus_NoError)
+ return(result);
+
result = mDNSPlatformInit(m);
#ifndef UNICAST_DISABLED
@@ -14471,7 +14589,8 @@ mDNSlocal void PurgeOrReconfirmCacheRecord(mDNS *const m, CacheRecord *cr, const
mDNSBool purge = cr->resrec.RecordType == kDNSRecordTypePacketNegative ||
cr->resrec.rrtype == kDNSType_A ||
cr->resrec.rrtype == kDNSType_AAAA ||
- cr->resrec.rrtype == kDNSType_SRV;
+ cr->resrec.rrtype == kDNSType_SRV ||
+ cr->resrec.rrtype == kDNSType_CNAME;
(void) lameduck;
(void) ptr;
@@ -14494,8 +14613,7 @@ mDNSlocal void PurgeOrReconfirmCacheRecord(mDNS *const m, CacheRecord *cr, const
mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
{
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
mDNSu8 validatingResponse = 0;
@@ -14530,8 +14648,7 @@ mDNSlocal void mDNS_PurgeForQuestion(mDNS *const m, DNSQuestion *q)
// them.
mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q)
{
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
for (rp = cg ? cg->members : mDNSNULL; rp; rp = rp->next)
@@ -14554,8 +14671,7 @@ mDNSlocal void CheckForDNSSECRecords(mDNS *const m, DNSQuestion *q)
mDNSexport mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype)
{
DNSQuestion question;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
CacheRecord *rp;
// Create an identical question but with qtype
@@ -14633,6 +14749,23 @@ mDNSlocal void SetConfigState(mDNS *const m, mDNSBool delete)
}
}
+mDNSlocal void SetDynDNSHostNameIfChanged(mDNS *const m, domainname *const fqdn)
+{
+ // Did our FQDN change?
+ if (!SameDomainName(fqdn, &m->FQDN))
+ {
+ if (m->FQDN.c[0]) mDNS_RemoveDynDNSHostName(m, &m->FQDN);
+
+ AssignDomainName(&m->FQDN, fqdn);
+
+ if (m->FQDN.c[0])
+ {
+ mDNSPlatformDynDNSHostNameStatusChanged(&m->FQDN, 1);
+ mDNS_AddDynDNSHostName(m, &m->FQDN, DynDNSHostNameCallback, mDNSNULL);
+ }
+ }
+}
+
mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
{
mDNSu32 slot;
@@ -14661,8 +14794,9 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// hence we are ready to ack the configuration as this is the last call to mDNSPlatformSetConfig
// for the dns configuration change notification.
SetConfigState(m, mDNStrue);
- if (!mDNSPlatformSetDNSConfig(m, mDNStrue, mDNSfalse, &fqdn, mDNSNULL, mDNSNULL, mDNStrue))
+ if (!mDNSPlatformSetDNSConfig(mDNStrue, mDNSfalse, &fqdn, mDNSNULL, mDNSNULL, mDNStrue))
{
+ SetDynDNSHostNameIfChanged(m, &fqdn);
SetConfigState(m, mDNSfalse);
mDNS_Unlock(m);
LogInfo("uDNS_SetupDNSConfig: No configuration change");
@@ -14716,6 +14850,9 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
// cache records and as the resGroupID is different, you can't use the cache record from the scoped DNSServer to answer the
// non-scoped question and vice versa.
//
+#if USE_DNS64
+ DNS64RestartQuestions(m);
+#endif
for (q = m->Questions; q; q=q->next)
{
if (!mDNSOpaque16IsZero(q->TargetQID))
@@ -14730,21 +14867,10 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
if (t != s)
{
mDNSBool old, new;
- mDNSIPPort tport, sport;
-
- if (t)
- tport = t->port;
- else
- tport = zeroIPPort;
-
- if (s)
- sport = s->port;
- else
- sport = zeroIPPort;
// If DNS Server for this question has changed, reactivate it
LogInfo("uDNS_SetupDNSConfig: Updating DNS Server from %#a:%d (%##s) to %#a:%d (%##s) for question %##s (%s) (scope:%p)",
- t ? &t->addr : mDNSNULL, mDNSVal16(tport), t ? t->domain.c : (mDNSu8*)"",
- s ? &s->addr : mDNSNULL, mDNSVal16(sport), s ? s->domain.c : (mDNSu8*)"",
+ t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zeroIPPort), t ? t->domain.c : (mDNSu8*)"",
+ s ? &s->addr : mDNSNULL, mDNSVal16(s ? s->port : zeroIPPort), s ? s->domain.c : (mDNSu8*)"",
q->qname.c, DNSTypeName(q->qtype), q->InterfaceID);
old = q->SuppressQuery;
@@ -14793,9 +14919,8 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
}
else
{
- mDNSIPPort zp = zeroIPPort;
debugf("uDNS_SetupDNSConfig: Not Updating DNS server question %p %##s (%s) DNS server %#a:%d %p %d",
- q, q->qname.c, DNSTypeName(q->qtype), t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zp), q->DuplicateOf, q->SuppressUnusable);
+ q, q->qname.c, DNSTypeName(q->qtype), t ? &t->addr : mDNSNULL, mDNSVal16(t ? t->port : zeroIPPort), q->DuplicateOf, q->SuppressUnusable);
for (qptr = q->next ; qptr; qptr = qptr->next)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
}
@@ -14851,6 +14976,14 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
PurgeOrReconfirmCacheRecord(m, cr, ptr, mDNSfalse);
}
}
+
+ // If a cache record's DNSServer pointer is NULL, but its active question got a DNSServer in this DNS configuration
+ // update, then use its DNSServer. This way, the active question and its duplicates don't miss out on RMV events.
+ if (!cr->resrec.rDNSServer && cr->CRActiveQuestion && cr->CRActiveQuestion->qDNSServer)
+ {
+ cr->resrec.rDNSServer = cr->CRActiveQuestion->qDNSServer;
+ LogInfo("uDNS_SetupDNSConfig: Using active question's DNS server %#a for cache record %s", &cr->resrec.rDNSServer->addr, CRDisplayString(m, cr));
+ }
}
while (*p)
@@ -14881,9 +15014,9 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
if (qptr->qDNSServer == ptr)
{
- LogMsg("uDNS_SetupDNSConfig: ERROR!! Cache Record %s Active question %##s (%s) (scope:%p) poining to DNSServer Address %#a"
+ LogMsg("uDNS_SetupDNSConfig: ERROR!! Cache Record %s Active question %##s (%s) (scope:%p) pointing to DNSServer Address %#a"
" to be freed", CRDisplayString(m, cr), qptr->qname.c, DNSTypeName(qptr->qtype), qptr->InterfaceID, &ptr->addr);
- qptr->validDNSServers = zeroOpaque64;
+ qptr->validDNSServers = zeroOpaque128;
qptr->qDNSServer = mDNSNULL;
cr->resrec.rDNSServer = mDNSNULL;
}
@@ -14891,7 +15024,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
{
LogInfo("uDNS_SetupDNSConfig: Cache Record %s, Active question %##s (%s) (scope:%p), pointing to DNSServer %#a (to be deleted),"
" resetting to question's DNSServer Address %#a", CRDisplayString(m, cr), qptr->qname.c, DNSTypeName(qptr->qtype),
- qptr->InterfaceID, &ptr->addr, (qptr->qDNSServer ? &qptr->qDNSServer->addr : mDNSNULL));
+ qptr->InterfaceID, &ptr->addr, (qptr->qDNSServer) ? &qptr->qDNSServer->addr : mDNSNULL);
cr->resrec.rDNSServer = qptr->qDNSServer;
}
}
@@ -14938,19 +15071,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
RestartRecordGetZoneData(m);
}
- // Did our FQDN change?
- if (!SameDomainName(&fqdn, &m->FQDN))
- {
- if (m->FQDN.c[0]) mDNS_RemoveDynDNSHostName(m, &m->FQDN);
-
- AssignDomainName(&m->FQDN, &fqdn);
-
- if (m->FQDN.c[0])
- {
- mDNSPlatformDynDNSHostNameStatusChanged(&m->FQDN, 1);
- mDNS_AddDynDNSHostName(m, &m->FQDN, DynDNSHostNameCallback, mDNSNULL);
- }
- }
+ SetDynDNSHostNameIfChanged(m, &fqdn);
mDNS_Unlock(m);
@@ -14958,7 +15079,7 @@ mDNSexport mStatus uDNS_SetupDNSConfig(mDNS *const m)
v4 = v6 = r = zeroAddr;
v4.type = r.type = mDNSAddrType_IPv4;
- if (mDNSPlatformGetPrimaryInterface(m, &v4, &v6, &r) == mStatus_NoError && !mDNSv4AddressIsLinkLocal(&v4.ip.v4))
+ if (mDNSPlatformGetPrimaryInterface(&v4, &v6, &r) == mStatus_NoError && !mDNSv4AddressIsLinkLocal(&v4.ip.v4))
{
mDNS_SetPrimaryInterfaceInfo(m,
!mDNSIPv4AddressIsZero(v4.ip.v4) ? &v4 : mDNSNULL,
@@ -15144,3 +15265,7 @@ mDNSexport void mDNS_FinalExit(mDNS *const m)
LogInfo("mDNS_FinalExit: done");
}
+
+#ifdef UNIT_TEST
+#include "../unittests/mdns_ut.c"
+#endif
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h
index 7bd783c568..68a696ef8a 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSDebug.h
@@ -87,9 +87,9 @@ extern "C" {
#define MDNS_GNU_VA_ARGS 0
#define MDNS_HAS_VA_ARG_MACROS 1
#else
- #define MDNS_C99_VA_ARGS 1
+ #define MDNS_C99_VA_ARGS 0
#define MDNS_GNU_VA_ARGS 0
- #define MDNS_HAS_VA_ARG_MACROS 1
+ #define MDNS_HAS_VA_ARG_MACROS 0
#endif
#if (MDNS_HAS_VA_ARG_MACROS)
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index 0b3e646423..cd52c20e53 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSEmbeddedAPI.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -96,9 +96,9 @@ extern "C" {
#ifdef LIMITED_RESOURCES_TARGET
// Don't support jumbo frames
// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
-#define AbsoluteMaxDNSMessageData 1440
+#define AbsoluteMaxDNSMessageData 1440
// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record (6 + 256 bytes)
-#define MaximumRDSize 264
+#define MaximumRDSize 264
#endif
// ***************************************************************************
@@ -276,8 +276,6 @@ typedef struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID;
// find you get code that doesn't work consistently on big-endian and little-endian machines.
#if defined(_WIN32)
#pragma pack(push,2)
-#elif !defined(__GNUC__)
- #pragma pack(1)
#endif
typedef union { mDNSu8 b[ 2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
typedef union { mDNSu8 b[ 4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
@@ -286,8 +284,6 @@ typedef union { mDNSu8 b[ 8]; mDNSu16 w[4]; mDNSu32 l[2]; } mDNSOpaque64;
typedef union { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
#if defined(_WIN32)
#pragma pack(pop)
-#elif !defined(__GNUC__)
- #pragma pack()
#endif
typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer)
@@ -301,20 +297,25 @@ typedef mDNSOpaque48 mDNSEthAddr; // An Ethernet address is a six-byte opa
#define bit_clr_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
#define bit_get_opaque64(op64, index) (op64.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
-enum
+// Bit operations for opaque 128 bit quantity. Uses the 32 bit quantity(l[4]) to set and clear bits
+#define bit_set_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] |= (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+#define bit_clr_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] &= ~(1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+#define bit_get_opaque128(op128, index) (op128.l[((index))/(sizeof(mDNSu32) * mDNSNBBY)] & (1 << ((index) % (sizeof(mDNSu32) * mDNSNBBY))))
+
+typedef enum
{
mDNSAddrType_None = 0,
mDNSAddrType_IPv4 = 4,
mDNSAddrType_IPv6 = 6,
mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording
-};
+} mDNSAddr_Type;
-enum
+typedef enum
{
mDNSTransport_None = 0,
mDNSTransport_UDP = 1,
mDNSTransport_TCP = 2
-};
+} mDNSTransport_Type;
typedef struct
{
@@ -368,7 +369,8 @@ enum
mStatus_NoRouter = -65566,
mStatus_PollingMode = -65567,
mStatus_Timeout = -65568,
- // -65568 to -65786 currently unused; available for allocation
+ mStatus_HostUnreachErr = -65569,
+ // -65570 to -65786 currently unused; available for allocation
// tcp connection status
mStatus_ConnPending = -65787,
@@ -485,7 +487,7 @@ typedef struct UDPSocket_struct UDPSocket;
#define mDNS_numPrereqs numAnswers
#define mDNS_numUpdates numAuthorities
-typedef packedstruct
+typedef struct
{
mDNSOpaque16 id;
mDNSOpaque16 flags;
@@ -502,7 +504,7 @@ typedef packedstruct
#define AbsoluteMaxDNSMessageData 8940
#endif
#define NormalMaxDNSMessageData 1440
-typedef packedstruct
+typedef struct
{
DNSMessageHeader h; // Note: Size 12 bytes
mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000
@@ -620,7 +622,7 @@ typedef packedstruct
mDNSu16 checksum;
} UDPHeader; // 8 bytes; IP protocol type 0x11
-typedef packedstruct
+typedef struct
{
mDNSu8 type; // 0x87 == Neighbor Solicitation, 0x88 == Neighbor Advertisement
mDNSu8 code;
@@ -725,7 +727,7 @@ typedef packedstruct
// Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
// Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
-enum
+typedef enum
{
kDNSRecordTypeUnregistered = 0x00, // Not currently in any list
kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list
@@ -753,7 +755,7 @@ enum
kDNSRecordTypePacketNegative = 0xF0, // Pseudo-RR generated to cache non-existence results like NXDomain
kDNSRecordTypePacketUniqueMask = 0x10 // True for PacketAddUnique, PacketAnsUnique, PacketAuthUnique, kDNSRecordTypePacketNegative
-};
+} kDNSRecordTypes;
typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV;
typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX;
@@ -812,14 +814,14 @@ typedef struct TrustAnchor
struct TrustAnchor *next;
int digestLen;
mDNSu32 validFrom;
- mDNSu32 validUntil;
+ mDNSu32 validUntil;
domainname zone;
rdataDS rds;
} TrustAnchor;
//size of rdataRRSIG excluding signerName and signature (which are variable fields)
#define RRSIG_FIXED_SIZE 18
-typedef packedstruct
+typedef struct
{
mDNSu16 typeCovered;
mDNSu8 alg;
@@ -828,7 +830,7 @@ typedef packedstruct
mDNSu32 sigExpireTime;
mDNSu32 sigInceptTime;
mDNSu16 keyTag;
- mDNSu8 *signerName;
+ mDNSu8 signerName[1]; // signerName is a dynamically-sized array
// mDNSu8 *signature
} rdataRRSig;
@@ -879,10 +881,10 @@ typedef packedstruct
// For example, SHA-1 hash of 20 bytes will be encoded as 20/5 * 8 = 32 base32
// bytes. For a max domain name size of 255 bytes of base32 encoding : (255/8)*5
// is the max hash length possible.
-#define NSEC3_MAX_HASH_LEN 155
+#define NSEC3_MAX_HASH_LEN 155
// In NSEC3, the names are hashed and stored in the first label and hence cannot exceed label
// size.
-#define NSEC3_MAX_B32_LEN MAX_DOMAIN_LABEL
+#define NSEC3_MAX_B32_LEN MAX_DOMAIN_LABEL
// We define it here instead of dnssec.h so that these values can be used
// in files without bringing in all of dnssec.h unnecessarily.
@@ -900,9 +902,9 @@ typedef enum
typedef enum
{
- platform_OSX = 1, // OSX Platform
- platform_iOS, // iOS Platform
- platform_Atv, // Atv Platform
+ platform_OSX = 1, // OSX Platform
+ platform_iOS, // iOS Platform
+ platform_Atv, // Atv Platform
platform_NonApple // Non-Apple (Windows, POSIX) Platform
} Platform_t;
@@ -913,7 +915,7 @@ typedef enum
#define kDNSOpt_Lease 2
#define kDNSOpt_NSID 3
#define kDNSOpt_Owner 4
-#define kDNSOpt_Trace 65001 // 65001-65534 Reserved for Local/Experimental Use
+#define kDNSOpt_Trace 65001 // 65001-65534 Reserved for Local/Experimental Use
typedef struct
{
@@ -941,7 +943,7 @@ typedef struct
} TracerOptData;
// Note: rdataOPT format may be repeated an arbitrary number of times in a single resource record
-typedef packedstruct
+typedef struct
{
mDNSu16 opt;
mDNSu16 optlen;
@@ -1185,7 +1187,7 @@ typedef enum
PCPResult_ExcesRemotePeer = 13
} PCPResult_t;
-typedef packedstruct
+typedef struct
{
mDNSu8 version;
mDNSu8 opCode;
@@ -1200,7 +1202,7 @@ typedef packedstruct
mDNSv6Addr extAddress;
} PCPMapRequest;
-typedef packedstruct
+typedef struct
{
mDNSu8 version;
mDNSu8 opCode;
@@ -1311,14 +1313,6 @@ struct NATTraversalInfo_struct
enum
{
- DNSServer_Untested = 0,
- DNSServer_Passed = 1,
- DNSServer_Failed = 2,
- DNSServer_Disabled = 3
-};
-
-enum
-{
DNSServer_FlagDelete = 0x1,
DNSServer_FlagNew = 0x2,
#if APPLE_OSX_mDNSResponder
@@ -1346,8 +1340,9 @@ enum
{
kScopeNone = 0, // DNS server used by unscoped questions
kScopeInterfaceID = 1, // Scoped DNS server used only by scoped questions
- kScopeServiceID = 2 // Service specific DNS server used only by questions
+ kScopeServiceID = 2, // Service specific DNS server used only by questions
// have a matching serviceID
+ kScopesMaxCount = 3 // Max count for scopes enum
};
// Note: DNSSECAware is set if we are able to get a valid response to
@@ -1364,22 +1359,19 @@ typedef struct DNSServer
mDNSs32 serviceID;
mDNSAddr addr;
mDNSIPPort port;
- mDNSOpaque16 testid;
mDNSu32 flags; // Set when we're planning to delete this from the list
- mDNSu32 teststate; // Have we sent bug-detection query to this server?
- mDNSs32 lasttest; // Time we sent last bug-detection query to this server
domainname domain; // name->server matching for "split dns"
mDNSs32 penaltyTime; // amount of time this server is penalized
mDNSu32 scoped; // See the scoped enum above
mDNSu32 timeout; // timeout value for questions
- mDNSBool cellIntf; // Resolver from Cellular Interface ?
mDNSu16 resGroupID; // ID of the resolver group that contains this DNSServer
+ mDNSu8 retransDO; // Total Retransmissions for queries sent with DO option
+ mDNSBool cellIntf; // Resolver from Cellular Interface?
mDNSBool req_A; // If set, send v4 query (DNSConfig allows A queries)
mDNSBool req_AAAA; // If set, send v6 query (DNSConfig allows AAAA queries)
mDNSBool req_DO; // If set, okay to send DNSSEC queries (EDNS DO bit is supported)
- mDNSBool retransDO; // Total Retransmissions for queries sent with DO option
- mDNSBool DNSSECAware; // set if we are able to receive a response to a request
- // sent with DO option.
+ mDNSBool DNSSECAware; // Set if we are able to receive a response to a request sent with DO option.
+ mDNSBool isExpensive; // True if the interface to this server is expensive.
} DNSServer;
typedef struct
@@ -1393,9 +1385,9 @@ typedef struct
struct ResourceRecord_struct
{
- mDNSu8 RecordType; // See enum above
- mDNSu16 rrtype;
- mDNSu16 rrclass;
+ mDNSu8 RecordType; // See kDNSRecordTypes enum.
+ mDNSu16 rrtype; // See DNS_TypeValues enum.
+ mDNSu16 rrclass; // See DNS_ClassValues enum.
mDNSu32 rroriginalttl; // In seconds
mDNSu16 rdlength; // Size of the raw rdata, in bytes, in the on-the-wire format
// (In-memory storage may be larger, for structures containing 'holes', like SOA)
@@ -1608,10 +1600,13 @@ struct AuthRecord_struct
// Everywhere else in the code, the determination of whether a question is unicast is made by checking to see if TargetQID is nonzero.
#define AuthRecord_uDNS(R) ((R)->resrec.InterfaceID == mDNSInterface_Any && !(R)->ForceMCast && !IsLocalDomain((R)->resrec.name))
#define Question_uDNS(Q) ((Q)->InterfaceID == mDNSInterface_Unicast || (Q)->ProxyQuestion || \
- ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
+ ((Q)->InterfaceID != mDNSInterface_LocalOnly && (Q)->InterfaceID != mDNSInterface_P2P && (Q)->InterfaceID != mDNSInterface_BLE && !(Q)->ForceMCast && !IsLocalDomain(&(Q)->qname)))
+// AuthRecordLocalOnly records are registered using mDNSInterface_LocalOnly and
+// AuthRecordP2P records are created by D2DServiceFound events. Both record types are kept on the same list.
#define RRLocalOnly(rr) ((rr)->ARType == AuthRecordLocalOnly || (rr)->ARType == AuthRecordP2P)
+// All other auth records, not including those defined as RRLocalOnly().
#define RRAny(rr) ((rr)->ARType == AuthRecordAny || (rr)->ARType == AuthRecordAnyIncludeP2P || (rr)->ARType == AuthRecordAnyIncludeAWDL || (rr)->ARType == AuthRecordAnyIncludeAWDLandP2P)
// Question (A or AAAA) that is suppressed currently because IPv4 or IPv6 address
@@ -1649,12 +1644,6 @@ struct CacheRecord_struct
mDNSu8 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
mDNSu8 CRDNSSECQuestion; // Set to 1 if this was created in response to a DNSSEC question
mDNSOpaque16 responseFlags; // Second 16 bit in the DNS response
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- mDNSu32 MPUnansweredQ; // Multi-packet query handling: Number of times we've seen a query for this record
- mDNSs32 MPLastUnansweredQT; // Multi-packet query handling: Last time we incremented MPUnansweredQ
- mDNSu32 MPUnansweredKA; // Multi-packet query handling: Number of times we've seen this record in a KA list
- mDNSBool MPExpectingKA; // Multi-packet query handling: Set when we increment MPUnansweredQ; allows one KA
-#endif
CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set
CacheRecord *nsec; // NSEC records needed for non-existence proofs
CacheRecord *soa; // SOA record to return for proxy questions
@@ -1745,7 +1734,7 @@ struct ServiceRecordSet_struct
mDNSu32 NumSubTypes;
AuthRecord *SubTypes;
const mDNSu8 *AnonData;
- mDNSu32 flags; // saved for subsequent calls to mDNS_RegisterService() if records
+ mDNSu32 flags; // saved for subsequent calls to mDNS_RegisterService() if records
// need to be re-registered.
AuthRecord RR_ADV; // e.g. _services._dns-sd._udp.local. PTR _printer._tcp.local.
AuthRecord RR_PTR; // e.g. _printer._tcp.local. PTR Name._printer._tcp.local.
@@ -1806,6 +1795,25 @@ enum
enum { NoAnswer_Normal = 0, NoAnswer_Suspended = 1, NoAnswer_Fail = 2 };
+// DNS Push Notification
+typedef enum
+{
+ DNSPUSH_NOERROR = 0,
+ DNSPUSH_FORMERR = 1,
+ DNSPUSH_SERVFAIL = 2,
+ DNSPUSH_NOTIMP = 4,
+ DNSPUSH_REFUSED = 5
+} DNSPUSH_ErrorCode;
+
+typedef enum {
+ DNSPUSH_INIT = 1,
+ DNSPUSH_NOSERVER = 2,
+ DNSPUSH_SERVERFOUND = 3,
+ DNSPUSH_ESTABLISHED = 4
+} DNSPush_State;
+
+
+
#define HMAC_LEN 64
#define HMAC_IPAD 0x36
#define HMAC_OPAD 0x5c
@@ -1862,7 +1870,7 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// ValidationRequired can be set to the following values:
//
-// SECURE validation is set to determine whether something is secure or bogus
+// SECURE validation is set to determine whether something is secure or bogus
// INSECURE validation is set internally by dnssec code to indicate that it is currently proving something
// is insecure
#define DNSSEC_VALIDATION_NONE 0x00
@@ -1885,10 +1893,12 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
(rr)->RecordType != kDNSRecordTypePacketNegative && \
(rr)->rrtype == kDNSType_CNAME)
-// RFC 4122 defines it to be 16 bytes
+// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
-#if TARGET_OS_EMBEDDED
+#define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
+
+#if AWD_METRICS
typedef struct
{
domainname * originalQName; // Name of original A/AAAA record if this question is for a CNAME record.
@@ -1899,6 +1909,18 @@ typedef struct
} uDNSMetrics;
#endif
+// DNS64 code is only for iOS, which is currently the only Apple OS that supports DNS proxy network extensions.
+#define USE_DNS64 (HAVE_DNS64 && TARGET_OS_IOS)
+
+#if USE_DNS64
+#include "DNS64State.h"
+#endif
+
+#if TARGET_OS_EMBEDDED
+extern mDNSu32 curr_num_regservices; // tracks the current number of services registered
+extern mDNSu32 max_num_regservices; // tracks the max number of simultaneous services registered by the device
+#endif
+
struct DNSQuestion_struct
{
// Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
@@ -1927,7 +1949,7 @@ struct DNSQuestion_struct
DupSuppressInfo DupSuppress[DupSuppressInfoSize];
mDNSInterfaceID SendQNow; // The interface this query is being sent on right now
mDNSBool SendOnAll; // Set if we're sending this question on all active interfaces
- mDNSBool CachedAnswerNeedsUpdate; // See SendQueries(). Set if we're sending this question
+ mDNSBool CachedAnswerNeedsUpdate; // See SendQueries(). Set if we're sending this question
// because a cached answer needs to be refreshed.
mDNSu32 RequestUnicast; // Non-zero if we want to send query with kDNSQClass_UnicastResponse bit set
mDNSs32 LastQTxTime; // Last time this Q was sent on one (but not necessarily all) interfaces
@@ -1951,7 +1973,7 @@ struct DNSQuestion_struct
// |-> DNS Configuration related fields used in uDNS (Subset of Wide Area/Unicast fields)
DNSServer *qDNSServer; // Caching server for this query (in the absence of an SRV saying otherwise)
- mDNSOpaque64 validDNSServers; // Valid DNSServers for this question
+ mDNSOpaque128 validDNSServers; // Valid DNSServers for this question
mDNSu16 noServerResponse; // At least one server did not respond.
mDNSu16 triedAllServersOnce; // Tried all DNS servers once
mDNSu8 unansweredQueries; // The number of unanswered queries to this server
@@ -1973,6 +1995,12 @@ struct DNSQuestion_struct
// for TCP: there is some ambiguity in the use of this variable, but in general, it is
// the number of TCP/TLS connection attempts for this LLQ state, or
// the number of packets sent for this TCP/TLS connection
+
+ // DNS Push Notification fields. These fields are only meaningful when LongLived flag is set
+ DNSPush_State dnsPushState; // The state of the DNS push notification negotiation
+ mDNSAddr dnsPushServerAddr; // Address of the system acting as the DNS Push Server
+ mDNSIPPort dnsPushServerPort; // Port on which the DNS Push Server is being advertised.
+
mDNSOpaque64 id;
// DNS Proxy fields
@@ -1980,7 +2008,7 @@ struct DNSQuestion_struct
// till we populate in the cache
mDNSBool DisallowPID; // Is the query allowed for the "PID" that we are sending on behalf of ?
mDNSs32 ServiceID; // Service identifier to match against the DNS server
-
+
// Client API fields: The client must set up these fields *before* calling mDNS_StartQuery()
mDNSInterfaceID InterfaceID; // Non-zero if you want to issue queries only on a single specific IP interface
mDNSu32 flags; // flags from original DNSService*() API request.
@@ -1995,8 +2023,6 @@ struct DNSQuestion_struct
mDNSBool ForceMCast; // Set by client to force mDNS query, even for apparently uDNS names
mDNSBool ReturnIntermed; // Set by client to request callbacks for intermediate CNAME/NXDOMAIN results
mDNSBool SuppressUnusable; // Set by client to suppress unusable queries to be sent on the wire
- mDNSBool DenyOnCellInterface; // Set by client to suppress uDNS queries on cellular interface
- mDNSBool DenyOnExpInterface; // Set by client to suppress uDNS queries on expensive interface
mDNSu8 RetryWithSearchDomains; // Retry with search domains if there is no entry in the cache or AuthRecords
mDNSu8 TimeoutQuestion; // Timeout this question if there is no reply in configured time
mDNSu8 WakeOnResolve; // Send wakeup on resolve
@@ -2016,45 +2042,12 @@ struct DNSQuestion_struct
#if TARGET_OS_EMBEDDED
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
#endif
+#if USE_DNS64
+ DNS64 dns64; // DNS64 state for performing IPv6 address synthesis on networks with NAT64.
+#endif
};
-typedef struct
-{
- // Client API fields: The client must set up name and InterfaceID *before* calling mDNS_StartResolveService()
- // When the callback is invoked, ip, port, TXTlen and TXTinfo will have been filled in with the results learned from the network.
- domainname name;
- mDNSInterfaceID InterfaceID; // ID of the interface the response was received on
- mDNSAddr ip; // Remote (destination) IP address where this service can be accessed
- mDNSIPPort port; // Port where this service can be accessed
- mDNSu16 TXTlen;
- mDNSu8 TXTinfo[2048]; // Additional demultiplexing information (e.g. LPR queue name)
-} ServiceInfo;
-
-// Note: Within an mDNSServiceInfoQueryCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Exit(), mDNS_Execute()
-typedef struct ServiceInfoQuery_struct ServiceInfoQuery;
-typedef void mDNSServiceInfoQueryCallback (mDNS *const m, ServiceInfoQuery *query);
-struct ServiceInfoQuery_struct
-{
- // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
- // No fields need to be set up by the client prior to calling mDNS_StartResolveService();
- // all required data is passed as parameters to that function.
- // The ServiceInfoQuery structure memory is working storage for mDNSCore to discover the requested information
- // and place it in the ServiceInfo structure. After the client has called mDNS_StopResolveService(), it may
- // dispose of the ServiceInfoQuery structure while retaining the results in the ServiceInfo structure.
- DNSQuestion qSRV;
- DNSQuestion qTXT;
- DNSQuestion qAv4;
- DNSQuestion qAv6;
- mDNSu8 GotSRV;
- mDNSu8 GotTXT;
- mDNSu8 GotADD;
- mDNSu32 Answers;
- ServiceInfo *info;
- mDNSServiceInfoQueryCallback *ServiceInfoQueryCallback;
- void *ServiceInfoQueryContext;
-};
-
-typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ } ZoneService;
+typedef enum { ZoneServiceUpdate, ZoneServiceQuery, ZoneServiceLLQ, ZoneServiceDNSPush } ZoneService;
typedef void ZoneDataCallback (mDNS *const m, mStatus err, const ZoneData *result);
@@ -2162,7 +2155,7 @@ struct NetworkInterfaceInfo_struct
mDNSBool DirectLink; // a direct link, indicating we can skip the probe for
// address records
mDNSBool SupportsUnicastMDNSResponse; // Indicates that the interface supports unicast responses
- // to Bonjour queries. Generally true for an interface.
+ // to Bonjour queries. Generally true for an interface
};
#define SLE_DELETE 0x00000001
@@ -2280,6 +2273,30 @@ typedef struct
extern void LogMDNSStatistics(mDNS *const m);
+typedef struct mDNS_DNSPushNotificationServer DNSPushNotificationServer;
+typedef struct mDNS_DNSPushNotificationZone DNSPushNotificationZone;
+
+struct mDNS_DNSPushNotificationServer
+{
+ mDNSAddr serverAddr; // Server Address
+ tcpInfo_t *connection; // TCP Connection pointer
+ mDNSu32 numberOfQuestions; // Number of questions for this server
+ DNSPushNotificationServer *next;
+} ;
+
+struct mDNS_DNSPushNotificationZone
+{
+ domainname zoneName;
+ DNSPushNotificationServer *servers; // DNS Push Notification Servers for this zone
+ mDNSu32 numberOfQuestions; // Number of questions for this zone
+ DNSPushNotificationZone *next;
+} ;
+
+
+// Time constant (~= 260 hours ~= 10 days and 21 hours) used to set
+// various time values to a point well into the future.
+#define FutureTime 0x38000000
+
struct mDNS_struct
{
// Internal state fields. These hold the main internal state of mDNSCore;
@@ -2324,6 +2341,11 @@ struct mDNS_struct
mDNSs32 NextScheduledNATOp; // Next time to send NAT-traversal packets
mDNSs32 NextScheduledSPS; // Next time to purge expiring Sleep Proxy records
mDNSs32 NextScheduledKA; // Next time to send Keepalive packets (SPS)
+#if BONJOUR_ON_DEMAND
+ mDNSs32 NextBonjourDisableTime; // Next time to leave multicast group if Bonjour on Demand is enabled
+ mDNSu8 BonjourEnabled; // Non zero if Bonjour is currently enabled by the Bonjour on Demand logic
+#endif // BONJOUR_ON_DEMAND
+ mDNSs32 DelayConflictProcessing; // To prevent spurious confilcts due to stale packets on the wire/air.
mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire
mDNSu32 RandomReconfirmDelay; // For de-synchronization of reconfirmation queries on the wire
mDNSs32 PktNum; // Unique sequence number assigned to each received packet
@@ -2340,9 +2362,6 @@ struct mDNS_struct
// during which underying platform layer should inhibit system sleep
mDNSs32 TimeSlept; // Time we went to sleep.
- mDNSs32 StatStartTime; // Time we started gathering statistics during this interval.
- mDNSs32 NextStatLogTime; // Next time to log statistics.
- mDNSs32 ActiveStatTime; // Total time awake/gathering statistics for this log period.
mDNSs32 UnicastPacketsSent; // Number of unicast packets sent.
mDNSs32 MulticastPacketsSent; // Number of multicast packets sent.
mDNSs32 RemoteSubnet; // Multicast packets received from outside our subnet.
@@ -2352,6 +2371,7 @@ struct mDNS_struct
mDNSs32 NextScheduledStopTime; // Next time to stop a question
+ mDNSs32 NextBLEServiceTime; // Next time to call the BLE discovery management layer. Non zero when active.
// These fields only required for mDNS Searcher...
DNSQuestion *Questions; // List of all registered questions, active and inactive
@@ -2388,7 +2408,7 @@ struct mDNS_struct
mDNSs32 ProbeFailTime;
mDNSu32 NumFailedProbes;
mDNSs32 SuppressProbes;
- Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
+ Platform_t mDNS_plat; // Why is this here in the “only required for mDNS Responder” section? -- SC
// Unicast-specific data
mDNSs32 NextuDNSEvent; // uDNS next event
@@ -2438,11 +2458,15 @@ struct mDNS_struct
mDNSBool SSDPWANPPPConnection; // whether we should send the SSDP query for WANIPConnection or WANPPPConnection
mDNSIPPort UPnPRouterPort; // port we send discovery messages to
mDNSIPPort UPnPSOAPPort; // port we send SOAP messages to
- mDNSu8 *UPnPRouterURL; // router's URL string
+ char *UPnPRouterURL; // router's URL string
mDNSBool UPnPWANPPPConnection; // whether we're using WANIPConnection or WANPPPConnection
- mDNSu8 *UPnPSOAPURL; // router's SOAP control URL string
- mDNSu8 *UPnPRouterAddressString; // holds both the router's address and port
- mDNSu8 *UPnPSOAPAddressString; // holds both address and port for SOAP messages
+ char *UPnPSOAPURL; // router's SOAP control URL string
+ char *UPnPRouterAddressString; // holds both the router's address and port
+ char *UPnPSOAPAddressString; // holds both address and port for SOAP messages
+
+ // DNS Push Notification fields
+ DNSPushNotificationServer *DNSPushServers; // DNS Push Notification Servers
+ DNSPushNotificationZone *DNSPushZones;
// Sleep Proxy client fields
AuthRecord *SPSRRSet; // To help the client keep track of the records registered with the sleep proxy
@@ -2465,7 +2489,6 @@ struct mDNS_struct
#if APPLE_OSX_mDNSResponder
ClientTunnel *TunnelClients;
- uuid_t asl_uuid; // uuid for ASL logging
void *WCF;
#endif
// DNS Proxy fields
@@ -2476,8 +2499,13 @@ struct mDNS_struct
int notifyToken;
int uds_listener_skt; // Listening socket for incoming UDS clients. This should not be here -- it's private to uds_daemon.c and nothing to do with mDNSCore -- SC
mDNSu32 AutoTargetServices; // # of services that have AutoTarget set
- mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
- mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
+
+#if BONJOUR_ON_DEMAND
+ // Counters used in Bonjour on Demand logic.
+ mDNSu32 NumAllInterfaceRecords; // Right now we count *all* multicast records here. Later we may want to change to count interface-specific records separately. (This count includes records on the DuplicateRecords list too.)
+ mDNSu32 NumAllInterfaceQuestions; // Right now we count *all* multicast questions here. Later we may want to change to count interface-specific questions separately.
+#endif // BONJOUR_ON_DEMAND
+
DNSSECStatistics DNSSECStats;
mDNSStatistics mDNSStats;
@@ -2505,6 +2533,9 @@ extern const mDNSInterfaceID mDNSInterface_Unicast; // Special value
extern const mDNSInterfaceID mDNSInterfaceMark; // Special value
extern const mDNSInterfaceID mDNSInterface_P2P; // Special value
extern const mDNSInterfaceID uDNSInterfaceMark; // Special value
+extern const mDNSInterfaceID mDNSInterface_BLE; // Special value
+
+#define LocalOnlyOrP2PInterface(INTERFACE) ((INTERFACE == mDNSInterface_LocalOnly) || (INTERFACE == mDNSInterface_P2P) || (INTERFACE == mDNSInterface_BLE))
extern const mDNSIPPort DiscardPort;
extern const mDNSIPPort SSHPort;
@@ -2546,8 +2577,11 @@ extern const mDNSOpaque16 DNSSecQFlags;
extern const mDNSOpaque16 ResponseFlags;
extern const mDNSOpaque16 UpdateReqFlags;
extern const mDNSOpaque16 UpdateRespFlags;
+extern const mDNSOpaque16 SubscribeFlags;
+extern const mDNSOpaque16 UnSubscribeFlags;
extern const mDNSOpaque64 zeroOpaque64;
+extern const mDNSOpaque128 zeroOpaque128;
extern mDNSBool StrictUnicastOrdering;
extern mDNSu8 NumUnicastDNSServers;
@@ -2570,8 +2604,6 @@ extern mDNSu8 NumUnreachableDNSServers;
#define mDNSinline static __inline
#elif ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
#define mDNSinline static inline
-#else
- #define mDNSinline static inline
#endif
// If we're not doing inline functions, then this header needs to have the extern declarations
@@ -2612,7 +2644,7 @@ mDNSinline mDNSOpaque16 mDNSOpaque16fromIntVal(mDNSu16 v)
// Every client should call mDNS_Init, passing in storage for the mDNS object and the mDNS_PlatformSupport object.
//
// Clients that are only advertising services should use mDNS_Init_NoCache and mDNS_Init_ZeroCacheSize.
-// Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, mDNS_StartResolveService, etc.)
+// Clients that plan to perform queries (mDNS_StartQuery, mDNS_StartBrowse, etc.)
// need to provide storage for the resource record cache, or the query calls will return 'mStatus_NoCache'.
// The rrcachestorage parameter is the address of memory for the resource record cache, and
// the rrcachesize parameter is the number of entries in the CacheRecord array passed in.
@@ -2725,11 +2757,6 @@ typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_De
// mDNS_RegisterService is a single call to register the set of resource records associated with a given named service.
//
-// mDNS_StartResolveService is single call which is equivalent to multiple calls to mDNS_StartQuery,
-// to find the IP address, port number, and demultiplexing information for a given named service.
-// As with mDNS_StartQuery, it executes asynchronously, and calls the ServiceInfoQueryCallback when the answer is
-// found. After the service is resolved, the client should call mDNS_StopResolveService to complete the transaction.
-// The client can also call mDNS_StopResolveService at any time to abort the transaction.
//
// mDNS_AddRecordToService adds an additional record to a Service Record Set. This record may be deregistered
// via mDNS_RemoveRecordFromService, or by deregistering the service. mDNS_RemoveRecordFromService is passed a
@@ -2748,17 +2775,7 @@ typedef enum { mDNS_Dereg_normal, mDNS_Dereg_rapid, mDNS_Dereg_conflict, mDNS_De
extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, AuthRecType artype, mDNSRecordCallback Callback, void *Context);
-// mDNS_RegisterService() flags parameter bit definitions.
-// Note these are only defined to transfer the corresponding DNSServiceFlags settings into mDNSCore routines,
-// since code in mDNSCore does not include the DNSServiceFlags definitions in dns_sd.h.
-enum
-{
- coreFlagIncludeP2P = 0x1, // include P2P interfaces when using mDNSInterface_Any
- coreFlagIncludeAWDL = 0x2, // include AWDL interface when using mDNSInterface_Any
- coreFlagKnownUnique = 0x4, // client guarantees that SRV and TXT record names are unique
- coreFlagWakeOnly = 0x8 // Service won't be registered with sleep proxy
-};
-
+extern mDNSu32 deriveD2DFlagsFromAuthRecType(AuthRecType authRecType);
extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr,
const domainlabel *const name, const domainname *const type, const domainname *const domain,
const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
@@ -2786,8 +2803,6 @@ extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
mDNSQuestionCallback *Callback, void *Context);
#define mDNS_StopBrowse mDNS_StopQuery
-extern mStatus mDNS_StartResolveService(mDNS *const m, ServiceInfoQuery *query, ServiceInfo *info, mDNSServiceInfoQueryCallback *Callback, void *Context);
-extern void mDNS_StopResolveService (mDNS *const m, ServiceInfoQuery *query);
typedef enum
{
@@ -2830,7 +2845,7 @@ extern mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question);
// because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size.
// This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid.
#define AssignDomainName(DST, SRC) do { mDNSu16 len__ = DomainNameLength((SRC)); \
- if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__);else (DST)->c[0] = 0;} while(0)
+ if (len__ <= MAX_DOMAIN_NAME) mDNSPlatformMemCopy((DST)->c, (SRC)->c, len__); else (DST)->c[0] = 0; } while(0)
// Comparison functions
#define SameDomainLabelCS(A,B) ((A)[0] == (B)[0] && mDNSPlatformMemSame((A)+1, (B)+1, (A)[0]))
@@ -2887,6 +2902,10 @@ extern char *ConvertDomainNameToCString_withescape(const domainname *const na
extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel);
+#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
+ ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
+ ((X)[4] | 0x20) == 'p')
+
extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain);
extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain);
@@ -2912,7 +2931,7 @@ extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel
// then the output will be truncated by one character to allow space for the terminating null.
// Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written,
// not the number of characters that *would* have been printed were buflen unlimited.
-extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg);
+extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg) IS_A_PRINTF_STYLE_FUNCTION(3,0);
extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id);
extern char *DNSTypeName(mDNSu16 rrtype);
@@ -2942,6 +2961,7 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
#define mDNSIPPortIsZero(A) ((A).NotAnInteger == 0)
#define mDNSOpaque16IsZero(A) ((A).NotAnInteger == 0)
#define mDNSOpaque64IsZero(A) (((A)->l[0] | (A)->l[1] ) == 0)
+#define mDNSOpaque128IsZero(A) (((A)->l[0] | (A)->l[1] | (A)->l[2] | (A)->l[3]) == 0)
#define mDNSIPv4AddressIsZero(A) ((A).NotAnInteger == 0)
#define mDNSIPv6AddressIsZero(A) (((A).l[0] | (A).l[1] | (A).l[2] | (A).l[3]) == 0)
#define mDNSEthAddressIsZero(A) (((A).w[0] | (A).w[1] | (A).w[2] ) == 0)
@@ -2976,12 +2996,6 @@ extern mDNSBool mDNSAddrIPv4FromMappedIPv6(mDNSv6Addr *in, mDNSv4Addr *out);
((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLinkLocal(&(X)->ip.v4) : \
((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLinkLocal(&(X)->ip.v6) : mDNSfalse)
-#define mDNSv4AddressIsLoopback(X) ((X)->b[0] == 127 && (X)->b[1] == 0 && (X)->b[2] == 0 && (X)->b[3] == 1)
-#define mDNSv6AddressIsLoopback(X) ((((X)->l[0] | (X)->l[1] | (X)->l[2]) == 0) && ((X)->b[12] == 0 && (X)->b[13] == 0 && (X)->b[14] == 0 && (X)->b[15] == 1))
-
-#define mDNSAddressIsLoopback(X) ( \
- ((X)->type == mDNSAddrType_IPv4) ? mDNSv4AddressIsLoopback(&(X)->ip.v4) : \
- ((X)->type == mDNSAddrType_IPv6) ? mDNSv6AddressIsLoopback(&(X)->ip.v6) : mDNSfalse)
// ***************************************************************************
#if 0
@@ -3025,8 +3039,8 @@ extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCa
extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router);
extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO);
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO);
extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags);
extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID);
@@ -3101,14 +3115,14 @@ extern mDNSBool DNSDigest_VerifyMessage(DNSMessage *msg, mDNSu8 *end, LargeCache
extern mStatus mDNSPlatformInit (mDNS *const m);
extern void mDNSPlatformClose (mDNS *const m);
extern mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
- mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
+ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
mDNSIPPort dstport, mDNSBool useBackgroundTrafficClass);
-extern mDNSBool mDNSPlatformPeekUDP (mDNS *const m, UDPSocket *src);
extern void mDNSPlatformLock (const mDNS *const m);
extern void mDNSPlatformUnlock (const mDNS *const m);
extern void mDNSPlatformStrCopy ( void *dst, const void *src);
+extern mDNSu32 mDNSPlatformStrLCopy ( void *dst, const void *src, mDNSu32 len);
extern mDNSu32 mDNSPlatformStrLen ( const void *src);
extern void mDNSPlatformMemCopy ( void *dst, const void *src, mDNSu32 len);
extern mDNSBool mDNSPlatformMemSame (const void *dst, const void *src, mDNSu32 len);
@@ -3144,17 +3158,6 @@ extern void mDNSPlatformWriteDebugMsg(const char *msg);
#endif
extern void mDNSPlatformWriteLogMsg(const char *ident, const char *msg, mDNSLogLevel_t loglevel);
-#if APPLE_OSX_mDNSResponder
-// Utility function for ASL logging
-mDNSexport void mDNSASLLog(uuid_t *uuid, const char *subdomain, const char *result, const char *signature, const char *fmt, ...);
-
-// Log unicast and multicast traffic statistics once a day. Also used for DNSSEC statistics.
-#define kDefaultNextStatsticsLogTime (24 * 60 * 60)
-
-extern void mDNSLogStatistics(mDNS *const m);
-
-#endif // APPLE_OSX_mDNSResponder
-
// Platform support modules should provide the following functions to map between opaque interface IDs
// and interface indexes in order to support the DNS-SD API. If your target platform does not support
// multiple interfaces and/or does not support the DNS-SD API, these functions can be empty.
@@ -3185,7 +3188,7 @@ typedef enum
} TCPSocketFlags;
typedef void (*TCPConnectionCallback)(TCPSocket *sock, void *context, mDNSBool ConnectionEstablished, mStatus err);
-extern TCPSocket *mDNSPlatformTCPSocket(mDNS *const m, TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
+extern TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort *port, mDNSBool useBackgroundTrafficClass); // creates a TCP socket
extern TCPSocket *mDNSPlatformTCPAccept(TCPSocketFlags flags, int sd);
extern int mDNSPlatformTCPGetFD(TCPSocket *sock);
extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, mDNSOpaque16 dstport, domainname *hostname,
@@ -3193,19 +3196,21 @@ extern mStatus mDNSPlatformTCPConnect(TCPSocket *sock, const mDNSAddr *dst, m
extern void mDNSPlatformTCPCloseConnection(TCPSocket *sock);
extern long mDNSPlatformReadTCP(TCPSocket *sock, void *buf, unsigned long buflen, mDNSBool *closed);
extern long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned long len);
-extern UDPSocket *mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport);
+extern UDPSocket *mDNSPlatformUDPSocket(const mDNSIPPort requestedport);
extern mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock);
extern void mDNSPlatformUDPClose(UDPSocket *sock);
-extern void mDNSPlatformReceiveBPF_fd(mDNS *const m, int fd);
-extern void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID);
+extern mDNSBool mDNSPlatformUDPSocketEncounteredEOF(const UDPSocket *sock);
+extern void mDNSPlatformReceiveBPF_fd(int fd);
+extern void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID);
extern void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID);
-extern void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
+extern void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID);
extern void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst);
extern void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIPPort *lport, mDNSIPPort *rport, mDNSu32 seq, mDNSu32 ack, mDNSu16 win);
-extern mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
-extern mStatus mDNSPlatformGetRemoteMacAddr(mDNS *const m, mDNSAddr *raddr);
+extern mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti);
+extern mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr);
extern mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifname);
-extern mStatus mDNSPlatformClearSPSMACAddr(void);
+extern mStatus mDNSPlatformClearSPSData(void);
+extern mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length);
// mDNSPlatformTLSSetupCerts/mDNSPlatformTLSTearDownCerts used by dnsextd
extern mStatus mDNSPlatformTLSSetupCerts(void);
@@ -3214,19 +3219,19 @@ extern void mDNSPlatformTLSTearDownCerts(void);
// Platforms that support unicast browsing and dynamic update registration for clients who do not specify a domain
// in browse/registration calls must implement these routines to get the "default" browse/registration list.
-extern mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
+extern mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
DNameListElem **BrowseDomains, mDNSBool ackConfig);
-extern mStatus mDNSPlatformGetPrimaryInterface(mDNS *const m, mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
+extern mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr *v4, mDNSAddr *v6, mDNSAddr *router);
extern void mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status);
-extern void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason);
-extern void mDNSPlatformPreventSleep(mDNS *const m, mDNSu32 timeout, const char *reason);
-extern void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
+extern void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason);
+extern void mDNSPlatformPreventSleep(mDNSu32 timeout, const char *reason);
+extern void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration);
extern mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID);
extern mDNSBool mDNSPlatformInterfaceIsAWDL(const NetworkInterfaceInfo *intf);
extern mDNSBool mDNSPlatformValidRecordForQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
-extern mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf);
+extern mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID);
extern mDNSBool mDNSPlatformValidQuestionForInterface(DNSQuestion *q, const NetworkInterfaceInfo *intf);
extern void mDNSPlatformFormatTime(unsigned long t, mDNSu8 *buf, int bufsize);
@@ -3279,10 +3284,19 @@ extern void LNT_ClearState(mDNS *const m);
extern void mDNS_SetFQDN(mDNS *const m);
extern void mDNS_ActivateNetWake_internal (mDNS *const m, NetworkInterfaceInfo *set);
extern void mDNS_DeactivateNetWake_internal(mDNS *const m, NetworkInterfaceInfo *set);
-extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
-extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping);
+
+// Attributes that controls the Bonjour operation initiation and response speed for an interface.
+typedef enum
+{
+ FastActivation, // For p2p* and DirectLink type interfaces
+ NormalActivation, // For standard interface timing
+ SlowActivation // For flapping interfaces
+} InterfaceActivationSpeed;
+
+extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
+extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed probeDelay);
extern void mDNSCoreInitComplete(mDNS *const m, mStatus result);
-extern void mDNSCoreReceive(mDNS *const m, void *const msg, const mDNSu8 *const end,
+extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID);
extern void mDNSCoreRestartQueries(mDNS *const m);
@@ -3302,7 +3316,7 @@ extern void mDNSCoreReceiveRawPacket (mDNS *const m, const mDNSu8 *const p,
extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
extern CacheRecord *CreateNewCacheEntry(mDNS *const m, const mDNSu32 slot, CacheGroup *cg, mDNSs32 delay, mDNSBool Add, const mDNSAddr *sourceAddress);
-extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
+extern CacheGroup *CacheGroupForName(const mDNS *const m, const mDNSu32 namehash, const domainname *const name);
extern void ReleaseCacheRecord(mDNS *const m, CacheRecord *r);
extern void ScheduleNextCacheCheckTime(mDNS *const m, const mDNSu32 slot, const mDNSs32 event);
extern void SetNextCacheCheckTimeForRecord(mDNS *const m, CacheRecord *const rr);
@@ -3321,13 +3335,13 @@ extern void RetrySearchDomainQuestions(mDNS *const m);
extern mDNSBool DomainEnumQuery(const domainname *qname);
extern mStatus UpdateKeepaliveRData(mDNS *const m, AuthRecord *rr, NetworkInterfaceInfo *const intf, mDNSBool updateMac, char *ethAddr);
extern void UpdateKeepaliveRMACAsync(mDNS *const m, void *context);
-extern void UpdateRMACCallback(mDNS *const m, void *context);
+extern void UpdateRMAC(mDNS *const m, void *context);
// Used only in logging to restrict the number of /etc/hosts entries printed
extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result);
// exported for using the hash for /etc/hosts AuthRecords
-extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 slot, const mDNSu32 namehash, const domainname *const name);
-extern AuthGroup *AuthGroupForRecord(AuthHash *r, const mDNSu32 slot, const ResourceRecord *const rr);
+extern AuthGroup *AuthGroupForName(AuthHash *r, const mDNSu32 namehash, const domainname *const name);
+extern AuthGroup *AuthGroupForRecord(AuthHash *r, const ResourceRecord *const rr);
extern AuthGroup *InsertAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
extern AuthGroup *RemoveAuthRecord(mDNS *const m, AuthHash *r, AuthRecord *rr);
extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16 qtype);
@@ -3336,38 +3350,36 @@ extern mDNSBool mDNS_CheckForCacheRecord(mDNS *const m, DNSQuestion *q, mDNSu16
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
#if APPLE_OSX_mDNSResponder
extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
-extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
-extern void StartServerTunnel(mDNS *const m, DomainAuthInfo *const info);
+extern void AddNewClientTunnel(DNSQuestion *const q);
+extern void StartServerTunnel(DomainAuthInfo *const info);
extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
extern void RemoveAutoTunnel6Record(mDNS *const m);
-extern mDNSBool RecordReadyForSleep(mDNS *const m, AuthRecord *rr);
+extern mDNSBool RecordReadyForSleep(AuthRecord *rr);
// For now this LocalSleepProxy stuff is specific to Mac OS X.
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
-extern mStatus ActivateLocalProxy(mDNS *const m, NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
-extern void mDNSPlatformUpdateDNSStatus(mDNS *const m, DNSQuestion *q);
-extern void mDNSPlatformTriggerDNSRetry(mDNS *const m, DNSQuestion *v4q, DNSQuestion *v6q);
+extern mStatus ActivateLocalProxy(NetworkInterfaceInfo *const intf, mDNSBool *keepaliveOnly);
+extern void mDNSPlatformUpdateDNSStatus(DNSQuestion *q);
+extern void mDNSPlatformTriggerDNSRetry(DNSQuestion *v4q, DNSQuestion *v6q);
extern void mDNSPlatformLogToFile(int log_level, const char *buffer);
extern mDNSBool SupportsInNICProxy(NetworkInterfaceInfo *const intf);
extern mStatus SymptomReporterDNSServerReachable(mDNS *const m, const mDNSAddr *addr);
extern mStatus SymptomReporterDNSServerUnreachable(DNSServer *s);
#endif
-typedef void ProxyCallback (mDNS *const m, void *socket, void *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
+typedef void ProxyCallback (void *socket, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr,
const mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, void *context);
-extern void mDNSPlatformInitDNSProxySkts(mDNS *const m, ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
+extern void mDNSPlatformInitDNSProxySkts(ProxyCallback *UDPCallback, ProxyCallback *TCPCallback);
extern void mDNSPlatformCloseDNSProxySkts(mDNS *const m);
extern void mDNSPlatformDisposeProxyContext(void *context);
extern mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DNSMessage *msg, mDNSu8 *start, mDNSu8 *limit);
-// Sleep Assertions are specific to Mac OS X
#if APPLE_OSX_mDNSResponder
-extern void mDNSPlatformSleepAssertion(mDNS *const m, double timeout);
+extern void mDNSPlatformGetDNSRoutePolicy(DNSQuestion *q, mDNSBool *isBlocked);
#endif
-
-extern void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isBlocked);
-extern void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q);
+extern void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q);
extern mDNSs32 mDNSPlatformGetPID(void);
extern mDNSBool mDNSValidKeepAliveRecord(AuthRecord *rr);
+extern mDNSBool CacheRecordRmvEventsForQuestion(mDNS *const m, DNSQuestion *q);
// ***************************************************************************
#if 0
@@ -3575,6 +3587,11 @@ struct CompileTimeAssertionChecks_mDNS
char assertK[(sizeof(UDPHeader ) == 8 ) ? 1 : -1];
char assertL[(sizeof(IKEHeader ) == 28 ) ? 1 : -1];
char assertM[(sizeof(TCPHeader ) == 20 ) ? 1 : -1];
+ char assertN[(sizeof(rdataOPT) == 24 ) ? 1 : -1];
+ char assertO[(sizeof(rdataRRSig) == 20 ) ? 1 : -1];
+ char assertP[(sizeof(PCPMapRequest) == 60 ) ? 1 : -1];
+ char assertQ[(sizeof(PCPMapReply) == 60 ) ? 1 : -1];
+
// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
// other overly-large structures instead of having a pointer to them, can inadvertently
@@ -3584,18 +3601,17 @@ struct CompileTimeAssertionChecks_mDNS
char sizecheck_AuthRecord [(sizeof(AuthRecord) <= 1208) ? 1 : -1];
char sizecheck_CacheRecord [(sizeof(CacheRecord) <= 232) ? 1 : -1];
char sizecheck_CacheGroup [(sizeof(CacheGroup) <= 232) ? 1 : -1];
- char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 864) ? 1 : -1];
+ char sizecheck_DNSQuestion [(sizeof(DNSQuestion) <= 912) ? 1 : -1];
- char sizecheck_ZoneData [(sizeof(ZoneData) <= 1700) ? 1 : -1];
+ char sizecheck_ZoneData [(sizeof(ZoneData) <= 1744) ? 1 : -1];
char sizecheck_NATTraversalInfo [(sizeof(NATTraversalInfo) <= 200) ? 1 : -1];
char sizecheck_HostnameInfo [(sizeof(HostnameInfo) <= 3050) ? 1 : -1];
- char sizecheck_DNSServer [(sizeof(DNSServer) <= 340) ? 1 : -1];
- char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7184) ? 1 : -1];
+ char sizecheck_DNSServer [(sizeof(DNSServer) <= 330) ? 1 : -1];
+ char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <= 7376) ? 1 : -1];
char sizecheck_ServiceRecordSet [(sizeof(ServiceRecordSet) <= 5540) ? 1 : -1];
char sizecheck_DomainAuthInfo [(sizeof(DomainAuthInfo) <= 7888) ? 1 : -1];
- char sizecheck_ServiceInfoQuery [(sizeof(ServiceInfoQuery) <= 3488) ? 1 : -1];
#if APPLE_OSX_mDNSResponder
- char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1208) ? 1 : -1];
+ char sizecheck_ClientTunnel [(sizeof(ClientTunnel) <= 1256) ? 1 : -1];
#endif
};
@@ -3605,6 +3621,13 @@ mDNSu32 initializeDeviceInfoTXT(mDNS *m, mDNSu8 *ptr);
#if APPLE_OSX_mDNSResponder
extern void D2D_start_advertising_interface(NetworkInterfaceInfo *interface);
extern void D2D_stop_advertising_interface(NetworkInterfaceInfo *interface);
+extern void D2D_start_advertising_record(AuthRecord *ar);
+extern void D2D_stop_advertising_record(AuthRecord *ar);
+#else
+#define D2D_start_advertising_interface(X)
+#define D2D_stop_advertising_interface(X)
+#define D2D_start_advertising_record(X)
+#define D2D_stop_advertising_record(X)
#endif
// ***************************************************************************
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h b/usr/src/contrib/mDNSResponder/mDNSCore/nsec.h
index 198f57db92..198f57db92 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/nsec.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/nsec.h
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c
index 56aced0180..0b1fe638ec 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.c
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.c
@@ -45,12 +45,12 @@ mDNSexport SearchListElem *SearchList = mDNSNULL;
mDNSBool StrictUnicastOrdering = mDNSfalse;
// We keep track of the number of unicast DNS servers and log a message when we exceed 64.
-// Currently the unicast queries maintain a 64 bit map to track the valid DNS servers for that
+// Currently the unicast queries maintain a 128 bit map to track the valid DNS servers for that
// question. Bit position is the index into the DNS server list. This is done so to try all
// the servers exactly once before giving up. If we could allocate memory in the core, then
-// arbitrary limitation of 64 DNSServers can be removed.
+// arbitrary limitation of 128 DNSServers can be removed.
mDNSu8 NumUnicastDNSServers = 0;
-#define MAX_UNICAST_DNS_SERVERS 64
+#define MAX_UNICAST_DNS_SERVERS 128
#if APPLE_OSX_mDNSResponder
mDNSu8 NumUnreachableDNSServers = 0;
#endif
@@ -112,8 +112,8 @@ mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
#endif
mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO)
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
{
DNSServer **p = &m->DNSServers;
DNSServer *tmp = mDNSNULL;
@@ -124,20 +124,20 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
return mDNSNULL;
}
- if (!d)
+ if (!d)
d = (const domainname *)"";
- LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s req_DO is %s",
+ LogInfo("mDNS_AddDNSServer(%d): Adding %#a for %##s, InterfaceID %p, serviceID %u, scoped %d, resGroupID %d req_A is %s req_AAAA is %s cell %s isExpensive %s req_DO is %s",
NumUnicastDNSServers, addr, d->c, interface, serviceID, scoped, resGroupID, reqA ? "True" : "False", reqAAAA ? "True" : "False",
- cellIntf ? "True" : "False", reqDO ? "True" : "False");
+ cellIntf ? "True" : "False", isExpensive ? "True" : "False", reqDO ? "True" : "False");
while (*p) // Check if we already have this {interface,address,port,domain} tuple registered + reqA/reqAAAA bits
{
- if ((*p)->scoped == scoped && (*p)->interface == interface && (*p)->serviceID == serviceID && (*p)->teststate != DNSServer_Disabled &&
- mDNSSameAddress(&(*p)->addr, addr) && mDNSSameIPPort((*p)->port, port) && SameDomainName(&(*p)->domain, d) &&
+ if ((*p)->scoped == scoped && (*p)->interface == interface && (*p)->serviceID == serviceID &&
+ mDNSSameAddress(&(*p)->addr, addr) && mDNSSameIPPort((*p)->port, port) && SameDomainName(&(*p)->domain, d) &&
(*p)->req_A == reqA && (*p)->req_AAAA == reqAAAA)
{
- if (!((*p)->flags & DNSServer_FlagDelete))
+ if (!((*p)->flags & DNSServer_FlagDelete))
debugf("Note: DNS Server %#a:%d for domain %##s (%p) registered more than once", addr, mDNSVal16(port), d->c, interface);
tmp = *p;
*p = tmp->next;
@@ -184,19 +184,18 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
}
else
{
- (*p)->scoped = scoped;
- (*p)->interface = interface;
- (*p)->serviceID = serviceID;
- (*p)->addr = *addr;
- (*p)->port = port;
- (*p)->flags = DNSServer_FlagNew;
- (*p)->teststate = /* DNSServer_Untested */ DNSServer_Passed;
- (*p)->lasttest = m->timenow - INIT_UCAST_POLL_INTERVAL;
- (*p)->timeout = timeout;
- (*p)->cellIntf = cellIntf;
- (*p)->req_A = reqA;
- (*p)->req_AAAA = reqAAAA;
- (*p)->req_DO = reqDO;
+ (*p)->scoped = scoped;
+ (*p)->interface = interface;
+ (*p)->serviceID = serviceID;
+ (*p)->addr = *addr;
+ (*p)->port = port;
+ (*p)->flags = DNSServer_FlagNew;
+ (*p)->timeout = timeout;
+ (*p)->cellIntf = cellIntf;
+ (*p)->isExpensive = isExpensive;
+ (*p)->req_A = reqA;
+ (*p)->req_AAAA = reqAAAA;
+ (*p)->req_DO = reqDO;
// We start off assuming that the DNS server is not DNSSEC aware and
// when we receive the first response to a DNSSEC question, we set
// it to true.
@@ -206,11 +205,13 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
(*p)->next = mDNSNULL;
}
}
- (*p)->penaltyTime = 0;
- // We always update the ID (not just when we allocate a new instance) because we could
- // be adding a new non-scoped resolver with a new ID and we want all the non-scoped
- // resolvers belong to the same group.
- (*p)->resGroupID = resGroupID;
+ if (*p) {
+ (*p)->penaltyTime = 0;
+ // We always update the ID (not just when we allocate a new instance) because we could
+ // be adding a new non-scoped resolver with a new ID and we want all the non-scoped
+ // resolvers belong to the same group.
+ (*p)->resGroupID = resGroupID;
+ }
return(*p);
}
@@ -229,14 +230,14 @@ mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 re
(q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL), q, q->qname.c, DNSTypeName(q->qtype), q->SuppressUnusable);
// If we get error from any DNS server, remember the error. If all of the servers,
- // return the error, then return the first error.
+ // return the error, then return the first error.
if (mDNSOpaque16IsZero(q->responseFlags))
q->responseFlags = responseFlags;
rcode = (mDNSu8)(responseFlags.b[1] & kDNSFlag1_RC_Mask);
// After we reset the qDNSServer to NULL, we could get more SERV_FAILS that might end up
- // peanlizing again.
+ // penalizing again.
if (!q->qDNSServer)
goto end;
@@ -480,10 +481,10 @@ mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info,
mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
{
mStatus err = mStatus_NoError;
-
+
if (!m->NATTraversals)
{
- m->retryGetAddr = NonZeroTime(m->timenow + 0x78000000);
+ m->retryGetAddr = NonZeroTime(m->timenow + FutureTime);
LogInfo("uDNS_RequestAddress: Setting retryGetAddr to future");
}
else if (m->timenow - m->retryGetAddr >= 0)
@@ -495,7 +496,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
mDNSu8* end = start + sizeof(NATAddrRequest);
err = mDNSPlatformSendUDP(m, start, end, 0, mDNSNULL, &m->Router, NATPMPPort, mDNSfalse);
debugf("uDNS_RequestAddress: Sent NAT-PMP external address request %d", err);
-
+
#ifdef _LEGACY_NAT_TRAVERSAL_
if (mDNSIPPortIsZero(m->UPnPRouterPort) || mDNSIPPortIsZero(m->UPnPSOAPPort))
{
@@ -507,7 +508,7 @@ mDNSlocal mStatus uDNS_RequestAddress(mDNS *m)
mStatus lnterr = LNT_GetExternalAddress(m);
if (lnterr)
LogMsg("uDNS_RequestAddress: LNT_GetExternalAddress returned error %d", lnterr);
-
+
err = err ? err : lnterr; // NAT-PMP error takes precedence
}
#endif // _LEGACY_NAT_TRAVERSAL_
@@ -552,7 +553,7 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
LogMsg("uDNS_SendNATMsg called unexpectedly with NULL info");
return mStatus_BadParamErr;
}
-
+
// send msg if the router's address is private (which means it's non-zero)
if (mDNSv4AddrIsRFC1918(&m->Router.ip.v4))
{
@@ -565,7 +566,7 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
static NATPortMapRequest NATPortReq;
static const mDNSu8* end = (mDNSu8 *)&NATPortReq + sizeof(NATPortMapRequest);
mDNSu8 *p = (mDNSu8 *)&NATPortReq.NATReq_lease;
-
+
NATPortReq.vers = NATMAP_VERS;
NATPortReq.opcode = info->Protocol;
NATPortReq.unused = zeroID;
@@ -575,7 +576,7 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
p[1] = (mDNSu8)((info->NATLease >> 16) & 0xFF);
p[2] = (mDNSu8)((info->NATLease >> 8) & 0xFF);
p[3] = (mDNSu8)( info->NATLease & 0xFF);
-
+
err = mDNSPlatformSendUDP(m, (mDNSu8 *)&NATPortReq, end, 0, mDNSNULL, &m->Router, NATPMPPort, mDNSfalse);
debugf("uDNS_SendNATMsg: Sent NAT-PMP mapping request %d", err);
}
@@ -602,34 +603,31 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
mDNSu8* start = (mDNSu8*)&req;
mDNSu8* end = start + sizeof(req);
mDNSu8* p = (mDNSu8*)&req.lifetime;
-
+
req.version = PCP_VERS;
req.opCode = PCPOp_Map;
req.reserved = zeroID;
-
+
p[0] = (mDNSu8)((info->NATLease >> 24) & 0xFF);
p[1] = (mDNSu8)((info->NATLease >> 16) & 0xFF);
p[2] = (mDNSu8)((info->NATLease >> 8) & 0xFF);
p[3] = (mDNSu8)( info->NATLease & 0xFF);
-
+
mDNSAddrMapIPv4toIPv6(&m->AdvertisedV4.ip.v4, &req.clientAddr);
-
+
req.nonce[0] = m->PCPNonce[0];
req.nonce[1] = m->PCPNonce[1];
req.nonce[2] = m->PCPNonce[2];
-
+
req.protocol = (info->Protocol == NATOp_MapUDP ? PCPProto_UDP : PCPProto_TCP);
-
+
req.reservedMapOp[0] = 0;
req.reservedMapOp[1] = 0;
req.reservedMapOp[2] = 0;
-
- if (info->Protocol)
- req.intPort = info->IntPort;
- else
- req.intPort = DiscardPort;
+
+ req.intPort = info->Protocol ? info->IntPort : DiscardPort;
req.extPort = info->RequestedPort;
-
+
// Since we only support IPv4, even if using the all-zeros address, map it, so
// the PCP gateway will give us an IPv4 address & not an IPv6 address.
mDNSAddrMapIPv4toIPv6(&info->NewAddress, &req.extAddress);
@@ -655,7 +653,7 @@ mDNSlocal mStatus uDNS_SendNATMsg(mDNS *m, NATTraversalInfo *info, mDNSBool useP
mStatus lnterr = LNT_MapPort(m, info);
if (lnterr)
LogMsg("uDNS_SendNATMsg: LNT_MapPort returned error %d", lnterr);
-
+
err = err ? err : lnterr; // PCP error takes precedence
}
#endif // _LEGACY_NAT_TRAVERSAL_
@@ -728,7 +726,7 @@ mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv
m->NextScheduledNATOp = m->retryGetAddr;
last_err = err;
-
+
for (n = m->NATTraversals; n; n=n->next)
{
// We should change n->NewAddress only when n is one of:
@@ -925,7 +923,7 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
{
traversal->NATLease = 0;
traversal->retryInterval = 0;
-
+
// In case we most recently sent NAT-PMP, we need to set sentNATPMP to false so
// that we'll send a NAT-PMP request to destroy the mapping. We do this because
// the NATTraversal struct has already been cut from the list, and the client
@@ -941,7 +939,7 @@ mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *tra
// would have requested an IPv4 address.
traversal->RequestedPort = zeroIPPort;
traversal->NewAddress = zerov4Addr;
-
+
uDNS_SendNATMsg(m, traversal, traversal->lastSuccessfulProtocol != NATTProtocolNATPMP);
}
@@ -1555,7 +1553,7 @@ mDNSlocal tcpInfo_t *MakeTCPConn(mDNS *const m, const DNSMessage *const msg, con
mDNSPlatformMemZero(info, sizeof(tcpInfo_t));
info->m = m;
- info->sock = mDNSPlatformTCPSocket(m, flags, &srcport, useBackgroundTrafficClass);
+ info->sock = mDNSPlatformTCPSocket(flags, &srcport, useBackgroundTrafficClass);
info->requestLen = 0;
info->question = question;
info->rr = rr;
@@ -1574,6 +1572,7 @@ mDNSlocal tcpInfo_t *MakeTCPConn(mDNS *const m, const DNSMessage *const msg, con
}
if (!info->sock) { LogMsg("MakeTCPConn: unable to create TCP socket"); mDNSPlatformMemFree(info); return(mDNSNULL); }
+ mDNSPlatformSetSocktOpt(info->sock, mDNSTransport_TCP, Addr->type, question);
err = mDNSPlatformTCPConnect(info->sock, Addr, Port, hostname, (question ? question->InterfaceID : mDNSNULL), tcpCallback, info);
// Probably suboptimal here.
@@ -1704,6 +1703,7 @@ mDNSexport void startLLQHandshake(mDNS *m, DNSQuestion *q)
}
}
+
// forward declaration so GetServiceTarget can do reverse lookup if needed
mDNSlocal void GetStaticHostname(mDNS *m);
@@ -1719,7 +1719,7 @@ mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
DomainAuthInfo *AuthInfo = GetAuthInfoForName_internal(m, rr->resrec.name);
if (AuthInfo && AuthInfo->AutoTunnel)
{
- StartServerTunnel(m, AuthInfo);
+ StartServerTunnel(AuthInfo);
if (AuthInfo->AutoTunnelHostRecord.namestorage.c[0] == 0) return(mDNSNULL);
debugf("GetServiceTarget: Returning %##s", AuthInfo->AutoTunnelHostRecord.namestorage.c);
return(&AuthInfo->AutoTunnelHostRecord.namestorage);
@@ -1755,11 +1755,13 @@ mDNSlocal const domainname *PUBLIC_LLQ_SERVICE_TYPE = (const domainname*)"\x
mDNSlocal const domainname *PRIVATE_UPDATE_SERVICE_TYPE = (const domainname*)"\x0F_dns-update-tls" "\x04_tcp";
mDNSlocal const domainname *PRIVATE_QUERY_SERVICE_TYPE = (const domainname*)"\x0E_dns-query-tls" "\x04_tcp";
mDNSlocal const domainname *PRIVATE_LLQ_SERVICE_TYPE = (const domainname*)"\x0C_dns-llq-tls" "\x04_tcp";
+mDNSlocal const domainname *DNS_PUSH_NOTIFICATION_SERVICE_TYPE = (const domainname*)"\x0C_dns-push-tls" "\x04_tcp";
#define ZoneDataSRV(X) ( \
- (X)->ZoneService == ZoneServiceUpdate ? ((X)->ZonePrivate ? PRIVATE_UPDATE_SERVICE_TYPE : PUBLIC_UPDATE_SERVICE_TYPE) : \
- (X)->ZoneService == ZoneServiceQuery ? ((X)->ZonePrivate ? PRIVATE_QUERY_SERVICE_TYPE : (const domainname*)"" ) : \
- (X)->ZoneService == ZoneServiceLLQ ? ((X)->ZonePrivate ? PRIVATE_LLQ_SERVICE_TYPE : PUBLIC_LLQ_SERVICE_TYPE ) : (const domainname*)"")
+ (X)->ZoneService == ZoneServiceUpdate ? ((X)->ZonePrivate ? PRIVATE_UPDATE_SERVICE_TYPE : PUBLIC_UPDATE_SERVICE_TYPE) : \
+ (X)->ZoneService == ZoneServiceQuery ? ((X)->ZonePrivate ? PRIVATE_QUERY_SERVICE_TYPE : (const domainname*)"" ) : \
+ (X)->ZoneService == ZoneServiceLLQ ? ((X)->ZonePrivate ? PRIVATE_LLQ_SERVICE_TYPE : PUBLIC_LLQ_SERVICE_TYPE ) : \
+ (X)->ZoneService == ZoneServiceDNSPush ? DNS_PUSH_NOTIFICATION_SERVICE_TYPE : (const domainname*)"")
// Forward reference: GetZoneData_StartQuery references GetZoneData_QuestionCallback, and
// GetZoneData_QuestionCallback calls GetZoneData_StartQuery
@@ -1854,10 +1856,7 @@ mDNSlocal void GetZoneData_QuestionCallback(mDNS *const m, DNSQuestion *question
if (question->ThisQInterval != -1)
LogMsg("GetZoneData_QuestionCallback: Question %##s (%s) ThisQInterval %d not -1", question->qname.c, DNSTypeName(question->qtype), question->ThisQInterval);
zd->Addr.type = mDNSAddrType_IPv4;
- if (answer->rdlength == 4)
- zd->Addr.ip.v4 = answer->rdata->u.ipv4;
- else
- zd->Addr.ip.v4 = zerov4Addr;
+ zd->Addr.ip.v4 = (answer->rdlength == 4) ? answer->rdata->u.ipv4 : zerov4Addr;
// In order to simulate firewalls blocking our outgoing TCP connections, returning immediate ICMP errors or TCP resets,
// the code below will make us try to connect to loopback, resulting in an immediate "port unreachable" failure.
// This helps us test to make sure we handle this case gracefully
@@ -1890,7 +1889,7 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
zd->question.InterfaceID = mDNSInterface_Any;
zd->question.flags = 0;
zd->question.Target = zeroAddr;
- //zd->question.qname.c[0] = 0; // Already set
+ //zd->question.qname.c[0] = 0; // Already set
zd->question.qtype = qtype;
zd->question.qclass = kDNSClass_IN;
zd->question.LongLived = mDNSfalse;
@@ -1898,8 +1897,6 @@ mDNSlocal mStatus GetZoneData_StartQuery(mDNS *const m, ZoneData *zd, mDNSu16 qt
zd->question.ForceMCast = mDNSfalse;
zd->question.ReturnIntermed = mDNStrue;
zd->question.SuppressUnusable = mDNSfalse;
- zd->question.DenyOnCellInterface = mDNSfalse;
- zd->question.DenyOnExpInterface = mDNSfalse;
zd->question.SearchListIndex = 0;
zd->question.AppendSearchDomains = 0;
zd->question.RetryWithSearchDomains = mDNSfalse;
@@ -2175,7 +2172,7 @@ mDNSlocal void StartRecordNatMap(mDNS *m, AuthRecord *rr)
else { LogMsg("StartRecordNatMap: could not determine transport protocol of service %##s", rr->resrec.name->c); return; }
//LogMsg("StartRecordNatMap: clientContext %p IntPort %d srv.port %d %s",
- // rr->NATinfo.clientContext, mDNSVal16(rr->NATinfo.IntPort), mDNSVal16(rr->resrec.rdata->u.srv.port), ARDisplayString(m, rr));
+ // rr->NATinfo.clientContext, mDNSVal16(rr->NATinfo.IntPort), mDNSVal16(rr->resrec.rdata->u.srv.port), ARDisplayString(m, rr));
if (rr->NATinfo.clientContext) mDNS_StopNATOperation_internal(m, &rr->NATinfo);
rr->NATinfo.Protocol = protocol;
@@ -2589,8 +2586,6 @@ mDNSlocal void GetStaticHostname(mDNS *m)
q->ForceMCast = mDNSfalse;
q->ReturnIntermed = mDNStrue;
q->SuppressUnusable = mDNSfalse;
- q->DenyOnCellInterface = mDNSfalse;
- q->DenyOnExpInterface = mDNSfalse;
q->SearchListIndex = 0;
q->AppendSearchDomains = 0;
q->RetryWithSearchDomains = mDNSfalse;
@@ -2650,12 +2645,30 @@ mDNSexport void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn)
// below could free the memory, and we have to make sure we don't touch hi fields after that.
mDNSBool f4 = hi->arv4.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv4.state != regState_Unregistered;
mDNSBool f6 = hi->arv6.resrec.RecordType != kDNSRecordTypeUnregistered && hi->arv6.state != regState_Unregistered;
- if (f4) LogInfo("mDNS_RemoveDynDNSHostName removing v4 %##s", fqdn);
- if (f6) LogInfo("mDNS_RemoveDynDNSHostName removing v6 %##s", fqdn);
*ptr = (*ptr)->next; // unlink
- if (f4) mDNS_Deregister_internal(m, &hi->arv4, mDNS_Dereg_normal);
- if (f6) mDNS_Deregister_internal(m, &hi->arv6, mDNS_Dereg_normal);
- // When both deregistrations complete we'll free the memory in the mStatus_MemFree callback
+ if (f4 || f6)
+ {
+ if (f4)
+ {
+ LogInfo("mDNS_RemoveDynDNSHostName removing v4 %##s", fqdn);
+ mDNS_Deregister_internal(m, &hi->arv4, mDNS_Dereg_normal);
+ }
+ if (f6)
+ {
+ LogInfo("mDNS_RemoveDynDNSHostName removing v6 %##s", fqdn);
+ mDNS_Deregister_internal(m, &hi->arv6, mDNS_Dereg_normal);
+ }
+ // When both deregistrations complete we'll free the memory in the mStatus_MemFree callback
+ }
+ else
+ {
+ if (hi->natinfo.clientContext)
+ {
+ mDNS_StopNATOperation_internal(m, &hi->natinfo);
+ hi->natinfo.clientContext = mDNSNULL;
+ }
+ mDNSPlatformMemFree(hi);
+ }
}
mDNS_CheckLock(m);
m->NextSRVUpdate = NonZeroTime(m->timenow);
@@ -2666,7 +2679,6 @@ mDNSexport void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn)
mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router)
{
mDNSBool v4Changed, v6Changed, RouterChanged;
- mDNSv6Addr v6;
if (m->mDNS_busy != m->mDNS_reentrancy)
LogMsg("mDNS_SetPrimaryInterfaceInfo: mDNS_busy (%ld) != mDNS_reentrancy (%ld)", m->mDNS_busy, m->mDNS_reentrancy);
@@ -2678,11 +2690,7 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
mDNS_Lock(m);
v4Changed = !mDNSSameIPv4Address(m->AdvertisedV4.ip.v4, v4addr ? v4addr->ip.v4 : zerov4Addr);
- if (v6addr)
- v6 = v6addr->ip.v6;
- else
- v6 = zerov6Addr;
- v6Changed = !mDNSSameIPv6Address(m->AdvertisedV6.ip.v6, v6);
+ v6Changed = !mDNSSameIPv6Address(m->AdvertisedV6.ip.v6, v6addr ? v6addr->ip.v6 : zerov6Addr);
RouterChanged = !mDNSSameIPv4Address(m->Router.ip.v4, router ? router->ip.v4 : zerov4Addr);
if (v4addr && (v4Changed || RouterChanged))
@@ -2751,7 +2759,6 @@ mDNSexport void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, co
m->NextSRVUpdate = NonZeroTime(m->timenow);
#if APPLE_OSX_mDNSResponder
- if (RouterChanged) uuid_generate(m->asl_uuid);
UpdateAutoTunnelDomainStatuses(m);
#endif
}
@@ -3026,7 +3033,6 @@ exit:
mDNSlocal mDNSBool IsRecordMergeable(mDNS *const m, AuthRecord *rr, mDNSs32 time)
{
DomainAuthInfo *info;
- (void) m; //unused
// A record is eligible for merge, if the following properties are met.
//
// 1. uDNS Resource Record
@@ -3631,13 +3637,13 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
// Minimum NAT-PMP packet is vers (1) opcode (1) + err (2) = 4 bytes
if (len < 4) { LogMsg("NAT-PMP message too short (%d bytes)", len); return; }
-
+
// Read multi-byte error value (field is identical in a NATPortMapReply)
AddrReply->err = (mDNSu16) ((mDNSu16)pkt[2] << 8 | pkt[3]);
-
+
if (AddrReply->err == NATErr_Vers)
{
- NATTraversalInfo *n;
+ NATTraversalInfo *n;
LogInfo("NAT-PMP version unsupported message received");
for (n = m->NATTraversals; n; n=n->next)
{
@@ -3645,7 +3651,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
// and update the state variables
uDNS_SendNATMsg(m, n, mDNSfalse);
}
-
+
m->NextScheduledNATOp = m->timenow;
return;
@@ -3659,7 +3665,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
LogMsg("NAT-PMP message too short (%d bytes) 0x%X 0x%X", len, AddrReply->opcode, AddrReply->err);
return;
}
-
+
// Read multi-byte upseconds value (field is identical in a NATPortMapReply)
AddrReply->upseconds = (mDNSs32) ((mDNSs32)pkt[4] << 24 | (mDNSs32)pkt[5] << 16 | (mDNSs32)pkt[6] << 8 | pkt[7]);
@@ -3689,9 +3695,7 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
if (AddrReply->opcode == NATOp_AddrResponse)
{
#if APPLE_OSX_mDNSResponder
- static char msgbuf[16];
- mDNS_snprintf(msgbuf, sizeof(msgbuf), "%d", AddrReply->err);
- mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.AddressRequest", AddrReply->err ? "failure" : "success", msgbuf, "");
+ LogInfo("uDNS_ReceiveNATPMPPacket: AddressRequest %s error %d", AddrReply->err ? "failure" : "success", AddrReply->err);
#endif
if (!AddrReply->err && len < sizeof(NATAddrReply)) { LogMsg("NAT-PMP AddrResponse message too short (%d bytes)", len); return; }
natTraversalHandleAddressReply(m, AddrReply->err, AddrReply->ExtAddr);
@@ -3700,9 +3704,8 @@ mDNSlocal void uDNS_ReceiveNATPMPPacket(mDNS *m, const mDNSInterfaceID Interface
{
mDNSu8 Protocol = AddrReply->opcode & 0x7F;
#if APPLE_OSX_mDNSResponder
- static char msgbuf[16];
- mDNS_snprintf(msgbuf, sizeof(msgbuf), "%s - %d", AddrReply->opcode == NATOp_MapUDPResponse ? "UDP" : "TCP", PortMapReply->err);
- mDNSASLLog((uuid_t *)&m->asl_uuid, "natt.natpmp.PortMapRequest", PortMapReply->err ? "failure" : "success", msgbuf, "");
+ LogInfo("uDNS_ReceiveNATPMPPacket: PortMapRequest %s %s - error %d",
+ PortMapReply->err ? "failure" : "success", (AddrReply->opcode == NATOp_MapUDPResponse) ? "UDP" : "TCP", PortMapReply->err);
#endif
if (!PortMapReply->err)
{
@@ -3736,16 +3739,16 @@ mDNSlocal void uDNS_ReceivePCPPacket(mDNS *m, const mDNSInterfaceID InterfaceID,
mDNSu8 protocol = 0;
mDNSIPPort intport = zeroIPPort;
mDNSIPPort extport = zeroIPPort;
-
+
// Minimum PCP packet is 24 bytes
if (len < 24)
{
LogMsg("uDNS_ReceivePCPPacket: message too short (%d bytes)", len);
return;
}
-
+
strippedOpCode = reply->opCode & 0x7f;
-
+
if ((reply->opCode & 0x80) == 0x00 || (strippedOpCode != PCPOp_Announce && strippedOpCode != PCPOp_Map))
{
LogMsg("uDNS_ReceivePCPPacket: unhandled opCode %u", reply->opCode);
@@ -3784,11 +3787,11 @@ mDNSlocal void uDNS_ReceivePCPPacket(mDNS *m, const mDNSInterfaceID InterfaceID,
if (strippedOpCode == PCPOp_Announce)
return;
-
+
// We globally keep track of the most recent error code for mappings.
// This seems bad to do with PCP, but best not change it now.
m->LastNATMapResultCode = reply->result;
-
+
if (!reply->result)
{
if (len < sizeof(PCPMapReply))
@@ -3796,7 +3799,7 @@ mDNSlocal void uDNS_ReceivePCPPacket(mDNS *m, const mDNSInterfaceID InterfaceID,
LogMsg("uDNS_ReceivePCPPacket: mapping response too short (%d bytes)", len);
return;
}
-
+
// Check the nonce
if (reply->nonce[0] != m->PCPNonce[0] || reply->nonce[1] != m->PCPNonce[1] || reply->nonce[2] != m->PCPNonce[2])
{
@@ -3835,7 +3838,7 @@ mDNSlocal void uDNS_ReceivePCPPacket(mDNS *m, const mDNSInterfaceID InterfaceID,
{
LogInfo("uDNS_ReceivePCPPacket: error received from server. opcode %X result %X lifetime %X epoch %X",
reply->opCode, reply->result, reply->lifetime, reply->epoch);
-
+
// If the packet is long enough, get the protocol & intport for matching to report
// the error
if (len >= sizeof(PCPMapReply))
@@ -3868,135 +3871,6 @@ mDNSexport void uDNS_ReceiveNATPacket(mDNS *m, const mDNSInterfaceID InterfaceID
LogMsg("uDNS_ReceiveNATPacket: packet with version %u (expected %u or %u)", pkt[0], PCP_VERS, NATMAP_VERS);
}
-// <rdar://problem/3925163> Shorten DNS-SD queries to avoid NAT bugs
-// <rdar://problem/4288449> Add check to avoid crashing NAT gateways that have buggy DNS relay code
-//
-// We know of bugs in home NAT gateways that cause them to crash if they receive certain DNS queries.
-// The DNS queries that make them crash are perfectly legal DNS queries, but even if they weren't,
-// the gateway shouldn't crash -- in today's world of viruses and network attacks, software has to
-// be written assuming that a malicious attacker could send them any packet, properly-formed or not.
-// Still, we don't want to be crashing people's home gateways, so we go out of our way to avoid
-// the queries that crash them.
-//
-// Some examples:
-//
-// 1. Any query where the name ends in ".in-addr.arpa." and the text before this is 32 or more bytes.
-// The query type does not need to be PTR -- the gateway will crash for any query type.
-// e.g. "ping long-name-crashes-the-buggy-router.in-addr.arpa" will crash one of these.
-//
-// 2. Any query that results in a large response with the TC bit set.
-//
-// 3. Any PTR query that doesn't begin with four decimal numbers.
-// These gateways appear to assume that the only possible PTR query is a reverse-mapping query
-// (e.g. "1.0.168.192.in-addr.arpa") and if they ever get a PTR query where the first four
-// labels are not all decimal numbers in the range 0-255, they handle that by crashing.
-// These gateways also ignore the remainder of the name following the four decimal numbers
-// -- whether or not it actually says in-addr.arpa, they just make up an answer anyway.
-//
-// The challenge therefore is to craft a query that will discern whether the DNS server
-// is one of these buggy ones, without crashing it. Furthermore we don't want our test
-// queries making it all the way to the root name servers, putting extra load on those
-// name servers and giving Apple a bad reputation. To this end we send this query:
-// dig -t ptr 1.0.0.127.dnsbugtest.1.0.0.127.in-addr.arpa.
-//
-// The text preceding the ".in-addr.arpa." is under 32 bytes, so it won't cause crash (1).
-// It will not yield a large response with the TC bit set, so it won't cause crash (2).
-// It starts with four decimal numbers, so it won't cause crash (3).
-// The name falls within the "1.0.0.127.in-addr.arpa." domain, the reverse-mapping name for the local
-// loopback address, and therefore the query will black-hole at the first properly-configured DNS server
-// it reaches, making it highly unlikely that this query will make it all the way to the root.
-//
-// Finally, the correct response to this query is NXDOMAIN or a similar error, but the
-// gateways that ignore the remainder of the name following the four decimal numbers
-// give themselves away by actually returning a result for this nonsense query.
-
-mDNSlocal const domainname *DNSRelayTestQuestion = (const domainname*)
- "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\xa" "dnsbugtest"
- "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\x7" "in-addr" "\x4" "arpa";
-
-// See comments above for DNSRelayTestQuestion
-// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
-mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
-{
- int i;
- mDNSu8 *p = q->qname.c;
- if (q->AuthInfo) return(mDNStrue); // Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
- if (q->qtype != kDNSType_PTR) return(mDNStrue); // Don't need a test query for any non-PTR queries
- for (i=0; i<4; i++) // If qname does not begin with num.num.num.num, can't skip the test query
- {
- if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
- if ( p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
- if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
- if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
- p += 1 + p[0];
- }
- // If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
- // we can safely do it without needing a test query first, otherwise we need the test query.
- return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
-}
-
-// Returns mDNStrue if response was handled
-mDNSlocal mDNSBool uDNS_ReceiveTestQuestionResponse(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
- const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
-{
- const mDNSu8 *ptr = msg->data;
- DNSQuestion pktq;
- DNSServer *s;
- mDNSu32 result = 0;
-
- // 1. Find out if this is an answer to one of our test questions
- if (msg->h.numQuestions != 1) return(mDNSfalse);
- ptr = getQuestion(msg, ptr, end, mDNSInterface_Any, &pktq);
- if (!ptr) return(mDNSfalse);
- if (pktq.qtype != kDNSType_PTR || pktq.qclass != kDNSClass_IN) return(mDNSfalse);
- if (!SameDomainName(&pktq.qname, DNSRelayTestQuestion)) return(mDNSfalse);
-
- // 2. If the DNS relay gave us a positive response, then it's got buggy firmware
- // else, if the DNS relay gave us an error or no-answer response, it passed our test
- if ((msg->h.flags.b[1] & kDNSFlag1_RC_Mask) == kDNSFlag1_RC_NoErr && msg->h.numAnswers > 0)
- result = DNSServer_Failed;
- else
- result = DNSServer_Passed;
-
- // 3. Find occurrences of this server in our list, and mark them appropriately
- for (s = m->DNSServers; s; s = s->next)
- {
- mDNSBool matchaddr = (s->teststate != result && mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port));
- mDNSBool matchid = (s->teststate == DNSServer_Untested && mDNSSameOpaque16(msg->h.id, s->testid));
- if (matchaddr || matchid)
- {
- DNSQuestion *q;
- s->teststate = result;
- if (result == DNSServer_Passed)
- {
- LogInfo("DNS Server %#a:%d (%#a:%d) %d passed%s",
- &s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
- matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
- }
- else
- {
- LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d (%#a:%d) %d%s",
- &s->addr, mDNSVal16(s->port), srcaddr, mDNSVal16(srcport), mDNSVal16(s->testid),
- matchaddr ? "" : " NOTE: Reply did not come from address to which query was sent");
- }
-
- // If this server has just changed state from DNSServer_Untested to DNSServer_Passed, then retrigger any waiting questions.
- // We use the NoTestQuery() test so that we only retrigger questions that were actually blocked waiting for this test to complete.
- if (result == DNSServer_Passed) // Unblock any questions that were waiting for this result
- for (q = m->Questions; q; q=q->next)
- if (q->qDNSServer == s && !NoTestQuery(q))
- {
- q->ThisQInterval = INIT_UCAST_POLL_INTERVAL / QuestionIntervalStep;
- q->unansweredQueries = 0;
- q->LastQTime = m->timenow - q->ThisQInterval;
- m->NextScheduledQuery = m->timenow;
- }
- }
- }
-
- return(mDNStrue); // Return mDNStrue to tell uDNS_ReceiveMsg it doesn't need to process this packet further
-}
-
// Called from mDNSCoreReceive with the lock held
mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
{
@@ -4025,7 +3899,6 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
if (QR_OP == StdR)
{
//if (srcaddr && recvLLQResponse(m, msg, end, srcaddr, srcport)) return;
- if (uDNS_ReceiveTestQuestionResponse(m, msg, end, srcaddr, srcport)) return;
for (qptr = m->Questions; qptr; qptr = qptr->next)
if (msg->h.flags.b[0] & kDNSFlag0_TC && mDNSSameOpaque16(qptr->TargetQID, msg->h.id) && m->timenow - qptr->LastQTime < RESPONSE_WINDOW)
{
@@ -4043,11 +3916,13 @@ mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNS
if (QR_OP == UpdateR)
{
- mDNSu32 lease = GetPktLease(m, msg, end);
+ mDNSu32 pktlease = 0;
+ mDNSBool gotlease = GetPktLease(m, msg, end, &pktlease);
+ mDNSu32 lease = gotlease ? pktlease : 60 * 60; // If lease option missing, assume one hour
mDNSs32 expire = m->timenow + (mDNSs32)lease * mDNSPlatformOneSecond;
mDNSu32 random = mDNSRandom((mDNSs32)lease * mDNSPlatformOneSecond/10);
- //rcode = kDNSFlag1_RC_ServFail; // Simulate server failure (rcode 2)
+ //rcode = kDNSFlag1_RC_ServFail; // Simulate server failure (rcode 2)
// Walk through all the records that matches the messageID. There could be multiple
// records if we had sent them in a group
@@ -4130,7 +4005,7 @@ mDNSexport void sendLLQRefresh(mDNS *m, DNSQuestion *q)
return;
// ThisQInterval is not adjusted when we return from here which means that we will get called back
// again immediately. As q->servAddr and q->servPort are still valid and the nta->Host is initialized
- // without any additional discovery for PrivateQuery, things work.
+ // without any additional discovery for PrivateQuery, things work.
}
q->tcp = MakeTCPConn(m, &m->omsg, end, kTCPSocketFlags_UseTLS, &q->servAddr, q->servPort, &q->nta->Host, q, mDNSNULL);
}
@@ -4210,6 +4085,41 @@ mDNSexport void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneI
mDNS_Unlock(m);
}
+#ifdef DNS_PUSH_ENABLED
+mDNSexport void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
+{
+ DNSQuestion *q = (DNSQuestion *)zoneInfo->ZoneDataContext;
+ mDNS_Lock(m);
+
+ // If we get here it means that the GetZoneData operation has completed.
+ // We hold on to the zone data if it is AutoTunnel as we use the hostname
+ // in zoneInfo during the TLS connection setup.
+ q->servAddr = zeroAddr;
+ q->servPort = zeroIPPort;
+ if (!err && zoneInfo && !mDNSIPPortIsZero(zoneInfo->Port) && !mDNSAddressIsZero(&zoneInfo->Addr) && zoneInfo->Host.c[0])
+ {
+ q->dnsPushState = DNSPUSH_SERVERFOUND;
+ q->dnsPushServerAddr = zoneInfo->Addr;
+ q->dnsPushServerPort = zoneInfo->Port;
+ q->ntries = 0;
+ LogInfo("DNSPushNotificationGotZoneData %#a:%d", &q->dnsPushServerAddr, mDNSVal16(q->dnsPushServerPort));
+ SubscribeToDNSPushNotificationServer(m,q);
+ }
+ else
+ {
+ q->dnsPushState = DNSPUSH_NOSERVER;
+ StartLLQPolling(m,q);
+ if (err == mStatus_NoSuchNameErr)
+ {
+ // this actually failed, so mark it by setting address to all ones
+ q->servAddr.type = mDNSAddrType_IPv4;
+ q->servAddr.ip.v4 = onesIPv4Addr;
+ }
+ }
+ mDNS_Unlock(m);
+}
+#endif // DNS_PUSH_ENABLED
+
// Called in normal callback context (i.e. mDNS_busy and mDNS_reentrancy are both 1)
mDNSlocal void PrivateQueryGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
{
@@ -4477,7 +4387,7 @@ mDNSlocal void SendRecordDeregistration(mDNS *m, AuthRecord *rr)
if (!rr->nta) { LogMsg("SendRecordDeregistration:ERROR!! nta is NULL for %s", ARDisplayString(m, rr)); return; }
err = mDNSSendDNSMessage(m, &m->omsg, ptr, mDNSInterface_Any, mDNSNULL, &rr->nta->Addr, rr->nta->Port, mDNSNULL, GetAuthInfoForName_internal(m, rr->resrec.name), mDNSfalse);
if (err) debugf("ERROR: SendRecordDeregistration - mDNSSendDNSMessage - %d", err);
- //if (rr->state == regState_DeregPending) CompleteDeregistration(m, rr); // Don't touch rr after this
+ //if (rr->state == regState_DeregPending) CompleteDeregistration(m, rr); // Don't touch rr after this
}
SetRecordRetry(m, rr, 0);
return;
@@ -4684,7 +4594,7 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
// the middlebox is DNSSEC aware. If we receive at least one response to a DNSSEC
// question, we don't turn off validation. Also, we wait for MAX_DNSSEC_RETRANSMISSIONS
// before turning off validation to accomodate packet loss.
- //
+ //
// Note: req_DO affects only DNSSEC_VALIDATION_SECURE_OPTIONAL questions;
// DNSSEC_VALIDATION_SECURE questions ignores req_DO.
@@ -4700,17 +4610,37 @@ mDNSlocal void handle_unanswered_query(mDNS *const m)
if (!q->qDNSServer->req_DO)
{
- q->ValidationState = DNSSECValNotRequired;
+ q->ValidationState = DNSSECValNotRequired;
q->ValidationRequired = DNSSEC_VALIDATION_NONE;
-
+
if (q->ProxyQuestion)
q->ProxyDNSSECOK = mDNSfalse;
- LogInfo("handle_unanswered_query: unanswered query for %##s (%s), so turned off validation for %#a",
+ LogInfo("handle_unanswered_query: unanswered query for %##s (%s), so turned off validation for %#a",
q->qname.c, DNSTypeName(q->qtype), &q->qDNSServer->addr);
}
}
}
+mDNSlocal void uDNS_HandleLLQState(mDNS *const m, DNSQuestion *q)
+{
+#ifdef DNS_PUSH_ENABLED
+ // First attempt to use DNS Push Notification.
+ if (q->dnsPushState == DNSPUSH_INIT)
+ DiscoverDNSPushNotificationServer(m, q);
+#endif // DNS_PUSH_ENABLED
+ switch (q->state)
+ {
+ case LLQ_InitialRequest: startLLQHandshake(m, q); break;
+ case LLQ_SecondaryRequest:
+ // For PrivateQueries, we need to start the handshake again as we don't do the Challenge/Response step
+ if (PrivateQuery(q)) startLLQHandshake(m, q);
+ else sendChallengeResponse(m, q, mDNSNULL);
+ break;
+ case LLQ_Established: sendLLQRefresh(m, q); break;
+ case LLQ_Poll: break; // Do nothing (handled below)
+ }
+}
+
// The question to be checked is not passed in as an explicit parameter;
// instead it is implicit that the question to be checked is m->CurrentQuestion.
mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
@@ -4720,22 +4650,10 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
if (q->LongLived)
{
- switch (q->state)
- {
- case LLQ_InitialRequest: startLLQHandshake(m, q); break;
- case LLQ_SecondaryRequest:
- // For PrivateQueries, we need to start the handshake again as we don't do the Challenge/Response step
- if (PrivateQuery(q))
- startLLQHandshake(m, q);
- else
- sendChallengeResponse(m, q, mDNSNULL);
- break;
- case LLQ_Established: sendLLQRefresh(m, q); break;
- case LLQ_Poll: break; // Do nothing (handled below)
- }
+ uDNS_HandleLLQState(m,q);
}
- handle_unanswered_query(m);
+ handle_unanswered_query(m);
// We repeat the check above (rather than just making this the "else" case) because startLLQHandshake can change q->state to LLQ_Poll
if (!(q->LongLived && q->state != LLQ_Poll))
{
@@ -4776,44 +4694,32 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
new = GetServerForQuestion(m, q);
if (new)
{
- mDNSIPPort zp = zeroIPPort;
LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%d ThisQInterval %d",
- q, q->qname.c, DNSTypeName(q->qtype), new ? &new->addr : mDNSNULL, mDNSVal16(new? new->port : zp), q->ThisQInterval);
+ q, q->qname.c, DNSTypeName(q->qtype), new ? &new->addr : mDNSNULL, mDNSVal16(new ? new->port : zeroIPPort), q->ThisQInterval);
DNSServerChangeForQuestion(m, q, new);
}
for (qptr = q->next ; qptr; qptr = qptr->next)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
}
- if (q->qDNSServer && q->qDNSServer->teststate != DNSServer_Disabled)
+ if (q->qDNSServer)
{
- mDNSu8 *end = m->omsg.data;
+ mDNSu8 *end;
mStatus err = mStatus_NoError;
mDNSBool private = mDNSfalse;
InitializeDNSMessage(&m->omsg.h, q->TargetQID, (DNSSECQuestion(q) ? DNSSecQFlags : uQueryFlags));
- if (q->qDNSServer->teststate != DNSServer_Untested || NoTestQuery(q))
- {
- end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
- if (DNSSECQuestion(q) && !q->qDNSServer->cellIntf)
- {
- if (q->ProxyQuestion)
- end = DNSProxySetAttributes(q, &m->omsg.h, &m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData);
- else
- end = putDNSSECOption(&m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData);
- }
- private = PrivateQuery(q);
- }
- else if (m->timenow - q->qDNSServer->lasttest >= INIT_UCAST_POLL_INTERVAL) // Make sure at least three seconds has elapsed since last test query
+ end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
+ if (DNSSECQuestion(q) && !q->qDNSServer->cellIntf)
{
- LogInfo("Sending DNS test query to %#a:%d", &q->qDNSServer->addr, mDNSVal16(q->qDNSServer->port));
- q->ThisQInterval = INIT_UCAST_POLL_INTERVAL / QuestionIntervalStep;
- q->qDNSServer->lasttest = m->timenow;
- end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, DNSRelayTestQuestion, kDNSType_PTR, kDNSClass_IN);
- q->qDNSServer->testid = m->omsg.h.id;
+ if (q->ProxyQuestion)
+ end = DNSProxySetAttributes(q, &m->omsg.h, &m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData);
+ else
+ end = putDNSSECOption(&m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData);
}
+ private = PrivateQuery(q);
- if (end > m->omsg.data && (q->qDNSServer->teststate != DNSServer_Failed || NoTestQuery(q)))
+ if (end > m->omsg.data)
{
//LogMsg("uDNS_CheckCurrentQuestion %p %d %p %##s (%s)", q, NextQSendTime(q) - m->timenow, private, q->qname.c, DNSTypeName(q->qtype));
if (private)
@@ -4824,15 +4730,28 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
}
else
{
- mDNSIPPort zp = zeroIPPort;
debugf("uDNS_CheckCurrentQuestion sending %p %##s (%s) %#a:%d UnansweredQueries %d",
q, q->qname.c, DNSTypeName(q->qtype),
- q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp), q->unansweredQueries);
+ q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->unansweredQueries);
+#if APPLE_OSX_mDNSResponder
+ // When a DNS proxy network extension initiates the close of a UDP flow (this usually happens when a DNS
+ // proxy gets disabled or crashes), mDNSResponder's corresponding UDP socket will be marked with the
+ // SS_CANTRCVMORE state flag. Reading from such a socket is no longer possible, so close the current
+ // socket pair so that we can create a new pair.
+ if (q->LocalSocket && mDNSPlatformUDPSocketEncounteredEOF(q->LocalSocket))
+ {
+ mDNSPlatformUDPClose(q->LocalSocket);
+ q->LocalSocket = mDNSNULL;
+ }
+#endif
if (!q->LocalSocket)
{
- q->LocalSocket = mDNSPlatformUDPSocket(m, zeroIPPort);
+ q->LocalSocket = mDNSPlatformUDPSocket(zeroIPPort);
if (q->LocalSocket)
- mDNSPlatformSetuDNSSocktOpt(q->LocalSocket, &q->qDNSServer->addr, q);
+ {
+ mDNSPlatformSetSocktOpt(q->LocalSocket, mDNSTransport_UDP, mDNSAddrType_IPv4, q);
+ mDNSPlatformSetSocktOpt(q->LocalSocket, mDNSTransport_UDP, mDNSAddrType_IPv6, q);
+ }
}
if (!q->LocalSocket) err = mStatus_NoMemoryErr; // If failed to make socket (should be very rare), we'll try again next time
else
@@ -4841,6 +4760,11 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
#if TARGET_OS_EMBEDDED
if (!err)
{
+ if (q->metrics.answered)
+ {
+ q->metrics.querySendCount = 0;
+ q->metrics.answered = mDNSfalse;
+ }
if (q->metrics.querySendCount++ == 0)
{
q->metrics.firstQueryTime = m->timenow;
@@ -4851,32 +4775,77 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
}
}
- if (err != mStatus_TransientErr) // if it is not a transient error backoff and DO NOT flood queries unnecessarily
+ if (err == mStatus_HostUnreachErr)
{
- q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep; // Only increase interval if send succeeded
- q->unansweredQueries++;
- if (q->ThisQInterval > MAX_UCAST_POLL_INTERVAL)
- q->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
- if (private && q->state != LLQ_Poll)
+ DNSServer *newServer;
+
+ LogInfo("uDNS_CheckCurrentQuestion: host unreachable error for DNS server %#a for question [%p] %##s (%s)",
+ &q->qDNSServer->addr, q, q->qname.c, DNSTypeName(q->qtype));
+
+ if (!StrictUnicastOrdering)
{
- // We don't want to retransmit too soon. Hence, we always schedule our first
- // retransmisson at 3 seconds rather than one second
- if (q->ThisQInterval < (3 * mDNSPlatformOneSecond))
- q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep;
- if (q->ThisQInterval > LLQ_POLL_INTERVAL)
- q->ThisQInterval = LLQ_POLL_INTERVAL;
- LogInfo("uDNS_CheckCurrentQuestion: private non polling question for %##s (%s) will be retried in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
+ q->qDNSServer->penaltyTime = NonZeroTime(m->timenow + DNSSERVER_PENALTY_TIME);
+ }
+
+ newServer = GetServerForQuestion(m, q);
+ if (!newServer)
+ {
+ q->triedAllServersOnce = 1;
+ SetValidDNSServers(m, q);
+ newServer = GetServerForQuestion(m, q);
+ }
+ if (newServer)
+ {
+ LogInfo("uDNS_checkCurrentQuestion: Retrying question %p %##s (%s) DNS Server %#a:%u ThisQInterval %d",
+ q, q->qname.c, DNSTypeName(q->qtype), newServer ? &newServer->addr : mDNSNULL, mDNSVal16(newServer ? newServer->port : zeroIPPort), q->ThisQInterval);
+ DNSServerChangeForQuestion(m, q, newServer);
}
- if (q->qDNSServer->cellIntf)
+ if (q->triedAllServersOnce)
+ {
+ q->LastQTime = m->timenow;
+ }
+ else
{
- // We don't want to retransmit too soon. Schedule our first retransmisson at
- // MIN_UCAST_RETRANS_TIMEOUT seconds.
- if (q->ThisQInterval < MIN_UCAST_RETRANS_TIMEOUT)
- q->ThisQInterval = MIN_UCAST_RETRANS_TIMEOUT;
+ q->ThisQInterval = InitialQuestionInterval;
+ q->LastQTime = m->timenow - q->ThisQInterval;
}
- debugf("uDNS_CheckCurrentQuestion: Increased ThisQInterval to %d for %##s (%s), cell %d", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer->cellIntf);
+ q->unansweredQueries = 0;
+ }
+ else
+ {
+ if (err != mStatus_TransientErr) // if it is not a transient error backoff and DO NOT flood queries unnecessarily
+ {
+ // If all DNS Servers are not responding, then we back-off using the multiplier UDNSBackOffMultiplier(*2).
+ // Only increase interval if send succeeded
+
+ q->ThisQInterval = q->ThisQInterval * UDNSBackOffMultiplier;
+ if ((q->ThisQInterval > 0) && (q->ThisQInterval < MinQuestionInterval)) // We do not want to retx within 1 sec
+ q->ThisQInterval = MinQuestionInterval;
+
+ q->unansweredQueries++;
+ if (q->ThisQInterval > MAX_UCAST_POLL_INTERVAL)
+ q->ThisQInterval = MAX_UCAST_POLL_INTERVAL;
+ if (private && q->state != LLQ_Poll)
+ {
+ // We don't want to retransmit too soon. Hence, we always schedule our first
+ // retransmisson at 3 seconds rather than one second
+ if (q->ThisQInterval < (3 * mDNSPlatformOneSecond))
+ q->ThisQInterval = q->ThisQInterval * QuestionIntervalStep;
+ if (q->ThisQInterval > LLQ_POLL_INTERVAL)
+ q->ThisQInterval = LLQ_POLL_INTERVAL;
+ LogInfo("uDNS_CheckCurrentQuestion: private non polling question for %##s (%s) will be retried in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
+ }
+ if (q->qDNSServer->cellIntf)
+ {
+ // We don't want to retransmit too soon. Schedule our first retransmisson at
+ // MIN_UCAST_RETRANS_TIMEOUT seconds.
+ if (q->ThisQInterval < MIN_UCAST_RETRANS_TIMEOUT)
+ q->ThisQInterval = MIN_UCAST_RETRANS_TIMEOUT;
+ }
+ debugf("uDNS_CheckCurrentQuestion: Increased ThisQInterval to %d for %##s (%s), cell %d", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer->cellIntf);
+ }
+ q->LastQTime = m->timenow;
}
- q->LastQTime = m->timenow;
SetNextQueryTime(m, q);
}
else
@@ -4890,20 +4859,20 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
// passed to uDNS_CheckCurrentQuestion -- we only want one set of query packets hitting the wire --
// but we want *all* of the questions to get answer callbacks.)
CacheRecord *rr;
- const mDNSu32 slot = HashSlot(&q->qname);
- CacheGroup *const cg = CacheGroupForName(m, slot, q->qnamehash, &q->qname);
+ const mDNSu32 slot = HashSlotFromNameHash(q->qnamehash);
+ CacheGroup *const cg = CacheGroupForName(m, q->qnamehash, &q->qname);
if (!q->qDNSServer)
{
- if (!mDNSOpaque64IsZero(&q->validDNSServers))
- LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x for question %##s (%s)",
- q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
+ if (!mDNSOpaque128IsZero(&q->validDNSServers))
+ LogMsg("uDNS_CheckCurrentQuestion: ERROR!!: valid DNSServer bits not zero 0x%x, 0x%x 0x%x 0x%x for question %##s (%s)",
+ q->validDNSServers.l[3], q->validDNSServers.l[2], q->validDNSServers.l[1], q->validDNSServers.l[0], q->qname.c, DNSTypeName(q->qtype));
// If we reached the end of list while picking DNS servers, then we don't want to deactivate the
// question. Try after 60 seconds. We find this by looking for valid DNSServers for this question,
// if we find any, then we must have tried them before we came here. This avoids maintaining
// another state variable to see if we had valid DNS servers for this question.
SetValidDNSServers(m, q);
- if (mDNSOpaque64IsZero(&q->validDNSServers))
+ if (mDNSOpaque128IsZero(&q->validDNSServers))
{
LogInfo("uDNS_CheckCurrentQuestion: no DNS server for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->ThisQInterval = 0;
@@ -4922,12 +4891,9 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
q->qDNSServer = GetServerForQuestion(m, q);
for (qptr = q->next ; qptr; qptr = qptr->next)
if (qptr->DuplicateOf == q) { qptr->validDNSServers = q->validDNSServers; qptr->qDNSServer = q->qDNSServer; }
- {
- mDNSIPPort zp = zeroIPPort;
- LogInfo("uDNS_checkCurrentQuestion: Tried all DNS servers, retry question %p SuppressUnusable %d %##s (%s) with DNS Server %#a:%d after 60 seconds, ThisQInterval %d",
+ LogInfo("uDNS_checkCurrentQuestion: Tried all DNS servers, retry question %p SuppressUnusable %d %##s (%s) with DNS Server %#a:%d after 60 seconds, ThisQInterval %d",
q, q->SuppressUnusable, q->qname.c, DNSTypeName(q->qtype),
- q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zp), q->ThisQInterval);
- }
+ q->qDNSServer ? &q->qDNSServer->addr : mDNSNULL, mDNSVal16(q->qDNSServer ? q->qDNSServer->port : zeroIPPort), q->ThisQInterval);
}
}
else
@@ -4942,7 +4908,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
{
if (SameNameRecordAnswersQuestion(&rr->resrec, q))
{
- LogInfo("uDNS_CheckCurrentQuestion: Purged resourcerecord %s", CRDisplayString(m, rr));
+ LogInfo("uDNS_CheckCurrentQuestion: Purged resourcerecord %s", CRDisplayString(m, rr));
mDNS_PurgeCacheResourceRecord(m, rr);
}
}
@@ -4970,7 +4936,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
{
mDNSBool rfc1918 = mDNSv4AddrIsRFC1918(&m->AdvertisedV4.ip.v4);
mDNSBool HaveRoutable = !rfc1918 && !mDNSIPv4AddressIsZero(m->AdvertisedV4.ip.v4);
- m->NextScheduledNATOp = m->timenow + 0x3FFFFFFF;
+ m->NextScheduledNATOp = m->timenow + FutureTime;
if (HaveRoutable) m->ExtAddress = m->AdvertisedV4.ip.v4;
@@ -4980,7 +4946,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
{
// we need to log a message if we can't get our socket, but only the first time (after success)
static mDNSBool needLog = mDNStrue;
- m->NATMcastRecvskt = mDNSPlatformUDPSocket(m, NATPMPAnnouncementPort);
+ m->NATMcastRecvskt = mDNSPlatformUDPSocket(NATPMPAnnouncementPort);
if (!m->NATMcastRecvskt)
{
if (needLog)
@@ -5025,7 +4991,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
cur->retryInterval = NATMAP_INIT_RETRY;
}
- (void)uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
+ uDNS_SendNATMsg(m, cur, mDNStrue); // Will also do UPnP discovery for us, if necessary
if (cur->ExpiryTime) // If have active mapping then set next renewal time halfway to expiry
NATSetNextRenewalTime(m, cur);
@@ -5062,14 +5028,8 @@ mDNSexport void CheckNATMappings(mDNS *m)
if (!mDNSIPv4AddressIsZero(EffectiveAddress) || cur->retryInterval > NATMAP_INIT_RETRY * 8)
{
const mStatus EffectiveResult = cur->NewResult ? cur->NewResult : mDNSv4AddrIsRFC1918(&EffectiveAddress) ? mStatus_DoubleNAT : mStatus_NoError;
- mDNSIPPort ExternalPort;
-
- if (HaveRoutable)
- ExternalPort = cur->IntPort;
- else if (!mDNSIPv4AddressIsZero(EffectiveAddress) && cur->ExpiryTime)
- ExternalPort = cur->RequestedPort;
- else
- ExternalPort = zeroIPPort;
+ const mDNSIPPort ExternalPort = HaveRoutable ? cur->IntPort :
+ !mDNSIPv4AddressIsZero(EffectiveAddress) && cur->ExpiryTime ? cur->RequestedPort : zeroIPPort;
if (!cur->Protocol || HaveRoutable || cur->ExpiryTime || cur->retryInterval > NATMAP_INIT_RETRY * 8)
{
@@ -5107,7 +5067,7 @@ mDNSexport void CheckNATMappings(mDNS *m)
mDNSlocal mDNSs32 CheckRecordUpdates(mDNS *m)
{
AuthRecord *rr;
- mDNSs32 nextevent = m->timenow + 0x3FFFFFFF;
+ mDNSs32 nextevent = m->timenow + FutureTime;
CheckGroupRecordUpdates(m);
@@ -5165,7 +5125,7 @@ mDNSexport void uDNS_Tasks(mDNS *const m)
mDNSs32 nexte;
DNSServer *d;
- m->NextuDNSEvent = m->timenow + 0x3FFFFFFF;
+ m->NextuDNSEvent = m->timenow + FutureTime;
nexte = CheckRecordUpdates(m);
if (m->NextuDNSEvent - nexte > 0)
@@ -5358,8 +5318,8 @@ mDNSexport void udns_validatelists(void *const v)
DNSServer *d;
for (d = m->DNSServers; d; d=d->next)
- if (d->next == (DNSServer *)~0 || d->teststate > DNSServer_Disabled)
- LogMemCorruption("m->DNSServers: %p is garbage (%d)", d, d->teststate);
+ if (d->next == (DNSServer *)~0)
+ LogMemCorruption("m->DNSServers: %p is garbage", d);
DomainAuthInfo *info;
for (info = m->AuthInfoList; info; info = info->next)
@@ -5460,7 +5420,7 @@ mDNSexport void uDNS_SetupWABQueries(mDNS *const m)
// Make sure we have the search domains from the platform layer so that if we start the WAB
// queries below, we have the latest information.
mDNS_Lock(m);
- if (!mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
+ if (!mDNSPlatformSetDNSConfig(mDNSfalse, mDNStrue, mDNSNULL, mDNSNULL, mDNSNULL, mDNSfalse))
{
// If the configuration did not change, clear the flag so that we don't free the searchlist.
// We still have to start the domain enumeration queries as we may not have started them
@@ -5708,11 +5668,10 @@ mDNSexport void uDNS_StopWABQueries(mDNS *const m, int queryType)
uDNS_SetupWABQueries(m);
}
-mDNSexport domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
{
SearchListElem *p = SearchList;
int count = *searchIndex;
- (void) m; // unused
if (count < 0) { LogMsg("uDNS_GetNextSearchDomain: count %d less than zero", count); return mDNSNULL; }
@@ -5831,101 +5790,335 @@ struct CompileTimeAssertionChecks_uDNS
char sizecheck_SearchListElem[(sizeof(SearchListElem) <= 5000) ? 1 : -1];
};
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark - DNS Push Notification functions
+#endif
+
+#ifdef DNS_PUSH_ENABLED
+mDNSlocal tcpInfo_t * GetTCPConnectionToPushServer(mDNS *m, DNSQuestion *q)
+{
+ DNSPushNotificationZone *zone;
+ DNSPushNotificationServer *server;
+ DNSPushNotificationZone *newZone;
+ DNSPushNotificationServer *newServer;
+
+ // If we already have a question for this zone and if the server is the same, reuse it
+ for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
+ {
+ if (SameDomainName(&q->nta->ChildName, &zone->zoneName))
+ {
+ DNSPushNotificationServer *zoneServer = mDNSNULL;
+ for (zoneServer = zone->servers; zoneServer != mDNSNULL; zoneServer = zoneServer->next)
+ {
+ if (mDNSSameAddress(&q->dnsPushServerAddr, &zoneServer->serverAddr))
+ {
+ zone->numberOfQuestions++;
+ zoneServer->numberOfQuestions++;
+ return zoneServer->connection;
+ }
+ }
+ }
+ }
+
+ // If we have a connection to this server but it is for a differnt zone, create a new zone entry and reuse the connection
+ for (server = m->DNSPushServers; server != mDNSNULL; server = server->next)
+ {
+ if (mDNSSameAddress(&q->dnsPushServerAddr, &server->serverAddr))
+ {
+ newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+ newZone->numberOfQuestions = 1;
+ newZone->zoneName = q->nta->ChildName;
+ newZone->servers = server;
+
+ // Add the new zone to the begining of the list
+ newZone->next = m->DNSPushZones;
+ m->DNSPushZones = newZone;
+
+ server->numberOfQuestions++;
+ return server->connection;
+ }
+ }
+
+ // If we do not have any existing connections, create a new connection
+ newServer = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationServer));
+ newZone = mDNSPlatformMemAllocate(sizeof(DNSPushNotificationZone));
+
+ newServer->numberOfQuestions = 1;
+ newServer->serverAddr = q->dnsPushServerAddr;
+ newServer->connection = MakeTCPConn(m, mDNSNULL, mDNSNULL, kTCPSocketFlags_UseTLS, &q->dnsPushServerAddr, q->dnsPushServerPort, &q->nta->Host, q, mDNSNULL);
+
+ newZone->numberOfQuestions = 1;
+ newZone->zoneName = q->nta->ChildName;
+ newZone->servers = newServer;
+
+ // Add the new zone to the begining of the list
+ newZone->next = m->DNSPushZones;
+ m->DNSPushZones = newZone;
+
+ newServer->next = m->DNSPushServers;
+ m->DNSPushServers = newServer;
+ return newServer->connection;
+}
+
+mDNSexport void DiscoverDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ /* Use the same NAT setup as in the LLQ case */
+ if (m->LLQNAT.clientContext != mDNSNULL) // LLQNAT just started, give it some time
+ {
+ LogInfo("startLLQHandshake: waiting for NAT status for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10); // Retry in approx 15 minutes
+ q->LastQTime = m->timenow;
+ SetNextQueryTime(m, q);
+ return;
+ }
+
+ // Either we don't have {PCP, NAT-PMP, UPnP/IGD} support (ExternalPort is zero) or behind a Double NAT that may or
+ // may not have {PCP, NAT-PMP, UPnP/IGD} support (NATResult is non-zero)
+ if (mDNSIPPortIsZero(m->LLQNAT.ExternalPort) || m->LLQNAT.Result)
+ {
+ LogInfo("startLLQHandshake: Cannot receive inbound packets; will poll for %##s (%s) External Port %d, NAT Result %d",
+ q->qname.c, DNSTypeName(q->qtype), mDNSVal16(m->LLQNAT.ExternalPort), m->LLQNAT.Result);
+ StartLLQPolling(m, q); // Actually sets up the NAT Auto Tunnel
+ return;
+ }
+
+ if (mDNSIPPortIsZero(q->dnsPushServerPort) && q->dnsPushState == DNSPUSH_INIT)
+ {
+ LogInfo("SubscribeToDNSPushNotificationServer: StartGetZoneData for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ q->ThisQInterval = LLQ_POLL_INTERVAL + mDNSRandom(LLQ_POLL_INTERVAL/10); // Retry in approx 15 minutes
+ q->LastQTime = m->timenow;
+ SetNextQueryTime(m, q);
+ q->dnsPushServerAddr = zeroAddr;
+ // We know q->dnsPushServerPort is zero because of check above
+ if (q->nta) CancelGetZoneData(m, q->nta);
+ q->nta = StartGetZoneData(m, &q->qname, ZoneServiceDNSPush, DNSPushNotificationGotZoneData, q);
+ return;
+ }
+
+ if (q->tcp)
+ {
+ LogInfo("SubscribeToDNSPushNotificationServer: Disposing existing TCP connection for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ DisposeTCPConn(q->tcp);
+ q->tcp = mDNSNULL;
+ }
+
+ if (!q->nta)
+ {
+ // Normally we lookup the zone data and then call this function. And we never free the zone data
+ // for "PrivateQuery". But sometimes this can happen due to some race conditions. When we
+ // switch networks, we might end up "Polling" the network e.g., we are behind a Double NAT.
+ // When we poll, we free the zone information as we send the query to the server (See
+ // PrivateQueryGotZoneData). The NAT callback (LLQNATCallback) may happen soon after that. If we
+ // are still behind Double NAT, we would have returned early in this function. But we could
+ // have switched to a network with no NATs and we should get the zone data again.
+ LogInfo("SubscribeToDNSPushNotificationServer: nta is NULL for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+ q->nta = StartGetZoneData(m, &q->qname, ZoneServiceDNSPush, DNSPushNotificationGotZoneData, q);
+ return;
+ }
+ else if (!q->nta->Host.c[0])
+ {
+ // This should not happen. If it happens, we print a log and MakeTCPConn will fail if it can't find a hostname
+ LogMsg("SubscribeToDNSPushNotificationServer: ERROR!!: nta non NULL for %##s (%s) but HostName %d NULL, LongLived %d", q->qname.c, DNSTypeName(q->qtype), q->nta->Host.c[0], q->LongLived);
+ }
+ q->tcp = GetTCPConnectionToPushServer(m,q);
+ // If TCP failed (transient networking glitch) try again in five seconds
+ q->ThisQInterval = (q->tcp != mDNSNULL) ? q->ThisQInterval = 0 : (mDNSPlatformOneSecond * 5);
+ q->LastQTime = m->timenow;
+ SetNextQueryTime(m, q);
+}
+
+
+mDNSexport void SubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ mDNSu8 *end = mDNSNULL;
+ InitializeDNSMessage(&m->omsg.h, zeroID, SubscribeFlags);
+ end = putQuestion(&m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
+ if (!end)
+ {
+ LogMsg("ERROR: SubscribeToDNSPushNotificationServer putQuestion failed");
+ return;
+ }
+
+ mDNSSendDNSMessage(m, &m->omsg, end, mDNSInterface_Any, q->LocalSocket, &q->dnsPushServerAddr, q->dnsPushServerPort, q->tcp->sock, mDNSNULL, mDNSfalse);
+
+ // update question state
+ q->dnsPushState = DNSPUSH_ESTABLISHED;
+ q->ThisQInterval = (kLLQ_INIT_RESEND * mDNSPlatformOneSecond);
+ q->LastQTime = m->timenow;
+ SetNextQueryTime(m, q);
+
+}
+
+mDNSlocal void reconcileDNSPushConnection(mDNS *m, DNSQuestion *q)
+{
+ DNSPushNotificationZone *zone;
+ DNSPushNotificationServer *server;
+ DNSPushNotificationServer *nextServer;
+ DNSPushNotificationZone *nextZone;
+
+ // Update the counts
+ for (zone = m->DNSPushZones; zone != mDNSNULL; zone = zone->next)
+ {
+ if (SameDomainName(&zone->zoneName, &q->nta->ChildName))
+ {
+ zone->numberOfQuestions--;
+ for (server = zone->servers; server != mDNSNULL; server = server->next)
+ {
+ if (mDNSSameAddress(&server->serverAddr, &q->dnsPushServerAddr))
+ server->numberOfQuestions--;
+ }
+ }
+ }
+
+ // Now prune the lists
+ server = m->DNSPushServers;
+ nextServer = mDNSNULL;
+ while(server != mDNSNULL)
+ {
+ nextServer = server->next;
+ if (server->numberOfQuestions <= 0)
+ {
+ DisposeTCPConn(server->connection);
+ if (server == m->DNSPushServers)
+ m->DNSPushServers = nextServer;
+ mDNSPlatformMemFree(server);
+ server = nextServer;
+ }
+ else server = server->next;
+ }
+
+ zone = m->DNSPushZones;
+ nextZone = mDNSNULL;
+ while(zone != mDNSNULL)
+ {
+ nextZone = zone->next;
+ if (zone->numberOfQuestions <= 0)
+ {
+ if (zone == m->DNSPushZones)
+ m->DNSPushZones = nextZone;
+ mDNSPlatformMemFree(zone);
+ zone = nextZone;
+ }
+ else zone = zone->next;
+ }
+
+}
+
+mDNSexport void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ mDNSu8 *end = mDNSNULL;
+ InitializeDNSMessage(&m->omsg.h, q->TargetQID, UnSubscribeFlags);
+ end = putQuestion(&m->omsg, end, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
+ if (!end)
+ {
+ LogMsg("ERROR: UnSubscribeToDNSPushNotificationServer - putQuestion failed");
+ return;
+ }
+
+ mDNSSendDNSMessage(m, &m->omsg, end, mDNSInterface_Any, q->LocalSocket, &q->dnsPushServerAddr, q->dnsPushServerPort, q->tcp->sock, mDNSNULL, mDNSfalse);
+
+ reconcileDNSPushConnection(m, q);
+}
+
+#endif // DNS_PUSH_ENABLED
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#endif
#else // !UNICAST_DISABLED
mDNSexport const domainname *GetServiceTarget(mDNS *m, AuthRecord *const rr)
{
- (void) m;
- (void) rr;
+ (void) m;
+ (void) rr;
- return mDNSNULL;
+ return mDNSNULL;
}
mDNSexport DomainAuthInfo *GetAuthInfoForName_internal(mDNS *m, const domainname *const name)
{
- (void) m;
- (void) name;
+ (void) m;
+ (void) name;
- return mDNSNULL;
+ return mDNSNULL;
}
mDNSexport DomainAuthInfo *GetAuthInfoForQuestion(mDNS *m, const DNSQuestion *const q)
{
- (void) m;
- (void) q;
+ (void) m;
+ (void) q;
- return mDNSNULL;
+ return mDNSNULL;
}
mDNSexport void startLLQHandshake(mDNS *m, DNSQuestion *q)
{
- (void) m;
- (void) q;
+ (void) m;
+ (void) q;
}
mDNSexport void DisposeTCPConn(struct tcpInfo_t *tcp)
{
- (void) tcp;
+ (void) tcp;
}
mDNSexport mStatus mDNS_StartNATOperation_internal(mDNS *m, NATTraversalInfo *traversal)
{
- (void) m;
- (void) traversal;
+ (void) m;
+ (void) traversal;
- return mStatus_UnsupportedErr;
+ return mStatus_UnsupportedErr;
}
mDNSexport mStatus mDNS_StopNATOperation_internal(mDNS *m, NATTraversalInfo *traversal)
{
- (void) m;
- (void) traversal;
+ (void) m;
+ (void) traversal;
- return mStatus_UnsupportedErr;
+ return mStatus_UnsupportedErr;
}
mDNSexport void sendLLQRefresh(mDNS *m, DNSQuestion *q)
{
- (void) m;
- (void) q;
+ (void) m;
+ (void) q;
}
mDNSexport ZoneData *StartGetZoneData(mDNS *const m, const domainname *const name, const ZoneService target, ZoneDataCallback callback, void *ZoneDataContext)
{
- (void) m;
- (void) name;
- (void) target;
- (void) callback;
- (void) ZoneDataContext;
+ (void) m;
+ (void) name;
+ (void) target;
+ (void) callback;
+ (void) ZoneDataContext;
- return mDNSNULL;
+ return mDNSNULL;
}
mDNSexport void RecordRegistrationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneData)
{
- (void) m;
- (void) err;
- (void) zoneData;
+ (void) m;
+ (void) err;
+ (void) zoneData;
}
mDNSexport uDNS_LLQType uDNS_recvLLQResponse(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport, DNSQuestion **matchQuestion)
{
- (void) m;
- (void) msg;
- (void) end;
- (void) srcaddr;
- (void) srcport;
- (void) matchQuestion;
+ (void) m;
+ (void) msg;
+ (void) end;
+ (void) srcaddr;
+ (void) srcport;
+ (void) matchQuestion;
- return uDNS_LLQ_Not;
+ return uDNS_LLQ_Not;
}
mDNSexport void PenalizeDNSServer(mDNS *const m, DNSQuestion *q, mDNSOpaque16 responseFlags)
{
- (void) m;
- (void) q;
- (void) responseFlags;
+ (void) m;
+ (void) q;
+ (void) responseFlags;
}
mDNSexport void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID)
@@ -5949,17 +6142,16 @@ mDNSexport mStatus mDNS_SetSecretForDomain(mDNS *m, DomainAuthInfo *info, const
(void) hostname;
(void) port;
(void) autoTunnel;
-
+
return mStatus_UnsupportedErr;
}
-mDNSexport domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
+mDNSexport domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal)
{
- (void) m;
(void) InterfaceID;
(void) searchIndex;
(void) ignoreDotLocal;
-
+
return mDNSNULL;
}
@@ -5967,7 +6159,7 @@ mDNSexport DomainAuthInfo *GetAuthInfoForName(mDNS *m, const domainname *const n
{
(void) m;
(void) name;
-
+
return mDNSNULL;
}
@@ -5975,7 +6167,7 @@ mDNSexport mStatus mDNS_StartNATOperation(mDNS *const m, NATTraversalInfo *trave
{
(void) m;
(void) traversal;
-
+
return mStatus_UnsupportedErr;
}
@@ -5983,13 +6175,13 @@ mDNSexport mStatus mDNS_StopNATOperation(mDNS *const m, NATTraversalInfo *traver
{
(void) m;
(void) traversal;
-
+
return mStatus_UnsupportedErr;
}
mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSs32 serviceID, const mDNSAddr *addr,
- const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA,
- mDNSBool reqAAAA, mDNSBool reqDO)
+ const mDNSIPPort port, mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID,
+ mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO)
{
(void) m;
(void) d;
@@ -6000,11 +6192,12 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
(void) scoped;
(void) timeout;
(void) cellIntf;
+ (void) isExpensive;
(void) resGroupID;
(void) reqA;
(void) reqAAAA;
(void) reqDO;
-
+
return mDNSNULL;
}
@@ -6055,8 +6248,26 @@ mDNSexport void RecreateNATMappings(mDNS *const m, const mDNSu32 waitTicks)
mDNSexport mDNSBool IsGetZoneDataQuestion(DNSQuestion *q)
{
(void)q;
-
+
return mDNSfalse;
}
+mDNSexport void SubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ (void)m;
+ (void)q;
+}
+
+mDNSexport void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ (void)m;
+ (void)q;
+}
+
+mDNSexport void DiscoverDNSPushNotificationServer(mDNS *m, DNSQuestion *q)
+{
+ (void)m;
+ (void)q;
+}
+
#endif // !UNICAST_DISABLED
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.h b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h
index eca8b70152..90f50a6fc1 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uDNS.h
+++ b/usr/src/contrib/mDNSResponder/mDNSCore/uDNS.h
@@ -47,9 +47,8 @@ extern "C" {
#define QuestionIntervalStep3 (QuestionIntervalStep*QuestionIntervalStep*QuestionIntervalStep)
#define InitialQuestionInterval ((mDNSPlatformOneSecond + QuestionIntervalStep-1) / QuestionIntervalStep)
#define MaxQuestionInterval (3600 * mDNSPlatformOneSecond)
-
-// just move to MaxQuestionInterval once over this threshold
-#define QuestionIntervalThreshold (QuestionIntervalStep3 * mDNSPlatformOneSecond)
+#define UDNSBackOffMultiplier 2
+#define MinQuestionInterval (1 * mDNSPlatformOneSecond)
// For Unicast record registrations, we initialize the interval to 1 second. When we send any query for
// the record registration e.g., GetZoneData, we always back off by QuestionIntervalStep
@@ -82,6 +81,11 @@ extern void LLQGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo)
extern void startLLQHandshake(mDNS *m, DNSQuestion *q);
extern void sendLLQRefresh(mDNS *m, DNSQuestion *q);
+extern void DNSPushNotificationGotZoneData(mDNS *const m, mStatus err, const ZoneData *zoneInfo);
+extern void DiscoverDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
+extern void SubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
+extern void UnSubscribeToDNSPushNotificationServer(mDNS *m, DNSQuestion *q);
+
extern void SleepRecordRegistrations(mDNS *m);
// uDNS_UpdateRecord
@@ -124,7 +128,7 @@ extern mStatus uDNS_SetupDNSConfig(mDNS *const m);
extern void uDNS_SetupWABQueries(mDNS *const m);
extern void uDNS_StartWABQueries(mDNS *const m, int queryType);
extern void uDNS_StopWABQueries(mDNS *const m, int queryType);
-extern domainname *uDNS_GetNextSearchDomain(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
+extern domainname *uDNS_GetNextSearchDomain(mDNSInterfaceID InterfaceID, mDNSs8 *searchIndex, mDNSBool ignoreDotLocal);
typedef enum
{
@@ -144,8 +148,12 @@ extern void uDNS_ReceiveNATPacket(mDNS *m, const mDNSInterfaceID InterfaceID, mD
extern void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr);
extern void natTraversalHandlePortMapReply(mDNS *const m, NATTraversalInfo *n, const mDNSInterfaceID InterfaceID, mDNSu16 err, mDNSIPPort extport, mDNSu32 lease, NATTProtocol protocol);
+// DNS Push Notification
+extern void SubscribeToDNSPushNotification(mDNS *m, DNSQuestion *q);
+
+
#ifdef __cplusplus
}
#endif
-#endif // __UDNS_H_
+#endif // __UDNS_H
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c b/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c
index 55edb0475d..26477da593 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PosixDaemon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/PosixDaemon.c
@@ -132,11 +132,11 @@ mDNSlocal void ToggleLogPacket(void)
mDNS_PacketLoggingEnabled = !mDNS_PacketLoggingEnabled;
}
-mDNSlocal void DumpStateLog(mDNS *const m)
+mDNSlocal void DumpStateLog()
// Dump a little log of what we've been up to.
{
- LogMsg("---- BEGIN STATE LOG ----");
- udsserver_info(m);
+ LogMsg("---- BEGIN STATE LOG ----");
+ udsserver_info();
LogMsg("---- END STATE LOG ----");
}
@@ -176,7 +176,7 @@ mDNSlocal mStatus MainLoop(mDNS *m) // Loop until we quit.
(void) mDNSPosixRunEventLoopOnce(m, &timeout, &signals, &gotData);
if (sigismember(&signals, SIGHUP )) Reconfigure(m);
- if (sigismember(&signals, SIGINFO)) DumpStateLog(m);
+ if (sigismember(&signals, SIGINFO)) DumpStateLog();
if (sigismember(&signals, SIGUSR1)) ToggleLog();
if (sigismember(&signals, SIGUSR2)) ToggleLogPacket();
// SIGPIPE happens when we try to write to a dead client; death should be detected soon in request_callback() and cleaned up.
@@ -260,9 +260,8 @@ mStatus udsSupportRemoveFDFromEventLoop(int fd, void *platform_data) // N
return err;
}
-mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
+mDNSexport void RecordUpdatedNiceLabel(mDNSs32 delay)
{
- (void)m;
(void)delay;
// No-op, for now
}
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c
index f16e82044a..b9c3cd58eb 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.c
@@ -52,6 +52,7 @@
#include "mDNSUNP.h"
#include "GenLinkedList.h"
+#include "dnsproxy.h"
// ***************************************************************************
// Structures
@@ -138,7 +139,7 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA
// mDNS core calls this routine when it needs to send a packet.
mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
- mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
+ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass)
{
int err = 0;
@@ -314,16 +315,8 @@ mDNSlocal void SocketDataReady(mDNS *const m, PosixNetworkInterface *intf, int s
&senderAddr, senderPort, &destAddr, MulticastDNSPort, InterfaceID);
}
-mDNSexport mDNSBool mDNSPlatformPeekUDP(mDNS *const m, UDPSocket *src)
+mDNSexport TCPSocket *mDNSPlatformTCPSocket(TCPSocketFlags flags, mDNSIPPort * port, mDNSBool useBackgroundTrafficClass)
{
- (void)m; // unused
- (void)src; // unused
- return mDNSfalse;
-}
-
-mDNSexport TCPSocket *mDNSPlatformTCPSocket(mDNS * const m, TCPSocketFlags flags, mDNSIPPort * port, mDNSBool useBackgroundTrafficClass)
-{
- (void)m; // Unused
(void)flags; // Unused
(void)port; // Unused
(void)useBackgroundTrafficClass; // Unused
@@ -378,9 +371,8 @@ mDNSexport long mDNSPlatformWriteTCP(TCPSocket *sock, const char *msg, unsigned
return 0;
}
-mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNS * const m, mDNSIPPort port)
+mDNSexport UDPSocket *mDNSPlatformUDPSocket(mDNSIPPort port)
{
- (void)m; // Unused
(void)port; // Unused
return NULL;
}
@@ -390,9 +382,8 @@ mDNSexport void mDNSPlatformUDPClose(UDPSocket *sock)
(void)sock; // Unused
}
-mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
+mDNSexport void mDNSPlatformUpdateProxyList(const mDNSInterfaceID InterfaceID)
{
- (void)m; // Unused
(void)InterfaceID; // Unused
}
@@ -403,9 +394,8 @@ mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *c
(void)InterfaceID; // Unused
}
-mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
+mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
{
- (void)m; // Unused
(void)tpa; // Unused
(void)tha; // Unused
(void)InterfaceID; // Unused
@@ -420,9 +410,8 @@ mDNSexport void mDNSPlatformTLSTearDownCerts(void)
{
}
-mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)
+mDNSexport void mDNSPlatformSetAllowSleep(mDNSBool allowSleep, const char *reason)
{
- (void) m;
(void) allowSleep;
(void) reason;
}
@@ -445,13 +434,12 @@ mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result
#endif
/*
- * Stub to set or get DNS config. Even if it actually does not do anything, it has to
- * make sure the data is zeroed properly.
+ * Stub to set or get DNS config. Even if it actually does not do anything,
+ * it has to make sure the data is zeroed properly.
*/
-mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
+mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **RegDomains,
DNameListElem **BrowseDomains, mDNSBool ackConfig)
{
- (void) m;
(void) setservers;
if (fqdn) fqdn->c[0] = 0;
(void) setsearch;
@@ -462,9 +450,8 @@ mDNSexport mDNSBool mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers,
return mDNStrue;
}
-mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router)
+mDNSexport mStatus mDNSPlatformGetPrimaryInterface(mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router)
{
- (void) m;
(void) v4;
(void) v6;
(void) router;
@@ -519,7 +506,7 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
mDNSAddr DNSAddr;
DNSAddr.type = mDNSAddrType_IPv4;
DNSAddr.ip.v4.NotAnInteger = ina.s_addr;
- mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
+ mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, 0, &DNSAddr, UnicastDNSPort, kScopeNone, 0, mDNSfalse, mDNSfalse, 0, mDNStrue, mDNStrue, mDNSfalse);
numOfServers++;
}
}
@@ -589,11 +576,20 @@ mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNS
// interface must have already been deregistered with the mDNS core.
mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
{
+ int rv;
assert(intf != NULL);
if (intf->intfName != NULL) free((void *)intf->intfName);
- if (intf->multicastSocket4 != -1) assert(close(intf->multicastSocket4) == 0);
+ if (intf->multicastSocket4 != -1)
+ {
+ rv = close(intf->multicastSocket4);
+ assert(rv == 0);
+ }
#if HAVE_IPV6
- if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0);
+ if (intf->multicastSocket6 != -1)
+ {
+ rv = close(intf->multicastSocket6);
+ assert(rv == 0);
+ }
#endif
// Move interface to the RecentInterfaces list for a minute
@@ -610,7 +606,7 @@ mDNSlocal void ClearInterfaceList(mDNS *const m)
while (m->HostInterfaces)
{
PosixNetworkInterface *intf = (PosixNetworkInterface*)(m->HostInterfaces);
- mDNS_DeregisterInterface(m, &intf->coreIntf, mDNSfalse);
+ mDNS_DeregisterInterface(m, &intf->coreIntf, NormalActivation);
if (gMDNSPlatformPosixVerboseLevel > 0) fprintf(stderr, "Deregistered interface %s\n", intf->intfName);
FreePosixNetworkInterface(intf);
}
@@ -671,9 +667,9 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
// Enable inbound packets on IFEF_AWDL interface.
// Only done for multicast sockets, since we don't expect unicast socket operations
// on the IFEF_AWDL interface. Operation is a no-op for other interface types.
- #ifdef SO_RECV_ANYIF
+ #ifdef SO_RECV_ANYIF
if (setsockopt(*sktPtr, SOL_SOCKET, SO_RECV_ANYIF, &kOn, sizeof(kOn)) < 0) perror("setsockopt - SO_RECV_ANYIF");
- #endif
+ #endif
}
// We want to receive destination addresses and interface identifiers.
@@ -775,11 +771,11 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
#warning This platform has no way to get the destination interface information for IPv6 -- will only work for single-homed hosts
#endif
#if defined(IPV6_RECVHOPLIMIT)
- if (err == 0)
- {
- err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &kOn, sizeof(kOn));
- if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVHOPLIMIT"); }
- }
+ if (err == 0)
+ {
+ err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &kOn, sizeof(kOn));
+ if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVHOPLIMIT"); }
+ }
#elif defined(IPV6_HOPLIMIT)
if (err == 0)
{
@@ -867,7 +863,13 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
}
// Clean up
- if (err != 0 && *sktPtr != -1) { assert(close(*sktPtr) == 0); *sktPtr = -1; }
+ if (err != 0 && *sktPtr != -1)
+ {
+ int rv;
+ rv = close(*sktPtr);
+ assert(rv == 0);
+ *sktPtr = -1;
+ }
assert((err == 0) == (*sktPtr != -1));
return err;
}
@@ -938,14 +940,14 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
// and skip the probe phase of the probe/announce packet sequence.
intf->coreIntf.DirectLink = mDNSfalse;
#ifdef DIRECTLINK_INTERFACE_NAME
- if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
- intf->coreIntf.DirectLink = mDNStrue;
+ if (strcmp(intfName, STRINGIFY(DIRECTLINK_INTERFACE_NAME)) == 0)
+ intf->coreIntf.DirectLink = mDNStrue;
#endif
intf->coreIntf.SupportsUnicastMDNSResponse = mDNStrue;
// The interface is all ready to go, let's register it with the mDNS core.
if (err == 0)
- err = mDNS_RegisterInterface(m, &intf->coreIntf, mDNSfalse);
+ err = mDNS_RegisterInterface(m, &intf->coreIntf, NormalActivation);
// Clean up.
if (err == 0)
@@ -1218,10 +1220,10 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd)
*/
case RTM_ADD:
case RTM_DELETE:
- if (pRSMsg->ifam_type == RTM_IFINFO)
- result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
- else
- result |= 1 << pRSMsg->ifam_index;
+ if (pRSMsg->ifam_type == RTM_IFINFO)
+ result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index;
+ else
+ result |= 1 << pRSMsg->ifam_index;
break;
}
@@ -1339,8 +1341,7 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
// Failure to observe interface changes is non-fatal.
if (err != mStatus_NoError)
{
- fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n",
- (int)getpid(), err);
+ fprintf(stderr, "mDNS(%d) WARNING: Unable to detect interface changes (%d).\n", getpid(), err);
err = mStatus_NoError;
}
}
@@ -1358,11 +1359,20 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
// In our case all we need to do is to tear down every network interface.
mDNSexport void mDNSPlatformClose(mDNS *const m)
{
+ int rv;
assert(m != NULL);
ClearInterfaceList(m);
- if (m->p->unicastSocket4 != -1) assert(close(m->p->unicastSocket4) == 0);
+ if (m->p->unicastSocket4 != -1)
+ {
+ rv = close(m->p->unicastSocket4);
+ assert(rv == 0);
+ }
#if HAVE_IPV6
- if (m->p->unicastSocket6 != -1) assert(close(m->p->unicastSocket6) == 0);
+ if (m->p->unicastSocket6 != -1)
+ {
+ rv = close(m->p->unicastSocket6);
+ assert(rv == 0);
+ }
#endif
}
@@ -1409,14 +1419,36 @@ mDNSexport void mDNSPlatformUnlock (const mDNS *const m)
// On the Posix platform this maps directly to the ANSI C strcpy.
mDNSexport void mDNSPlatformStrCopy(void *dst, const void *src)
{
- strcpy((char *)dst, (char *)src);
+ strcpy((char *)dst, (const char *)src);
+}
+
+mDNSexport mDNSu32 mDNSPlatformStrLCopy(void *dst, const void *src, mDNSu32 len)
+{
+#if HAVE_STRLCPY
+ return ((mDNSu32)strlcpy((char *)dst, (const char *)src, len));
+#else
+ size_t srcLen;
+
+ srcLen = strlen((const char *)src);
+ if (srcLen < len)
+ {
+ memcpy(dst, src, srcLen + 1);
+ }
+ else if (len > 0)
+ {
+ memcpy(dst, src, len - 1);
+ ((char *)dst)[len - 1] = '\0';
+ }
+
+ return ((mDNSu32)srcLen);
+#endif
}
// mDNS core calls this routine to get the length of a C string.
// On the Posix platform this maps directly to the ANSI C strlen.
mDNSexport mDNSu32 mDNSPlatformStrLen (const void *src)
{
- return strlen((char*)src);
+ return strlen((const char*)src);
}
// mDNS core calls this routine to copy memory.
@@ -1482,16 +1514,14 @@ mDNSexport mDNSu8 *DNSProxySetAttributes(DNSQuestion *q, DNSMessageHeader *h, DN
return ptr;
}
-mDNSexport void DNSProxyInit(mDNS *const m, mDNSu32 IpIfArr[], mDNSu32 OpIf)
+mDNSexport void DNSProxyInit(mDNSu32 IpIfArr[], mDNSu32 OpIf)
{
- (void) m;
(void) IpIfArr;
(void) OpIf;
}
-mDNSexport void DNSProxyTerminate(mDNS *const m)
+mDNSexport void DNSProxyTerminate(void)
{
- (void) m;
}
// mDNS core calls this routine to clear blocks of memory.
@@ -1504,12 +1534,19 @@ mDNSexport void mDNSPlatformMemZero(void *dst, mDNSu32 len)
mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(malloc(len)); }
mDNSexport void mDNSPlatformMemFree (void *mem) { free(mem); }
+#if _PLATFORM_HAS_STRONG_PRNG_
+mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
+{
+ return(arc4random());
+}
+#else
mDNSexport mDNSu32 mDNSPlatformRandomSeed(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec);
}
+#endif
mDNSexport mDNSs32 mDNSPlatformOneSecond = 1024;
@@ -1539,19 +1576,18 @@ mDNSexport mDNSs32 mDNSPlatformUTC(void)
return time(NULL);
}
-mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
+mDNSexport void mDNSPlatformSendWakeupPacket(mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
{
- (void) m;
(void) InterfaceID;
(void) EthAddr;
(void) IPAddr;
(void) iteration;
}
-mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
+mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(const AuthRecord *rr, mDNSInterfaceID InterfaceID)
{
(void) rr;
- (void) intf;
+ (void) InterfaceID;
return 1;
}
@@ -1582,9 +1618,8 @@ mDNSexport void mDNSPlatformSendKeepalive(mDNSAddr *sadd, mDNSAddr *dadd, mDNSIP
(void) win; // Unused
}
-mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti)
+mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNSAddr *laddr, mDNSIPPort *lport, mDNSAddr *raddr, mDNSIPPort *rport, mDNSTCPInfo *mti)
{
- (void) m; // Unused
(void) laddr; // Unused
(void) raddr; // Unused
(void) lport; // Unused
@@ -1594,10 +1629,9 @@ mDNSexport mStatus mDNSPlatformRetrieveTCPInfo(mDNS *const m, mDNSAddr *laddr, m
return mStatus_NoError;
}
-mDNSexport mStatus mDNSPlatformGetRemoteMacAddr(mDNS *const m, mDNSAddr *raddr)
+mDNSexport mStatus mDNSPlatformGetRemoteMacAddr(mDNSAddr *raddr)
{
(void) raddr; // Unused
- (void) m; // Unused
return mStatus_NoError;
}
@@ -1610,37 +1644,38 @@ mDNSexport mStatus mDNSPlatformStoreSPSMACAddr(mDNSAddr *spsaddr, char *ifnam
return mStatus_NoError;
}
-mDNSexport mStatus mDNSPlatformClearSPSMACAddr(void)
+mDNSexport mStatus mDNSPlatformClearSPSData(void)
{
return mStatus_NoError;
}
+mDNSexport mStatus mDNSPlatformStoreOwnerOptRecord(char *ifname, DNSMessage *msg, int length)
+{
+ (void) ifname; // Unused
+ (void) msg; // Unused
+ (void) length; // Unused
+ return mStatus_UnsupportedErr;
+}
+
mDNSexport mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock)
{
(void) sock; // unused
-
+
return (mDNSu16)-1;
}
mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
{
(void) InterfaceID; // unused
-
- return mDNSfalse;
-}
-mDNSexport void mDNSPlatformGetDNSRoutePolicy(mDNS *const m, DNSQuestion *q, mDNSBool *isCellBlocked)
-{
- (void) m;
-
- q->ServiceID = -1;
- *isCellBlocked = mDNSfalse;
+ return mDNSfalse;
}
-mDNSexport void mDNSPlatformSetuDNSSocktOpt(UDPSocket *src, const mDNSAddr *dst, DNSQuestion *q)
+mDNSexport void mDNSPlatformSetSocktOpt(void *sock, mDNSTransport_Type transType, mDNSAddr_Type addrType, const DNSQuestion *q)
{
- (void) src;
- (void) dst;
+ (void) sock;
+ (void) transType;
+ (void) addrType;
(void) q;
}
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.h b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.h
index d3d413eb3c..ca60d806ab 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSPosix.h
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSPosix.h
@@ -65,7 +65,7 @@ extern mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m);
// Call mDNSPosixGetFDSet before calling select(), to update the parameters
// as may be necessary to meet the needs of the mDNSCore code.
// The timeout pointer MUST NOT be NULL.
-// Set timeout->tv_sec to 0x3FFFFFFF if you want to have effectively no timeout
+// Set timeout->tv_sec to FutureTime if you want to have effectively no timeout
// After calling mDNSPosixGetFDSet(), call select(nfds, &readfds, NULL, NULL, &timeout); as usual
// After select() returns, call mDNSPosixProcessFDSet() to let mDNSCore do its work
extern void mDNSPosixGetFDSet(mDNS *m, int *nfds, fd_set *readfds, struct timeval *timeout);
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c
index 0b174e8301..ed6da80953 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.c
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.c
@@ -203,7 +203,9 @@ gotError:
}
done:
if (sockfd != -1) {
- assert(close(sockfd) == 0);
+ int rv;
+ rv = close(sockfd);
+ assert(rv == 0);
}
if (fp != NULL) {
fclose(fp);
@@ -220,7 +222,8 @@ done:
* Unlike plen_to_mask returns netmask in binary form and not
* in text form.
*/
-static void plen_to_netmask(int prefix, unsigned char *addr) {
+static void plen_to_netmask(int prefix, unsigned char *addr)
+{
for (; prefix > 8; prefix -= 8)
*addr++ = 0xff;
for (; prefix > 0; prefix--)
@@ -836,7 +839,7 @@ recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
*ttl = 255; // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
- msg.msg_control = (void *) control_un.control;
+ msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_flags = 0;
#else
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.h b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h
index cc81b7d393..cc81b7d393 100644..100755
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSUNP.h
+++ b/usr/src/contrib/mDNSResponder/mDNSPosix/mDNSUNP.h
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c b/usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.c
index 1c6cb5be7c..1c6cb5be7c 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.c
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.h b/usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.h
index 2d0ada6dcd..2d0ada6dcd 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/GenLinkedList.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/GenLinkedList.h
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c
index afba1c66bf..909efed5c5 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.c
@@ -23,6 +23,10 @@
#include <netinet/in.h> // Needed for sockaddr_in
#include <syslog.h>
+#if APPLE_OSX_mDNSResponder
+#include <os/log.h>
+#endif
+
#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above
#include "DNSCommon.h"
#include "PlatformCommon.h"
@@ -65,9 +69,10 @@ mDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAdd
else return;
if ((connect(sock, &addr.s, inner_len)) < 0) {
- if (errno != ENETUNREACH)
- LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno,
- strerror(errno));
+ if (errno != ENETUNREACH) {
+ LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d "
+ "(%s)", dst, errno, strerror(errno));
+ }
goto exit;
}
@@ -178,6 +183,14 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
int syslog_level = LOG_ERR;
switch (loglevel)
{
+#if APPLE_OSX_mDNSResponder
+ case MDNS_LOG_MSG: syslog_level = OS_LOG_TYPE_DEFAULT; break;
+ case MDNS_LOG_OPERATION: syslog_level = OS_LOG_TYPE_INFO; break;
+ case MDNS_LOG_SPS: syslog_level = OS_LOG_TYPE_INFO; break;
+ case MDNS_LOG_INFO: syslog_level = OS_LOG_TYPE_INFO; break;
+ case MDNS_LOG_DEBUG: syslog_level = OS_LOG_TYPE_DEBUG; break;
+ default: syslog_level = OS_LOG_TYPE_DEFAULT; break;
+#else
case MDNS_LOG_MSG: syslog_level = LOG_ERR; break;
case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break;
case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break;
@@ -186,6 +199,7 @@ mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, m
default:
fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
fflush(stderr);
+#endif
}
if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; }
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.h b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.h
index 2a068711e0..2a068711e0 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/PlatformCommon.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/PlatformCommon.h
diff --git a/usr/src/lib/libdns_sd/common/dns_sd.h b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h
index cf32ea1eda..701c4ff3a6 100644
--- a/usr/src/lib/libdns_sd/common/dns_sd.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd.h
@@ -66,7 +66,7 @@
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 6254102
+#define _DNS_SD_H 8780101
#ifdef __cplusplus
extern "C" {
@@ -88,6 +88,13 @@ extern "C" {
#define DNSSD_API
#endif
+#if defined(_WIN32)
+#include <winsock2.h>
+typedef SOCKET dnssd_sock_t;
+#else
+typedef int dnssd_sock_t;
+#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 <sys/types.h>
@@ -156,11 +163,11 @@ struct sockaddr;
* The reliable way to test whether a particular bit is set is not with an equality test,
* but with a bitwise mask:
* if (flags & kDNSServiceFlagsAdd) ...
- * With the exception of kDNSServiceFlagsValidate, each flag can be valid(be set)
+ * With the exception of kDNSServiceFlagsValidate, each flag can be valid(be set)
* EITHER only as an input to one of the DNSService*() APIs OR only as an output
* (provide status) through any of the callbacks used. For example, kDNSServiceFlagsAdd
* can be set only as an output in the callback, whereas the kDNSServiceFlagsIncludeP2P
- * can be set only as an input to the DNSService*() APIs. See comments on kDNSServiceFlagsValidate
+ * can be set only as an input to the DNSService*() APIs. See comments on kDNSServiceFlagsValidate
* defined in enum below.
*/
enum
@@ -180,6 +187,15 @@ enum
* in the future they will be delivered as usual.
*/
+ kDNSServiceFlagsAutoTrigger = 0x1,
+ /* Valid for browses using kDNSServiceInterfaceIndexAny.
+ * Will auto trigger the browse over AWDL as well once the service is discoveryed
+ * over BLE.
+ * This flag is an input value to DNSServiceBrowse(), which is why we can
+ * use the same value as kDNSServiceFlagsMoreComing, which is an output flag
+ * for various client callbacks.
+ */
+
kDNSServiceFlagsAdd = 0x2,
kDNSServiceFlagsDefault = 0x4,
/* Flags for domain enumeration and browse/query reply callbacks.
@@ -229,7 +245,7 @@ enum
kDNSServiceFlagsForce = 0x800, // This flag is deprecated.
kDNSServiceFlagsKnownUnique = 0x800,
- /*
+ /*
* Client guarantees that record names are unique, so we can skip sending out initial
* probe messages. Standard name conflict resolution is still done if a conflict is discovered.
* Currently only valid for a DNSServiceRegister call.
@@ -330,10 +346,21 @@ enum
*
* 5. Thread Safety
* The dns_sd.h API does not presuppose any particular threading model, and consequently
- * does no locking of its own (which would require linking some specific threading library).
- * If client code calls API routines on the same DNSServiceRef concurrently
- * from multiple threads, it is the client's responsibility to use a mutext
- * lock or take similar appropriate precautions to serialize those calls.
+ * does no locking internally (which would require linking with a specific threading library).
+ * If the client concurrently, from multiple threads (or contexts), calls API routines using
+ * the same DNSServiceRef, it is the client's responsibility to provide mutual exclusion for
+ * that DNSServiceRef.
+
+ * For example, use of DNSServiceRefDeallocate requires caution. A common mistake is as follows:
+ * Thread B calls DNSServiceRefDeallocate to deallocate sdRef while Thread A is processing events
+ * using sdRef. Doing this will lead to intermittent crashes on thread A if the sdRef is used after
+ * it was deallocated.
+
+ * A telltale sign of this crash type is to see DNSServiceProcessResult on the stack preceding the
+ * actual crash location.
+
+ * To state this more explicitly, mDNSResponder does not queue DNSServiceRefDeallocate so
+ * that it occurs discretely before or after an event is handled.
*/
kDNSServiceFlagsSuppressUnusable = 0x8000,
@@ -370,7 +397,7 @@ enum
kDNSServiceFlagsBackgroundTrafficClass = 0x80000,
/*
- * This flag is meaningful for Unicast DNS queries. When set, it uses the background traffic
+ * This flag is meaningful for Unicast DNS queries. When set, it uses the background traffic
* class for packets that service the request.
*/
@@ -381,32 +408,32 @@ enum
kDNSServiceFlagsValidate = 0x200000,
/*
- * This flag is meaningful in DNSServiceGetAddrInfo and DNSServiceQueryRecord. This is the ONLY flag to be valid
+ * This flag is meaningful in DNSServiceGetAddrInfo and DNSServiceQueryRecord. This is the ONLY flag to be valid
* as an input to the APIs and also an output through the callbacks in the APIs.
*
- * When this flag is passed to DNSServiceQueryRecord and DNSServiceGetAddrInfo to resolve unicast names,
- * the response will be validated using DNSSEC. The validation results are delivered using the flags field in
+ * When this flag is passed to DNSServiceQueryRecord and DNSServiceGetAddrInfo to resolve unicast names,
+ * the response will be validated using DNSSEC. The validation results are delivered using the flags field in
* the callback and kDNSServiceFlagsValidate is marked in the flags to indicate that DNSSEC status is also available.
- * When the callback is called to deliver the query results, the validation results may or may not be available.
+ * When the callback is called to deliver the query results, the validation results may or may not be available.
* If it is not delivered along with the results, the validation status is delivered when the validation completes.
- *
+ *
* When the validation results are delivered in the callback, it is indicated by marking the flags with
* kDNSServiceFlagsValidate and kDNSServiceFlagsAdd along with the DNSSEC status flags (described below) and a NULL
* sockaddr will be returned for DNSServiceGetAddrInfo and zero length rdata will be returned for DNSServiceQueryRecord.
* DNSSEC validation results are for the whole RRSet and not just individual records delivered in the callback. When
- * kDNSServiceFlagsAdd is not set in the flags, applications should implicitly assume that the DNSSEC status of the
+ * kDNSServiceFlagsAdd is not set in the flags, applications should implicitly assume that the DNSSEC status of the
* RRSet that has been delivered up until that point is not valid anymore, till another callback is called with
* kDNSServiceFlagsAdd and kDNSServiceFlagsValidate.
*
* The following four flags indicate the status of the DNSSEC validation and marked in the flags field of the callback.
- * When any of the four flags is set, kDNSServiceFlagsValidate will also be set. To check the validation status, the
+ * When any of the four flags is set, kDNSServiceFlagsValidate will also be set. To check the validation status, the
* other applicable output flags should be masked. See kDNSServiceOutputFlags below.
*/
kDNSServiceFlagsSecure = 0x200010,
/*
- * The response has been validated by verifying all the signaures in the response and was able to
- * build a successful authentication chain starting from a known trust anchor.
+ * The response has been validated by verifying all the signatures in the response and was able to
+ * build a successful authentication chain starting from a known trust anchor.
*/
kDNSServiceFlagsInsecure = 0x200020,
@@ -472,11 +499,11 @@ enum
* should not rely on this behavior being supported in any given software release.
*
* When kDNSServiceFlagsThresholdReached is set in the client callback add or remove event,
- * it indicates that the browse answer threshold has been reached and no
+ * it indicates that the browse answer threshold has been reached and no
* browse requests will be generated on the network until the number of answers falls
* below the threshold value. Add and remove events can still occur based
* on incoming Bonjour traffic observed by the system.
- * The set of services return to the client is not guaranteed to represent the
+ * The set of services return to the client is not guaranteed to represent the
* entire set of services present on the network once the threshold has been reached.
*
* Note, while kDNSServiceFlagsThresholdReached and kDNSServiceFlagsThresholdOne
@@ -484,29 +511,24 @@ enum
* is only set in the callbacks and kDNSServiceFlagsThresholdOne is only set on
* input to a DNSServiceBrowse call.
*/
- kDNSServiceFlagsDenyCellular = 0x8000000,
+ kDNSServiceFlagsPrivateOne = 0x8000000,
/*
- * This flag is meaningful only for Unicast DNS queries. When set, the kernel will restrict
- * DNS resolutions on the cellular interface for that request.
+ * This flag is private and should not be used.
*/
- kDNSServiceFlagsServiceIndex = 0x10000000,
+ kDNSServiceFlagsPrivateTwo = 0x10000000,
/*
- * This flag is meaningful only for DNSServiceGetAddrInfo() for Unicast DNS queries.
- * When set, DNSServiceGetAddrInfo() will interpret the "interfaceIndex" argument of the call
- * as the "serviceIndex".
+ * This flag is private and should not be used.
*/
- kDNSServiceFlagsDenyExpensive = 0x20000000,
+ kDNSServiceFlagsPrivateThree = 0x20000000,
/*
- * This flag is meaningful only for Unicast DNS queries. When set, the kernel will restrict
- * DNS resolutions on interfaces defined as expensive for that request.
+ * This flag is private and should not be used.
*/
- kDNSServiceFlagsPathEvaluationDone = 0x40000000
+ kDNSServiceFlagsPrivateFour = 0x40000000
/*
- * This flag is meaningful for only Unicast DNS queries.
- * When set, it indicates that Network PathEvaluation has already been performed.
+ * This flag is private and should not be used.
*/
};
@@ -673,24 +695,49 @@ enum
* -- or --
* "Why is kDNSServiceMaxDomainName 1009, when the maximum legal domain name is 256 bytes?"
*
- * All strings used in the DNS-SD APIs are UTF-8 strings. Apart from the exceptions noted below,
- * the APIs expect the strings to be properly escaped, using the conventional DNS escaping rules:
+ * All strings used in the DNS-SD APIs are UTF-8 strings.
+ * Apart from the exceptions noted below, the APIs expect the strings to be properly escaped, using the
+ * conventional DNS escaping rules, as used by the traditional DNS res_query() API, as described below:
+ *
+ * Generally all UTF-8 characters (which includes all US ASCII characters) represent themselves,
+ * with two exceptions, the dot ('.') character, which is the label separator,
+ * and the backslash ('\') character, which is the escape character.
+ * The escape character ('\') is interpreted as described below:
*
- * '\\' 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.
+ * represents a single literal byte with that value. Any byte value may be
+ * represented in '\ddd' format, even characters that don't strictly need to be escaped.
+ * For example, the ASCII code for 'w' is 119, and therefore '\119' is equivalent to 'w'.
+ * Thus the command "ping '\119\119\119.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
+ * Nonprinting ASCII characters in the range 0-31 are often represented this way.
+ * In particular, the ASCII NUL character (0) cannot appear in a C string because C uses it as the
+ * string terminator character, so ASCII NUL in a domain name has to be represented in a C string as '\000'.
+ * Other characters like space (ASCII code 32) are sometimes represented as '\032'
+ * in contexts where having an actual space character in a C string would be inconvenient.
+ *
+ * Otherwise, for all cases where a '\' is followed by anything other than a three-digit decimal value
+ * from 000 to 255, the character sequence '\x' represents a single literal occurrence of character 'x'.
+ * This is legal for any character, so, for example, '\w' is equivalent to 'w'.
+ * Thus the command "ping '\w\w\w.apple.com'" is the equivalent to the command "ping 'www.apple.com'".
+ * However, this encoding is most useful when representing the characters '.' and '\',
+ * which otherwise would have special meaning in DNS name strings.
+ * This means that the following encodings are particularly common:
+ * '\\' represents a single literal '\' in the name
+ * '\.' represents a single literal '.' in the name
+ *
+ * A lone escape character ('\') appearing at the end of a string is not allowed, since it is
+ * followed by neither a three-digit decimal value from 000 to 255 nor a single character.
+ * If a lone escape character ('\') does appear as the last character of a string, it is silently ignored.
*
* 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.
+ * escaped, but since legal regtypes are only allowed to contain US ASCII 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.
*
@@ -710,7 +757,7 @@ enum
* 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"
+ * Suppose you have a 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.
@@ -742,12 +789,29 @@ enum
* 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.
+ * If the client passes kDNSServiceInterfaceIndexLocalOnly when querying or
+ * browsing, then the LocalOnly authoritative records and /etc/hosts caches
+ * are searched and will find *all* records registered or configured on that
+ * same local machine.
+ *
+ * If interested in getting negative answers to local questions while querying
+ * or browsing, then set both the kDNSServiceInterfaceIndexLocalOnly and the
+ * kDNSServiceFlagsReturnIntermediates flags. If no local answers exist at this
+ * moment in time, then the reply will return an immediate negative answer. If
+ * local records are subsequently created that answer the question, then those
+ * answers will be delivered, for as long as the question is still active.
+ *
+ * If the kDNSServiceFlagsTimeout and kDNSServiceInterfaceIndexLocalOnly flags
+ * are set simultaneously when either DNSServiceQueryRecord or DNSServiceGetAddrInfo
+ * is called then both flags take effect. However, if DNSServiceQueryRecord is called
+ * with both the kDNSServiceFlagsSuppressUnusable and kDNSServiceInterfaceIndexLocalOnly
+ * flags set, then the kDNSServiceFlagsSuppressUnusable flag is ignored.
+ *
+ * Clients explicitly wishing to discover *only* LocalOnly services during a
+ * browse may do this, without flags, by inspecting the interfaceIndex of each
+ * service reported to a DNSServiceBrowseReply() callback function, and
+ * discarding those answers where the interface index is not set to
+ * kDNSServiceInterfaceIndexLocalOnly.
*
* kDNSServiceInterfaceIndexP2P is meaningful only in Browse, QueryRecord, Register,
* and Resolve operations. It should not be used in other DNSService APIs.
@@ -761,7 +825,7 @@ enum
*
* - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceResolve, it is
* mapped internally to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
- * set, because resolving a P2P service may create and/or enable an interface whose
+ * set, because resolving a P2P service may create and/or enable an interface whose
* index is not known a priori. The resolve callback will indicate the index of the
* interface via which the service can be accessed.
*
@@ -776,6 +840,7 @@ enum
#define kDNSServiceInterfaceIndexLocalOnly ((uint32_t)-1)
#define kDNSServiceInterfaceIndexUnicast ((uint32_t)-2)
#define kDNSServiceInterfaceIndexP2P ((uint32_t)-3)
+#define kDNSServiceInterfaceIndexBLE ((uint32_t)-4)
typedef uint32_t DNSServiceFlags;
typedef uint32_t DNSServiceProtocol;
@@ -833,29 +898,6 @@ DNSServiceErrorType DNSSD_API DNSServiceGetProperty
#define kDNSServiceProperty_DaemonVersion "DaemonVersion"
-
-// Map the source port of the local UDP socket that was opened for sending the DNS query
-// to the process ID of the application that triggered the DNS resolution.
-//
-/* DNSServiceGetPID() Parameters:
- *
- * srcport: Source port (in network byte order) of the UDP socket that was created by
- * the daemon to send the DNS query on the wire.
- *
- * pid: Process ID of the application that started the name resolution which triggered
- * the daemon to send the query on the wire. The value can be -1 if the srcport
- * cannot be mapped.
- *
- * return value: Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
- * if the daemon is not running. The value of the pid is undefined if the return
- * value has error.
- */
-DNSServiceErrorType DNSSD_API DNSServiceGetPID
-(
- uint16_t srcport,
- int32_t *pid
-);
-
/*********************************************************************************************
*
* Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
@@ -876,8 +918,8 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID
* a client can choose to fork a thread and have it loop calling "DNSServiceProcessResult(ref);"
* If DNSServiceProcessResult() is called when no data is available for reading on the socket, it
* will block until data does become available, and then process the data and return to the caller.
- * The application is reponsible for checking the return value of DNSServiceProcessResult() to determine
- * if the socket is valid and if it should continue to process data on the socket.
+ * The application is responsible for checking the return value of DNSServiceProcessResult()
+ * to determine if the socket is valid and if it should continue to process data on the socket.
* When data arrives on the socket, the client is responsible for calling DNSServiceProcessResult(ref)
* in a timely fashion -- if the client allows a large backlog of data to build up the daemon
* may terminate the connection.
@@ -888,7 +930,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID
* error.
*/
-int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
+dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
/* DNSServiceProcessResult()
@@ -1090,14 +1132,14 @@ typedef void (DNSSD_API *DNSServiceRegisterReply)
* and the registration will remain active indefinitely until the client
* terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
*
+ * flags: Indicates the renaming behavior on name conflict (most applications
+ * will pass 0). See flag definitions above for details.
+ *
* 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).
@@ -1149,15 +1191,15 @@ typedef void (DNSSD_API *DNSServiceRegisterReply)
* service type using a colon (":") as a delimeter. If subtypes are also present,
* it should be given before the subtype as shown below.
*
- * % dns-sd -R _test1 _http._tcp:mygroup1 local 1001
- * % dns-sd -R _test2 _http._tcp:mygroup2 local 1001
- * % dns-sd -R _test3 _http._tcp:mygroup3,HasFeatureA local 1001
+ * % dns-sd -R _test1 _http._tcp:mygroup1 local 1001
+ * % dns-sd -R _test2 _http._tcp:mygroup2 local 1001
+ * % dns-sd -R _test3 _http._tcp:mygroup3,HasFeatureA local 1001
*
* Now:
* % dns-sd -B _http._tcp:"mygroup1" # will discover only test1
* % dns-sd -B _http._tcp:"mygroup2" # will discover only test2
* % dns-sd -B _http._tcp:"mygroup3",HasFeatureA # will discover only test3
- *
+ *
* By specifying the group information, only the members of that group are
* discovered.
*
@@ -1237,7 +1279,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
* 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
+ * DNSServiceRef, then it's the caller's responsibility to use a mutex lock
* or take similar appropriate precautions to serialize those calls.
*
* Parameters;
@@ -1320,7 +1362,7 @@ DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
/* DNSServiceRemoveRecord
*
* Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
- * an record registered individually via DNSServiceRegisterRecord().
+ * a record registered individually via DNSServiceRegisterRecord().
*
* Parameters:
*
@@ -1628,7 +1670,9 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
* only applies to clients that cancel the asynchronous operation when
* they get a result. Clients that leave the asynchronous operation
* running can safely assume that the data remains valid until they
- * get another callback telling them otherwise.
+ * get another callback telling them otherwise. The ttl value is not
+ * updated when the daemon answers from the cache, hence relying on
+ * the accuracy of the ttl value is not recommended.
*
* context: The context pointer that was passed to the callout.
*
@@ -1734,7 +1778,9 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
* only applies to clients that cancel the asynchronous operation when
* they get a result. Clients that leave the asynchronous operation
* running can safely assume that the data remains valid until they
- * get another callback telling them otherwise.
+ * get another callback telling them otherwise. The ttl value is not
+ * updated when the daemon answers from the cache, hence relying on
+ * the accuracy of the ttl value is not recommended.
*
* context: The context pointer that was passed to the callout.
*
@@ -2247,8 +2293,8 @@ typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignmen
* 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
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
+ * Recommended size limits for DNS-SD TXT Records are discussed in RFC 6763
+ * <https://tools.ietf.org/html/rfc6763#section-6.2>
*
* Note: When passing parameters to and from these TXT record APIs,
* the key name does not include the '=' character. The '=' character
@@ -2298,8 +2344,8 @@ void DNSSD_API TXTRecordDeallocate
* - 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
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
+ * For more details refer to "Data Syntax for DNS-SD TXT Records" in RFC 6763
+ * <https://tools.ietf.org/html/rfc6763#section-6>
*
* txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
*
@@ -2611,13 +2657,6 @@ DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
);
#endif
-#ifdef __APPLE_API_PRIVATE
-
-#define kDNSServiceCompPrivateDNS "PrivateDNS"
-#define kDNSServiceCompMulticastDNS "MulticastDNS"
-
-#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
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_internal.h b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_internal.h
new file mode 100644
index 0000000000..4be93e943b
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_internal.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2016 Apple Inc. All rights reserved.
+ */
+
+#ifndef _DNS_SD_INTERNAL_H
+#define _DNS_SD_INTERNAL_H
+
+#if !APPLE_OSX_mDNSResponder
+#define DNSSD_NO_CREATE_DELEGATE_CONNECTION 1
+#endif
+
+#include "dns_sd_private.h"
+
+#endif
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h
new file mode 100644
index 0000000000..ccec1403d0
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dns_sd_private.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2015 Apple Inc. All rights reserved.
+ */
+
+#ifndef _DNS_SD_PRIVATE_H
+#define _DNS_SD_PRIVATE_H
+
+
+// Private flags (kDNSServiceFlagsPrivateOne, kDNSServiceFlagsPrivateTwo, kDNSServiceFlagsPrivateThree, kDNSServiceFlagsPrivateFour) from dns_sd.h
+enum
+{
+ kDNSServiceFlagsDenyCellular = 0x8000000,
+ /*
+ * This flag is meaningful only for Unicast DNS queries. When set, the daemon will restrict
+ * DNS resolutions on the cellular interface for that request.
+ */
+ kDNSServiceFlagsServiceIndex = 0x10000000,
+ /*
+ * This flag is meaningful only for DNSServiceGetAddrInfo() for Unicast DNS queries.
+ * When set, DNSServiceGetAddrInfo() will interpret the "interfaceIndex" argument of the call
+ * as the "serviceIndex".
+ */
+
+ kDNSServiceFlagsDenyExpensive = 0x20000000,
+ /*
+ * This flag is meaningful only for Unicast DNS queries. When set, the daemon will restrict
+ * DNS resolutions on interfaces defined as expensive for that request.
+ */
+
+ kDNSServiceFlagsPathEvaluationDone = 0x40000000
+ /*
+ * This flag is meaningful for only Unicast DNS queries.
+ * When set, it indicates that Network PathEvaluation has already been performed.
+ */
+};
+
+
+#if !DNSSD_NO_CREATE_DELEGATE_CONNECTION
+/* DNSServiceCreateDelegateConnection()
+ *
+ * Parameters:
+ *
+ * sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
+ * the reference (via DNSServiceRefDeallocate()) severs the
+ * connection and deregisters all records registered on this connection.
+ *
+ * pid : Process ID of the delegate
+ *
+ * uuid: UUID of the delegate
+ *
+ * Note that only one of the two arguments (pid or uuid) can be specified. If pid
+ * is zero, uuid will be assumed to be a valid value; otherwise pid will be used.
+ *
+ * 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). kDNSServiceErr_NotAuth is
+ * returned to indicate that the calling process does not have entitlements
+ * to use this API.
+ */
+DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *sdRef, int32_t pid, uuid_t uuid);
+#endif
+
+// Map the source port of the local UDP socket that was opened for sending the DNS query
+// to the process ID of the application that triggered the DNS resolution.
+//
+/* DNSServiceGetPID() Parameters:
+ *
+ * srcport: Source port (in network byte order) of the UDP socket that was created by
+ * the daemon to send the DNS query on the wire.
+ *
+ * pid: Process ID of the application that started the name resolution which triggered
+ * the daemon to send the query on the wire. The value can be -1 if the srcport
+ * cannot be mapped.
+ *
+ * return value: Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
+ * if the daemon is not running. The value of the pid is undefined if the return
+ * value has error.
+ */
+DNSServiceErrorType DNSSD_API DNSServiceGetPID
+(
+ uint16_t srcport,
+ int32_t *pid
+);
+
+#define kDNSServiceCompPrivateDNS "PrivateDNS"
+#define kDNSServiceCompMulticastDNS "MulticastDNS"
+
+#endif
diff --git a/usr/src/lib/libdns_sd/common/dnssd_clientlib.c b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c
index 649d403f02..649d403f02 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_clientlib.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientlib.c
diff --git a/usr/src/lib/libdns_sd/common/dnssd_clientstub.c b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c
index b0fd9f9983..e943c47f80 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_clientstub.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_clientstub.c
@@ -28,7 +28,6 @@
#include <errno.h>
#include <stdlib.h>
-#include <fcntl.h>
#include "dnssd_ipc.h"
@@ -36,7 +35,7 @@
#include <mach-o/dyld.h>
#include <uuid/uuid.h>
#include <TargetConditionals.h>
-#include "dns_sd_private.h"
+#include "dns_sd_internal.h"
#endif
#if defined(_WIN32)
@@ -81,7 +80,7 @@ static void syslog( int priority, const char * message, ...)
}
#else
- #include <sys/fcntl.h> // For O_RDWR etc.
+ #include <fcntl.h> // For O_RDWR etc.
#include <sys/time.h>
#include <sys/socket.h>
#include <syslog.h>
@@ -173,6 +172,19 @@ struct _DNSRecordRef_t
DNSServiceOp *sdr;
};
+#if !defined(USE_TCP_LOOPBACK)
+static void SetUDSPath(struct sockaddr_un *saddr, const char *path)
+{
+ size_t pathLen;
+
+ pathLen = strlen(path);
+ if (pathLen < sizeof(saddr->sun_path))
+ memcpy(saddr->sun_path, path, pathLen + 1);
+ else
+ saddr->sun_path[0] = '\0';
+}
+#endif
+
// Write len bytes. Return 0 on success, -1 on error
static int write_all(dnssd_sock_t sd, char *buf, size_t len)
{
@@ -183,10 +195,11 @@ static int write_all(dnssd_sock_t sd, char *buf, size_t len)
ssize_t num_written = send(sd, buf, (long)len, 0);
if (num_written < 0 || (size_t)num_written > len)
{
- // Should never happen. If it does, it indicates some OS bug,
+ // Check whether socket has gone defunct,
+ // otherwise, an error here indicates some OS bug
// or that the mDNSResponder daemon crashed (which should never happen).
- #if !defined(__ppc__) && defined(SO_ISDEFUNCT)
- int defunct;
+#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
+ int defunct = 0;
socklen_t dlen = sizeof (defunct);
if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
syslog(LOG_WARNING, "dnssd_clientstub write_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
@@ -197,12 +210,12 @@ static int write_all(dnssd_sock_t sd, char *buf, size_t len)
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
else
syslog(LOG_INFO, "dnssd_clientstub write_all(%d) DEFUNCT", sd);
- #else
+#else
syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
(long)num_written, (long)len,
(num_written < 0) ? dnssd_errno : 0,
(num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
- #endif
+#endif
return -1;
}
buf += num_written;
@@ -224,16 +237,18 @@ static int read_all(dnssd_sock_t sd, char *buf, int len)
ssize_t num_read = recv(sd, buf, len, 0);
// It is valid to get an interrupted system call error e.g., somebody attaching
// in a debugger, retry without failing
- if ((num_read < 0) && (errno == EINTR))
- {
- syslog(LOG_INFO, "dnssd_clientstub read_all: EINTR continue");
- continue;
+ if ((num_read < 0) && (errno == EINTR))
+ {
+ syslog(LOG_INFO, "dnssd_clientstub read_all: EINTR continue");
+ continue;
}
if ((num_read == 0) || (num_read < 0) || (num_read > len))
{
int printWarn = 0;
int defunct = 0;
- // Should never happen. If it does, it indicates some OS bug,
+
+ // Check whether socket has gone defunct,
+ // otherwise, an error here indicates some OS bug
// or that the mDNSResponder daemon crashed (which should never happen).
#if defined(WIN32)
// <rdar://problem/7481776> Suppress logs for "A non-blocking socket operation
@@ -273,6 +288,12 @@ static int more_bytes(dnssd_sock_t sd)
fd_set *fs;
int ret;
+#if defined(_WIN32)
+ fs = &readfds;
+ FD_ZERO(fs);
+ FD_SET(sd, fs);
+ ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
+#else
if (sd < FD_SETSIZE)
{
fs = &readfds;
@@ -287,24 +308,25 @@ static int more_bytes(dnssd_sock_t sd)
int nfdbits = sizeof (int) * 8;
int nints = (sd/nfdbits) + 1;
fs = (fd_set *)calloc(nints, (size_t)sizeof(int));
- if (fs == NULL)
- {
- syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed");
- return 0;
+ if (fs == NULL)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed");
+ return 0;
}
}
FD_SET(sd, fs);
ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
- if (fs != &readfds)
+ if (fs != &readfds)
free(fs);
+#endif
return (ret > 0);
}
// set_waitlimit() implements a timeout using select. It is called from deliver_request() before recv() OR accept()
// to ensure the UDS clients are not blocked in these system calls indefinitely.
// Note: Ideally one should never be blocked here, because it indicates either mDNSResponder daemon is not yet up/hung/
-// superbusy/crashed or some other OS bug. For eg: On Windows which suffers from 3rd party software
-// (primarily 3rd party firewall software) interfering with proper functioning of the TCP protocol stack it is possible
+// superbusy/crashed or some other OS bug. For eg: On Windows which suffers from 3rd party software
+// (primarily 3rd party firewall software) interfering with proper functioning of the TCP protocol stack it is possible
// the next operation on this socket(recv/accept) is blocked since we depend on TCP to communicate with the system service.
static int set_waitlimit(dnssd_sock_t sock, int timeout)
{
@@ -431,8 +453,8 @@ static void FreeDNSServiceOp(DNSServiceOp *x)
x->disp_queue = NULL;
#endif
// DNSRecords may have been added to subordinate sdRef e.g., DNSServiceRegister/DNSServiceAddRecord
- // or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiveRegisterRecord. DNSRecords may have
- // been freed if the application called DNSRemoveRecord
+ // or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiceRegisterRecord.
+ // DNSRecords may have been freed if the application called DNSRemoveRecord.
FreeDNSRecords(x);
if (x->kacontext)
{
@@ -451,10 +473,10 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
dnssd_sockaddr_t saddr;
DNSServiceOp *sdr;
- if (!ref)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSService operation with NULL DNSServiceRef");
- return kDNSServiceErr_BadParam;
+ if (!ref)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub DNSService operation with NULL DNSServiceRef");
+ return kDNSServiceErr_BadParam;
}
if (flags & kDNSServiceFlagsShareConnection)
@@ -481,16 +503,16 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { *ref = NULL; return kDNSServiceErr_ServiceNotRunning; }
}
// <rdar://problem/4096913> If the system service is disabled, we only want to try to connect once
- if (IsSystemServiceDisabled())
+ if (IsSystemServiceDisabled())
NumTries = DNSSD_CLIENT_MAXTRIES;
#endif
sdr = malloc(sizeof(DNSServiceOp));
- if (!sdr)
- {
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: malloc failed");
- *ref = NULL;
- return kDNSServiceErr_NoMemory;
+ if (!sdr)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: malloc failed");
+ *ref = NULL;
+ return kDNSServiceErr_NoMemory;
}
sdr->next = NULL;
sdr->primary = NULL;
@@ -515,11 +537,11 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
if (flags & kDNSServiceFlagsShareConnection)
{
DNSServiceOp **p = &(*ref)->next; // Append ourselves to end of primary's list
- while (*p)
+ while (*p)
p = &(*p)->next;
*p = sdr;
// Preincrement counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
- if (++(*ref)->uid.u32[0] == 0)
+ if (++(*ref)->uid.u32[0] == 0)
++(*ref)->uid.u32[1]; // In parent DNSServiceOp increment UID counter
sdr->primary = *ref; // Set our primary pointer
sdr->sockfd = (*ref)->sockfd; // Inherit primary's socket
@@ -562,7 +584,7 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
saddr.sin_port = htons(MDNS_TCP_SERVERPORT);
#else
saddr.sun_family = AF_LOCAL;
- strcpy(saddr.sun_path, uds_serverpath);
+ SetUDSPath(&saddr, uds_serverpath);
#if !defined(__ppc__) && defined(SO_DEFUNCTOK)
{
int defunct = 1;
@@ -571,7 +593,7 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
}
#endif
#endif
-
+
while (1)
{
int err = connect(sdr->sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
@@ -584,18 +606,18 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
// then we give up and return a failure code.
if (++NumTries < DNSSD_CLIENT_MAXTRIES)
{
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect()-> No of tries: %d", NumTries);
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect()-> No of tries: %d", NumTries);
sleep(1); // Sleep a bit, then try again
}
- else
+ else
{
#if !defined(USE_TCP_LOOPBACK)
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect() failed path:%s Socket:%d Err:%d Errno:%d %s",
+ syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: connect() failed path:%s Socket:%d Err:%d Errno:%d %s",
uds_serverpath, sdr->sockfd, err, dnssd_errno, dnssd_strerror(dnssd_errno));
#endif
- dnssd_close(sdr->sockfd);
- FreeDNSServiceOp(sdr);
- return kDNSServiceErr_ServiceNotRunning;
+ dnssd_close(sdr->sockfd);
+ FreeDNSServiceOp(sdr);
+ return kDNSServiceErr_ServiceNotRunning;
}
}
//printf("ConnectToServer opened socket %d\n", sdr->sockfd);
@@ -606,28 +628,34 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f
}
#define deliver_request_bailout(MSG) \
- syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup
+ do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)
static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
{
+ uint32_t datalen;
+ dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
+ DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
+ int MakeSeparateReturnSocket;
+ #if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
+ char *data;
+ #endif
+
if (!hdr)
{
syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr");
return kDNSServiceErr_Unknown;
}
- uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
+ datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
- char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
+ data = (char *)hdr + sizeof(ipc_msg_hdr);
#endif
- dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
- DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
// Note: need to check hdr->op, not sdr->op.
// hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
// contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
// add_record_request but the parent sdr->op will be connection_request or reg_service_request)
- const int MakeSeparateReturnSocket = (sdr->primary ||
+ MakeSeparateReturnSocket = (sdr->primary ||
hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request);
if (!DNSServiceRefValid(sdr))
@@ -646,22 +674,14 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
dnssd_sockaddr_t caddr;
dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) {
- deliver_request_bailout("TCP socket");
- }
+ if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");
caddr.sin_family = AF_INET;
caddr.sin_port = 0;
caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
- if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) {
- deliver_request_bailout("TCP bind");
- }
- if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) {
- deliver_request_bailout("TCP getsockname");
- }
- if (listen(listenfd, 1) < 0) {
- deliver_request_bailout("TCP listen");
- }
+ if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
+ if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) deliver_request_bailout("TCP getsockname");
+ if (listen(listenfd, 1) < 0) deliver_request_bailout("TCP listen");
port.s = caddr.sin_port;
data[0] = port.b[0]; // don't switch the byte order, as the
data[1] = port.b[1]; // daemon expects it in network byte order
@@ -672,9 +692,7 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
int bindresult;
dnssd_sockaddr_t caddr;
listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) {
- deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
- }
+ if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
caddr.sun_family = AF_LOCAL;
// According to Stevens (section 3.2), there is no portable way to
@@ -682,23 +700,17 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
#ifndef NOT_HAVE_SA_LEN
caddr.sun_len = sizeof(struct sockaddr_un);
#endif
- strcpy(caddr.sun_path, data);
+ SetUDSPath(&caddr, data);
mask = umask(0);
bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
umask(mask);
- if (bindresult < 0) {
- deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
- }
- if (listen(listenfd, 1) < 0) {
- deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
- }
+ if (bindresult < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
+ if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
}
#else
{
dnssd_sock_t sp[2];
- if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) {
- deliver_request_bailout("socketpair");
- }
+ if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
else
{
errsd = sp[0]; // We'll read our four-byte error code from sp[0]
@@ -722,7 +734,7 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
// any associated data does not work reliably -- e.g. one particular issue we ran
// into is that if the receiving program is in a kqueue loop waiting to be notified
// of the received message, it doesn't get woken up when the control message arrives.
- if (MakeSeparateReturnSocket || sdr->op == send_bpf)
+ if (MakeSeparateReturnSocket || sdr->op == send_bpf)
datalen--; // Okay to use sdr->op when checking for op == send_bpf
#endif
@@ -751,7 +763,7 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
}
#endif
- if (!MakeSeparateReturnSocket)
+ if (!MakeSeparateReturnSocket)
errsd = sdr->sockfd;
if (MakeSeparateReturnSocket || sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
{
@@ -761,12 +773,11 @@ static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
// set_waitlimit() ensures we do not block indefinitely just in case something is wrong
dnssd_sockaddr_t daddr;
dnssd_socklen_t len = sizeof(daddr);
- if ((err = set_waitlimit(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError)
+ if ((err = set_waitlimit(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError)
goto cleanup;
errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
- if (!dnssd_SocketValid(errsd)) {
+ if (!dnssd_SocketValid(errsd))
deliver_request_bailout("accept");
- }
#else
struct iovec vec = { ((char *)hdr) + sizeof(ipc_msg_hdr) + datalen, 1 }; // Send the last byte along with the SCM_RIGHTS
@@ -870,7 +881,7 @@ cleanup:
return err;
}
-int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
+dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
{
if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with NULL DNSServiceRef"); return dnssd_InvalidSocket; }
@@ -887,7 +898,7 @@ int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
return dnssd_InvalidSocket;
}
- return (int) sdRef->sockfd;
+ return sdRef->sockfd;
}
#if _DNS_SD_LIBDISPATCH
@@ -1172,13 +1183,18 @@ void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *result, uint32_t *size)
{
+ DNSServiceErrorType err;
char *ptr;
- size_t len = strlen(property) + 1;
+ size_t len;
ipc_msg_hdr *hdr;
DNSServiceOp *tmp;
uint32_t actualsize;
- DNSServiceErrorType err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
+ if (!property || !result || !size)
+ return kDNSServiceErr_BadParam;
+
+ len = strlen(property) + 1;
+ err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
if (err) return err;
hdr = create_hdr(getproperty_request, &len, &ptr, 0, tmp);
@@ -1208,7 +1224,7 @@ DNSServiceErrorType DNSSD_API DNSServiceGetPID(const uint16_t srcport, int32_t *
{
char *ptr;
ipc_msg_hdr *hdr;
- DNSServiceOp *tmp;
+ DNSServiceOp *tmp = NULL;
size_t len = sizeof(int32_t);
DNSServiceErrorType err = ConnectToServer(&tmp, 0, getpid_request, NULL, NULL, NULL);
@@ -1298,14 +1314,15 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
ipc_msg_hdr *hdr;
DNSServiceErrorType err;
- if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
+ if (!sdRef || !name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
// Need a real InterfaceID for WakeOnResolve
if ((flags & kDNSServiceFlagsWakeOnResolve) != 0 &&
((interfaceIndex == kDNSServiceInterfaceIndexAny) ||
(interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) ||
(interfaceIndex == kDNSServiceInterfaceIndexUnicast) ||
- (interfaceIndex == kDNSServiceInterfaceIndexP2P)))
+ (interfaceIndex == kDNSServiceInterfaceIndexP2P) ||
+ (interfaceIndex == kDNSServiceInterfaceIndexBLE)))
{
return kDNSServiceErr_BadParam;
}
@@ -1313,7 +1330,7 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
// Calculate total message length
@@ -1373,10 +1390,13 @@ DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
ipc_msg_hdr *hdr;
DNSServiceErrorType err;
+ // NULL name handled below.
+ if (!sdRef || !callBack) return kDNSServiceErr_BadParam;
+
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, query_request, handle_query_response, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, query_request, handle_query_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
if (!name) name = "\0";
@@ -1482,9 +1502,9 @@ DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
ipc_msg_hdr *hdr;
DNSServiceErrorType err;
- if (!hostname) return kDNSServiceErr_BadParam;
+ if (!sdRef || !hostname || !callBack) return kDNSServiceErr_BadParam;
- err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
if (err)
{
return err; // On error ConnectToServer leaves *sdRef set to NULL
@@ -1536,10 +1556,13 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
ipc_msg_hdr *hdr;
DNSServiceErrorType err;
+ // NULL domain handled below
+ if (!sdRef || !regtype || !callBack) return kDNSServiceErr_BadParam;
+
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
if (!domain) domain = "";
@@ -1564,11 +1587,16 @@ DNSServiceErrorType DNSSD_API DNSServiceBrowse
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
{
+ DNSServiceErrorType err;
DNSServiceOp *tmp;
char *ptr;
- size_t len = sizeof(flags) + strlen(domain) + 1;
+ size_t len;
ipc_msg_hdr *hdr;
- DNSServiceErrorType err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
+
+ if (!domain) return kDNSServiceErr_BadParam;
+ len = sizeof(flags) + strlen(domain) + 1;
+
+ err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
if (err) return err;
hdr = create_hdr(setdomain_request, &len, &ptr, 0, tmp);
@@ -1614,8 +1642,8 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
DNSServiceErrorType err;
union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };
+ if (!sdRef || !regtype) return kDNSServiceErr_BadParam;
if (!name) name = "";
- if (!regtype) return kDNSServiceErr_BadParam;
if (!domain) domain = "";
if (!host) host = "";
if (!txtRecord) txtRecord = (void*)"";
@@ -1626,7 +1654,7 @@ DNSServiceErrorType DNSSD_API DNSServiceRegister
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(DNSServiceFlags);
@@ -1677,12 +1705,16 @@ DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
size_t len;
ipc_msg_hdr *hdr;
DNSServiceErrorType err;
+ int f1;
+ int f2;
- int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
- int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
+ if (!sdRef || !callBack) return kDNSServiceErr_BadParam;
+
+ f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
+ f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
- err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, (void *)callBack, context);
+ err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(DNSServiceFlags);
@@ -1754,10 +1786,13 @@ static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *co
DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
{
+ DNSServiceErrorType err;
char *ptr;
size_t len = 0;
ipc_msg_hdr *hdr;
- DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
+
+ if (!sdRef) return kDNSServiceErr_BadParam;
+ err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
hdr = create_hdr(connection_request, &len, &ptr, 0, *sdRef);
@@ -1775,13 +1810,14 @@ DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *
size_t len = 0;
ipc_msg_hdr *hdr;
+ if (!sdRef) return kDNSServiceErr_BadParam;
DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_delegate_request, ConnectionResponse, NULL, NULL);
if (err)
{
return err; // On error ConnectToServer leaves *sdRef set to NULL
}
- // Only one of the two options can be set. If pid is zero, uuid is used.
+ // Only one of the two options can be set. If pid is zero, uuid is used.
// If both are specified only pid will be used. We send across the pid
// so that the daemon knows what to read from the socket.
@@ -1796,9 +1832,9 @@ DNSServiceErrorType DNSSD_API DNSServiceCreateDelegateConnection(DNSServiceRef *
}
if (pid && setsockopt((*sdRef)->sockfd, SOL_SOCKET, SO_DELEGATED, &pid, sizeof(pid)) == -1)
- {
- syslog(LOG_WARNING, "dnssdclientstub: Could not setsockopt() for PID[%d], no entitlements or process(pid) invalid errno:%d (%s)", pid, errno, strerror(errno));
- // Free the hdr in case we return before calling deliver_request()
+ {
+ syslog(LOG_WARNING, "dnssdclientstub: Could not setsockopt() for PID[%d], no entitlements or process(pid) invalid errno:%d (%s)", pid, errno, strerror(errno));
+ // Free the hdr in case we return before calling deliver_request()
if (hdr)
free(hdr);
DNSServiceRefDeallocate(*sdRef);
@@ -1864,7 +1900,11 @@ DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
flags |= kDNSServiceFlagsIncludeP2P;
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
+ if (!sdRef || !RecordRef || !fullname || (!rdata && rdlen) || !callBack)
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL parameter");
+ return kDNSServiceErr_BadParam;
+ }
if (!DNSServiceRefValid(sdRef))
{
@@ -1945,8 +1985,11 @@ DNSServiceErrorType DNSSD_API DNSServiceAddRecord
DNSRecordRef rref;
DNSRecord **p;
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
- if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSRecordRef pointer"); return kDNSServiceErr_BadParam; }
+ if (!sdRef || !RecordRef || (!rdata && rdlen))
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL parameter");
+ return kDNSServiceErr_BadParam;
+ }
if (sdRef->op != reg_service_request)
{
syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with non-DNSServiceRegister DNSServiceRef %p %d", sdRef, sdRef->op);
@@ -2006,7 +2049,11 @@ DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
size_t len = 0;
char *ptr;
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
+ if (!sdRef || (!rdata && rdlen))
+ {
+ syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL parameter");
+ return kDNSServiceErr_BadParam;
+ }
if (!DNSServiceRefValid(sdRef))
{
@@ -2082,12 +2129,15 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
const void *rdata
)
{
+ DNSServiceErrorType err;
char *ptr;
size_t len;
ipc_msg_hdr *hdr;
- DNSServiceOp *tmp;
+ DNSServiceOp *tmp = NULL;
+
+ if (!fullname || (!rdata && rdlen)) return kDNSServiceErr_BadParam;
- DNSServiceErrorType err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
+ err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
if (err) return err;
len = sizeof(DNSServiceFlags);
@@ -2161,7 +2211,7 @@ DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
union { uint16_t s; u_char b[2]; } internalPort = { internalPortInNetworkByteOrder };
union { uint16_t s; u_char b[2]; } externalPort = { externalPortInNetworkByteOrder };
- DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, (void *)callBack, context);
+ DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
len = sizeof(flags);
@@ -2363,7 +2413,7 @@ DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
ka = malloc(sizeof(SleepKAContext));
if (!ka) return kDNSServiceErr_NoMemory;
- ka->AppCallback = (void *)callBack;
+ ka->AppCallback = callBack;
ka->AppContext = context;
err = DNSServiceCreateConnection(sdRef);
diff --git a/usr/src/lib/libdns_sd/common/dnssd_ipc.c b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.c
index 0fd75824f5..0fd75824f5 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_ipc.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.c
diff --git a/usr/src/lib/libdns_sd/common/dnssd_ipc.h b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.h
index b9c0b144d3..c054188453 100644
--- a/usr/src/lib/libdns_sd/common/dnssd_ipc.h
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/dnssd_ipc.h
@@ -41,7 +41,6 @@
# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
# define dnssd_EINTR WSAEINTR
# define dnssd_ECONNRESET WSAECONNRESET
-# define dnssd_sock_t SOCKET
# define dnssd_socklen_t int
# define dnssd_close(sock) closesocket(sock)
# define dnssd_errno WSAGetLastError()
@@ -67,7 +66,6 @@ extern char *win32_strerror(int inErrorCode);
# define dnssd_EINTR EINTR
# define dnssd_ECONNRESET ECONNRESET
# define dnssd_EPIPE EPIPE
-# define dnssd_sock_t int
# define dnssd_socklen_t unsigned int
# define dnssd_close(sock) close(sock)
# define dnssd_errno errno
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c b/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c
index 1243ae77a7..3f78384c81 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/mDNSDebug.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/mDNSDebug.c
@@ -33,7 +33,7 @@
mDNSexport int mDNS_LoggingEnabled = 0;
mDNSexport int mDNS_PacketLoggingEnabled = 0;
mDNSexport int mDNS_McastLoggingEnabled = 0;
-mDNSexport int mDNS_McastTracingEnabled = 0;
+mDNSexport int mDNS_McastTracingEnabled = 0;
#if MDNS_DEBUGMSGS
mDNSexport int mDNS_DebugMode = mDNStrue;
diff --git a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c
index 9af68dc95d..de30ef13a1 100644
--- a/usr/src/cmd/cmd-inet/usr.lib/mdnsd/uds_daemon.c
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.c
@@ -34,6 +34,7 @@
#include "DNSCommon.h"
#include "uDNS.h"
#include "uds_daemon.h"
+#include "dns_sd_internal.h"
// Normally we append search domains only for queries with a single label that are not
// fully qualified. This can be overridden to apply search domains for queries (that are
@@ -48,17 +49,20 @@ mDNSBool AlwaysAppendSearchDomains = mDNSfalse;
#endif
#endif
-#ifdef LOCAL_PEERPID
-#include <sys/un.h> // for LOCAL_PEERPID
+#ifdef LOCAL_PEEREPID
+#include <sys/un.h> // for LOCAL_PEEREPID
#include <sys/socket.h> // for getsockopt
#include <sys/proc_info.h> // for struct proc_bsdshortinfo
#include <libproc.h> // for proc_pidinfo()
-#endif //LOCAL_PEERPID
-//upto 16 characters of process name (defined in <sys/proc.h> but we do not want to include that file)
-#define MAXCOMLEN 16
+#endif //LOCAL_PEEREPID
+
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
#if APPLE_OSX_mDNSResponder
#include <WebFilterDNS/WebFilterDNS.h>
+#include "BLE.h"
#if !NO_WCF
@@ -83,187 +87,6 @@ int WCFNameResolvesToName(WCFConnection *conn, char* fromName, char* toName, uid
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
-#pragma mark - Types and Data Structures
-#endif
-
-typedef enum
-{
- t_uninitialized,
- t_morecoming,
- t_complete,
- t_error,
- t_terminated
-} transfer_state;
-
-typedef struct request_state request_state;
-
-typedef void (*req_termination_fn)(request_state *request);
-
-typedef struct registered_record_entry
-{
- struct registered_record_entry *next;
- mDNSu32 key;
- client_context_t regrec_client_context;
- request_state *request;
- mDNSBool external_advertise;
- mDNSInterfaceID origInterfaceID;
- AuthRecord *rr; // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?)
-} registered_record_entry;
-
-// A single registered service: ServiceRecordSet + bookkeeping
-// Note that we duplicate some fields from parent service_info object
-// to facilitate cleanup, when instances and parent may be deallocated at different times.
-typedef struct service_instance
-{
- struct service_instance *next;
- request_state *request;
- AuthRecord *subtypes;
- mDNSBool renameonmemfree; // Set on config change when we deregister original name
- mDNSBool clientnotified; // Has client been notified of successful registration yet?
- mDNSBool default_local; // is this the "local." from an empty-string registration?
- mDNSBool external_advertise; // is this is being advertised externally?
- domainname domain;
- ServiceRecordSet srs; // note -- variable-sized object -- must be last field in struct
-} service_instance;
-
-// for multi-domain default browsing
-typedef struct browser_t
-{
- struct browser_t *next;
- domainname domain;
- DNSQuestion q;
-} browser_t;
-
-#ifdef _WIN32
- typedef unsigned int pid_t;
- typedef unsigned int socklen_t;
-#endif
-
-struct request_state
-{
- request_state *next;
- request_state *primary; // If this operation is on a shared socket, pointer to primary
- // request_state for the original DNSServiceCreateConnection() operation
- dnssd_sock_t sd;
- pid_t process_id; // Client's PID value
- char pid_name[MAXCOMLEN]; // Client's process name
- char uuid[UUID_SIZE];
- mDNSBool validUUID;
- dnssd_sock_t errsd;
- mDNSu32 uid;
- void * platform_data;
-
- // Note: On a shared connection these fields in the primary structure, including hdr, are re-used
- // for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
- // operation is, we don't know if we're going to need to allocate a new request_state or not.
- transfer_state ts;
- mDNSu32 hdr_bytes; // bytes of header already read
- ipc_msg_hdr hdr;
- mDNSu32 data_bytes; // bytes of message data already read
- char *msgbuf; // pointer to data storage to pass to free()
- const char *msgptr; // pointer to data to be read from (may be modified)
- char *msgend; // pointer to byte after last byte of message
-
- // reply, termination, error, and client context info
- int no_reply; // don't send asynchronous replies to client
- mDNSs32 time_blocked; // record time of a blocked client
- int unresponsiveness_reports;
- struct reply_state *replies; // corresponding (active) reply list
- req_termination_fn terminate;
- DNSServiceFlags flags;
- mDNSu32 interfaceIndex;
-
- union
- {
- registered_record_entry *reg_recs; // list of registrations for a connection-oriented request
- struct
- {
- mDNSInterfaceID interface_id;
- mDNSBool default_domain;
- mDNSBool ForceMCast;
- domainname regtype;
- browser_t *browsers;
- const mDNSu8 *AnonData;
- } browser;
- struct
- {
- mDNSInterfaceID InterfaceID;
- mDNSu16 txtlen;
- void *txtdata;
- mDNSIPPort port;
- domainlabel name;
- char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
- domainname type;
- mDNSBool default_domain;
- domainname host;
- mDNSBool autoname; // Set if this name is tied to the Computer Name
- mDNSBool autorename; // Set if this client wants us to automatically rename on conflict
- mDNSBool allowremotequery; // Respond to unicast queries from outside the local link?
- int num_subtypes;
- mDNSBool AnonData;
- service_instance *instances;
- } servicereg;
- struct
- {
- mDNSInterfaceID interface_id;
- mDNSu32 flags;
- mDNSu32 protocol;
- DNSQuestion q4;
- DNSQuestion *q42;
- DNSQuestion q6;
- DNSQuestion *q62;
- mDNSu8 v4ans;
- mDNSu8 v6ans;
- } addrinfo;
- struct
- {
- mDNSIPPort ReqExt; // External port we originally requested, for logging purposes
- NATTraversalInfo NATinfo;
- } pm;
- struct
- {
- DNSServiceFlags flags;
- DNSQuestion q_all;
- DNSQuestion q_default;
- } enumeration;
- struct
- {
- DNSQuestion q;
- DNSQuestion *q2;
- mDNSu8 ans;
- } queryrecord;
- struct
- {
- DNSQuestion qtxt;
- DNSQuestion qsrv;
- const ResourceRecord *txt;
- const ResourceRecord *srv;
- mDNSs32 ReportTime;
- mDNSBool external_advertise;
- } resolve;
- } u;
-};
-
-// struct physically sits between ipc message header and call-specific fields in the message buffer
-typedef struct
-{
- DNSServiceFlags flags; // Note: This field is in NETWORK byte order
- mDNSu32 ifi; // Note: This field is in NETWORK byte order
- DNSServiceErrorType error; // Note: This field is in NETWORK byte order
-} reply_hdr;
-
-typedef struct reply_state
-{
- struct reply_state *next; // If there are multiple unsent replies
- mDNSu32 totallen;
- mDNSu32 nwriten;
- ipc_msg_hdr mhdr[1];
- reply_hdr rhdr[1];
-} reply_state;
-
-// ***************************************************************************
-#if COMPILER_LIKES_PRAGMA_MARK
-#pragma mark -
#pragma mark - Globals
#endif
@@ -271,11 +94,19 @@ typedef struct reply_state
mDNSexport mDNS mDNSStorage;
mDNSexport const char ProgramName[] = "mDNSResponder";
+#if defined(USE_TCP_LOOPBACK)
+static char* boundPath = NULL;
+#else
+static char* boundPath = MDNS_UDS_SERVERPATH;
+#endif
+#if DEBUG
+#define MDNS_UDS_SERVERPATH_DEBUG "/var/tmp/mDNSResponder"
+#endif
static dnssd_sock_t listenfd = dnssd_InvalidSocket;
static request_state *all_requests = NULL;
-#ifdef LOCAL_PEERPID
+#ifdef LOCAL_PEEREPID
struct proc_bsdshortinfo proc;
-#endif //LOCAL_PEERPID
+#endif //LOCAL_PEEREPID
mDNSlocal void set_peer_pid(request_state *request);
mDNSlocal void LogMcastClientInfo(request_state *req);
mDNSlocal void GetMcastClients(request_state *req);
@@ -284,6 +115,13 @@ static mDNSu32 i_mcount; // sets mcount when McastLogging is enabled(PROF sign
static mDNSu32 n_mrecords; // tracks the current active mcast records for McastLogging
static mDNSu32 n_mquests; // tracks the current active mcast questions for McastLogging
+
+#if TARGET_OS_EMBEDDED
+mDNSu32 curr_num_regservices = 0;
+mDNSu32 max_num_regservices = 0;
+#endif
+
+
// Note asymmetry here between registration and browsing.
// For service registrations we only automatically register in domains that explicitly appear in local configuration data
// (so AutoRegistrationDomains could equally well be called SCPrefRegDomains)
@@ -340,13 +178,13 @@ mDNSlocal void my_perror(char *errmsg)
mDNSlocal void my_throttled_perror(char *err_msg)
{
static int uds_throttle_count = 0;
- if ((uds_throttle_count++ % 250) == 0)
+ if ((uds_throttle_count++ % 250) == 0)
my_perror(err_msg);
-}
+}
// LogMcastQuestion/LogMcastQ should be called after the DNSQuestion struct is initialized(especially for q->TargetQID)
// Hence all calls are made after mDNS_StartQuery()/mDNS_StopQuery()/mDNS_StopBrowse() is called.
-mDNSlocal void LogMcastQuestion(mDNS *const m, const DNSQuestion *const q, request_state *req, q_state status)
+mDNSlocal void LogMcastQuestion(const DNSQuestion *const q, request_state *req, q_state status)
{
if (mDNSOpaque16IsZero(q->TargetQID)) // Check for Mcast Query
{
@@ -360,18 +198,20 @@ mDNSlocal void LogMcastQuestion(mDNS *const m, const DNSQuestion *const q, reque
{
mcount--;
}
- LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Question" : "-Question", q->qname.c, DNSTypeName(q->qtype),
- q->InterfaceID == mDNSInterface_LocalOnly ? "lo" : q->InterfaceID == mDNSInterface_P2P ? "p2p" :
- q->InterfaceID == mDNSInterface_Any ? "any" : InterfaceNameForID(m, q->InterfaceID),
+ LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Question" : "-Question", q->qname.c, DNSTypeName(q->qtype),
+ q->InterfaceID == mDNSInterface_LocalOnly ? "lo" :
+ q->InterfaceID == mDNSInterface_P2P ? "p2p" :
+ q->InterfaceID == mDNSInterface_BLE ? "BLE" :
+ q->InterfaceID == mDNSInterface_Any ? "any" : InterfaceNameForID(&mDNSStorage, q->InterfaceID),
req->process_id, req->pid_name);
- LogMcastStateInfo(m, mflag, mDNSfalse, mDNSfalse);
+ LogMcastStateInfo(mflag, mDNSfalse, mDNSfalse);
}
return;
}
// LogMcastService/LogMcastS should be called after the AuthRecord struct is initialized
// Hence all calls are made after mDNS_Register()/ just before mDNS_Deregister()
-mDNSlocal void LogMcastService(mDNS *const m, const AuthRecord *const ar, request_state *req, reg_state status)
+mDNSlocal void LogMcastService(const AuthRecord *const ar, request_state *req, reg_state status)
{
if (!AuthRecord_uDNS(ar)) // Check for Mcast Service
{
@@ -386,17 +226,20 @@ mDNSlocal void LogMcastService(mDNS *const m, const AuthRecord *const ar, reques
mcount--;
}
LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Service" : "-Service", ar->resrec.name->c, DNSTypeName(ar->resrec.rrtype),
- ar->resrec.InterfaceID == mDNSInterface_LocalOnly ? "lo" : ar->resrec.InterfaceID == mDNSInterface_P2P ? "p2p" :
- ar->resrec.InterfaceID == mDNSInterface_Any ? "all" : InterfaceNameForID(m, ar->resrec.InterfaceID),
+ ar->resrec.InterfaceID == mDNSInterface_LocalOnly ? "lo" :
+ ar->resrec.InterfaceID == mDNSInterface_P2P ? "p2p" :
+ ar->resrec.InterfaceID == mDNSInterface_BLE ? "BLE" :
+ ar->resrec.InterfaceID == mDNSInterface_Any ? "all" : InterfaceNameForID(&mDNSStorage, ar->resrec.InterfaceID),
req->process_id, req->pid_name);
- LogMcastStateInfo(m, mflag, mDNSfalse, mDNSfalse);
+ LogMcastStateInfo(mflag, mDNSfalse, mDNSfalse);
}
return;
}
// For complete Mcast State Log, pass mDNStrue to mstatelog in LogMcastStateInfo()
-mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start, mDNSBool mstatelog)
+mDNSexport void LogMcastStateInfo(mDNSBool mflag, mDNSBool start, mDNSBool mstatelog)
{
+ mDNS *const m = &mDNSStorage;
if (!mstatelog)
{
if (!all_requests)
@@ -407,13 +250,13 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
{
request_state *req, *r;
for (req = all_requests; req; req=req->next)
- {
+ {
if (req->primary) // If this is a subbordinate operation, check that the parent is in the list
- {
- for (r = all_requests; r && r != req; r=r->next)
- if (r == req->primary)
+ {
+ for (r = all_requests; r && r != req; r=r->next)
+ if (r == req->primary)
goto foundpar;
- }
+ }
// For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
GetMcastClients(req);
foundpar:;
@@ -432,28 +275,28 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
// wrong value if MulticastLogging is disabled and then re-enabled
LogMcastNoIdent("--- START MCAST STATE LOG ---");
if (!all_requests)
- {
+ {
mcount = 0;
LogMcastNoIdent("<None>");
- }
- else
- {
+ }
+ else
+ {
request_state *req, *r;
for (req = all_requests; req; req=req->next)
- {
+ {
if (req->primary) // If this is a subbordinate operation, check that the parent is in the list
- {
- for (r = all_requests; r && r != req; r=r->next)
- if (r == req->primary)
+ {
+ for (r = all_requests; r && r != req; r=r->next)
+ if (r == req->primary)
goto foundparent;
LogMcastNoIdent("%3d: Orphan operation; parent not found in request list", req->sd);
- }
+ }
// For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
LogMcastClientInfo(req);
foundparent:;
}
if(!mcount) // To initially set mcount
- mcount = i_mcount;
+ mcount = i_mcount;
}
if (mcount == 0)
{
@@ -461,7 +304,7 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
LogMcastNoIdent("--- MCOUNT[%d]: IMPKTNUM[%d] ---", mcount, i_mpktnum);
}
if (mflag)
- LogMcastNoIdent("--- MCOUNT[%d]: CMPKTNUM[%d] - IMPKTNUM[%d] = [%d]PKTS ---", mcount, m->MPktNum, i_mpktnum, (m->MPktNum - i_mpktnum));
+ LogMcastNoIdent("--- MCOUNT[%d]: CMPKTNUM[%d] - IMPKTNUM[%d] = [%d]PKTS ---", mcount, m->MPktNum, i_mpktnum, (m->MPktNum - i_mpktnum));
LogMcastNoIdent("--- END MCAST STATE LOG ---");
}
}
@@ -507,6 +350,24 @@ mDNSlocal void abort_request(request_state *req)
req->terminate = (req_termination_fn) ~0;
}
+#if DEBUG
+mDNSexport void SetDebugBoundPath(void)
+{
+#if !defined(USE_TCP_LOOPBACK)
+ boundPath = MDNS_UDS_SERVERPATH_DEBUG;
+#endif
+}
+
+mDNSexport int IsDebugSocketInUse(void)
+{
+#if !defined(USE_TCP_LOOPBACK)
+ return !strcmp(boundPath, MDNS_UDS_SERVERPATH_DEBUG);
+#else
+ return mDNSfalse;
+#endif
+}
+#endif
+
mDNSlocal void AbortUnlinkAndFree(request_state *req)
{
request_state **p = &all_requests;
@@ -611,9 +472,7 @@ mDNSlocal mStatus GenerateNTDResponse(const domainname *const servicename, const
}
}
-// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
-// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
-mDNSlocal void GenerateBonjourBrowserResponse(const domainname *const servicename, const mDNSInterfaceID id,
+mDNSlocal void GenerateBrowseReply(const domainname *const servicename, const mDNSInterfaceID id,
request_state *const request, reply_state **const rep, reply_op_t op, DNSServiceFlags flags, mStatus err)
{
char namestr[MAX_DOMAIN_LABEL+1];
@@ -665,7 +524,7 @@ mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, i
mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
const char *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
mDNSu32 ttl = GetTTL ? get_uint32(&request->msgptr, request->msgend) : 0;
- int storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ size_t storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
AuthRecord *rr;
mDNSInterfaceID InterfaceID;
AuthRecType artype;
@@ -691,7 +550,7 @@ mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, i
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
if (InterfaceID == mDNSInterface_LocalOnly)
artype = AuthRecordLocalOnly;
- else if (InterfaceID == mDNSInterface_P2P)
+ else if (InterfaceID == mDNSInterface_P2P || InterfaceID == mDNSInterface_BLE)
artype = AuthRecordP2P;
else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P)
&& (flags & kDNSServiceFlagsIncludeAWDL))
@@ -782,12 +641,14 @@ mDNSlocal mDNSBool AuthorizedDomain(const request_state * const request, const d
#pragma mark - external helpers
#endif
-mDNSlocal mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags)
+mDNSexport mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags)
{
#if APPLE_OSX_mDNSResponder
- if ( ((InterfaceID == mDNSInterface_Any) && (flags & (kDNSServiceFlagsIncludeP2P | kDNSServiceFlagsIncludeAWDL)) && IsLocalDomain(domain))
- || mDNSPlatformInterfaceIsD2D(InterfaceID))
+ // Only call D2D layer routines if request applies to a D2D interface and the domain is "local".
+ if ( (((InterfaceID == mDNSInterface_Any) && (flags & (kDNSServiceFlagsIncludeP2P | kDNSServiceFlagsIncludeAWDL | kDNSServiceFlagsAutoTrigger)))
+ || mDNSPlatformInterfaceIsD2D(InterfaceID) || (InterfaceID == mDNSInterface_BLE))
+ && IsLocalDomain(domain))
{
return mDNStrue;
}
@@ -822,6 +683,7 @@ mDNSlocal void external_start_advertising_helper(service_instance *const instanc
external_start_advertising_service(&instance->srs.RR_PTR.resrec, instance->request->flags);
external_start_advertising_service(&instance->srs.RR_SRV.resrec, instance->request->flags);
+
external_start_advertising_service(&instance->srs.RR_TXT.resrec, instance->request->flags);
for (e = instance->srs.Extras; e; e = e->next)
@@ -917,13 +779,13 @@ mDNSlocal void unlink_and_free_service_instance(service_instance *srv)
// Count how many other service records we have locally with the same name, but different rdata.
// For auto-named services, we can have at most one per machine -- if we allowed two auto-named services of
// the same type on the same machine, we'd get into an infinite autoimmune-response loop of continuous renaming.
-mDNSexport int CountPeerRegistrations(mDNS *const m, ServiceRecordSet *const srs)
+mDNSexport int CountPeerRegistrations(ServiceRecordSet *const srs)
{
int count = 0;
ResourceRecord *r = &srs->RR_SRV.resrec;
AuthRecord *rr;
- for (rr = m->ResourceRecords; rr; rr=rr->next)
+ for (rr = mDNSStorage.ResourceRecords; rr; rr=rr->next)
if (rr->resrec.rrtype == kDNSType_SRV && SameDomainName(rr->resrec.name, r->name) && !IdenticalSameNameRecord(&rr->resrec, r))
count++;
@@ -1009,11 +871,14 @@ mDNSlocal void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, m
LogInfo("regservice_callback: calling external_start_advertising_helper()");
external_start_advertising_helper(instance);
}
- if (instance->request->u.servicereg.autoname && CountPeerRegistrations(m, srs) == 0)
- RecordUpdatedNiceLabel(m, 0); // Successfully got new name, tell user immediately
+ if (instance->request->u.servicereg.autoname && CountPeerRegistrations(srs) == 0)
+ RecordUpdatedNiceLabel(0); // Successfully got new name, tell user immediately
}
else if (result == mStatus_MemFree)
{
+#if TARGET_OS_EMBEDDED
+ curr_num_regservices--;
+#endif
if (instance->request && instance->renameonmemfree)
{
external_stop_advertising_helper(instance);
@@ -1030,7 +895,7 @@ mDNSlocal void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, m
if (instance->request->u.servicereg.autorename)
{
external_stop_advertising_helper(instance);
- if (instance->request->u.servicereg.autoname && CountPeerRegistrations(m, srs) == 0)
+ if (instance->request->u.servicereg.autoname && CountPeerRegistrations(srs) == 0)
{
// On conflict for an autoname service, rename and reregister *all* autoname services
IncrementLabelSuffix(&m->nicelabel, mDNStrue);
@@ -1144,32 +1009,30 @@ mDNSlocal void regrecord_callback(mDNS *const m, AuthRecord *rr, mStatus result)
// This accounts for 2 places (connect_callback, request_callback)
mDNSlocal void set_peer_pid(request_state *request)
{
-#ifdef LOCAL_PEERPID
+#ifdef LOCAL_PEEREPID
pid_t p = (pid_t) -1;
socklen_t len = sizeof(p);
+#endif
request->pid_name[0] = '\0';
request->process_id = -1;
-
- if (request->sd < 0)
+#ifdef LOCAL_PEEREPID
+ if (request->sd < 0)
return;
- // to extract the pid value
- if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEERPID, &p, &len) != 0)
+ // to extract the effective pid value
+ if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREPID, &p, &len) != 0)
return;
// to extract the process name from the pid value
if (proc_pidinfo(p, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
return;
- mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
+ mDNSPlatformStrLCopy(request->pid_name, proc.pbsi_comm, sizeof(request->pid_name));
request->process_id = p;
- debugf("set_peer_pid: Client PEERPID is %d %s", p, request->pid_name);
-#else // !LOCAL_PEERPID
- request->pid_name[0] = '\0';
- request->process_id = -1;
-
+ debugf("set_peer_pid: Client PEEREPID is %d %s", p, request->pid_name);
+#else // !LOCAL_PEEREPID
LogInfo("set_peer_pid: Not Supported on this version of OS");
if (request->sd < 0)
return;
-#endif // LOCAL_PEERPID
+#endif // LOCAL_PEEREPID
}
mDNSlocal void connection_termination(request_state *request)
@@ -1200,14 +1063,14 @@ mDNSlocal void connection_termination(request_state *request)
{
registered_record_entry *ptr = request->u.reg_recs;
LogOperation("%3d: DNSServiceRegisterRecord(%u %s) STOP PID[%d](%s)", request->sd, ptr->key, RRDisplayString(&mDNSStorage, &ptr->rr->resrec), request->process_id, request->pid_name);
- request->u.reg_recs = request->u.reg_recs->next;
+ request->u.reg_recs = request->u.reg_recs->next;
ptr->rr->RecordContext = NULL;
if (ptr->external_advertise)
{
ptr->external_advertise = mDNSfalse;
external_stop_advertising_service(&ptr->rr->resrec, request->flags);
}
- LogMcastS(&mDNSStorage, ptr->rr, request, reg_stop);
+ LogMcastS(ptr->rr, request, reg_stop);
mDNS_Deregister(&mDNSStorage, ptr->rr); // Will free ptr->rr for us
freeL("registered_record_entry/connection_termination", ptr);
}
@@ -1237,7 +1100,12 @@ mDNSlocal void handle_cancel_request(request_state *request)
mDNSlocal mStatus handle_regrecord_request(request_state *request)
{
mStatus err = mStatus_BadParamErr;
- AuthRecord *rr = read_rr_from_ipc_msg(request, 1, 1);
+ AuthRecord *rr;
+
+ if (request->terminate != connection_termination)
+ { LogMsg("%3d: DNSServiceRegisterRecord(not a shared connection ref)", request->sd); return(err); }
+
+ rr = read_rr_from_ipc_msg(request, 1, 1);
if (rr)
{
registered_record_entry *re;
@@ -1252,7 +1120,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
}
// allocate registration entry, link into list
re = mallocL("registered_record_entry", sizeof(registered_record_entry));
- if (!re)
+ if (!re)
FatalError("ERROR: malloc");
re->key = request->hdr.reg_index;
re->rr = rr;
@@ -1263,7 +1131,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
rr->RecordCallback = regrecord_callback;
re->origInterfaceID = rr->resrec.InterfaceID;
- if (rr->resrec.InterfaceID == mDNSInterface_P2P)
+ if (rr->resrec.InterfaceID == mDNSInterface_P2P)
rr->resrec.InterfaceID = mDNSInterface_Any;
#if 0
if (!AuthorizedDomain(request, rr->resrec.name, AutoRegistrationDomains)) return (mStatus_NoError);
@@ -1271,7 +1139,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
if (rr->resrec.rroriginalttl == 0)
rr->resrec.rroriginalttl = DefaultTTLforRRType(rr->resrec.rrtype);
- LogOperation("%3d: DNSServiceRegisterRecord(%u %s) START PID[%d](%s)", request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec),
+ LogOperation("%3d: DNSServiceRegisterRecord(%u %s) START PID[%d](%s)", request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec),
request->process_id, request->pid_name);
err = mDNS_Register(&mDNSStorage, rr);
@@ -1283,7 +1151,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
}
else
{
- LogMcastS(&mDNSStorage, rr, request, reg_start);
+ LogMcastS(rr, request, reg_start);
re->next = request->u.reg_recs;
request->u.reg_recs = re;
}
@@ -1295,17 +1163,17 @@ mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m);
mDNSlocal void regservice_termination_callback(request_state *request)
{
- if (!request)
- {
- LogMsg("regservice_termination_callback context is NULL");
- return;
+ if (!request)
+ {
+ LogMsg("regservice_termination_callback context is NULL");
+ return;
}
while (request->u.servicereg.instances)
{
service_instance *p = request->u.servicereg.instances;
request->u.servicereg.instances = request->u.servicereg.instances->next;
// only safe to free memory if registration is not valid, i.e. deregister fails (which invalidates p)
- LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP PID[%d](%s)", request->sd, p->srs.RR_SRV.resrec.name->c,
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP PID[%d](%s)", request->sd, p->srs.RR_SRV.resrec.name->c,
mDNSVal16(p->srs.RR_SRV.resrec.rdata->u.srv.port), request->process_id, request->pid_name);
external_stop_advertising_helper(p);
@@ -1316,7 +1184,7 @@ mDNSlocal void regservice_termination_callback(request_state *request)
// We can't clear p->request *after* the calling mDNS_DeregisterService/unlink_and_free_service_instance
// because by then we might have already freed p
p->request = NULL;
- LogMcastS(&mDNSStorage, &p->srs.RR_SRV, request, reg_stop);
+ LogMcastS(&p->srs.RR_SRV, request, reg_stop);
if (mDNS_DeregisterService(&mDNSStorage, &p->srs))
{
unlink_and_free_service_instance(p);
@@ -1324,9 +1192,9 @@ mDNSlocal void regservice_termination_callback(request_state *request)
}
}
if (request->u.servicereg.txtdata)
- {
- freeL("service_info txtdata", request->u.servicereg.txtdata);
- request->u.servicereg.txtdata = NULL;
+ {
+ freeL("service_info txtdata", request->u.servicereg.txtdata);
+ request->u.servicereg.txtdata = NULL;
}
if (request->u.servicereg.autoname)
{
@@ -1350,8 +1218,7 @@ mDNSlocal mStatus add_record_to_service(request_state *request, service_instance
{
ServiceRecordSet *srs = &instance->srs;
mStatus result;
- mDNSu32 coreFlags = 0; // translate to corresponding mDNSCore flag definitions
- int size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ size_t size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
ExtraResourceRecord *extra = mallocL("ExtraResourceRecord", sizeof(*extra) - sizeof(RDataBody) + size);
if (!extra) { my_perror("ERROR: malloc"); return mStatus_NoMemoryErr; }
@@ -1363,19 +1230,14 @@ mDNSlocal mStatus add_record_to_service(request_state *request, service_instance
// use InterfaceID value from DNSServiceRegister() call that created the original service
extra->r.resrec.InterfaceID = request->u.servicereg.InterfaceID;
- if (request->flags & kDNSServiceFlagsIncludeP2P)
- coreFlags |= coreFlagIncludeP2P;
- if (request->flags & kDNSServiceFlagsIncludeAWDL)
- coreFlags |= coreFlagIncludeAWDL;
-
- result = mDNS_AddRecordToService(&mDNSStorage, srs, extra, &extra->r.rdatastorage, ttl, coreFlags);
- if (result)
- {
- freeL("ExtraResourceRecord/add_record_to_service", extra);
- return result;
- }
- LogMcastS(&mDNSStorage, &srs->RR_PTR, request, reg_start);
-
+ result = mDNS_AddRecordToService(&mDNSStorage, srs, extra, &extra->r.rdatastorage, ttl, request->flags);
+ if (result)
+ {
+ freeL("ExtraResourceRecord/add_record_to_service", extra);
+ return result;
+ }
+ LogMcastS(&srs->RR_PTR, request, reg_start);
+
extra->ClientID = request->hdr.reg_index;
if ( instance->external_advertise
&& callExternalHelpers(request->u.servicereg.InterfaceID, &instance->domain, request->flags))
@@ -1411,8 +1273,9 @@ mDNSlocal mStatus handle_add_request(request_state *request)
if (mDNSIPPortIsZero(request->u.servicereg.port))
{ LogMsg("%3d: DNSServiceAddRecord: adding record to a service registered with zero port", request->sd); return(mStatus_BadParamErr); }
- LogOperation("%3d: DNSServiceAddRecord(%X, %##s, %s, %d)", request->sd, flags,
- (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL, DNSTypeName(rrtype), rdlen);
+ LogOperation("%3d: DNSServiceAddRecord(%X, %##s, %s, %d) PID[%d](%s)", request->sd, flags,
+ (request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL, DNSTypeName(rrtype), rdlen,
+ request->process_id, request->pid_name);
for (i = request->u.servicereg.instances; i; i = i->next)
{
@@ -1441,14 +1304,7 @@ mDNSlocal void update_callback(mDNS *const m, AuthRecord *const rr, RData *oldrd
if (external_advertise)
{
ResourceRecord ext = rr->resrec;
- DNSServiceFlags flags = 0;
-
- // Since we don't have a copy of the flags value used when the record was registered,
- // we'll have to derive it from the ARType field.
- if (rr->ARType == AuthRecordAnyIncludeP2P)
- flags |= kDNSServiceFlagsIncludeP2P;
- else if (rr->ARType == AuthRecordAnyIncludeAWDL)
- flags |= kDNSServiceFlagsIncludeAWDL;
+ DNSServiceFlags flags = deriveD2DFlagsFromAuthRecType(rr->ARType);
if (ext.rdlength == oldrdlen && mDNSPlatformMemSame(&ext.rdata->u, &oldrd->u, oldrdlen)) goto exit;
SetNewRData(&ext, oldrd, oldrdlen);
@@ -1463,7 +1319,7 @@ exit:
mDNSlocal mStatus update_record(AuthRecord *rr, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl, const mDNSBool *const external_advertise)
{
mStatus result;
- const int rdsize = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ const size_t rdsize = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
RData *newrd = mallocL("RData/update_record", sizeof(RData) - sizeof(RDataBody) + rdsize);
if (!newrd) FatalError("ERROR: malloc");
newrd->MaxRDLength = (mDNSu16) rdsize;
@@ -1509,8 +1365,9 @@ mDNSlocal mStatus handle_update_request(request_state *request)
if (reptr->key == hdr->reg_index)
{
result = update_record(reptr->rr, rdlen, rdata, ttl, &reptr->external_advertise);
- LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)",
- request->sd, reptr->rr->resrec.name->c, reptr->rr ? DNSTypeName(reptr->rr->resrec.rrtype) : "<NONE>");
+ LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s) PID[%d](%s)",
+ request->sd, reptr->rr->resrec.name->c, reptr->rr ? DNSTypeName(reptr->rr->resrec.rrtype) : "<NONE>",
+ request->process_id, request->pid_name);
goto end;
}
}
@@ -1558,9 +1415,10 @@ mDNSlocal mStatus handle_update_request(request_state *request)
end:
if (request->terminate == regservice_termination_callback)
- LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s)", request->sd,
+ LogOperation("%3d: DNSServiceUpdateRecord(%##s, %s) PID[%d](%s)", request->sd,
(request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
- rr ? DNSTypeName(rr->resrec.rrtype) : "<NONE>");
+ rr ? DNSTypeName(rr->resrec.rrtype) : "<NONE>",
+ request->process_id, request->pid_name);
return(result);
}
@@ -1576,14 +1434,15 @@ mDNSlocal mStatus remove_record(request_state *request)
e = *ptr;
*ptr = e->next; // unlink
- LogOperation("%3d: DNSServiceRemoveRecord(%u %s)", request->sd, e->key, RRDisplayString(&mDNSStorage, &e->rr->resrec));
+ LogOperation("%3d: DNSServiceRemoveRecord(%u %s) PID[%d](%s)",
+ request->sd, e->key, RRDisplayString(&mDNSStorage, &e->rr->resrec), request->process_id, request->pid_name);
e->rr->RecordContext = NULL;
if (e->external_advertise)
{
external_stop_advertising_service(&e->rr->resrec, request->flags);
e->external_advertise = mDNSfalse;
}
- LogMcastS(&mDNSStorage, e->rr, request, reg_stop);
+ LogMcastS(e->rr, request, reg_stop);
err = mDNS_Deregister(&mDNSStorage, e->rr); // Will free e->rr for us; we're responsible for freeing e
if (err)
{
@@ -1630,9 +1489,9 @@ mDNSlocal mStatus handle_removerecord_request(request_state *request)
{
service_instance *i;
mDNSu16 rrtype = 0;
- LogOperation("%3d: DNSServiceRemoveRecord(%##s, %s)", request->sd,
+ LogOperation("%3d: DNSServiceRemoveRecord(%##s, %s) PID[%d](%s)", request->sd,
(request->u.servicereg.instances) ? request->u.servicereg.instances->srs.RR_SRV.resrec.name->c : NULL,
- rrtype ? DNSTypeName(rrtype) : "<NONE>");
+ rrtype ? DNSTypeName(rrtype) : "<NONE>", request->process_id, request->pid_name);
for (i = request->u.servicereg.instances; i; i = i->next)
{
err = remove_extra(request, i, &rrtype);
@@ -1713,7 +1572,7 @@ mDNSexport mDNSs32 ChopSubTypes(char *regtype, char **AnonData)
mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData)
{
AuthRecord *st = mDNSNULL;
- //
+ //
// "p" is pointing at the regtype e.g., _http._tcp followed by ":<AnonData>" indicated
// by AnonData being non-NULL which is in turn follwed by ",<SubTypes>" indicated by
// NumSubTypes being non-zero. We need to skip the initial regtype to get to the actual
@@ -1761,7 +1620,7 @@ mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **Ano
if (!MakeDomainNameFromDNSNameString(&st[i].namestorage, p))
{
freeL("ServiceSubTypes", st);
- if (*AnonData)
+ if (AnonData && *AnonData)
freeL("AnonymousData", *AnonData);
return(mDNSNULL);
}
@@ -1775,24 +1634,10 @@ mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **Ano
mDNSlocal mStatus register_service_instance(request_state *request, const domainname *domain)
{
service_instance **ptr, *instance;
- const int extra_size = (request->u.servicereg.txtlen > sizeof(RDataBody)) ? (request->u.servicereg.txtlen - sizeof(RDataBody)) : 0;
+ size_t extra_size = (request->u.servicereg.txtlen > sizeof(RDataBody)) ? (request->u.servicereg.txtlen - sizeof(RDataBody)) : 0;
const mDNSBool DomainIsLocal = SameDomainName(domain, &localdomain);
mStatus result;
mDNSInterfaceID interfaceID = request->u.servicereg.InterfaceID;
- mDNSu32 coreFlags = 0;
-
- if (request->flags & kDNSServiceFlagsIncludeP2P)
- coreFlags |= coreFlagIncludeP2P;
- if (request->flags & kDNSServiceFlagsIncludeAWDL)
- coreFlags |= coreFlagIncludeAWDL;
-
- // Client guarantees that record names are unique, so we can skip sending out initial
- // probe messages. Standard name conflict resolution is still done if a conflict is discovered.
- if (request->flags & kDNSServiceFlagsKnownUnique)
- coreFlags |= coreFlagKnownUnique;
-
- if (request->flags & kDNSServiceFlagsWakeOnlyService)
- coreFlags |= coreFlagWakeOnly;
// If the client specified an interface, but no domain, then we honor the specified interface for the "local" (mDNS)
// registration but for the wide-area registrations we don't (currently) have any concept of a wide-area unicast
@@ -1832,14 +1677,14 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
char *AnonData = mDNSNULL;
instance->subtypes = AllocateSubTypes(request->u.servicereg.num_subtypes, request->u.servicereg.type_as_string, &AnonData);
if (AnonData)
- instance->srs.AnonData = (const mDNSu8 *)AnonData;
+ instance->srs.AnonData = (const mDNSu8 *)AnonData;
}
if (request->u.servicereg.num_subtypes && !instance->subtypes)
- {
- unlink_and_free_service_instance(instance);
- instance = NULL;
- FatalError("ERROR: malloc");
+ {
+ unlink_and_free_service_instance(instance);
+ instance = NULL;
+ FatalError("ERROR: malloc");
}
result = mDNS_RegisterService(&mDNSStorage, &instance->srs,
@@ -1848,14 +1693,14 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
request->u.servicereg.port,
request->u.servicereg.txtdata, request->u.servicereg.txtlen,
instance->subtypes, request->u.servicereg.num_subtypes,
- interfaceID, regservice_callback, instance, coreFlags);
+ interfaceID, regservice_callback, instance, request->flags);
if (!result)
{
*ptr = instance; // Append this to the end of our request->u.servicereg.instances list
- LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED", instance->request->sd,
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED", instance->request->sd,
instance->srs.RR_SRV.resrec.name->c, mDNSVal16(request->u.servicereg.port));
- LogMcastS(&mDNSStorage, &instance->srs.RR_SRV, request, reg_start);
+ LogMcastS(&instance->srs.RR_SRV, request, reg_start);
}
else
{
@@ -1871,10 +1716,6 @@ mDNSlocal void udsserver_default_reg_domain_changed(const DNameListElem *const d
{
request_state *request;
-#if APPLE_OSX_mDNSResponder
- machserver_automatic_registration_domain_changed(&d->name, add);
-#endif // APPLE_OSX_mDNSResponder
-
LogMsg("%s registration domain %##s", add ? "Adding" : "Removing", d->name.c);
for (request = all_requests; request; request = request->next)
{
@@ -1989,6 +1830,7 @@ mDNSlocal mDNSBool PreDefinedInterfaceIndex(mDNSu32 interfaceIndex)
case kDNSServiceInterfaceIndexLocalOnly:
case kDNSServiceInterfaceIndexUnicast:
case kDNSServiceInterfaceIndexP2P:
+ case kDNSServiceInterfaceIndexBLE:
return mDNStrue;
default:
return mDNSfalse;
@@ -2009,7 +1851,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
mDNSInterfaceID InterfaceID;
- // Map kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny with the
+ // Map kDNSServiceInterfaceIndexP2P to kDNSServiceInterfaceIndexAny with the
// kDNSServiceFlagsIncludeP2P flag set.
if (interfaceIndex == kDNSServiceInterfaceIndexP2P)
{
@@ -2020,7 +1862,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
- // The registration is scoped to a specific interface index, but the
+ // The registration is scoped to a specific interface index, but the
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
@@ -2049,7 +1891,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
request->u.servicereg.instances = NULL;
request->u.servicereg.txtlen = 0;
request->u.servicereg.txtdata = NULL;
- mDNSPlatformStrCopy(request->u.servicereg.type_as_string, type_as_string);
+ mDNSPlatformStrLCopy(request->u.servicereg.type_as_string, type_as_string, sizeof(request->u.servicereg.type_as_string));
if (request->msgptr + 2 > request->msgend) request->msgptr = NULL;
else
@@ -2151,8 +1993,17 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
request->pid_name, count+1, srv.c, mDNSVal16(request->u.servicereg.port));
}
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ // Determine if this request should be promoted to use BLE triggered feature.
+ if (shouldUseBLE(InterfaceID, 0, &request->u.servicereg.type, &d))
+ {
+ request->flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ LogInfo("handle_regservice_request: registration promoted to use kDNSServiceFlagsAutoTrigger");
+ }
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+
LogOperation("%3d: DNSServiceRegister(%X, %d, \"%s\", \"%s\", \"%s\", \"%s\", %u) START PID[%d](%s)",
- request->sd, flags, interfaceIndex, name, request->u.servicereg.type_as_string, domain, host,
+ request->sd, request->flags, interfaceIndex, name, request->u.servicereg.type_as_string, domain, host,
mDNSVal16(request->u.servicereg.port), request->process_id, request->pid_name);
// We need to unconditionally set request->terminate, because even if we didn't successfully
@@ -2165,6 +2016,12 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
err = register_service_instance(request, &d);
+#if TARGET_OS_EMBEDDED
+ ++curr_num_regservices;
+ if (curr_num_regservices > max_num_regservices)
+ max_num_regservices = curr_num_regservices;
+#endif
+
#if 0
err = AuthorizedDomain(request, &d, AutoRegistrationDomains) ? register_service_instance(request, &d) : mStatus_NoError;
#endif
@@ -2211,14 +2068,21 @@ mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const Resourc
flags |= kDNSServiceFlagsThresholdReached;
}
+ // if returning a negative answer, then use question's name in reply
+ if (answer->RecordType == kDNSRecordTypePacketNegative)
+ {
+ GenerateBrowseReply(&question->qname, answer->InterfaceID, req, &rep, browse_reply_op, flags, kDNSServiceErr_NoSuchRecord);
+ goto validReply;
+ }
+
if (GenerateNTDResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError) != mStatus_NoError)
{
if (SameDomainName(&req->u.browser.regtype, (const domainname*)"\x09_services\x07_dns-sd\x04_udp"))
{
// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
- GenerateBonjourBrowserResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
- goto bonjourbrowserhack;
+ GenerateBrowseReply(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
+ goto validReply;
}
LogMsg("%3d: FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
@@ -2226,15 +2090,41 @@ mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const Resourc
return;
}
-bonjourbrowserhack:
+validReply:
- LogOperation("%3d: DNSServiceBrowse(%##s, %s) RESULT %s %d: %s",
- req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "Add" : "Rmv",
+ LogOperation("%3d: DNSServiceBrowse(%##s, %s) RESULT %s interface %d: %s",
+ req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV",
mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse), RRDisplayString(m, answer));
append_reply(req, rep);
}
+mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
+{
+ q->euid = req->uid;
+ // The policy is either based on pid or UUID. Pass a zero pid
+ // to the "core" if the UUID is valid. If we always pass the pid,
+ // then the "core" needs to determine whether the uuid is valid
+ // by examining all the 16 bytes at the time of the policy
+ // check and also when setting the delegate socket option. Also, it
+ // requires that we zero out the uuid wherever the question is
+ // initialized to make sure that it is not interpreted as valid.
+ // To prevent these intrusive changes, just pass a zero pid to indicate
+ // that pid is not valid when uuid is valid. In future if we need the
+ // pid in the question, we will reevaluate this strategy.
+ if (req->validUUID)
+ {
+ mDNSPlatformMemCopy(q->uuid, req->uuid, UUID_SIZE);
+ q->pid = 0;
+ }
+ else
+ {
+ q->pid = req->process_id;
+ }
+
+ //debugf("SetQuestionPolicy: q->euid[%d] q->pid[%d] uuid is valid : %s", q->euid, q->pid, req->validUUID ? "true" : "false");
+}
+
mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d)
{
browser_t *b, *p;
@@ -2248,8 +2138,10 @@ mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d
b = mallocL("browser_t", sizeof(*b));
if (!b) return mStatus_NoMemoryErr;
+ mDNSPlatformMemZero(b, sizeof(*b));
AssignDomainName(&b->domain, d);
- err = mDNS_StartBrowse(&mDNSStorage, &b->q, &info->u.browser.regtype, d, info->u.browser.AnonData, info->u.browser.interface_id, info->flags,
+ SetQuestionPolicy(&b->q, info);
+ err = mDNS_StartBrowse(&mDNSStorage, &b->q, &info->u.browser.regtype, d, info->u.browser.AnonData, info->u.browser.interface_id, info->flags,
info->u.browser.ForceMCast, (info->flags & kDNSServiceFlagsBackgroundTrafficClass) != 0, FoundInstance, info);
if (err)
{
@@ -2260,9 +2152,18 @@ mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d
{
b->next = info->u.browser.browsers;
info->u.browser.browsers = b;
- LogOperation("%3d: DNSServiceBrowse(%##s) START PID[%d](%s)", info->sd, b->q.qname.c, info->process_id,
- info->pid_name);
- LogMcastQ(&mDNSStorage, &b->q, info, q_start);
+
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ // Determine if this request should be promoted to use BLE triggered discovery.
+ if (shouldUseBLE(info->u.browser.interface_id, 0, &info->u.browser.regtype, (domainname *) d))
+ {
+ info->flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ b->q.flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ LogInfo("add_domain_to_browser: request promoted to use kDNSServiceFlagsAutoTrigger");
+ }
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+
+ LogMcastQ(&b->q, info, q_start);
if (callExternalHelpers(info->u.browser.interface_id, &b->domain, info->flags))
{
domainname tmp;
@@ -2288,18 +2189,20 @@ mDNSlocal void browse_termination_callback(request_state *info)
{
browser_t *ptr = info->u.browser.browsers;
- if (callExternalHelpers(info->u.browser.interface_id, &ptr->domain, info->flags))
+ if (callExternalHelpers(ptr->q.InterfaceID, &ptr->domain, ptr->q.flags))
{
domainname tmp;
ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &ptr->domain);
LogInfo("browse_termination_callback: calling external_stop_browsing_for_service()");
- external_stop_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags);
+ external_stop_browsing_for_service(ptr->q.InterfaceID, &tmp, kDNSType_PTR, ptr->q.flags);
}
+ LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\") STOP PID[%d](%s)",
+ info->sd, info->flags, info->interfaceIndex, ptr->q.qname.c, info->process_id, info->pid_name);
+
info->u.browser.browsers = ptr->next;
- LogOperation("%3d: DNSServiceBrowse(%##s) STOP PID[%d](%s)", info->sd, ptr->q.qname.c, info->process_id, info->pid_name);
mDNS_StopBrowse(&mDNSStorage, &ptr->q); // no need to error-check result
- LogMcastQ(&mDNSStorage, &ptr->q, info, q_stop);
+ LogMcastQ(&ptr->q, info, q_stop);
freeL("browser_t/browse_termination_callback", ptr);
}
}
@@ -2309,10 +2212,6 @@ mDNSlocal void udsserver_automatic_browse_domain_changed(const DNameListElem *co
request_state *request;
debugf("udsserver_automatic_browse_domain_changed: %s default browse domain %##s", add ? "Adding" : "Removing", d->name.c);
-#if APPLE_OSX_mDNSResponder
- machserver_automatic_browse_domain_changed(&d->name, add);
-#endif // APPLE_OSX_mDNSResponder
-
for (request = all_requests; request; request = request->next)
{
if (request->terminate != browse_termination_callback) continue; // Not a browse operation
@@ -2537,7 +2436,7 @@ mDNSexport void udsserver_handle_configchange(mDNS *const m)
// Let the platform layer get the current DNS information
mDNS_Lock(m);
- mDNSPlatformSetDNSConfig(m, mDNSfalse, mDNSfalse, mDNSNULL, &RegDomains, &BrowseDomains, mDNSfalse);
+ mDNSPlatformSetDNSConfig(mDNSfalse, mDNSfalse, mDNSNULL, &RegDomains, &BrowseDomains, mDNSfalse);
mDNS_Unlock(m);
// Any automatic registration domains are also implicitly automatic browsing domains
@@ -2619,7 +2518,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
- // The browse is scoped to a specific interface index, but the
+ // The browse is scoped to a specific interface index, but the
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
@@ -2669,7 +2568,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
if (!MakeDomainNameFromDNSNameString(&temp, regtype)) return(mStatus_BadParamErr);
// For over-long service types, we only allow domain "local"
- if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrCopy(domain, "local.");
+ if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrLCopy(domain, "local.", sizeof(domain));
// Set up browser info
request->u.browser.ForceMCast = (flags & kDNSServiceFlagsForceMulticast) != 0;
@@ -2678,8 +2577,8 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
request->u.browser.default_domain = !domain[0];
request->u.browser.browsers = NULL;
- LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\", \"%s\") START PID[%d](%s)",
- request->sd, request->flags, interfaceIndex, request->u.browser.regtype.c, domain, request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\", \"%s\") START PID[%d](%s)",
+ request->sd, request->flags, interfaceIndex, request->u.browser.regtype.c, domain, request->process_id, request->pid_name);
if (request->u.browser.default_domain)
{
@@ -2734,13 +2633,17 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
size_t len = 0;
- char fullname[MAX_ESCAPED_DOMAIN_NAME], target[MAX_ESCAPED_DOMAIN_NAME];
+ char fullname[MAX_ESCAPED_DOMAIN_NAME], target[MAX_ESCAPED_DOMAIN_NAME] = "0";
char *data;
reply_state *rep;
request_state *req = question->QuestionContext;
+ const DNSServiceErrorType error =
+ (answer->RecordType == kDNSRecordTypePacketNegative) ? kDNSServiceErr_NoSuchRecord : kDNSServiceErr_NoError;
(void)m; // Unused
- LogOperation("%3d: DNSServiceResolve(%##s) %s %s", req->sd, question->qname.c, AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
+ LogOperation("%3d: DNSServiceResolve(%##s) %s interface %d: %s",
+ req->sd, question->qname.c, AddRecord ? "ADD" : "RMV",
+ mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse), RRDisplayString(m, answer));
if (!AddRecord)
{
@@ -2755,7 +2658,9 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con
if (!req->u.resolve.txt || !req->u.resolve.srv) return; // only deliver result to client if we have both answers
ConvertDomainNameToCString(answer->name, fullname);
- ConvertDomainNameToCString(&req->u.resolve.srv->rdata->u.srv.target, target);
+
+ if (answer->RecordType != kDNSRecordTypePacketNegative)
+ ConvertDomainNameToCString(&req->u.resolve.srv->rdata->u.srv.target, target);
// calculate reply length
len += sizeof(DNSServiceFlags);
@@ -2770,7 +2675,7 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con
rep = create_reply(resolve_reply_op, len, req);
rep->rhdr->flags = dnssd_htonl(0);
rep->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse));
- rep->rhdr->error = dnssd_htonl(kDNSServiceErr_NoError);
+ rep->rhdr->error = dnssd_htonl(error);
data = (char *)&rep->rhdr[1];
@@ -2788,11 +2693,12 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con
mDNSlocal void resolve_termination_callback(request_state *request)
{
- LogOperation("%3d: DNSServiceResolve(%##s) STOP PID[%d](%s)", request->sd, request->u.resolve.qtxt.qname.c, request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceResolve(%X, %d, \"%##s\") STOP PID[%d](%s)",
+ request->sd, request->flags, request->interfaceIndex, request->u.resolve.qtxt.qname.c, request->process_id, request->pid_name);
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qtxt);
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
- LogMcastQ(&mDNSStorage, &request->u.resolve.qsrv, request, q_stop);
- if (request->u.resolve.external_advertise)
+ LogMcastQ(&request->u.resolve.qsrv, request, q_stop);
+ if (request->u.resolve.external_advertise)
external_stop_resolving_service(request->u.resolve.qsrv.InterfaceID, &request->u.resolve.qsrv.qname, request->flags);
}
@@ -2818,7 +2724,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
- // The operation is scoped to a specific interface index, but the
+ // The operation is scoped to a specific interface index, but the
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
@@ -2847,6 +2753,15 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
mDNSPlatformMemZero(&request->u.resolve, sizeof(request->u.resolve));
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ // Determine if this request should be promoted to use BLE triggered discovery.
+ if (shouldUseBLE(InterfaceID, 0, (domainname *)SkipLeadingLabels(&fqdn, 1), &fqdn))
+ {
+ flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ LogInfo("handle_resolve_request: request promoted to use kDNSServiceFlagsAutoTrigger");
+ }
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+
request->flags = flags;
request->interfaceIndex = interfaceIndex;
@@ -2862,8 +2777,6 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qsrv.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
request->u.resolve.qsrv.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
request->u.resolve.qsrv.SuppressUnusable = mDNSfalse;
- request->u.resolve.qsrv.DenyOnCellInterface = mDNSfalse;
- request->u.resolve.qsrv.DenyOnExpInterface = mDNSfalse;
request->u.resolve.qsrv.SearchListIndex = 0;
request->u.resolve.qsrv.AppendSearchDomains = 0;
request->u.resolve.qsrv.RetryWithSearchDomains = mDNSfalse;
@@ -2891,8 +2804,6 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qtxt.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
request->u.resolve.qtxt.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
request->u.resolve.qtxt.SuppressUnusable = mDNSfalse;
- request->u.resolve.qtxt.DenyOnCellInterface = mDNSfalse;
- request->u.resolve.qtxt.DenyOnExpInterface = mDNSfalse;
request->u.resolve.qtxt.SearchListIndex = 0;
request->u.resolve.qtxt.AppendSearchDomains = 0;
request->u.resolve.qtxt.RetryWithSearchDomains = mDNSfalse;
@@ -2918,21 +2829,22 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
#endif
// ask the questions
- LogOperation("%3d: DNSServiceResolve(%X %d %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex,
- request->u.resolve.qsrv.qname.c, request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceResolve(%X, %d, \"%##s\") START PID[%d](%s)", request->sd, flags, interfaceIndex,
+ request->u.resolve.qsrv.qname.c, request->process_id, request->pid_name);
+
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qsrv);
-
+
if (!err)
{
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qtxt);
if (err)
- {
+ {
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
}
else
{
request->terminate = resolve_termination_callback;
- LogMcastQ(&mDNSStorage, &request->u.resolve.qsrv, request, q_start);
+ LogMcastQ(&request->u.resolve.qsrv, request, q_start);
if (callExternalHelpers(InterfaceID, &fqdn, flags))
{
request->u.resolve.external_advertise = mDNStrue;
@@ -2959,7 +2871,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
// Returns -1 to tell the caller that it should not try to reissue the query anymore
// Returns 1 on successfully appending a search domain and the caller should reissue the new query
// Returns 0 when there are no more search domains and the caller should reissue the query
-mDNSlocal int AppendNewSearchDomain(mDNS *const m, DNSQuestion *question)
+mDNSlocal int AppendNewSearchDomain(DNSQuestion *question)
{
domainname *sd;
mStatus err;
@@ -2988,7 +2900,7 @@ mDNSlocal int AppendNewSearchDomain(mDNS *const m, DNSQuestion *question)
LogInfo("AppendSearchDomain: qnameOrig %##s", question->qnameOrig->c);
}
- sd = uDNS_GetNextSearchDomain(m, question->InterfaceID, &question->SearchListIndex, !question->AppendLocalSearchDomains);
+ sd = uDNS_GetNextSearchDomain(question->InterfaceID, &question->SearchListIndex, !question->AppendLocalSearchDomains);
// We use -1 to indicate that we have searched all the domains and should try the single label
// query directly on the wire. uDNS_GetNextSearchDomain should never return a negative value
if (question->SearchListIndex == -1)
@@ -3008,7 +2920,7 @@ mDNSlocal int AppendNewSearchDomain(mDNS *const m, DNSQuestion *question)
// without appending search domains, then we are done.
if (!sd && !ApplySearchDomainsFirst(question))
{
- LogInfo("AppnedNewSearchDomain: No more search domains for question with name %##s (%s), not trying anymore", question->qname.c, DNSTypeName(question->qtype));
+ LogInfo("AppendNewSearchDomain: No more search domains for question with name %##s (%s), not trying anymore", question->qname.c, DNSTypeName(question->qtype));
return -1;
}
@@ -3059,7 +2971,7 @@ mDNSlocal mDNSBool DomainInSearchList(const domainname *domain, mDNSBool exclude
}
// The caller already checks that this is a dotlocal question.
-mDNSlocal mDNSBool ShouldDeliverNegativeResponse(mDNS *const m, DNSQuestion *question)
+mDNSlocal mDNSBool ShouldDeliverNegativeResponse(DNSQuestion *question)
{
mDNSu16 qtype;
@@ -3085,7 +2997,7 @@ mDNSlocal mDNSBool ShouldDeliverNegativeResponse(mDNS *const m, DNSQuestion *que
return mDNSfalse;
}
qtype = (question->qtype == kDNSType_A ? kDNSType_AAAA : kDNSType_A);
- if (!mDNS_CheckForCacheRecord(m, question, qtype))
+ if (!mDNS_CheckForCacheRecord(&mDNSStorage, question, qtype))
{
LogOperation("ShouldDeliverNegativeResponse:Question %##s (%s) not answering local question with negative unicast response"
" (can't find positive record)", question->qname.c, DNSTypeName(question->qtype));
@@ -3202,14 +3114,14 @@ mDNSlocal mStatus SendAdditionalQuery(DNSQuestion *q, request_state *request, mS
(void) q;
(void) request;
(void) err;
-
+
return mStatus_NoError;
#endif // !UNICAST_DISABLED
}
#endif // APPLE_OSX_mDNSResponder
// This function tries to append a search domain if valid and possible. If so, returns true.
-mDNSlocal mDNSBool RetryQuestionWithSearchDomains(mDNS *const m, DNSQuestion *question, request_state *req, QC_result AddRecord)
+mDNSlocal mDNSBool RetryQuestionWithSearchDomains(DNSQuestion *question, request_state *req, QC_result AddRecord)
{
int result;
// RetryWithSearchDomains tells the core to call us back so that we can retry with search domains if there is no
@@ -3223,7 +3135,7 @@ mDNSlocal mDNSBool RetryQuestionWithSearchDomains(mDNS *const m, DNSQuestion *qu
if ((AddRecord != QC_suppressed) && question->SearchListIndex != -1 && question->AppendSearchDomains)
{
question->RetryWithSearchDomains = 0;
- result = AppendNewSearchDomain(m, question);
+ result = AppendNewSearchDomain(question);
// As long as the result is either zero or 1, we retry the question. If we exahaust the search
// domains (result is zero) we try the original query (as it was before appending the search
// domains) as such on the wire as a last resort if we have not tried them before. For queries
@@ -3232,7 +3144,7 @@ mDNSlocal mDNSBool RetryQuestionWithSearchDomains(mDNS *const m, DNSQuestion *qu
if (result != -1)
{
mStatus err;
- err = mDNS_StartQuery(m, question);
+ err = mDNS_StartQuery(&mDNSStorage, question);
if (!err)
{
LogOperation("%3d: RetryQuestionWithSearchDomains(%##s, %s), retrying after appending search domain", req->sd, question->qname.c, DNSTypeName(question->qtype));
@@ -3268,9 +3180,10 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
ConvertDomainNameToCString(answer->name, name);
- LogOperation("%3d: %s(%##s, %s) %s %s", req->sd,
+ LogOperation("%3d: %s(%##s, %s) RESULT %s interface %d: %s", req->sd,
req->hdr.op == query_request ? "DNSServiceQueryRecord" : "DNSServiceGetAddrInfo",
- question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
+ question->qname.c, DNSTypeName(question->qtype), AddRecord ? "ADD" : "RMV",
+ mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse), RRDisplayString(m, answer));
len = sizeof(DNSServiceFlags); // calculate reply data length
len += sizeof(mDNSu32); // interface index
@@ -3283,7 +3196,7 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
rep = create_reply(req->hdr.op == query_request ? query_reply_op : addrinfo_reply_op, len, req);
if (AddRecord)
- flags |= kDNSServiceFlagsAdd;
+ flags |= kDNSServiceFlagsAdd;
if (question->ValidationStatus != 0)
{
error = kDNSServiceErr_NoError;
@@ -3308,7 +3221,7 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
}
}
}
-
+
rep->rhdr->flags = dnssd_htonl(flags);
// Call mDNSPlatformInterfaceIndexfromInterfaceID, but suppressNetworkChange (last argument). Otherwise, if the
// InterfaceID is not valid, then it simulates a "NetworkChanged" which in turn makes questions
@@ -3517,7 +3430,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
// As we ignore negative unicast answers below, we would never reach the code where the search domains are appended.
// To keep things simple, we handle unicast ".local" separately here.
LogInfo("queryrecord_result_callback: Retrying .local question %##s (%s) as unicast after appending search domains", question->qname.c, DNSTypeName(question->qtype));
- if (RetryQuestionWithSearchDomains(m, question, req, AddRecord))
+ if (RetryQuestionWithSearchDomains(question, req, AddRecord))
return;
if (question->AppendSearchDomains && !question->AppendLocalSearchDomains && IsLocalDomain(&question->qname))
{
@@ -3581,7 +3494,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
return;
}
#if APPLE_OSX_mDNSResponder
- if (!ShouldDeliverNegativeResponse(m, question))
+ if (!ShouldDeliverNegativeResponse(question))
{
return;
}
@@ -3607,7 +3520,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
// normally happen just once because after we append .local, we ignore all negative
// responses for .local above.
LogInfo("queryrecord_result_callback: Retrying question %##s (%s) after appending search domains", question->qname.c, DNSTypeName(question->qtype));
- if (RetryQuestionWithSearchDomains(m, question, req, AddRecord))
+ if (RetryQuestionWithSearchDomains(question, req, AddRecord))
{
// Note: We need to call SendAdditionalQuery every time after appending a search domain as .local could
// be anywhere in the search domain list.
@@ -3625,12 +3538,12 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question,
mDNSlocal void queryrecord_termination_callback(request_state *request)
{
- LogOperation("%3d: DNSServiceQueryRecord(%##s, %s) STOP PID[%d](%s)",
- request->sd, request->u.queryrecord.q.qname.c, DNSTypeName(request->u.queryrecord.q.qtype), request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceQueryRecord(%X, %d, %##s, %s) STOP PID[%d](%s)",
+ request->sd, request->flags, request->interfaceIndex, request->u.queryrecord.q.qname.c, DNSTypeName(request->u.queryrecord.q.qtype), request->process_id, request->pid_name);
if (request->u.queryrecord.q.QuestionContext)
{
mDNS_StopQuery(&mDNSStorage, &request->u.queryrecord.q); // no need to error check
- LogMcastQ(&mDNSStorage, &request->u.queryrecord.q, request, q_stop);
+ LogMcastQ(&request->u.queryrecord.q, request, q_stop);
request->u.queryrecord.q.QuestionContext = mDNSNULL;
}
else
@@ -3645,10 +3558,10 @@ mDNSlocal void queryrecord_termination_callback(request_state *request)
request->u.queryrecord.q.qnameOrig = mDNSNULL;
}
- if (callExternalHelpers(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->flags))
+ if (callExternalHelpers(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->u.queryrecord.q.flags))
{
LogInfo("queryrecord_termination_callback: calling external_stop_browsing_for_service()");
- external_stop_browsing_for_service(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->u.queryrecord.q.qtype, request->flags);
+ external_stop_browsing_for_service(request->u.queryrecord.q.InterfaceID, &request->u.queryrecord.q.qname, request->u.queryrecord.q.qtype, request->u.queryrecord.q.flags);
}
if (request->u.queryrecord.q2)
{
@@ -3656,7 +3569,7 @@ mDNSlocal void queryrecord_termination_callback(request_state *request)
{
LogInfo("queryrecord_termination_callback: Stopping q2 %##s", request->u.queryrecord.q2->qname.c);
mDNS_StopQuery(&mDNSStorage, request->u.queryrecord.q2);
- LogMcastQ(&mDNSStorage, request->u.queryrecord.q2, request, q_stop);
+ LogMcastQ(request->u.queryrecord.q2, request, q_stop);
}
else
{
@@ -3684,46 +3597,17 @@ mDNSlocal void queryrecord_termination_callback(request_state *request)
v4q = &request->u.queryrecord.q;
else if (request->u.queryrecord.q.qtype == kDNSType_AAAA)
v6q = &request->u.queryrecord.q;
- mDNSPlatformTriggerDNSRetry(&mDNSStorage, v4q, v6q);
+ mDNSPlatformTriggerDNSRetry(v4q, v6q);
}
}
#endif // APPLE_OSX_mDNSResponder
}
-mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
-{
- int i;
- q->euid = req->uid;
- // The policy is either based on pid or UUID. Pass a zero pid
- // to the "core" if the UUID is valid. If we always pass the pid,
- // then the "core" needs to determine whether the uuid is valid
- // by examining all the 16 bytes at the time of the policy
- // check and also when setting the delegate socket option. Also, it
- // requires that we zero out the uuid wherever the question is
- // initialized to make sure that it is not interpreted as valid.
- // To prevent these intrusive changes, just pass a zero pid to indicate
- // that pid is not valid when uuid is valid. In future if we need the
- // pid in the question, we will reevaluate this strategy.
- if (req->validUUID)
- {
- for (i = 0; i < UUID_SIZE; i++)
- {
- q->uuid[i] = req->uuid[i];
- }
- q->pid = 0;
- }
- else
- {
- q->pid = req->process_id;
- }
-
- //debugf("SetQuestionPolicy: q->euid[%d] q->pid[%d] uuid is valid : %s", q->euid, q->pid, req->validUUID ? "true" : "false");
-}
-
mDNSlocal mStatus handle_queryrecord_request(request_state *request)
{
DNSQuestion *const q = &request->u.queryrecord.q;
char name[256];
+ size_t nameLen;
mDNSu16 rrtype, rrclass;
mStatus err;
@@ -3731,10 +3615,13 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
- // The request is scoped to a specific interface index, but the
+ // The request is scoped to a specific interface index, but the
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
+ if (interfaceIndex > 1)
+ LogMsg("handle_queryrecord_request: interfaceIndex %d is currently inactive requested by client[%d][%s]",
+ interfaceIndex, request->process_id, request->pid_name);
// If it's one of the specially defined inteface index values, just return an error.
// Also, caller should return an error immediately if lo0 (index 1) is not configured
// into the current active interfaces. See background in Radar 21967160.
@@ -3778,8 +3665,6 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
q->TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
q->WakeOnResolve = 0;
q->UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
- q->DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular) != 0;
- q->DenyOnExpInterface = (flags & kDNSServiceFlagsDenyExpensive) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
q->ValidationRequired = DNSSEC_VALIDATION_SECURE;
else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
@@ -3790,6 +3675,7 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
q->QuestionCallback = queryrecord_result_callback;
q->QuestionContext = request;
q->SearchListIndex = 0;
+ q->StopTime = 0;
q->DNSSECAuthInfo = mDNSNULL;
q->DAIFreeCallback = mDNSNULL;
@@ -3797,19 +3683,20 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
//Turn off dnssec validation for local domains and Question Types: RRSIG/ANY(ANY Type is not supported yet)
if ((IsLocalDomain(&q->qname)) || (q->qtype == kDNSServiceType_RRSIG) || (q->qtype == kDNSServiceType_ANY))
q->ValidationRequired = 0;
-
+
// Don't append search domains for fully qualified domain names including queries
// such as e.g., "abc." that has only one label. We convert all names to FQDNs as internally
// we only deal with FQDNs. Hence, we cannot look at qname to figure out whether we should
// append search domains or not. So, we record that information in AppendSearchDomains.
//
- // We append search domains only for queries that are a single label. If overriden using command line
+ // We append search domains only for queries that are a single label. If overriden using command line
// argument "AlwaysAppendSearchDomains", then we do it for any query which is not fully qualified.
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set.
- if ((!(q->ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(q->ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && (rrtype == kDNSType_A || rrtype == kDNSType_AAAA) && name[strlen(name) - 1] != '.' &&
- (AlwaysAppendSearchDomains || CountLabels(&q->qname) == 1))
+ nameLen = strlen(name);
+ if ((!(q->ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(q->ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && (rrtype == kDNSType_A || rrtype == kDNSType_AAAA) && ((nameLen == 0) || (name[nameLen - 1] != '.')) &&
+ (AlwaysAppendSearchDomains || CountLabels(&q->qname) == 1))
{
q->AppendSearchDomains = 1;
q->AppendLocalSearchDomains = 1;
@@ -3828,10 +3715,20 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
q->qnameOrig = mDNSNULL;
SetQuestionPolicy(q, request);
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ // Determine if this request should be promoted to use BLE triggered discovery.
+ if (shouldUseBLE(InterfaceID, rrtype, (domainname *)SkipLeadingLabels(&q->qname, 1), &q->qname))
+ {
+ q->flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ request->flags |= (kDNSServiceFlagsAutoTrigger | kDNSServiceFlagsIncludeAWDL);
+ LogInfo("handle_queryrecord_request: request promoted to use kDNSServiceFlagsAutoTrigger");
+ }
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+
LogOperation("%3d: DNSServiceQueryRecord(%X, %d, %##s, %s) START PID[%d](%s)",
- request->sd, flags, interfaceIndex, q->qname.c, DNSTypeName(q->qtype), request->process_id, request->pid_name);
+ request->sd, request->flags, interfaceIndex, q->qname.c, DNSTypeName(q->qtype), request->process_id, request->pid_name);
err = mDNS_StartQuery(&mDNSStorage, q);
-
+
if (err)
{
LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q->qname.c, DNSTypeName(q->qtype), (int)err);
@@ -3839,11 +3736,11 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
else
{
request->terminate = queryrecord_termination_callback;
- LogMcastQ(&mDNSStorage, q, request, q_start);
- if (callExternalHelpers(q->InterfaceID, &q->qname, flags))
+ LogMcastQ(q, request, q_start);
+ if (callExternalHelpers(q->InterfaceID, &q->qname, q->flags))
{
LogInfo("handle_queryrecord_request: calling external_start_browsing_for_service()");
- external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, flags);
+ external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, q->flags);
}
}
@@ -3892,7 +3789,8 @@ mDNSlocal void enum_termination_callback(request_state *request)
else
{
LogInfo("%3d: DNSServiceEnumeration Cancel WAB Browse PID[%d](%s)", request->sd, request->process_id, request->pid_name);
- uDNS_StopWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY);
+ uDNS_StopWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY | UDNS_WAB_LBROWSE_QUERY);
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_autoall);
}
mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_default);
@@ -3930,7 +3828,7 @@ mDNSlocal void enum_result_callback(mDNS *const m,
reply = format_enumeration_reply(request, domain, flags, kDNSServiceInterfaceIndexAny, kDNSServiceErr_NoError);
if (!reply) { LogMsg("ERROR: enum_result_callback, format_enumeration_reply"); return; }
- LogOperation("%3d: DNSServiceEnumerateDomains(%#2s) RESULT %s: %s", request->sd, question->qname.c, AddRecord ? "Add" : "Rmv", domain);
+ LogOperation("%3d: DNSServiceEnumerateDomains(%#2s) RESULT %s: %s", request->sd, question->qname.c, AddRecord ? "ADD" : "RMV", domain);
append_reply(request, reply);
}
@@ -3959,6 +3857,7 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
// necessary context can be reached from the callbacks
request->u.enumeration.q_all.QuestionContext = request;
request->u.enumeration.q_default.QuestionContext = request;
+ if (!reg) request->u.enumeration.q_autoall.QuestionContext = request;
// if the caller hasn't specified an explicit interface, we use local-only to get the system-wide list.
if (!InterfaceID) InterfaceID = mDNSInterface_LocalOnly;
@@ -3972,7 +3871,16 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
{
err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_default, t_default, NULL, InterfaceID, enum_result_callback, request);
if (err) mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
- else request->terminate = enum_termination_callback;
+ else if (!reg)
+ {
+ err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_autoall, mDNS_DomainTypeBrowseAutomatic, NULL, InterfaceID, enum_result_callback, request);
+ if (err)
+ {
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_default);
+ }
+ }
+ if (!err) request->terminate = enum_termination_callback;
}
if (!err)
{
@@ -3982,10 +3890,10 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
LogInfo("%3d: DNSServiceEnumerateDomains Start WAB Registration PID[%d](%s)", request->sd, request->process_id, request->pid_name);
uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_REG_QUERY);
}
- else
+ else
{
LogInfo("%3d: DNSServiceEnumerateDomains Start WAB Browse PID[%d](%s)", request->sd, request->process_id, request->pid_name);
- uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY);
+ uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY | UDNS_WAB_LBROWSE_QUERY);
}
}
@@ -4007,10 +3915,11 @@ mDNSlocal mStatus handle_reconfirm_request(request_state *request)
status = mDNS_ReconfirmByValue(&mDNSStorage, &rr->resrec);
LogOperation(
(status == mStatus_NoError) ?
- "%3d: DNSServiceReconfirmRecord(%s) interface %d initiated" :
- "%3d: DNSServiceReconfirmRecord(%s) interface %d failed: %d",
+ "%3d: DNSServiceReconfirmRecord(%s) interface %d initiated PID[%d](%s)" :
+ "%3d: DNSServiceReconfirmRecord(%s) interface %d failed PID[%d](%s) status %d",
request->sd, RRDisplayString(&mDNSStorage, &rr->resrec),
- mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, rr->resrec.InterfaceID, mDNSfalse), status);
+ mDNSPlatformInterfaceIndexfromInterfaceID(&mDNSStorage, rr->resrec.InterfaceID, mDNSfalse),
+ request->process_id, request->pid_name, status);
freeL("AuthRecord/handle_reconfirm_request", rr);
}
return(status);
@@ -4049,7 +3958,7 @@ mDNSlocal mStatus handle_release_request(request_state *request)
LogOperation("%3d: PeerConnectionRelease(%X %##s) START PID[%d](%s)",
request->sd, flags, instance.c, request->process_id, request->pid_name);
-
+
external_connection_release(&instance);
return(err);
}
@@ -4058,7 +3967,7 @@ mDNSlocal mStatus handle_release_request(request_state *request)
mDNSlocal mStatus handle_release_request(request_state *request)
{
- (void) request;
+ (void) request;
return mStatus_UnsupportedErr;
}
@@ -4113,6 +4022,10 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
mDNSs32 pid;
socklen_t len;
+ LogOperation("%3d: DNSServiceCreateDelegateConnection START PID[%d](%s)",
+ request->sd, request->process_id, request->pid_name);
+ request->terminate = connection_termination;
+
len = 0;
pid = get_uint32(&request->msgptr, request->msgend);
#ifdef LOCAL_PEEREPID
@@ -4120,11 +4033,14 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
{
len = sizeof(pid);
if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREPID, &request->process_id, &len) != 0)
+ {
+ LogMsg("handle_connection_delegate_request: getsockopt for LOCAL_PEEREPID failed errno:%d / %s", errno, strerror(errno));
return;
+ }
// to extract the process name from the pid value
if (proc_pidinfo(request->process_id, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
return;
- mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
+ mDNSPlatformStrLCopy(request->pid_name, proc.pbsi_comm, sizeof(request->pid_name));
debugf("handle_connection_delegate_request: process id %d, name %s", request->process_id, request->pid_name);
}
#endif
@@ -4133,7 +4049,10 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
{
len = UUID_SIZE;
if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREUUID, request->uuid, &len) != 0)
+ {
+ LogMsg("handle_connection_delegate_request: getsockopt for LOCAL_PEEREUUID failed errno:%d / %s", errno, strerror(errno));
return;
+ }
request->validUUID = mDNStrue;
}
#endif
@@ -4201,7 +4120,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
}
}
}
-
+
pi.err = 0;
pi.pid = pid;
send_all(request->sd, (const char *)&pi, sizeof(PIDInfo));
@@ -4220,8 +4139,8 @@ mDNSlocal void port_mapping_termination_callback(request_state *request)
{
LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) STOP PID[%d](%s)", request->sd,
DNSServiceProtocol(request->u.pm.NATinfo.Protocol),
- mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
- request->process_id, request->pid_name);
+ mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
+ request->process_id, request->pid_name);
mDNS_StopNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
}
@@ -4313,8 +4232,8 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
request->u.pm.NATinfo.clientContext = request;
LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) START PID[%d](%s)", request->sd,
- protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
- request->process_id, request->pid_name);
+ protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
+ request->process_id, request->pid_name);
err = mDNS_StartNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
if (err) LogMsg("ERROR: mDNS_StartNATOperation: %d", (int)err);
else request->terminate = port_mapping_termination_callback;
@@ -4331,13 +4250,19 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
mDNSlocal void addrinfo_termination_callback(request_state *request)
{
LogOperation("%3d: DNSServiceGetAddrInfo(%##s) STOP PID[%d](%s)", request->sd, request->u.addrinfo.q4.qname.c,
- request->process_id, request->pid_name);
+ request->process_id, request->pid_name);
if (request->u.addrinfo.q4.QuestionContext)
{
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q4);
- LogMcastQ(&mDNSStorage, &request->u.addrinfo.q4, request, q_stop);
+ LogMcastQ(&request->u.addrinfo.q4, request, q_stop);
request->u.addrinfo.q4.QuestionContext = mDNSNULL;
+
+ if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, request->flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_A record");
+ external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, kDNSServiceType_A, request->flags);
+ }
}
if (request->u.addrinfo.q4.qnameOrig)
{
@@ -4350,7 +4275,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
{
LogInfo("addrinfo_termination_callback: Stopping q42 %##s", request->u.addrinfo.q42->qname.c);
mDNS_StopQuery(&mDNSStorage, request->u.addrinfo.q42);
- LogMcastQ(&mDNSStorage, request->u.addrinfo.q42, request, q_stop);
+ LogMcastQ(request->u.addrinfo.q42, request, q_stop);
}
if (request->u.addrinfo.q42->qnameOrig)
{
@@ -4365,8 +4290,14 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
if (request->u.addrinfo.q6.QuestionContext)
{
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q6);
- LogMcastQ(&mDNSStorage, &request->u.addrinfo.q6, request, q_stop);
+ LogMcastQ(&request->u.addrinfo.q6, request, q_stop);
request->u.addrinfo.q6.QuestionContext = mDNSNULL;
+
+ if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, request->flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, kDNSServiceType_AAAA, request->flags);
+ }
}
if (request->u.addrinfo.q6.qnameOrig)
{
@@ -4379,7 +4310,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
{
LogInfo("addrinfo_termination_callback: Stopping q62 %##s", request->u.addrinfo.q62->qname.c);
mDNS_StopQuery(&mDNSStorage, request->u.addrinfo.q62);
- LogMcastQ(&mDNSStorage, request->u.addrinfo.q62, request, q_stop);
+ LogMcastQ(request->u.addrinfo.q62, request, q_stop);
}
if (request->u.addrinfo.q62->qnameOrig)
{
@@ -4401,7 +4332,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
// valid response again.
if (request->u.addrinfo.q4.TimeoutQuestion && !request->u.addrinfo.v4ans)
{
- mDNSPlatformUpdateDNSStatus(&mDNSStorage, &request->u.addrinfo.q4);
+ mDNSPlatformUpdateDNSStatus(&request->u.addrinfo.q4);
}
// If we have a v4 answer and if we timed out prematurely before, provide
// a trigger to the upper layer so that it can retry questions if needed.
@@ -4412,12 +4343,12 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
{
if (request->u.addrinfo.q6.TimeoutQuestion && !request->u.addrinfo.v6ans)
{
- mDNSPlatformUpdateDNSStatus(&mDNSStorage, &request->u.addrinfo.q6);
+ mDNSPlatformUpdateDNSStatus(&request->u.addrinfo.q6);
}
if (request->u.addrinfo.v6ans)
v6q = &request->u.addrinfo.q6;
}
- mDNSPlatformTriggerDNSRetry(&mDNSStorage, v4q, v6q);
+ mDNSPlatformTriggerDNSRetry(v4q, v6q);
}
#endif // APPLE_OSX_mDNSResponder
}
@@ -4425,13 +4356,14 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
mDNSlocal mStatus handle_addrinfo_request(request_state *request)
{
char hostname[256];
+ size_t hostnameLen;
domainname d;
mStatus err = 0;
mDNSs32 serviceIndex = -1; // default unscoped value for ServiceID is -1
mDNSInterfaceID InterfaceID;
-
+
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
-
+
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
if (flags & kDNSServiceFlagsServiceIndex)
@@ -4443,15 +4375,18 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
serviceIndex = interfaceIndex;
interfaceIndex = 0;
}
-
+
mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
- // The request is scoped to a specific interface index, but the
+ // The request is scoped to a specific interface index, but the
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
+ if (interfaceIndex > 1)
+ LogMsg("handle_addrinfo_request: interfaceIndex %d is currently inactive requested by client[%d][%s]",
+ interfaceIndex, request->process_id, request->pid_name);
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
@@ -4459,7 +4394,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
return(mStatus_BadParamErr);
}
- // Otherwise, use the specified interface index value and the registration will
+ // Otherwise, use the specified interface index value and the request will
// be applied to that interface when it comes up.
InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
LogInfo("handle_addrinfo_request: query pending for interface index %d", interfaceIndex);
@@ -4504,8 +4439,6 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
request->u.addrinfo.q4.TimeoutQuestion = request->u.addrinfo.q6.TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
request->u.addrinfo.q4.WakeOnResolve = request->u.addrinfo.q6.WakeOnResolve = 0;
request->u.addrinfo.q4.UseBackgroundTrafficClass = request->u.addrinfo.q6.UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
- request->u.addrinfo.q4.DenyOnCellInterface = request->u.addrinfo.q6.DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular) != 0;
- request->u.addrinfo.q4.DenyOnExpInterface = request->u.addrinfo.q6.DenyOnExpInterface = (flags & kDNSServiceFlagsDenyExpensive) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = DNSSEC_VALIDATION_SECURE;
else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
@@ -4518,6 +4451,8 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
SetQuestionPolicy(&request->u.addrinfo.q4, request);
SetQuestionPolicy(&request->u.addrinfo.q6, request);
+ request->u.addrinfo.q4.StopTime = request->u.addrinfo.q6.StopTime = 0;
+
request->u.addrinfo.q4.DNSSECAuthInfo = request->u.addrinfo.q6.DNSSECAuthInfo = mDNSNULL;
request->u.addrinfo.q4.DAIFreeCallback = request->u.addrinfo.q6.DAIFreeCallback = mDNSNULL;
@@ -4525,13 +4460,18 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
if (IsLocalDomain(&d))
request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = 0;
+ hostnameLen = strlen(hostname);
+
+ LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)",
+ request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
+
if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv6)
{
request->u.addrinfo.q6.qtype = kDNSServiceType_AAAA;
request->u.addrinfo.q6.SearchListIndex = 0;
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set
- if ((!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
+ if ((!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && ((hostnameLen == 0) || (hostname[hostnameLen - 1] != '.')) && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
{
request->u.addrinfo.q6.AppendSearchDomains = 1;
request->u.addrinfo.q6.AppendLocalSearchDomains = 1;
@@ -4554,9 +4494,14 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
err = SendAdditionalQuery(&request->u.addrinfo.q6, request, err);
#endif // APPLE_OSX_mDNSResponder
if (!err)
- {
+ {
request->terminate = addrinfo_termination_callback;
- LogMcastQ(&mDNSStorage, &request->u.addrinfo.q6, request, q_start);
+ LogMcastQ(&request->u.addrinfo.q6, request, q_start);
+ if (callExternalHelpers(InterfaceID, &d, flags))
+ {
+ LogInfo("handle_addrinfo_request: calling external_start_browsing_for_service() for kDNSServiceType_AAAA record");
+ external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags);
+ }
}
}
@@ -4569,8 +4514,8 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
// "AlwaysAppendSearchDomains", then we do it for any query which is not fully qualified.
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set.
- if ((!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
+ if ((!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && ((hostnameLen == 0) || (hostname[hostnameLen - 1] != '.')) && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
{
request->u.addrinfo.q4.AppendSearchDomains = 1;
request->u.addrinfo.q4.AppendLocalSearchDomains = 1;
@@ -4589,11 +4534,17 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
request->u.addrinfo.q4.QuestionContext = mDNSNULL;
if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv6)
- {
- // If we started a query for IPv6, we need to cancel it
+ {
+ // If we started a query for IPv6, we need to cancel it
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q6);
request->u.addrinfo.q6.QuestionContext = mDNSNULL;
- }
+
+ if (callExternalHelpers(InterfaceID, &d, flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ external_stop_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags);
+ }
+ }
}
#if APPLE_OSX_mDNSResponder
err = SendAdditionalQuery(&request->u.addrinfo.q4, request, err);
@@ -4601,11 +4552,15 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
if (!err)
{
request->terminate = addrinfo_termination_callback;
- LogMcastQ(&mDNSStorage, &request->u.addrinfo.q4, request, q_start);
- }
+ LogMcastQ(&request->u.addrinfo.q4, request, q_start);
+ if (callExternalHelpers(InterfaceID, &d, flags))
+ {
+ LogInfo("handle_addrinfo_request: calling external_start_browsing_for_service() for kDNSServiceType_A record");
+ external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_A, flags);
+ }
+ }
}
- LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
return(err);
}
@@ -4618,10 +4573,10 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
mDNSlocal request_state *NewRequest(void)
{
request_state **p = &all_requests;
- while (*p)
+ while (*p)
p=&(*p)->next;
*p = mallocL("request_state", sizeof(request_state));
- if (!*p)
+ if (!*p)
FatalError("ERROR: malloc");
mDNSPlatformMemZero(*p, sizeof(request_state));
return(*p);
@@ -4723,7 +4678,7 @@ mDNSlocal void read_msg(request_state *req)
{
dnssd_sock_t x = *(dnssd_sock_t *)CMSG_DATA(cmsg);
LogOperation("%3d: Got len %d, BPF %d", req->sd, cmsg->cmsg_len, x);
- mDNSPlatformReceiveBPF_fd(&mDNSStorage, x);
+ mDNSPlatformReceiveBPF_fd(x);
}
else
#endif // APPLE_OSX_mDNSResponder
@@ -4762,7 +4717,7 @@ mDNSlocal void read_msg(request_state *req)
get_string(&req->msgptr, req->msgend, ctrl_path, MAX_CTLPATH); // path is first element in message buffer
mDNSPlatformMemZero(&cliaddr, sizeof(cliaddr));
cliaddr.sun_family = AF_LOCAL;
- mDNSPlatformStrCopy(cliaddr.sun_path, ctrl_path);
+ mDNSPlatformStrLCopy(cliaddr.sun_path, ctrl_path, sizeof(cliaddr.sun_path));
// If the error return path UDS name is empty string, that tells us
// that this is a new version of the library that's going to pass us
// the error return path socket via sendmsg/recvmsg
@@ -4775,8 +4730,8 @@ mDNSlocal void read_msg(request_state *req)
#endif
req->errsd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(req->errsd))
- {
+ if (!dnssd_SocketValid(req->errsd))
+ {
my_throttled_perror("ERROR: socket");
req->ts = t_error;
return;
@@ -4825,6 +4780,52 @@ rerror:
req->ts = t_error;
}
+mDNSlocal mStatus handle_client_request(request_state *req)
+{
+ mStatus err = mStatus_NoError;
+ switch(req->hdr.op)
+ {
+ // These are all operations that have their own first-class request_state object
+ case connection_request:
+ LogOperation("%3d: DNSServiceCreateConnection START PID[%d](%s)",
+ req->sd, req->process_id, req->pid_name);
+ req->terminate = connection_termination;
+ break;
+ case connection_delegate_request:
+ LogOperation("%3d: DNSServiceCreateDelegateConnection START PID[%d](%s)",
+ req->sd, req->process_id, req->pid_name);
+ req->terminate = connection_termination;
+ handle_connection_delegate_request(req);
+ break;
+ case resolve_request: err = handle_resolve_request (req); break;
+ case query_request: err = handle_queryrecord_request (req); break;
+ case browse_request: err = handle_browse_request (req); break;
+ case reg_service_request: err = handle_regservice_request (req); break;
+ case enumeration_request: err = handle_enum_request (req); break;
+ case reconfirm_record_request: err = handle_reconfirm_request (req); break;
+ case setdomain_request: err = handle_setdomain_request (req); break;
+ case getproperty_request: handle_getproperty_request (req); break;
+ case getpid_request: handle_getpid_request (req); break;
+ case port_mapping_request: err = handle_port_mapping_request(req); break;
+ case addrinfo_request: err = handle_addrinfo_request (req); break;
+ case send_bpf: /* Do nothing for send_bpf */ break;
+
+ // These are all operations that work with an existing request_state object
+ case reg_record_request: err = handle_regrecord_request (req); break;
+ case add_record_request: err = handle_add_request (req); break;
+ case update_record_request: err = handle_update_request (req); break;
+ case remove_record_request: err = handle_removerecord_request(req); break;
+ case cancel_request: handle_cancel_request (req); break;
+ case release_request: err = handle_release_request (req); break;
+ default: LogMsg("request_callback: %3d:ERROR: Unsupported UDS req:%d PID[%d][%s]",
+ req->sd, req->hdr.op, req->process_id, req->pid_name);
+ err = mStatus_BadParamErr;
+ break;
+ }
+
+ return err;
+}
+
#define RecordOrientedOp(X) \
((X) == reg_record_request || (X) == add_record_request || (X) == update_record_request || (X) == remove_record_request)
@@ -4842,23 +4843,16 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
for (;;)
{
read_msg(req);
- if (req->ts == t_morecoming)
+ if (req->ts == t_morecoming)
+ return;
+ if (req->ts == t_terminated || req->ts == t_error)
+ {
+ AbortUnlinkAndFree(req);
return;
- if (req->ts == t_terminated || req->ts == t_error)
- {
- AbortUnlinkAndFree(req);
- return;
- }
- if (req->ts != t_complete)
- {
- LogMsg("request_callback: req->ts %d != t_complete PID[%d][%s]", req->ts, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
}
- if (req->hdr.version != VERSION)
+ if (req->ts != t_complete)
{
- LogMsg("request_callback: ERROR: client IPC version %d incompatible with daemon IPC version %d PID[%d][%s]",
- req->hdr.version, VERSION, req->process_id, req->pid_name);
+ LogMsg("request_callback: req->ts %d != t_complete PID[%d][%s]", req->ts, req->process_id, req->pid_name);
AbortUnlinkAndFree(req);
return;
}
@@ -4885,24 +4879,24 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
case send_bpf: // Same as cancel_request below
case cancel_request: min_size = 0; break;
case release_request: min_size += sizeof(mDNSu32) + 3 /* type, type, domain */; break;
- default: LogMsg("request_callback: ERROR: validate_message - unsupported req type: %d PID[%d][%s]",
- req->hdr.op, req->process_id, req->pid_name);
+ default: LogMsg("request_callback: ERROR: validate_message - unsupported req type: %d PID[%d][%s]",
+ req->hdr.op, req->process_id, req->pid_name);
min_size = -1; break;
}
if ((mDNSs32)req->data_bytes < min_size)
- {
- LogMsg("request_callback: Invalid message %d bytes; min for %d is %d PID[%d][%s]",
- req->data_bytes, req->hdr.op, min_size, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
+ {
+ LogMsg("request_callback: Invalid message %d bytes; min for %d is %d PID[%d][%s]",
+ req->data_bytes, req->hdr.op, min_size, req->process_id, req->pid_name);
+ AbortUnlinkAndFree(req);
+ return;
}
if (LightweightOp(req->hdr.op) && !req->terminate)
- {
- LogMsg("request_callback: Reg/Add/Update/Remove %d require existing connection PID[%d][%s]",
- req->hdr.op, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
+ {
+ LogMsg("request_callback: Reg/Add/Update/Remove %d require existing connection PID[%d][%s]",
+ req->hdr.op, req->process_id, req->pid_name);
+ AbortUnlinkAndFree(req);
+ return;
}
// If req->terminate is already set, this means this operation is sharing an existing connection
@@ -4921,18 +4915,15 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
// relevant bits
if (req->validUUID)
{
- int i;
newreq->validUUID = mDNStrue;
- for (i = 0; i < UUID_SIZE; i++)
- {
- newreq->uuid[i] = req->uuid[i];
- }
+ mDNSPlatformMemCopy(newreq->uuid, req->uuid, UUID_SIZE);
}
else
{
if (req->process_id)
{
newreq->process_id = req->process_id;
+ mDNSPlatformStrLCopy(newreq->pid_name, req->pid_name, (mDNSu32)sizeof(newreq->pid_name));
}
else
{
@@ -4948,49 +4939,10 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
// If we're shutting down, don't allow new client requests
// We do allow "cancel" and "getproperty" during shutdown
if (mDNSStorage.ShutdownTime && req->hdr.op != cancel_request && req->hdr.op != getproperty_request)
- {
err = mStatus_ServiceNotRunning;
- }
else
- {
- switch(req->hdr.op)
- {
- // These are all operations that have their own first-class request_state object
- case connection_request:
- LogOperation("%3d: DNSServiceCreateConnection START PID[%d](%s)",
- req->sd, req->process_id, req->pid_name);
- req->terminate = connection_termination;
- break;
- case connection_delegate_request:
- LogOperation("%3d: DNSServiceCreateDelegateConnection START PID[%d](%s)",
- req->sd, req->process_id, req->pid_name);
- req->terminate = connection_termination;
- handle_connection_delegate_request(req);
- break;
- case resolve_request: err = handle_resolve_request (req); break;
- case query_request: err = handle_queryrecord_request (req); break;
- case browse_request: err = handle_browse_request (req); break;
- case reg_service_request: err = handle_regservice_request (req); break;
- case enumeration_request: err = handle_enum_request (req); break;
- case reconfirm_record_request: err = handle_reconfirm_request (req); break;
- case setdomain_request: err = handle_setdomain_request (req); break;
- case getproperty_request: handle_getproperty_request (req); break;
- case getpid_request: handle_getpid_request (req); break;
- case port_mapping_request: err = handle_port_mapping_request(req); break;
- case addrinfo_request: err = handle_addrinfo_request (req); break;
- case send_bpf: /* Do nothing for send_bpf */ break;
-
- // These are all operations that work with an existing request_state object
- case reg_record_request: err = handle_regrecord_request (req); break;
- case add_record_request: err = handle_add_request (req); break;
- case update_record_request: err = handle_update_request (req); break;
- case remove_record_request: err = handle_removerecord_request(req); break;
- case cancel_request: handle_cancel_request (req); break;
- case release_request: err = handle_release_request (req); break;
- default: LogMsg("request_callback: %3d:ERROR: Unsupported UDS req:%d PID[%d][%s]",
- req->sd, req->hdr.op, req->process_id, req->pid_name); break;
- }
- }
+ err = handle_client_request(req);
+
// req->msgbuf may be NULL, e.g. for connection_request or remove_record_request
if (req->msgbuf) freeL("request_state msgbuf", req->msgbuf);
@@ -5036,7 +4988,7 @@ mDNSlocal void connect_callback(int fd, short filter, void *info)
if (!dnssd_SocketValid(sd))
{
- if (dnssd_errno != dnssd_EWOULDBLOCK)
+ if (dnssd_errno != dnssd_EWOULDBLOCK)
my_throttled_perror("ERROR: accept");
return;
}
@@ -5114,7 +5066,7 @@ mDNSlocal mDNSBool uds_socket_setup(dnssd_sock_t skt)
return mDNSfalse;
}
else
- {
+ {
LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", skt);
mDNSStorage.uds_listener_skt = skt;
}
@@ -5135,7 +5087,7 @@ mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
FILE *fp = fopen(PID_FILE, "w");
if (fp != NULL)
{
- fprintf(fp, "%d\n", (int)getpid());
+ fprintf(fp, "%d\n", getpid());
fclose(fp);
}
}
@@ -5172,19 +5124,19 @@ mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
#else
{
mode_t mask = umask(0);
- unlink(MDNS_UDS_SERVERPATH); // OK if this fails
+ unlink(boundPath); // OK if this fails
laddr.sun_family = AF_LOCAL;
#ifndef NOT_HAVE_SA_LEN
// According to Stevens (section 3.2), there is no portable way to
// determine whether sa_len is defined on a particular platform.
laddr.sun_len = sizeof(struct sockaddr_un);
#endif
- if (strlen(MDNS_UDS_SERVERPATH) >= sizeof(laddr.sun_path))
+ if (strlen(boundPath) >= sizeof(laddr.sun_path))
{
LogMsg("ERROR: MDNS_UDS_SERVERPATH must be < %d characters", (int)sizeof(laddr.sun_path));
goto error;
}
- mDNSPlatformStrCopy(laddr.sun_path, MDNS_UDS_SERVERPATH);
+ mDNSPlatformStrLCopy(laddr.sun_path, boundPath, sizeof(laddr.sun_path));
ret = bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr));
umask(mask);
if (ret < 0)
@@ -5264,7 +5216,7 @@ mDNSexport int udsserver_exit(void)
// Currently, we're unable to remove /var/run/mdnsd because we've changed to userid "nobody"
// to give up unnecessary privilege, but we need to be root to remove this Unix Domain Socket.
// It would be nice if we could find a solution to this problem
- if (unlink(MDNS_UDS_SERVERPATH))
+ if (unlink(boundPath))
debugf("Unable to remove %s", MDNS_UDS_SERVERPATH);
#endif
}
@@ -5274,12 +5226,12 @@ mDNSexport int udsserver_exit(void)
return 0;
}
-mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
+mDNSlocal void LogClientInfo(request_state *req)
{
char prefix[16];
- if (req->primary)
+ if (req->primary)
mDNS_snprintf(prefix, sizeof(prefix), " -> ");
- else
+ else
mDNS_snprintf(prefix, sizeof(prefix), "%3d:", req->sd);
if (!req->terminate)
@@ -5291,13 +5243,13 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
request_state *r;
for (p = req->u.reg_recs; p; p=p->next) num_records++;
for (r = req->next; r; r=r->next) if (r->primary == req) num_ops++;
- LogMsgNoIdent("%s DNSServiceCreateConnection: %d registered record%s, %d kDNSServiceFlagsShareConnection operation%s PID[%d](%s)",
- prefix, num_records, num_records != 1 ? "s" : "", num_ops, num_ops != 1 ? "s" : "",
+ LogMsgNoIdent("%s DNSServiceCreateConnection: %d registered record%s, %d kDNSServiceFlagsShareConnection operation%s PID[%d](%s)",
+ prefix, num_records, num_records != 1 ? "s" : "", num_ops, num_ops != 1 ? "s" : "",
req->process_id, req->pid_name);
for (p = req->u.reg_recs; p; p=p->next)
LogMsgNoIdent(" -> DNSServiceRegisterRecord 0x%08X %2d %3d %s PID[%d](%s)",
- req->flags, req->interfaceIndex, p->key, ARDisplayString(m, p->rr), req->process_id, req->pid_name);
- for (r = req->next; r; r=r->next) if (r->primary == req) LogClientInfo(m, r);
+ req->flags, req->interfaceIndex, p->key, ARDisplayString(&mDNSStorage, p->rr), req->process_id, req->pid_name);
+ for (r = req->next; r; r=r->next) if (r->primary == req) LogClientInfo(r);
}
else if (req->terminate == regservice_termination_callback)
{
@@ -5340,7 +5292,7 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
mDNSVal16(req->u.pm.NATinfo.ExternalPort),
req->u.pm.NATinfo.NATLease,
req->u.pm.NATinfo.Lifetime,
- req->process_id, req->pid_name);
+ req->process_id, req->pid_name);
else if (req->terminate == addrinfo_termination_callback)
LogMsgNoIdent("%s DNSServiceGetAddrInfo 0x%08X %2d %s%s %##s PID[%d](%s)",
prefix, req->flags, req->interfaceIndex,
@@ -5358,18 +5310,18 @@ mDNSlocal void GetMcastClients(request_state *req)
int num_records = 0, num_ops = 0;
const registered_record_entry *p;
request_state *r;
- for (p = req->u.reg_recs; p; p=p->next)
+ for (p = req->u.reg_recs; p; p=p->next)
num_records++;
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
num_ops++;
for (p = req->u.reg_recs; p; p=p->next)
{
if (!AuthRecord_uDNS(p->rr))
n_mrecords++;
}
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
GetMcastClients(r);
}
else if (req->terminate == regservice_termination_callback)
@@ -5378,7 +5330,7 @@ mDNSlocal void GetMcastClients(request_state *req)
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
{
if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
- n_mrecords++;
+ n_mrecords++;
}
}
else if (req->terminate == browse_termination_callback)
@@ -5421,19 +5373,19 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
int num_records = 0, num_ops = 0;
const registered_record_entry *p;
request_state *r;
- for (p = req->u.reg_recs; p; p=p->next)
+ for (p = req->u.reg_recs; p; p=p->next)
num_records++;
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
num_ops++;
for (p = req->u.reg_recs; p; p=p->next)
{
if (!AuthRecord_uDNS(p->rr))
- LogMcastNoIdent("R: -> DNSServiceRegisterRecord: %##s %s PID[%d](%s)", p->rr->resrec.name->c,
+ LogMcastNoIdent("R: -> DNSServiceRegisterRecord: %##s %s PID[%d](%s)", p->rr->resrec.name->c,
DNSTypeName(p->rr->resrec.rrtype), req->process_id, req->pid_name, i_mcount++);
}
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
LogMcastClientInfo(r);
}
else if (req->terminate == regservice_termination_callback)
@@ -5441,8 +5393,8 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
service_instance *ptr;
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
{
- if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
- LogMcastNoIdent("R: DNSServiceRegister: %##s %u/%u PID[%d](%s)", ptr->srs.RR_SRV.resrec.name->c, mDNSVal16(req->u.servicereg.port),
+ if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
+ LogMcastNoIdent("R: DNSServiceRegister: %##s %u/%u PID[%d](%s)", ptr->srs.RR_SRV.resrec.name->c, mDNSVal16(req->u.servicereg.port),
SRS_PORT(&ptr->srs), req->process_id, req->pid_name, i_mcount++);
}
}
@@ -5465,7 +5417,7 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
else if (req->terminate == queryrecord_termination_callback)
{
if ((mDNSOpaque16IsZero(req->u.queryrecord.q.TargetQID)) && (req->u.queryrecord.q.ThisQInterval > 0))
- LogMcastNoIdent("Q: DNSServiceQueryRecord %##s %s PID[%d](%s)", req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype),
+ LogMcastNoIdent("Q: DNSServiceQueryRecord %##s %s PID[%d](%s)", req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype),
req->process_id, req->pid_name, i_mcount++);
}
else if (req->terminate == addrinfo_termination_callback)
@@ -5480,7 +5432,7 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
{
return;
}
-
+
}
mDNSlocal char *RecordTypeName(mDNSu8 rtype)
@@ -5498,7 +5450,7 @@ mDNSlocal char *RecordTypeName(mDNSu8 rtype)
}
}
-mDNSlocal void LogEtcHosts(mDNS *const m)
+mDNSlocal int LogEtcHosts(mDNS *const m)
{
mDNSBool showheader = mDNStrue;
const AuthRecord *ar;
@@ -5534,6 +5486,7 @@ mDNSlocal void LogEtcHosts(mDNS *const m)
if (showheader) LogMsgNoIdent("<None>");
else if (truncated) LogMsgNoIdent("<Truncated: to 50 records, Total records %d, Total Auth Groups %d, Auth Slots %d>", count, m->rrauth.rrauth_totalused, authslot);
+ return count;
}
mDNSlocal void LogLocalOnlyAuthRecords(mDNS *const m)
@@ -5553,9 +5506,14 @@ mDNSlocal void LogLocalOnlyAuthRecords(mDNS *const m)
// Print a maximum of 400 records
if (ar->ARType == AuthRecordLocalOnly)
- LogMsgNoIdent(" %s LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ LogMsgNoIdent(" %s LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
else if (ar->ARType == AuthRecordP2P)
- LogMsgNoIdent(" %s PP %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ {
+ if (ar->resrec.InterfaceID == mDNSInterface_BLE)
+ LogMsgNoIdent(" %s BLE %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ else
+ LogMsgNoIdent(" %s PP %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ }
}
}
@@ -5572,42 +5530,44 @@ mDNSlocal char *AnonInfoToString(AnonymousInfo *ai, char *anonstr, int anstrlen)
return anonstr;
}
-mDNSlocal void LogOneAuthRecord(mDNS *const m, const AuthRecord *ar, mDNSs32 now, const char *const ifname)
+mDNSlocal void LogOneAuthRecord(const AuthRecord *ar, mDNSs32 now, const char *const ifname)
{
char anstr[256];
if (AuthRecord_uDNS(ar))
{
- LogMsgNoIdent("%7d %7d %7d %7d %s %s",
+ LogMsgNoIdent("%7d %7d %7d %-7s %4d %s %s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
(ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
+ "-U-",
ar->state,
ar->AllowRemoteQuery ? "☠" : " ",
- ARDisplayString(m, ar));
+ ARDisplayString(&mDNSStorage, ar));
}
else
{
- LogMsgNoIdent("%7d %7d %7d %7s %s %s%s",
+ LogMsgNoIdent("%7d %7d %7d %-7s 0x%02X %s %s%s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
ar->TimeExpire ? (ar->TimeExpire - now) / mDNSPlatformOneSecond : 0,
ifname ? ifname : "ALL",
+ ar->resrec.RecordType,
ar->AllowRemoteQuery ? "☠" : " ",
- ARDisplayString(m, ar), AnonInfoToString(ar->resrec.AnonInfo, anstr, sizeof(anstr)));
+ ARDisplayString(&mDNSStorage, ar), AnonInfoToString(ar->resrec.AnonInfo, anstr, sizeof(anstr)));
}
}
-mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *ResourceRecords, int *proxy)
+mDNSlocal void LogAuthRecords(const mDNSs32 now, AuthRecord *ResourceRecords, int *proxy)
{
mDNSBool showheader = mDNStrue;
const AuthRecord *ar;
OwnerOptData owner = zeroOwner;
for (ar = ResourceRecords; ar; ar=ar->next)
{
- const char *const ifname = InterfaceNameForID(m, ar->resrec.InterfaceID);
+ const char *const ifname = InterfaceNameForID(&mDNSStorage, ar->resrec.InterfaceID);
if ((ar->WakeUp.HMAC.l[0] != 0) == (proxy != mDNSNULL))
{
- if (showheader) { showheader = mDNSfalse; LogMsgNoIdent(" Int Next Expire State"); }
+ if (showheader) { showheader = mDNSfalse; LogMsgNoIdent(" Int Next Expire if State"); }
if (proxy) (*proxy)++;
if (!mDNSPlatformMemSame(&owner, &ar->WakeUp, sizeof(owner)))
{
@@ -5621,19 +5581,22 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
}
if (AuthRecord_uDNS(ar))
{
- LogOneAuthRecord(m, ar, now, ifname);
+ LogOneAuthRecord(ar, now, ifname);
}
else if (ar->ARType == AuthRecordLocalOnly)
{
- LogMsgNoIdent(" LO %s", ARDisplayString(m, ar));
+ LogMsgNoIdent(" LO %s", ARDisplayString(&mDNSStorage, ar));
}
else if (ar->ARType == AuthRecordP2P)
{
- LogMsgNoIdent(" PP %s", ARDisplayString(m, ar));
+ if (ar->resrec.InterfaceID == mDNSInterface_BLE)
+ LogMsgNoIdent(" BLE %s", ARDisplayString(&mDNSStorage, ar));
+ else
+ LogMsgNoIdent(" PP %s", ARDisplayString(&mDNSStorage, ar));
}
else
{
- LogOneAuthRecord(m, ar, now, ifname);
+ LogOneAuthRecord(ar, now, ifname);
if (ar->resrec.AnonInfo)
{
ResourceRecord *nsec3 = ar->resrec.AnonInfo->nsec3RR;
@@ -5644,7 +5607,7 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
ar->TimeExpire ? (ar->TimeExpire - now) / mDNSPlatformOneSecond : 0,
ifname ? ifname : "ALL",
- RRDisplayString(m, nsec3));
+ RRDisplayString(&mDNSStorage, nsec3));
}
}
}
@@ -5652,7 +5615,7 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
if (showheader) LogMsgNoIdent("<None>");
}
-mDNSlocal void PrintOneCacheRecord(mDNS *const m, const CacheRecord *cr, mDNSu32 slot, const mDNSu32 remain, const char *ifname, mDNSu32 *CacheUsed)
+mDNSlocal void PrintOneCacheRecord(const CacheRecord *cr, mDNSu32 slot, const mDNSu32 remain, const char *ifname, mDNSu32 *CacheUsed)
{
LogMsgNoIdent("%3d %s%8d %-7s%s %-6s%s",
slot,
@@ -5662,11 +5625,11 @@ mDNSlocal void PrintOneCacheRecord(mDNS *const m, const CacheRecord *cr, mDNSu32
(cr->resrec.RecordType == kDNSRecordTypePacketNegative) ? "-" :
(cr->resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
DNSTypeName(cr->resrec.rrtype),
- CRDisplayString(m, cr));
+ CRDisplayString(&mDNSStorage, cr));
(*CacheUsed)++;
}
-mDNSlocal void PrintCachedRecords(mDNS *const m, const CacheRecord *cr, mDNSu32 slot, const mDNSu32 remain, const char *ifname, mDNSu32 *CacheUsed)
+mDNSlocal void PrintCachedRecords(const CacheRecord *cr, mDNSu32 slot, const mDNSu32 remain, const char *ifname, mDNSu32 *CacheUsed)
{
CacheRecord *nsec;
CacheRecord *soa;
@@ -5676,13 +5639,13 @@ mDNSlocal void PrintCachedRecords(mDNS *const m, const CacheRecord *cr, mDNSu32
// their own lifetime. If the main cache record expires, they also expire.
while (nsec)
{
- PrintOneCacheRecord(m, nsec, slot, remain, ifname, CacheUsed);
+ PrintOneCacheRecord(nsec, slot, remain, ifname, CacheUsed);
nsec = nsec->next;
}
soa = cr->soa;
if (soa)
{
- PrintOneCacheRecord(m, soa, slot, remain, ifname, CacheUsed);
+ PrintOneCacheRecord(soa, slot, remain, ifname, CacheUsed);
}
if (cr->resrec.AnonInfo)
{
@@ -5699,7 +5662,7 @@ mDNSlocal void PrintCachedRecords(mDNS *const m, const CacheRecord *cr, mDNSu32
(nsec3->RecordType == kDNSRecordTypePacketNegative) ? "-" :
(nsec3->RecordType & kDNSRecordTypePacketUniqueMask) ? " " : "+",
DNSTypeName(nsec3->rrtype),
- RRDisplayString(m, nsec3));
+ RRDisplayString(&mDNSStorage, nsec3));
}
}
}
@@ -5735,7 +5698,7 @@ mDNSlocal char *AnonDataToString(const mDNSu8 *ad, int adlen, char *adstr, int a
mDNSexport void LogMDNSStatistics(mDNS *const m)
{
LogMsgNoIdent("--- MDNS Statistics ---");
-
+
LogMsgNoIdent("Name Conflicts %u", m->mDNSStats.NameConflicts);
LogMsgNoIdent("KnownUnique Name Conflicts %u", m->mDNSStats.KnownUniqueNameConflicts);
LogMsgNoIdent("Duplicate Query Suppressions %u", m->mDNSStats.DupQuerySuppressions);
@@ -5766,11 +5729,15 @@ mDNSexport void LogMDNSStatistics(mDNS *const m)
LogMsgNoIdent("Wakeup on Resolves %u", m->mDNSStats.WakeOnResolves);
}
-mDNSexport void udsserver_info(mDNS *const m)
+mDNSexport void udsserver_info()
{
+ mDNS *const m = &mDNSStorage;
const mDNSs32 now = mDNS_TimeNow(m);
mDNSu32 CacheUsed = 0, CacheActive = 0, slot;
int ProxyA = 0, ProxyD = 0;
+ mDNSu32 groupCount = 0;
+ mDNSu32 mcastRecordCount = 0;
+ mDNSu32 ucastRecordCount = 0;
const CacheGroup *cg;
const CacheRecord *cr;
const DNSQuestion *q;
@@ -5785,30 +5752,33 @@ mDNSexport void udsserver_info(mDNS *const m)
{
for (cg = m->rrcache_hash[slot]; cg; cg=cg->next)
{
- CacheUsed++; // Count one cache entity for the CacheGroup object
+ groupCount++; // Count one cache entity for the CacheGroup object
for (cr = cg->members; cr; cr=cr->next)
{
const mDNSs32 remain = cr->resrec.rroriginalttl - (now - cr->TimeRcvd) / mDNSPlatformOneSecond;
const char *ifname;
mDNSInterfaceID InterfaceID = cr->resrec.InterfaceID;
+ mDNSu32 *const countPtr = InterfaceID ? &mcastRecordCount : &ucastRecordCount;
if (!InterfaceID && cr->resrec.rDNSServer && cr->resrec.rDNSServer->scoped)
InterfaceID = cr->resrec.rDNSServer->interface;
ifname = InterfaceNameForID(m, InterfaceID);
if (cr->CRActiveQuestion) CacheActive++;
- PrintOneCacheRecord(m, cr, slot, remain, ifname, &CacheUsed);
- PrintCachedRecords(m, cr, slot, remain, ifname, &CacheUsed);
+ PrintOneCacheRecord(cr, slot, remain, ifname, countPtr);
+ PrintCachedRecords(cr, slot, remain, ifname, countPtr);
}
}
}
+ CacheUsed = groupCount + mcastRecordCount + ucastRecordCount;
if (m->rrcache_totalused != CacheUsed)
LogMsgNoIdent("Cache use mismatch: rrcache_totalused is %lu, true count %lu", m->rrcache_totalused, CacheUsed);
if (m->rrcache_active != CacheActive)
LogMsgNoIdent("Cache use mismatch: rrcache_active is %lu, true count %lu", m->rrcache_active, CacheActive);
- LogMsgNoIdent("Cache currently contains %lu entities; %lu referenced by active questions", CacheUsed, CacheActive);
+ LogMsgNoIdent("Cache size %u entities; %u in use (%u group, %u multicast, %u unicast); %u referenced by active questions",
+ m->rrcache_size, CacheUsed, groupCount, mcastRecordCount, ucastRecordCount, CacheActive);
LogMsgNoIdent("--------- Auth Records ---------");
- LogAuthRecords(m, now, m->ResourceRecords, mDNSNULL);
+ LogAuthRecords(now, m->ResourceRecords, mDNSNULL);
LogMsgNoIdent("--------- LocalOnly, P2P Auth Records ---------");
LogLocalOnlyAuthRecords(m);
@@ -5817,13 +5787,13 @@ mDNSexport void udsserver_info(mDNS *const m)
LogEtcHosts(m);
LogMsgNoIdent("------ Duplicate Records -------");
- LogAuthRecords(m, now, m->DuplicateRecords, mDNSNULL);
+ LogAuthRecords(now, m->DuplicateRecords, mDNSNULL);
LogMsgNoIdent("----- Auth Records Proxied -----");
- LogAuthRecords(m, now, m->ResourceRecords, &ProxyA);
+ LogAuthRecords(now, m->ResourceRecords, &ProxyA);
LogMsgNoIdent("-- Duplicate Records Proxied ---");
- LogAuthRecords(m, now, m->DuplicateRecords, &ProxyD);
+ LogAuthRecords(now, m->DuplicateRecords, &ProxyD);
LogMsgNoIdent("---------- Questions -----------");
if (!m->Questions) LogMsgNoIdent("<None>");
@@ -5840,12 +5810,13 @@ mDNSexport void udsserver_info(mDNS *const m)
char *ifname = InterfaceNameForID(m, q->InterfaceID);
CacheUsed++;
if (q->ThisQInterval) CacheActive++;
- LogMsgNoIdent("%6d%6d %-7s%s%s %5d 0x%x%x 0x%p 0x%p %1d %2d %-5s%##s%s%s",
+ LogMsgNoIdent("%6d%6d %-7s%s%s %5d 0x%x%x%x%x 0x%p 0x%p %1d %2d %-5s%##s%s%s",
i, n,
ifname ? ifname : mDNSOpaque16IsZero(q->TargetQID) ? "" : "-U-",
mDNSOpaque16IsZero(q->TargetQID) ? (q->LongLived ? "l" : " ") : (q->LongLived ? "L" : "O"),
PrivateQuery(q) ? "P" : q->ValidationRequired ? "V" : q->ValidatingResponse ? "R" : " ",
- q->CurrentAnswers, q->validDNSServers.l[1], q->validDNSServers.l[0], q, q->DuplicateOf,
+ q->CurrentAnswers, q->validDNSServers.l[3], q->validDNSServers.l[2], q->validDNSServers.l[1],
+ q->validDNSServers.l[0], q, q->DuplicateOf,
q->SuppressUnusable, q->SuppressQuery, DNSTypeName(q->qtype), q->qname.c,
AnonInfoToString(q->AnonInfo, anonstr, sizeof(anonstr)),
q->DuplicateOf ? " (dup)" : "");
@@ -5853,10 +5824,11 @@ mDNSexport void udsserver_info(mDNS *const m)
LogMsgNoIdent("%lu question%s; %lu active", CacheUsed, CacheUsed > 1 ? "s" : "", CacheActive);
}
- LogMsgNoIdent("----- Local-Only Questions -----");
+ LogMsgNoIdent("----- LocalOnly, P2P Questions -----");
if (!m->LocalOnlyQuestions) LogMsgNoIdent("<None>");
else for (q = m->LocalOnlyQuestions; q; q=q->next)
- LogMsgNoIdent(" %5d %-6s%##s%s",
+ LogMsgNoIdent(" %3s %5d %-6s%##s%s",
+ q->InterfaceID == mDNSInterface_LocalOnly ? "LO ": q->InterfaceID == mDNSInterface_BLE ? "BLE": "P2P",
q->CurrentAnswers, DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");
LogMsgNoIdent("---- Active UDS Client Requests ----");
@@ -5872,7 +5844,7 @@ mDNSexport void udsserver_info(mDNS *const m)
LogMsgNoIdent("%3d: Orhpan operation %p; parent %p not found in request list", req->sd);
}
// For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
- LogClientInfo(m, req);
+ LogClientInfo(req);
foundparent:;
}
}
@@ -5969,7 +5941,7 @@ foundparent:;
}
}
LogInfo("--- Trust Anchors ---");
- if (!m->TrustAnchors)
+ if (!m->TrustAnchors)
{
LogInfo("<None>");
}
@@ -5990,7 +5962,6 @@ foundparent:;
LogInfo("--- DNSSEC Statistics ---");
- LogInfo("Next Stats Time %u", m->NextStatLogTime - mDNSPlatformUTC());
LogMsgNoIdent("Unicast Cache size %u", m->rrcache_totalused_unicast);
LogInfo("DNSSEC Cache size %u", m->DNSSECStats.TotalMemUsed);
if (m->rrcache_totalused_unicast)
@@ -6021,6 +5992,15 @@ foundparent:;
LogMsgNoIdent("---- Task Scheduling Timers ----");
+#if BONJOUR_ON_DEMAND
+ LogMsgNoIdent("BonjourEnabled %d", m->BonjourEnabled);
+#endif // BONJOUR_ON_DEMAND
+
+#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+ LogMsgNoIdent("EnableBLEBasedDiscovery %d", EnableBLEBasedDiscovery);
+ LogMsgNoIdent("DefaultToBLETriggered %d", DefaultToBLETriggered);
+#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR
+
if (!m->NewQuestions)
LogMsgNoIdent("NewQuestion <NONE>");
else
@@ -6062,6 +6042,11 @@ foundparent:;
LogTimer("m->NextCacheCheck ", m->NextCacheCheck);
LogTimer("m->NextScheduledSPS ", m->NextScheduledSPS);
LogTimer("m->NextScheduledKA ", m->NextScheduledKA);
+
+#if BONJOUR_ON_DEMAND
+ LogTimer("m->NextBonjourDisableTime ", m->NextBonjourDisableTime);
+#endif // BONJOUR_ON_DEMAND
+
LogTimer("m->NextScheduledSPRetry ", m->NextScheduledSPRetry);
LogTimer("m->DelaySleep ", m->DelaySleep);
@@ -6190,15 +6175,16 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
if (r->u.resolve.ReportTime && now - r->u.resolve.ReportTime >= 0)
{
r->u.resolve.ReportTime = 0;
- LogMsgNoIdent("Client application bug PID[%d](%s) : DNSServiceResolve(%##s) active for over two minutes. "
- "This places considerable burden on the network.", r->process_id, r->pid_name, r->u.resolve.qsrv.qname.c);
+ // if client received results and resolve still active
+ if (r->u.resolve.txt && r->u.resolve.srv)
+ LogMsgNoIdent("Client application PID[%d](%s) has received results for DNSServiceResolve(%##s) yet remains active over two minutes.", r->process_id, r->pid_name, r->u.resolve.qsrv.qname.c);
}
// Note: Only primary req's have reply lists, not subordinate req's.
while (r->replies) // Send queued replies
{
transfer_state result;
- if (r->replies->next)
+ if (r->replies->next)
r->replies->rhdr->flags |= dnssd_htonl(kDNSServiceFlagsMoreComing);
result = send_msg(r); // Returns t_morecoming if buffer full because client is not reading
if (result == t_complete)
@@ -6210,10 +6196,15 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
r->unresponsiveness_reports = 0;
continue;
}
- else if (result == t_terminated || result == t_error)
+ else if (result == t_terminated)
+ {
+ LogInfo("%3d: Could not write data to client PID[%d](%s) because connection is terminated by the client", r->sd, r->process_id, r->pid_name);
+ abort_request(r);
+ }
+ else if (result == t_error)
{
LogMsg("%3d: Could not write data to client PID[%d](%s) because of error - aborting connection", r->sd, r->process_id, r->pid_name);
- LogClientInfo(&mDNSStorage, r);
+ LogClientInfo(r);
abort_request(r);
}
break;
@@ -6221,28 +6212,28 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
if (r->replies) // If we failed to send everything, check our time_blocked timer
{
- if (nextevent - now > mDNSPlatformOneSecond)
+ if (nextevent - now > mDNSPlatformOneSecond)
nextevent = now + mDNSPlatformOneSecond;
- if (mDNSStorage.SleepState != SleepState_Awake)
+ if (mDNSStorage.SleepState != SleepState_Awake)
r->time_blocked = 0;
- else if (!r->time_blocked)
+ else if (!r->time_blocked)
r->time_blocked = NonZeroTime(now);
else if (now - r->time_blocked >= 10 * mDNSPlatformOneSecond * (r->unresponsiveness_reports+1))
{
int num = 0;
struct reply_state *x = r->replies;
- while (x)
- {
- num++;
- x=x->next;
+ while (x)
+ {
+ num++;
+ x=x->next;
}
LogMsg("%3d: Could not write data to client PID[%d](%s) after %ld seconds, %d repl%s waiting",
r->sd, r->process_id, r->pid_name, (now - r->time_blocked) / mDNSPlatformOneSecond, num, num == 1 ? "y" : "ies");
if (++r->unresponsiveness_reports >= 60)
{
LogMsg("%3d: Client PID[%d](%s) unresponsive; aborting connection", r->sd, r->process_id, r->pid_name);
- LogClientInfo(&mDNSStorage, r);
+ LogClientInfo(r);
abort_request(r);
}
}
@@ -6265,10 +6256,14 @@ struct CompileTimeAssertionChecks_uds_daemon
// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
// other overly-large structures instead of having a pointer to them, can inadvertently
// cause structure sizes (and therefore memory usage) to balloon unreasonably.
- char sizecheck_request_state [(sizeof(request_state) <= 2000) ? 1 : -1];
+ char sizecheck_request_state [(sizeof(request_state) <= 2954) ? 1 : -1];
char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <= 60) ? 1 : -1];
char sizecheck_service_instance [(sizeof(service_instance) <= 6552) ? 1 : -1];
- char sizecheck_browser_t [(sizeof(browser_t) <= 1128) ? 1 : -1];
+ char sizecheck_browser_t [(sizeof(browser_t) <= 1202) ? 1 : -1];
char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 12) ? 1 : -1];
char sizecheck_reply_state [(sizeof(reply_state) <= 64) ? 1 : -1];
};
+
+#ifdef UNIT_TEST
+#include "../unittests/uds_daemon_ut.c"
+#endif // UNIT_TEST
diff --git a/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.h b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.h
new file mode 100644
index 0000000000..dc7d9ac26b
--- /dev/null
+++ b/usr/src/contrib/mDNSResponder/mDNSShared/uds_daemon.h
@@ -0,0 +1,282 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2013 Apple 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.
+ */
+
+#ifndef UDS_DAEMON_H
+#define UDS_DAEMON_H
+
+#include "mDNSEmbeddedAPI.h"
+#include "dnssd_ipc.h"
+
+/* Client request: */
+
+// ***************************************************************************
+#if COMPILER_LIKES_PRAGMA_MARK
+#pragma mark -
+#pragma mark - Types and Data Structures
+#endif
+
+typedef enum
+{
+ t_uninitialized,
+ t_morecoming,
+ t_complete,
+ t_error,
+ t_terminated
+} transfer_state;
+
+typedef struct request_state request_state;
+
+typedef void (*req_termination_fn)(request_state *request);
+
+typedef struct registered_record_entry
+{
+ struct registered_record_entry *next;
+ mDNSu32 key;
+ client_context_t regrec_client_context;
+ request_state *request;
+ mDNSBool external_advertise;
+ mDNSInterfaceID origInterfaceID;
+ AuthRecord *rr; // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?)
+} registered_record_entry;
+
+// A single registered service: ServiceRecordSet + bookkeeping
+// Note that we duplicate some fields from parent service_info object
+// to facilitate cleanup, when instances and parent may be deallocated at different times.
+typedef struct service_instance
+{
+ struct service_instance *next;
+ request_state *request;
+ AuthRecord *subtypes;
+ mDNSBool renameonmemfree; // Set on config change when we deregister original name
+ mDNSBool clientnotified; // Has client been notified of successful registration yet?
+ mDNSBool default_local; // is this the "local." from an empty-string registration?
+ mDNSBool external_advertise; // is this is being advertised externally?
+ domainname domain;
+ ServiceRecordSet srs; // note -- variable-sized object -- must be last field in struct
+} service_instance;
+
+// for multi-domain default browsing
+typedef struct browser_t
+{
+ struct browser_t *next;
+ domainname domain;
+ DNSQuestion q;
+} browser_t;
+
+#ifdef _WIN32
+typedef unsigned int pid_t;
+typedef unsigned int socklen_t;
+#endif
+
+#if (!defined(MAXCOMLEN))
+#define MAXCOMLEN 16
+#endif
+
+struct request_state
+{
+ request_state *next;
+ request_state *primary; // If this operation is on a shared socket, pointer to primary
+ // request_state for the original DNSServiceCreateConnection() operation
+ dnssd_sock_t sd;
+ pid_t process_id; // Client's PID value
+ char pid_name[MAXCOMLEN]; // Client's process name
+ mDNSu8 uuid[UUID_SIZE];
+ mDNSBool validUUID;
+ dnssd_sock_t errsd;
+ mDNSu32 uid;
+ void * platform_data;
+
+ // Note: On a shared connection these fields in the primary structure, including hdr, are re-used
+ // for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
+ // operation is, we don't know if we're going to need to allocate a new request_state or not.
+ transfer_state ts;
+ mDNSu32 hdr_bytes; // bytes of header already read
+ ipc_msg_hdr hdr;
+ mDNSu32 data_bytes; // bytes of message data already read
+ char *msgbuf; // pointer to data storage to pass to free()
+ const char *msgptr; // pointer to data to be read from (may be modified)
+ char *msgend; // pointer to byte after last byte of message
+
+ // reply, termination, error, and client context info
+ int no_reply; // don't send asynchronous replies to client
+ mDNSs32 time_blocked; // record time of a blocked client
+ int unresponsiveness_reports;
+ struct reply_state *replies; // corresponding (active) reply list
+ req_termination_fn terminate;
+ DNSServiceFlags flags;
+ mDNSu32 interfaceIndex;
+
+ union
+ {
+ registered_record_entry *reg_recs; // list of registrations for a connection-oriented request
+ struct
+ {
+ mDNSInterfaceID interface_id;
+ mDNSBool default_domain;
+ mDNSBool ForceMCast;
+ domainname regtype;
+ browser_t *browsers;
+ const mDNSu8 *AnonData;
+ } browser;
+ struct
+ {
+ mDNSInterfaceID InterfaceID;
+ mDNSu16 txtlen;
+ void *txtdata;
+ mDNSIPPort port;
+ domainlabel name;
+ char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
+ domainname type;
+ mDNSBool default_domain;
+ domainname host;
+ mDNSBool autoname; // Set if this name is tied to the Computer Name
+ mDNSBool autorename; // Set if this client wants us to automatically rename on conflict
+ mDNSBool allowremotequery; // Respond to unicast queries from outside the local link?
+ int num_subtypes;
+ mDNSBool AnonData;
+ service_instance *instances;
+ } servicereg;
+ struct
+ {
+ mDNSInterfaceID interface_id;
+ mDNSu32 flags;
+ mDNSu32 protocol;
+ DNSQuestion q4;
+ DNSQuestion *q42;
+ DNSQuestion q6;
+ DNSQuestion *q62;
+ mDNSu8 v4ans;
+ mDNSu8 v6ans;
+ } addrinfo;
+ struct
+ {
+ mDNSIPPort ReqExt; // External port we originally requested, for logging purposes
+ NATTraversalInfo NATinfo;
+ } pm;
+ struct
+ {
+ DNSServiceFlags flags;
+ DNSQuestion q_all;
+ DNSQuestion q_default;
+ DNSQuestion q_autoall;
+ } enumeration;
+ struct
+ {
+ DNSQuestion q;
+ DNSQuestion *q2;
+ mDNSu8 ans;
+ } queryrecord;
+ struct
+ {
+ DNSQuestion qtxt;
+ DNSQuestion qsrv;
+ const ResourceRecord *txt;
+ const ResourceRecord *srv;
+ mDNSs32 ReportTime;
+ mDNSBool external_advertise;
+ } resolve;
+ } u;
+};
+
+// struct physically sits between ipc message header and call-specific fields in the message buffer
+typedef struct
+{
+ DNSServiceFlags flags; // Note: This field is in NETWORK byte order
+ mDNSu32 ifi; // Note: This field is in NETWORK byte order
+ DNSServiceErrorType error; // Note: This field is in NETWORK byte order
+} reply_hdr;
+
+typedef struct reply_state
+{
+ struct reply_state *next; // If there are multiple unsent replies
+ mDNSu32 totallen;
+ mDNSu32 nwriten;
+ ipc_msg_hdr mhdr[1];
+ reply_hdr rhdr[1];
+} reply_state;
+
+/* Client interface: */
+
+#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)
+
+#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now)
+
+extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
+extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
+extern void udsserver_info(void); // print out info about current state
+extern void udsserver_handle_configchange(mDNS *const m);
+extern int udsserver_exit(void); // should be called prior to app exit
+extern void LogMcastStateInfo(mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
+#define LogMcastQ (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion
+#define LogMcastS (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService
+#define LogMcast (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg
+#define LogMcastNoIdent (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsgNoIdent
+
+/* Routines that uds_daemon expects to link against: */
+
+typedef void (*udsEventCallback)(int fd, short filter, void *context);
+extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data);
+extern int udsSupportReadFD(dnssd_sock_t fd, char* buf, int len, int flags, void *platform_data);
+extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well
+
+extern void RecordUpdatedNiceLabel(mDNSs32 delay);
+
+// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X
+
+extern mDNS mDNSStorage;
+extern DNameListElem *AutoRegistrationDomains;
+extern DNameListElem *AutoBrowseDomains;
+
+extern mDNSs32 ChopSubTypes(char *regtype, char **AnonData);
+extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData);
+extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
+extern mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags);
+extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
+extern int CountPeerRegistrations(ServiceRecordSet *const srs);
+
+#if APPLE_OSX_mDNSResponder
+
+// D2D interface support
+extern void external_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
+extern void external_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
+extern void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
+extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
+extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
+extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
+extern void external_connection_release(const domainname *instance);
+
+#else // APPLE_OSX_mDNSResponder
+
+#define external_start_browsing_for_service(A,B,C,D) (void)(A)
+#define external_stop_browsing_for_service(A,B,C,D) (void)(A)
+#define external_start_advertising_service(A,B) (void)(A)
+#define external_stop_advertising_service(A,B) do { (void)(A); (void)(B); } while (0)
+#define external_start_resolving_service(A,B,C) (void)(A)
+#define external_stop_resolving_service(A,B,C) (void)(A)
+#define external_connection_release(A) (void)(A)
+
+#endif // APPLE_OSX_mDNSResponder
+
+extern const char mDNSResponderVersionString_SCCS[];
+#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)
+
+#if DEBUG
+extern void SetDebugBoundPath(void);
+extern int IsDebugSocketInUse(void);
+#endif
+
+#endif /* UDS_DAEMON_H */
diff --git a/usr/src/lib/libdns_sd/Makefile b/usr/src/lib/libdns_sd/Makefile
index 5e33bde9f9..b08abfb1be 100644
--- a/usr/src/lib/libdns_sd/Makefile
+++ b/usr/src/lib/libdns_sd/Makefile
@@ -25,21 +25,20 @@
include ../Makefile.lib
HDR = dns_sd.h
-HDRDIR = common
+HDRDIR = $(SRC)/contrib/mDNSResponder/mDNSShared
SUBDIRS = $(MACH)
$(BUILD64)SUBDIRS += $(MACH64)
-all := TARGET = all
+all := TARGET = all
clean := TARGET = clean
clobber := TARGET = clobber
install := TARGET = install
-lint := TARGET = lint
.KEEP_STATE:
-all install: install_h $(SUBDIRS) .WAIT java
+all install: install_h $(SUBDIRS)
-clean clobber: $(SUBDIRS) java
+clean clobber: $(SUBDIRS)
ROOTHDRDIR= $(ROOT)/usr/include
ROOTHDRS= $(HDR:%=$(ROOTHDRDIR)/%)
@@ -48,9 +47,7 @@ install_h: $(ROOTHDRS)
check:
-lint: $(SUBDIRS)
-
-$(SUBDIRS) java: FRC
+$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
FRC:
diff --git a/usr/src/lib/libdns_sd/Makefile.com b/usr/src/lib/libdns_sd/Makefile.com
index 5363d2dead..217ef72c05 100644
--- a/usr/src/lib/libdns_sd/Makefile.com
+++ b/usr/src/lib/libdns_sd/Makefile.com
@@ -29,10 +29,9 @@ OBJECTS = dnssd_clientlib.o dnssd_clientstub.o dnssd_ipc.o
include ../../Makefile.lib
-LIBS = $(DYNLIB) $(LINTLIB)
-$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
-
-SRCDIR = ../common
+MAPFILEDIR= ../common
+SRCDIR= $(SRC)/contrib/mDNSResponder/mDNSShared
+LIBS = $(DYNLIB)
LDLIBS += -lsocket -lnsl -lc
@@ -45,8 +44,10 @@ pics/dnssd_clientstub.o := CERRWARN += -_gcc=-Wno-unused-but-set-variable
.PARALLEL = $(OBJECTS)
.KEEP_STATE:
-lint: lintcheck
-
all: $(LIBS)
+pics/%.o: $(SRCDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
include ../../Makefile.targ
diff --git a/usr/src/lib/libdns_sd/THIRDPARTYLICENSE b/usr/src/lib/libdns_sd/THIRDPARTYLICENSE
deleted file mode 100644
index f4589044ee..0000000000
--- a/usr/src/lib/libdns_sd/THIRDPARTYLICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-The majority of the source code in the mDNSResponder project is licensed
-under the terms of the Apache License, Version 2.0, available from:
- <http://www.apache.org/licenses/LICENSE-2.0>
-
-To accommodate license compatibility with the widest possible range
-of client code licenses, the shared library code, which is linked
-at runtime into the same address space as the client using it, is
-licensed under the terms of the "Three-Clause BSD License".
-
-The Linux Name Service Switch code, contributed by National ICT
-Australia Ltd (NICTA) is licensed under the terms of the NICTA Public
-Software Licence (which is substantially similar to the "Three-Clause
-BSD License", with some additional language pertaining to Australian law).
diff --git a/usr/src/lib/libdns_sd/THIRDPARTYLICENSE.descrip b/usr/src/lib/libdns_sd/THIRDPARTYLICENSE.descrip
deleted file mode 100644
index 3a395f72de..0000000000
--- a/usr/src/lib/libdns_sd/THIRDPARTYLICENSE.descrip
+++ /dev/null
@@ -1 +0,0 @@
-MDNS LIBRARY
diff --git a/usr/src/lib/libdns_sd/amd64/Makefile b/usr/src/lib/libdns_sd/amd64/Makefile
index 2fa1329472..f4938d1ce4 100644
--- a/usr/src/lib/libdns_sd/amd64/Makefile
+++ b/usr/src/lib/libdns_sd/amd64/Makefile
@@ -21,10 +21,8 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
include ../Makefile.com
include ../../Makefile.lib.64
-CFLAGS64 += -erroff=E_ASSIGNMENT_TYPE_MISMATCH
-install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libdns_sd/common/llib-ldns_sd b/usr/src/lib/libdns_sd/common/llib-ldns_sd
deleted file mode 100644
index 464e3b9a6d..0000000000
--- a/usr/src/lib/libdns_sd/common/llib-ldns_sd
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <dns_sd.h>
diff --git a/usr/src/lib/libdns_sd/i386/Makefile b/usr/src/lib/libdns_sd/i386/Makefile
index 9c1be5bf3a..32145a695a 100644
--- a/usr/src/lib/libdns_sd/i386/Makefile
+++ b/usr/src/lib/libdns_sd/i386/Makefile
@@ -21,8 +21,7 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
include ../Makefile.com
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/libdns_sd/java/Makefile b/usr/src/lib/libdns_sd/java/Makefile
deleted file mode 100644
index 5b015fc86e..0000000000
--- a/usr/src/lib/libdns_sd/java/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include $(SRC)/lib/Makefile.lib
-
-POFILE = libjdns_sd.po
-
-SUBDIRS = $(MACH)
-$(BUILD64)SUBDIRS += $(MACH64)
-
-all := TARGET= all
-clean := TARGET= clean
-clobber := TARGET= clobber
-install := TARGET= install
-lint := TARGET= lint
-
-.KEEP_STATE:
-
-all install clean clobber lint: com/apple .WAIT $(SUBDIRS)
-
-com/apple $(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
-
-FRC:
diff --git a/usr/src/lib/libdns_sd/java/Makefile.com b/usr/src/lib/libdns_sd/java/Makefile.com
deleted file mode 100644
index acfcc13dbd..0000000000
--- a/usr/src/lib/libdns_sd/java/Makefile.com
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-LIBRARY= libjdns_sd.a
-VERS= .1
-
-OBJECTS= JNISupport.o
-
-include $(SRC)/lib/Makefile.lib
-
-LIBS = $(DYNLIB)
-
-SRCDIR = ../common
-
-CSTD = $(CSTD_GNU99)
-CPPFLAGS += -I$(JAVA_ROOT)/include -I$(JAVA_ROOT)/include/solaris
-CPPFLAGS += -I../com/apple/dnssd
-CPPFLAGS += -D_REENTRANT
-CPPFLAGS += -DMDNS_VERSIONSTR_NODTS
-
-LDLIBS += -lc -lsocket -ldns_sd
-
-CLEANFILES= $(LINTOUT) $(LINTLIB)
-
-LINTLIB =
-
-.KEEP_STATE:
-
-lint: lintcheck
-
-include $(SRC)/lib/Makefile.targ
-
-pics/%.o: ../common/%.c
- $(COMPILE.c) -o $@ $<
- $(POST_PROCESS_O)
diff --git a/usr/src/lib/libdns_sd/java/amd64/Makefile b/usr/src/lib/libdns_sd/java/amd64/Makefile
deleted file mode 100644
index b645e1caed..0000000000
--- a/usr/src/lib/libdns_sd/java/amd64/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-include ../../../Makefile.lib.64
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libdns_sd/java/com/apple/Makefile b/usr/src/lib/libdns_sd/java/com/apple/Makefile
deleted file mode 100644
index 8cfdc2e941..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include Makefile.com
-
-SUBDIRS = dnssd
-
-all:= TARGET = all
-clean:= TARGET = clean
-clobber:= TARGET = clobber
-install:= TARGET = install
-
-.KEEP_STATE:
-
-all clean install clobber: ${SUBDIRS}
-
-${SUBDIRS}: FRC
- cd $@; pwd; $(MAKE) $(TARGET)
-
-lint:
-
-.WAIT:
-
-FRC:
diff --git a/usr/src/lib/libdns_sd/java/com/apple/Makefile.com b/usr/src/lib/libdns_sd/java/com/apple/Makefile.com
deleted file mode 100644
index e699ff14a4..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/Makefile.com
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include $(SRC)/lib/Makefile.lib
-
-ROOTDNSSDJAVAHOME = $(ROOT)/usr/share/lib/java
-
-.KEEP_STATE:
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/BaseListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/BaseListener.java
deleted file mode 100644
index b99d341c2f..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/BaseListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A base class for DNSSD listeners. */
-
-public interface BaseListener
-{
- /** Called to report DNSSD operation failures.<P>
-
- @param service
- The service that encountered the failure.
- <P>
- @param errorCode
- Indicates the failure that occurred. See {@link DNSSDException} for error codes.
- */
- void operationFailed( DNSSDService service, int errorCode);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/BrowseListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/BrowseListener.java
deleted file mode 100644
index b92b9dc59f..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/BrowseListener.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A listener that receives results from {@link DNSSD#browse}. */
-
-public interface BrowseListener extends BaseListener
-{
- /** Called to report discovered services.<P>
-
- @param browser
- The active browse service.
- <P>
- @param flags
- Possible values are DNSSD.MORE_COMING.
- <P>
- @param ifIndex
- The interface on which the service is advertised. This index should be passed
- to {@link DNSSD#resolve} when resolving the service.
- <P>
- @param serviceName
- The service name discovered.
- <P>
- @param regType
- The registration type, as passed in to DNSSD.browse().
- <P>
- @param domain
- The domain in which the service was discovered.
- */
- void serviceFound( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain);
-
- /** Called to report services which have been deregistered.<P>
-
- @param browser
- The active browse service.
- <P>
- @param flags
- Possible values are DNSSD.MORE_COMING.
- <P>
- @param ifIndex
- The interface on which the service is advertised.
- <P>
- @param serviceName
- The service name which has deregistered.
- <P>
- @param regType
- The registration type, as passed in to DNSSD.browse().
- <P>
- @param domain
- The domain in which the service was discovered.
- */
- void serviceLost( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSRecord.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSRecord.java
deleted file mode 100644
index a853d091fa..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSRecord.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/**
- Reference to a record returned by {@link DNSSDRegistration#addRecord}.<P>
-
- Note: client is responsible for serializing access to these objects if
- they are shared between concurrent threads.
-*/
-
-public interface DNSRecord
-{
- /** Update a registered resource record.<P>
- The record must either be the primary txt record of a service registered via DNSSD.register(),
- or a record added to a registered service via addRecord().<P>
-
- @param flags
- Currently unused, reserved for future use.
- <P>
- @param rData
- The new rdata to be contained in the updated resource record.
- <P>
- @param ttl
- The time to live of the updated resource record, in seconds.
- */
- void update( int flags, byte[] rData, int ttl)
- throws DNSSDException;
-
- /** Remove a registered resource record.<P>
- */
- void remove()
- throws DNSSDException;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSD.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSD.java
deleted file mode 100644
index f749a88ead..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSD.java
+++ /dev/null
@@ -1,860 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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 file declares and implements DNSSD, the central Java factory class
- for doing DNS Service Discovery. It includes the mostly-abstract public
- interface, as well as the Apple* implementation subclasses.
- */
-
-
-package com.apple.dnssd;
-
-
-/**
- DNSSD provides access to DNS Service Discovery features of ZeroConf networking.<P>
-
- It is a factory class that is used to invoke registration and discovery-related
- operations. Most operations are non-blocking; clients are called back through an interface
- with the result of an operation. Callbacks are made from a separate worker thread.<P>
-
- For example, in this program<P>
- <PRE><CODE>
- class MyClient implements BrowseListener {
- void lookForWebServers() {
- myBrowser = DNSSD.browse("_http._tcp", this);
- }
-
- public void serviceFound(DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain) {}
- ...
- }</CODE></PRE>
- <CODE>MyClient.serviceFound()</CODE> would be called for every HTTP server discovered in the
- default browse domain(s).
-*/
-
-abstract public class DNSSD
-{
- /** Flag indicates to a {@link BrowseListener} that another result is
- queued. Applications should not update their UI to display browse
- results if the MORE_COMING flag is set; they will be called at least once
- more with the flag clear.
- */
- public static final int MORE_COMING = ( 1 << 0 );
-
- /** If flag is set in a {@link DomainListener} callback, indicates that the result is the default domain. */
- public static final int DEFAULT = ( 1 << 2 );
-
- /** If flag is set, a name conflict will trigger an exception when registering non-shared records.<P>
- A name must be explicitly specified when registering a service if this bit is set
- (i.e. the default name may not not be used).
- */
- public static final int NO_AUTO_RENAME = ( 1 << 3 );
-
- /** If flag is set, allow multiple records with this name on the network (e.g. PTR records)
- when registering individual records on a {@link DNSSDRegistration}.
- */
- public static final int SHARED = ( 1 << 4 );
-
- /** If flag is set, records with this name must be unique on the network (e.g. SRV records). */
- public static final int UNIQUE = ( 1 << 5 );
-
- /** Set flag when calling enumerateDomains() to restrict results to domains recommended for browsing. */
- public static final int BROWSE_DOMAINS = ( 1 << 6 );
- /** Set flag when calling enumerateDomains() to restrict results to domains recommended for registration. */
- public static final int REGISTRATION_DOMAINS = ( 1 << 7 );
-
- /** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
- public static final int MAX_DOMAIN_NAME = 1009;
-
- /** Pass for ifIndex to specify all available interfaces. */
- public static final int ALL_INTERFACES = 0;
-
- /** Pass for ifIndex to specify the localhost interface. */
- public static final int LOCALHOST_ONLY = -1;
-
- /** Browse for instances of a service.<P>
-
- Note: browsing consumes network bandwidth. Call {@link DNSSDService#stop} when you have finished browsing.<P>
-
- @param flags
- Currently ignored, reserved for future use.
- <P>
- @param ifIndex
- 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. Pass -1 to only browse for services provided on the local host.
- <P>
- @param regType
- The registration type being browsed for followed by the protocol, separated by a
- dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- <P>
- @param 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).
- <P>
- @param listener
- This object will get called when instances of the service are discovered (or disappear).
- <P>
- @return A {@link DNSSDService} that represents the active browse operation.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDService browse( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
- throws DNSSDException
- { return getInstance()._makeBrowser( flags, ifIndex, regType, domain, listener); }
-
- /** Browse for instances of a service. Use default flags, ifIndex and domain.<P>
-
- @param regType
- The registration type being browsed for followed by the protocol, separated by a
- dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- <P>
- @param listener
- This object will get called when instances of the service are discovered (or disappear).
- <P>
- @return A {@link DNSSDService} that represents the active browse operation.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDService browse( String regType, BrowseListener listener)
- throws DNSSDException
- { return browse( 0, 0, regType, "", listener); }
-
- /** Resolve a service name discovered via browse() to a target host name, port number, and txt record.<P>
-
- Note: Applications should NOT use resolve() solely for txt record monitoring - use
- queryRecord() instead, as it is more efficient for this task.<P>
-
- Note: When the desired results have been returned, the client MUST terminate the resolve by
- calling {@link DNSSDService#stop}.<P>
-
- Note: resolve() behaves correctly for typical services that have a single SRV record and
- a single TXT record (the TXT record may be empty.) To resolve non-standard services with
- multiple SRV or TXT records, use queryRecord().<P>
-
- @param flags
- Currently ignored, reserved for future use.
- <P>
- @param ifIndex
- The interface on which to resolve the service. The client should
- pass the interface on which the serviceName was discovered (i.e.
- the ifIndex passed to the serviceFound() callback)
- or 0 to resolve the named service on all available interfaces.
- <P>
- @param serviceName
- The servicename to be resolved.
- <P>
- @param regType
- The registration type being resolved followed by the protocol, separated by a
- dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- <P>
- @param domain
- The domain on which the service is registered, i.e. the domain passed
- to the serviceFound() callback.
- <P>
- @param listener
- This object will get called when the service is resolved.
- <P>
- @return A {@link DNSSDService} that represents the active resolve operation.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDService resolve( int flags, int ifIndex, String serviceName, String regType,
- String domain, ResolveListener listener)
- throws DNSSDException
- { return getInstance()._resolve( flags, ifIndex, serviceName, regType, domain, listener); }
-
- /** Register a service, to be discovered via browse() and resolve() calls.<P>
- @param flags
- Possible values are: NO_AUTO_RENAME.
- <P>
- @param ifIndex
- 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. Pass -1 to register a service only on the local
- machine (service will not be visible to remote hosts).
- <P>
- @param serviceName
- If non-null, specifies the service name to be registered.
- Applications need not specify a name, in which case the
- computer name is used (this name is communicated to the client via
- the serviceRegistered() callback).
- <P>
- @param regType
- The registration type being registered followed by the protocol, separated by a
- dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- <P>
- @param 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).
- <P>
- @param 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 {@link DNSSDRegistration#addRecord}.
- <P>
- @param port
- The port 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.
- <P>
- @param txtRecord
- The txt record rdata. May be null. Note that a non-null txtRecord
- MUST be a properly formatted DNS TXT record, i.e. &lt;length byte&gt; &lt;data&gt;
- &lt;length byte&gt; &lt;data&gt; ...
- <P>
- @param listener
- This object will get called when the service is registered.
- <P>
- @return A {@link DNSSDRegistration} that controls the active registration.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDRegistration register( int flags, int ifIndex, String serviceName, String regType,
- String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
- throws DNSSDException
- { return getInstance()._register( flags, ifIndex, serviceName, regType, domain, host, port, txtRecord, listener); }
-
- /** Register a service, to be discovered via browse() and resolve() calls. Use default flags, ifIndex, domain, host and txtRecord.<P>
- @param serviceName
- If non-null, specifies the service name to be registered.
- Applications need not specify a name, in which case the
- computer name is used (this name is communicated to the client via
- the serviceRegistered() callback).
- <P>
- @param regType
- The registration type being registered followed by the protocol, separated by a
- dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- <P>
- @param port
- The port 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.
- <P>
- @param listener
- This object will get called when the service is registered.
- <P>
- @return A {@link DNSSDRegistration} that controls the active registration.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDRegistration register( String serviceName, String regType, int port, RegisterListener listener)
- throws DNSSDException
- { return register( 0, 0, serviceName, regType, null, null, port, null, listener); }
-
- /** Create a {@link DNSSDRecordRegistrar} allowing efficient registration of
- multiple individual records.<P>
- <P>
- @return A {@link DNSSDRecordRegistrar} that can be used to register records.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDRecordRegistrar createRecordRegistrar( RegisterRecordListener listener)
- throws DNSSDException
- { return getInstance()._createRecordRegistrar( listener); }
-
- /** Query for an arbitrary DNS record.<P>
- @param flags
- Possible values are: MORE_COMING.
- <P>
- @param ifIndex
- 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. Passing -1 causes the name to be queried for only on the
- local host.
- <P>
- @param serviceName
- The full domain name of the resource record to be queried for.
- <P>
- @param rrtype
- The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
- as defined in nameser.h.
- <P>
- @param rrclass
- The class of the resource record, as defined in nameser.h
- (usually 1 for the Internet class).
- <P>
- @param listener
- This object will get called when the query completes.
- <P>
- @return A {@link DNSSDService} that controls the active query.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDService queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
- int rrclass, QueryListener listener)
- throws DNSSDException
- { return getInstance()._queryRecord( flags, ifIndex, serviceName, rrtype, rrclass, listener); }
-
- /** Asynchronously enumerate domains available for browsing and registration.<P>
-
- Currently, the only domain returned is "local.", but other domains will be returned in future.<P>
-
- The enumeration MUST be cancelled by calling {@link DNSSDService#stop} when no more domains
- are to be found.<P>
- @param flags
- Possible values are: BROWSE_DOMAINS, REGISTRATION_DOMAINS.
- <P>
- @param ifIndex
- 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.
- <P>
- @param listener
- This object will get called when domains are found.
- <P>
- @return A {@link DNSSDService} that controls the active enumeration.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static DNSSDService enumerateDomains( int flags, int ifIndex, DomainListener listener)
- throws DNSSDException
- { return getInstance()._enumerateDomains( flags, ifIndex, listener); }
-
- /** Concatenate a three-part domain name (as provided to the listeners) into a
- properly-escaped full domain name. Note that strings passed to listeners are
- ALREADY ESCAPED where necessary.<P>
- @param serviceName
- The service name - any dots or slashes must NOT be escaped.
- May be null (to construct a PTR record name, e.g. "_ftp._tcp.apple.com").
- <P>
- @param regType
- The registration type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
- <P>
- @param domain
- The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
- <P>
- @return The full domain name.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static String constructFullName( String serviceName, String regType, String domain)
- throws DNSSDException
- { return getInstance()._constructFullName( serviceName, regType, domain); }
-
- /** 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.) <P>
-
- 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.<P>
- @param flags
- Currently unused, reserved for future use.
- <P>
- @param ifIndex
- If non-zero, specifies the interface on which to reconfirm the record
- (the index for a given interface is determined via the if_nametoindex()
- family of calls.) Passing 0 causes the name to be reconfirmed on all
- interfaces. Passing -1 causes the name to be reconfirmed only on the
- local host.
- <P>
- @param fullName
- The resource record's full domain name.
- <P>
- @param rrtype
- The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
- <P>
- @param rrclass
- The class of the resource record, as defined in nameser.h (usually 1).
- <P>
- @param rdata
- The raw rdata of the resource record.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static void reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
- int rrclass, byte[] rdata)
- { getInstance()._reconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata); }
-
- /** Return the canonical name of a particular interface index.<P>
- @param ifIndex
- A valid interface index. Must not be ALL_INTERFACES.
- <P>
- @return The name of the interface, which should match java.net.NetworkInterface.getName().
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static String getNameForIfIndex( int ifIndex)
- { return getInstance()._getNameForIfIndex( ifIndex); }
-
- /** Return the index of a named interface.<P>
- @param ifName
- A valid interface name. An example is java.net.NetworkInterface.getName().
- <P>
- @return The interface index.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public static int getIfIndexForName( String ifName)
- { return getInstance()._getIfIndexForName( ifName); }
-
- protected DNSSD() {} // prevent direct instantiation
-
- /** Return the single instance of DNSSD. */
- static protected final DNSSD getInstance()
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null)
- sm.checkPermission( new RuntimePermission( "getDNSSDInstance"));
- return fInstance;
- }
-
- abstract protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
- throws DNSSDException;
-
- abstract protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
- String domain, ResolveListener listener)
- throws DNSSDException;
-
- abstract protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
- String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
- throws DNSSDException;
-
- abstract protected DNSSDRecordRegistrar _createRecordRegistrar( RegisterRecordListener listener)
- throws DNSSDException;
-
- abstract protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
- int rrclass, QueryListener listener)
- throws DNSSDException;
-
- abstract protected DNSSDService _enumerateDomains( int flags, int ifIndex, DomainListener listener)
- throws DNSSDException;
-
- abstract protected String _constructFullName( String serviceName, String regType, String domain)
- throws DNSSDException;
-
- abstract protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
- int rrclass, byte[] rdata);
-
- abstract protected String _getNameForIfIndex( int ifIndex);
-
- abstract protected int _getIfIndexForName( String ifName);
-
- protected static DNSSD fInstance;
-
- static
- {
- try
- {
- String name = System.getProperty( "com.apple.dnssd.DNSSD" );
- if (name == null)
- name = "com.apple.dnssd.AppleDNSSD"; // Fall back to Apple-provided class.
- fInstance = (DNSSD) Class.forName(name).newInstance();
- }
- catch( Exception e )
- {
- throw new InternalError( "cannot instantiate DNSSD" + e );
- }
- }
-}
-
-
-// Concrete implementation of DNSSDException
-class AppleDNSSDException extends DNSSDException
-{
- public AppleDNSSDException( int errorCode) { fErrorCode = errorCode; }
-
- public int getErrorCode() { return fErrorCode; }
-
- public String getMessage()
- {
- final String kMessages[] = { // should probably be put into a resource or something
- "UNKNOWN",
- "NO_SUCH_NAME",
- "NO_MEMORY",
- "BAD_PARAM",
- "BAD_REFERENCE",
- "BAD_STATE",
- "BAD_FLAGS",
- "UNSUPPORTED",
- "NOT_INITIALIZED",
- "NO_CACHE",
- "ALREADY_REGISTERED",
- "NAME_CONFLICT",
- "INVALID",
- "FIREWALL",
- "INCOMPATIBLE",
- "BAD_INTERFACE_INDEX",
- "REFUSED",
- "NOSUCHRECORD",
- "NOAUTH",
- "NOSUCHKEY",
- "NATTRAVERSAL",
- "DOUBLENAT",
- "BADTIME",
- "BADSIG",
- "BADKEY",
- "TRANSIENT",
- "SERVICENOTRUNNING",
- "NATPORTMAPPINGUNSUPPORTED",
- "NATPORTMAPPINGDISABLED"
- };
-
- if (fErrorCode <= UNKNOWN && fErrorCode > ( UNKNOWN - kMessages.length))
- {
- return "DNS-SD Error " + String.valueOf( fErrorCode) + ": " + kMessages[ UNKNOWN - fErrorCode];
- }
- else
- return super.getMessage() + "(" + String.valueOf( fErrorCode) + ")";
- }
-
- protected int fErrorCode;
-}
-
-// The concrete, default implementation.
-class AppleDNSSD extends DNSSD
-{
- static
- {
- System.loadLibrary( "jdns_sd");
-
- int libInitResult = InitLibrary( 2); // Current version number (must be sync'd with jnilib version)
-
- if (libInitResult != DNSSDException.NO_ERROR)
- throw new InternalError( "cannot instantiate DNSSD: " + new AppleDNSSDException( libInitResult).getMessage());
- }
-
- static public boolean hasAutoCallbacks; // Set by InitLibrary() to value of AUTO_CALLBACKS
-
- protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
- throws DNSSDException
- {
- return new AppleBrowser( flags, ifIndex, regType, domain, client);
- }
-
- protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
- String domain, ResolveListener client)
- throws DNSSDException
- {
- return new AppleResolver( flags, ifIndex, serviceName, regType, domain, client);
- }
-
- protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
- String domain, String host, int port, TXTRecord txtRecord, RegisterListener client)
- throws DNSSDException
- {
- return new AppleRegistration( flags, ifIndex, serviceName, regType, domain, host, port,
- ( txtRecord != null) ? txtRecord.getRawBytes() : null, client);
- }
-
- protected DNSSDRecordRegistrar _createRecordRegistrar( RegisterRecordListener listener)
- throws DNSSDException
- {
- return new AppleRecordRegistrar( listener);
- }
-
- protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
- int rrclass, QueryListener client)
- throws DNSSDException
- {
- return new AppleQuery( flags, ifIndex, serviceName, rrtype, rrclass, client);
- }
-
- protected DNSSDService _enumerateDomains( int flags, int ifIndex, DomainListener listener)
- throws DNSSDException
- {
- return new AppleDomainEnum( flags, ifIndex, listener);
- }
-
- protected String _constructFullName( String serviceName, String regType, String domain)
- throws DNSSDException
- {
- String[] responseHolder = new String[1]; // lame maneuver to get around Java's lack of reference parameters
-
- int rc = ConstructName( serviceName, regType, domain, responseHolder);
- if (rc != 0)
- throw new AppleDNSSDException( rc);
-
- return responseHolder[0];
- }
-
- protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
- int rrclass, byte[] rdata)
- {
- ReconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata);
- }
-
- protected String _getNameForIfIndex( int ifIndex)
- {
- return GetNameForIfIndex( ifIndex);
- }
-
- protected int _getIfIndexForName( String ifName)
- {
- return GetIfIndexForName( ifName);
- }
-
-
- protected native int ConstructName( String serviceName, String regType, String domain, String[] pOut);
-
- protected native void ReconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
- int rrclass, byte[] rdata);
-
- protected native String GetNameForIfIndex( int ifIndex);
-
- protected native int GetIfIndexForName( String ifName);
-
- protected static native int InitLibrary( int callerVersion);
-}
-
-class AppleService implements DNSSDService, Runnable
-{
- public AppleService(BaseListener listener) { fNativeContext = 0; fListener = listener; }
-
- public void stop() { this.HaltOperation(); }
-
- /* Block until data arrives, or one second passes. Returns 1 if data present, 0 otherwise. */
- protected native int BlockForData();
-
- /* Call ProcessResults when data appears on socket descriptor. */
- protected native int ProcessResults();
-
- protected synchronized native void HaltOperation();
-
- protected void ThrowOnErr( int rc) throws DNSSDException
- {
- if (rc != 0)
- throw new AppleDNSSDException( rc);
- }
-
- protected long /* warning */ fNativeContext; // Private storage for native side
-
- public void run()
- {
- while ( true )
- {
- // Note: We want to allow our DNS-SD operation to be stopped from other threads, so we have to
- // block waiting for data *outside* the synchronized section. Because we're doing this unsynchronized
- // we have to write some careful code. Suppose our DNS-SD operation is stopped from some other thread,
- // and then immediately afterwards that thread (or some third, unrelated thread) starts a new DNS-SD
- // operation. The Unix kernel always allocates the lowest available file descriptor to a new socket,
- // so the same file descriptor is highly likely to be reused for the new operation, and if our old
- // stale ServiceThread accidentally consumes bytes off that new socket we'll get really messed up.
- // To guard against that, before calling ProcessResults we check to ensure that our
- // fNativeContext has not been deleted, which is a telltale sign that our operation was stopped.
- // After calling ProcessResults we check again, because it's extremely common for callback
- // functions to stop their own operation and start others. For example, a resolveListener callback
- // may well stop the resolve and then start a QueryRecord call to monitor the TXT record.
- //
- // The remaining risk is that between our checking fNativeContext and calling ProcessResults(),
- // some other thread could stop the operation and start a new one using same file descriptor, and
- // we wouldn't know. To prevent this, the AppleService object's HaltOperation() routine is declared
- // synchronized and we perform our checks synchronized on the AppleService object, which ensures
- // that HaltOperation() can't execute while we're doing it. Because Java locks are re-entrant this
- // locking DOESN'T prevent the callback routine from stopping its own operation, but DOES prevent
- // any other thread from stopping it until after the callback has completed and returned to us here.
-
- int result = BlockForData();
- synchronized (this)
- {
- if (fNativeContext == 0) break; // Some other thread stopped our DNSSD operation; time to terminate this thread
- if (result == 0) continue; // If BlockForData() said there was no data, go back and block again
- result = ProcessResults();
- if (fNativeContext == 0) break; // Event listener stopped its own DNSSD operation; terminate this thread
- if (result != 0) { fListener.operationFailed(this, result); break; } // If error, notify listener
- }
- }
- }
-
- protected BaseListener fListener;
-}
-
-
-class AppleBrowser extends AppleService
-{
- public AppleBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
- throws DNSSDException
- {
- super(client);
- this.ThrowOnErr( this.CreateBrowser( flags, ifIndex, regType, domain));
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int CreateBrowser( int flags, int ifIndex, String regType, String domain);
-}
-
-class AppleResolver extends AppleService
-{
- public AppleResolver( int flags, int ifIndex, String serviceName, String regType,
- String domain, ResolveListener client)
- throws DNSSDException
- {
- super(client);
- this.ThrowOnErr( this.CreateResolver( flags, ifIndex, serviceName, regType, domain));
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int CreateResolver( int flags, int ifIndex, String serviceName, String regType,
- String domain);
-}
-
-// An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
-class AppleDNSRecord implements DNSRecord
-{
- public AppleDNSRecord( AppleService owner)
- {
- fOwner = owner;
- fRecord = 0; // record always starts out empty
- }
-
- public void update( int flags, byte[] rData, int ttl)
- throws DNSSDException
- {
- this.ThrowOnErr( this.Update( flags, rData, ttl));
- }
-
- public void remove()
- throws DNSSDException
- {
- this.ThrowOnErr( this.Remove());
- }
-
- protected long fRecord; // Really a DNSRecord; sizeof(long) == sizeof(void*) ?
- protected AppleService fOwner;
-
- protected void ThrowOnErr( int rc) throws DNSSDException
- {
- if (rc != 0)
- throw new AppleDNSSDException( rc);
- }
-
- protected native int Update( int flags, byte[] rData, int ttl);
-
- protected native int Remove();
-}
-
-class AppleRegistration extends AppleService implements DNSSDRegistration
-{
- public AppleRegistration( int flags, int ifIndex, String serviceName, String regType, String domain,
- String host, int port, byte[] txtRecord, RegisterListener client)
- throws DNSSDException
- {
- super(client);
- this.ThrowOnErr( this.BeginRegister( ifIndex, flags, serviceName, regType, domain, host, port, txtRecord));
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- public DNSRecord addRecord( int flags, int rrType, byte[] rData, int ttl)
- throws DNSSDException
- {
- AppleDNSRecord newRecord = new AppleDNSRecord( this);
-
- this.ThrowOnErr( this.AddRecord( flags, rrType, rData, ttl, newRecord));
- return newRecord;
- }
-
- public DNSRecord getTXTRecord()
- throws DNSSDException
- {
- return new AppleDNSRecord( this); // A record with ref 0 is understood to be primary TXT record
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int BeginRegister( int ifIndex, int flags, String serviceName, String regType,
- String domain, String host, int port, byte[] txtRecord);
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int AddRecord( int flags, int rrType, byte[] rData, int ttl, AppleDNSRecord destObj);
-}
-
-class AppleRecordRegistrar extends AppleService implements DNSSDRecordRegistrar
-{
- public AppleRecordRegistrar( RegisterRecordListener listener)
- throws DNSSDException
- {
- super(listener);
- this.ThrowOnErr( this.CreateConnection());
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype,
- int rrclass, byte[] rdata, int ttl)
- throws DNSSDException
- {
- AppleDNSRecord newRecord = new AppleDNSRecord( this);
-
- this.ThrowOnErr( this.RegisterRecord( flags, ifIndex, fullname, rrtype, rrclass, rdata, ttl, newRecord));
- return newRecord;
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int CreateConnection();
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int RegisterRecord( int flags, int ifIndex, String fullname, int rrtype,
- int rrclass, byte[] rdata, int ttl, AppleDNSRecord destObj);
-}
-
-class AppleQuery extends AppleService
-{
- public AppleQuery( int flags, int ifIndex, String serviceName, int rrtype,
- int rrclass, QueryListener client)
- throws DNSSDException
- {
- super(client);
- this.ThrowOnErr( this.CreateQuery( flags, ifIndex, serviceName, rrtype, rrclass));
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int CreateQuery( int flags, int ifIndex, String serviceName, int rrtype, int rrclass);
-}
-
-class AppleDomainEnum extends AppleService
-{
- public AppleDomainEnum( int flags, int ifIndex, DomainListener client)
- throws DNSSDException
- {
- super(client);
- this.ThrowOnErr( this.BeginEnum( flags, ifIndex));
- if (!AppleDNSSD.hasAutoCallbacks)
- new Thread(this).start();
- }
-
- // Sets fNativeContext. Returns non-zero on error.
- protected native int BeginEnum( int flags, int ifIndex);
-}
-
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDException.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDException.java
deleted file mode 100644
index 99549b5d68..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDException.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-package com.apple.dnssd;
-
-
-/**
- Used to report various DNS-SD-related error conditions.
-*/
-
-abstract public class DNSSDException extends Exception
-{
- public static final int NO_ERROR = 0;
- public static final int UNKNOWN = -65537;
- public static final int NO_SUCH_NAME = -65538;
- public static final int NO_MEMORY = -65539;
- public static final int BAD_PARAM = -65540;
- public static final int BAD_REFERENCE = -65541;
- public static final int BAD_STATE = -65542;
- public static final int BAD_FLAGS = -65543;
- public static final int UNSUPPORTED = -65544;
- public static final int NOT_INITIALIZED = -65545;
- public static final int NO_CACHE = -65546;
- public static final int ALREADY_REGISTERED = -65547;
- public static final int NAME_CONFLICT = -65548;
- public static final int INVALID = -65549;
- public static final int FIREWALL = -65550;
- public static final int INCOMPATIBLE = -65551;
- public static final int BAD_INTERFACE_INDEX = -65552;
- public static final int REFUSED = -65553;
- public static final int NOSUCHRECORD = -65554;
- public static final int NOAUTH = -65555;
- public static final int NOSUCHKEY = -65556;
- public static final int NATTRAVERSAL = -65557;
- public static final int DOUBLENAT = -65558;
- public static final int BADTIME = -65559;
- public static final int BADSIG = -65560;
- public static final int BADKEY = -65561;
- public static final int TRANSIENT = -65562;
- public static final int SERVICENOTRUNNING = -65563;
- public static final int NATPORTMAPPINGUNSUPPORTED = -65564;
- public static final int NATPORTMAPPINGDISABLED = -65565;
-
- // Note: When adding new error values here, remember also
- // to update the corresponding kMessages array in AppleDNSSDException (DNSSD.java)
-
- /** Returns the sub-code that identifies the particular error. */
- abstract public int getErrorCode();
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java
deleted file mode 100644
index 62c5330840..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** An object for registering records, created by {@link DNSSD#createRecordRegistrar}. */
-
-public interface DNSSDRecordRegistrar extends DNSSDService
-{
- /** Register an independent {@link DNSRecord}.<P>
- @param flags
- Possible values are SHARED or UNIQUE (see flag type definitions for details).
- <P>
- @param ifIndex
- 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.
- <P>
- @param fullname
- The full domain name of the resource record.
- <P>
- @param rrtype
- The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
- as defined in nameser.h.
- <P>
- @param rrclass
- The class of the resource record, as defined in nameser.h
- (usually 1 for the Internet class).
- <P>
- @param rdata
- The new rdata as it is to appear in the DNS record.
- <P>
- @param ttl
- The time to live of the resource record, in seconds. Pass 0 to use a default value.
- <P>
- @return A {@link DNSSDService} that can be used to abort the record registration.
-
- @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
- @see RuntimePermission
- */
- public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype,
- int rrclass, byte[] rdata, int ttl)
- throws DNSSDException;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRegistration.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRegistration.java
deleted file mode 100644
index 720df0b847..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRegistration.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A tracking object for a registration created by {@link DNSSD#register}. */
-
-public interface DNSSDRegistration extends DNSSDService
-{
- /** Get a reference to the primary TXT record of a registered service.<P>
- The record can be updated by sending it an update() message.<P>
-
- <P>
- @return A {@link DNSRecord}.
- If {@link DNSSDRegistration#stop} is called, the DNSRecord is also
- invalidated and may not be used further.
- */
- DNSRecord getTXTRecord()
- throws DNSSDException;
-
- /** Add a record to a registered service.<P>
- The name of the record will be the same as the registered service's name.<P>
- The record can be updated or deregistered by sending it an update() or remove() message.<P>
-
- @param flags
- Currently unused, reserved for future use.
- <P>
- @param rrType
- The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
- <P>
- @param rData
- The raw rdata to be contained in the added resource record.
- <P>
- @param ttl
- The time to live of the resource record, in seconds.
- <P>
- @return A {@link DNSRecord} that may be passed to updateRecord() or removeRecord().
- If {@link DNSSDRegistration#stop} is called, the DNSRecord is also
- invalidated and may not be used further.
- */
- DNSRecord addRecord( int flags, int rrType, byte[] rData, int ttl)
- throws DNSSDException;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDService.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDService.java
deleted file mode 100644
index 10f74021e6..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-/** A tracking object for a service created by {@link DNSSD}. */
-
-public interface DNSSDService
-{
- /**
- Halt the active operation and free resources associated with the DNSSDService.<P>
-
- Any services or records registered with this DNSSDService will be deregistered. Any
- Browse, Resolve, or Query operations associated with this reference will be terminated.<P>
-
- Note: if the service was initialized with DNSSD.register(), and an extra resource record was
- added to the service via {@link DNSSDRegistration#addRecord}, the DNSRecord so created
- is invalidated when this method is called - the DNSRecord may not be used afterward.
- */
- void stop();
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DomainListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DomainListener.java
deleted file mode 100644
index 852f6430e5..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DomainListener.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/**
- A listener that receives results from {@link DNSSD#enumerateDomains}.
-*/
-
-public interface DomainListener extends BaseListener
-{
- /** Called to report discovered domains.<P>
-
- @param domainEnum
- The active domain enumerator.
- @param flags
- Possible values are: DNSSD.MORE_COMING, DNSSD.DEFAULT
- <P>
- @param ifIndex
- Specifies the interface on which the domain exists. (The index for a given
- interface is determined via the if_nametoindex() family of calls.)
- <P>
- @param domain
- The name of the domain.
- */
- void domainFound( DNSSDService domainEnum, int flags, int ifIndex, String domain);
-
- /** Called to report that a domain has disappeared.<P>
-
- @param domainEnum
- The active domain enumerator.
- @param flags
- Possible values are: DNSSD.MORE_COMING, DNSSD.DEFAULT
- <P>
- @param ifIndex
- Specifies the interface on which the domain exists. (The index for a given
- interface is determined via the if_nametoindex() family of calls.)
- <P>
- @param domain
- The name of the domain.
- */
- void domainLost( DNSSDService domainEnum, int flags, int ifIndex, String domain);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/Makefile b/usr/src/lib/libdns_sd/java/com/apple/dnssd/Makefile
deleted file mode 100644
index 334b97f158..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/Makefile
+++ /dev/null
@@ -1,150 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-
-include ../Makefile.com
-
-DNSSD_PKG = com.apple.dnssd
-
-TOP = $(SRC)/lib/libdns_sd/java
-JAVASRCDIR = $(TOP)/com/apple/dnssd
-CLASSPATH = $(TOP):com/apple/dnssd
-
-JAVAFLAGS += -source 1.4 -target 1.4
-SOURCE:sh = ls *.java
-CLASSES = $(SOURCE:java=class)
-JNIH = DNSSD.java.h
-JAR_FILE = dnssd.jar
-
-DOCDIR = $(JAVASRCDIR)/docs
-DOCAPIDIR = $(JAVASRCDIR)/docs/api
-DOCDESTDIR = $(ROOTDNSSDJAVAHOME)/javadoc/dnssd
-DOCAPIDESTDIR = $(DOCDESTDIR)/api
-DOCEXAMPLESDESTDIR = $(DOCDESTDIR)/examples
-$(BLD_JAVA_8)XDOCLINT_OPTION = -Xdoclint:none
-
-EXAMPLESDIR = $(JAVASRCDIR)/docs/examples
-EXAMPLESSRC = $(JAVASRCDIR)/docs/examples/src
-SIMPLECHATOBJ = $(EXAMPLESDIR)/SwingBrowseListener.class \
- $(EXAMPLESDIR)/SwingQueryListener.class \
- $(EXAMPLESDIR)/SimpleChat.class
-BROWSERAPPOBJ = $(EXAMPLESDIR)/SwingResolveListener.class \
- $(EXAMPLESDIR)/SwingDomainListener.class \
- $(EXAMPLESDIR)/BrowserApp.class
-EXAMPLEOBJS = $(SIMPLECHATOBJ) $(BROWSERAPPOBJ)
-EXAMPLEJARS = SimpleChat.jar BrowserApp.jar
-
-INSTALL_JAR = $(ROOTDNSSDJAVAHOME)/$(JAR_FILE)
-INSTALL_EXAMPLEJARS = $(DOCEXAMPLESDESTDIR)/SimpleChat.jar \
- $(DOCEXAMPLESDESTDIR)/BrowserApp.jar
-
-CLEAN_FILES = *.class $(JNIH) *.jar $(EXAMPLESDIR)/*.class $(EXAMPLESDIR)/*.jar
-
-DEFINES=
-
-INCLUDES= -I${JAVA_HOME}/include \
- -I${JAVA_HOME}/include/solaris
-
-.KEEP_STATE:
-
-all: $(JNIH) $(CLASSES) $(EXAMPLEOBJS) doc
-
-install: $(CLASSES) $(ROOTDNSSDJAVAHOME) \
- $(DOCEXAMPLESDESTDIR) $(DOCEXAMPLESSRCDESTDIR) \
- $(JAR_FILE) $(INSTALL_JAR) $(JNIH) \
- $(EXAMPLEJARS) $(INSTALL_EXAMPLEJARS) \
- install_doc
-
-$(JNIH): $(CLASSES)
- class="com.apple.dnssd.AppleDNSSD \
- com.apple.dnssd.AppleBrowser \
- com.apple.dnssd.AppleResolver \
- com.apple.dnssd.AppleRegistration \
- com.apple.dnssd.AppleQuery \
- com.apple.dnssd.AppleDomainEnum \
- com.apple.dnssd.AppleService"; \
- $(JAVAH) -classpath $(CLASSPATH) -jni -o $(JNIH) $$class
-
-clean clobber:
- $(RM) $(CLEAN_FILES)
-
-$(JAR_FILE): $(CLASSES)
- cd $(TOP); \
- $(JAR) -cvf $(TOP)/com/apple/dnssd/$(JAR_FILE) com/apple/dnssd/*.class
-
-$(EXAMPLESDIR)/%.class: $(EXAMPLESSRC)/%.java
- $(JAVAC) $(JAVAFLAGS) $< -classpath $(CLASSPATH):$(EXAMPLESDIR) -d $(EXAMPLESDIR)
-
-SIMPLECHATMAN = $(EXAMPLESSRC)/SimpleChat.manifest
-
-SimpleChat.jar: $(SIMPLECHATOBJ) $(SIMPLECHATMAN)
- cd $(EXAMPLESDIR); $(JAR) -cvfm $@ $(SIMPLECHATMAN) \
- SwingBrowseListener.class SwingQueryListener.class \
- SimpleChat.class SimpleChat\$$1.class \
- ListenerThread.class TargetListElem.class \
- TargetListModel.class src/SimpleChat.java \
- src/SimpleChat.manifest src/SwingBrowseListener.java \
- src/SwingQueryListener.java
-
-BROWSERAPPMAN = $(EXAMPLESSRC)/BrowserApp.manifest
-
-BrowserApp.jar: $(BROWSERAPPOBJ) $(BROWSERAPPMAN)
- cd $(EXAMPLESDIR); $(JAR) -cvfm $@ $(BROWSERAPPMAN) \
- BrowserApp\$$1.class BrowserApp.class \
- BrowserListModel\$$BrowserListElem.class \
- BrowserListModel.class DomainListModel.class \
- ServicesBrowserListModel.class \
- SwingResolveListener.class SwingDomainListener.class \
- src/BrowserApp.java src/SwingResolveListener.java \
- src/SwingDomainListener.java src/BrowserApp.manifest
-
-$(ROOTDNSSDJAVAHOME):
- $(INS.dir)
-
-$(ROOTDNSSDJAVAHOME)/%: %
- $(INS.file)
-
-$(DOCDESTDIR):
- $(INS.dir)
-
-$(DOCAPIDESTDIR): $(DOCDESTDIR)
- $(INS.dir)
-
-$(DOCEXAMPLESDESTDIR): $(DOCDESTDIR)
- $(INS.dir)
-
-$(DOCEXAMPLESDESTDIR)/%: %
- $(RM) $@; $(INS) -s -m $(FILEMODE) -f $(@D) $(EXAMPLESDIR)/$<
-
-install_doc: $(CLASSES) $(DOCAPIDESTDIR)
- -$(RM) -r $(DOCAPIDESTDIR)/*
- cd $(TOP); umask 022; \
- $(JAVADOC) $(JAVASRCDIR)/*.java $(XDOCLINT_OPTION) -notimestamp -classpath \
- $(CLASSPATH) -d $(DOCAPIDESTDIR) -public $(DNSSD_PKG)
-
-doc:
- -@mkdir -p $(DOCAPIDIR)
- cd $(TOP); umask 022; \
- $(JAVADOC) $(JAVASRCDIR)/*.java $(XDOCLINT_OPTION) -notimestamp -classpath \
- $(CLASSPATH) -d $(DOCAPIDIR) -public $(DNSSD_PKG)
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/QueryListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/QueryListener.java
deleted file mode 100644
index 0decb7fc4a..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/QueryListener.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A listener that receives results from {@link DNSSD#queryRecord}. */
-
-public interface QueryListener extends BaseListener
-{
- /** Called when a record query has been completed. Inspect flags
- parameter to determine nature of query event.<P>
-
- @param query
- The active query object.
- <P>
- @param flags
- If kDNSServiceFlagsAdd bit is set, this is a newly discovered answer;
- otherwise this is a previously discovered answer which has expired.
- Other possible values are DNSSD.MORE_COMING.
- <P>
- @param ifIndex
- The interface on which the query was resolved. (The index for a given
- interface is determined via the if_nametoindex() family of calls.)
- <P>
- @param fullName
- The resource record's full domain name.
- <P>
- @param rrtype
- The resource record's type (e.g. PTR, SRV, etc) as defined by RFC 1035 and its updates.
- <P>
- @param rrclass
- The class of the resource record, as defined by RFC 1035 and its updates.
- <P>
- @param rdata
- The raw rdata of the resource record.
- <P>
- @param ttl
- The resource record's time to live, in seconds.
- */
- void queryAnswered( DNSSDService query, int flags, int ifIndex, String fullName,
- int rrtype, int rrclass, byte[] rdata, int ttl);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterListener.java
deleted file mode 100644
index 00fa1a6344..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A listener that receives results from {@link DNSSD#register}. */
-
-public interface RegisterListener extends BaseListener
-{
- /** Called when a registration has been completed.<P>
-
- @param registration
- The active registration.
- <P>
- @param flags
- Currently unused, reserved for future use.
- <P>
- @param serviceName
- The service name registered (if the application did not specify a name in
- DNSSD.register(), this indicates what name was automatically chosen).
- <P>
- @param regType
- The type of service registered, as it was passed to DNSSD.register().
- <P>
- @param domain
- The domain on which the service was registered. If the application did not
- specify a domain in DNSSD.register(), this is the default domain
- on which the service was registered.
- */
- void serviceRegistered( DNSSDRegistration registration, int flags, String serviceName,
- String regType, String domain);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterRecordListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterRecordListener.java
deleted file mode 100644
index 6fecf8d81e..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/RegisterRecordListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A listener that receives results from {@link DNSSDRecordRegistrar#registerRecord}. */
-
-public interface RegisterRecordListener extends BaseListener
-{
- /** Called when a record registration succeeds.<P>
-
- @param record
- A {@link DNSRecord}.
- <P>
- @param flags
- Currently ignored, reserved for future use.
- <P>
- */
- void recordRegistered( DNSRecord record, int flags);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/ResolveListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/ResolveListener.java
deleted file mode 100644
index 33dafa38df..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/ResolveListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
- */
-
-
-package com.apple.dnssd;
-
-
-/** A listener that receives results from {@link DNSSD#resolve}. */
-
-public interface ResolveListener extends BaseListener
-{
- /** Called when a service has been resolved.<P>
-
- @param resolver
- The active resolver object.
- <P>
- @param flags
- Currently unused, reserved for future use.
- <P>
- @param fullName
- The full service domain name, in the form &lt;servicename&gt;.&lt;protocol&gt;.&lt;domain&gt;.
- (Any literal dots (".") are escaped with a backslash ("\."), and literal
- backslashes are escaped with a second backslash ("\\"), e.g. a web server
- named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
- This is the appropriate format to pass to standard system DNS APIs such as
- res_query(), or to the special-purpose functions included in this API that
- take fullname parameters.
- <P>
- @param hostName
- The target hostname of the machine providing the service. This name can
- be passed to functions like queryRecord() to look up the host's IP address.
- <P>
- @param port
- The port number on which connections are accepted for this service.
- <P>
- @param txtRecord
- The service's primary txt record.
- */
- void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
- String hostName, int port, TXTRecord txtRecord);
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/TXTRecord.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/TXTRecord.java
deleted file mode 100644
index 8d9df7a149..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/TXTRecord.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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.
-
- To do:
- - implement remove()
- - fix set() to replace existing values
- */
-
-
-package com.apple.dnssd;
-
-
-/**
- Object used to construct and parse DNS-SD format TXT records.
- For more info see <a href="http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt">DNS-Based Service Discovery</a>, section 6.
-*/
-
-public class TXTRecord
-{
- /*
- DNS-SD specifies that a TXT record corresponding to an SRV record consist of
- a packed array of bytes, each preceded by a length byte. Each string
- is an attribute-value pair.
-
- The TXTRecord object stores the entire TXT data as a single byte array, traversing it
- as need be to implement its various methods.
- */
-
- static final protected byte kAttrSep = '=';
-
- protected byte[] fBytes;
-
- /** Constructs a new, empty TXT record. */
- public TXTRecord()
- { fBytes = new byte[0]; }
-
- /** Constructs a new TXT record from a byte array in the standard format. */
- public TXTRecord( byte[] initBytes)
- { fBytes = (byte[]) initBytes.clone(); }
-
- /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
- @param key
- The key name. Must be ASCII, with no '=' characters.
- <P>
- @param value
- Value to be encoded into bytes using the default platform character set.
- */
- public void set( String key, String value)
- {
- byte[] valBytes = (value != null) ? value.getBytes() : null;
- this.set( key, valBytes);
- }
-
- /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
- @param key
- The key name. Must be ASCII, with no '=' characters.
- <P>
- @param value
- Binary representation of the value.
- */
- public void set( String key, byte[] value)
- {
- byte[] keyBytes;
- int valLen = (value != null) ? value.length : 0;
-
- try {
- keyBytes = key.getBytes( "US-ASCII");
- }
- catch ( java.io.UnsupportedEncodingException uee) {
- throw new IllegalArgumentException();
- }
-
- for ( int i=0; i < keyBytes.length; i++)
- if ( keyBytes[i] == '=')
- throw new IllegalArgumentException();
-
- if ( keyBytes.length + valLen >= 255)
- throw new ArrayIndexOutOfBoundsException();
-
- int prevLoc = this.remove( key);
- if ( prevLoc == -1)
- prevLoc = this.size();
-
- this.insert( keyBytes, value, prevLoc);
- }
-
- protected void insert( byte[] keyBytes, byte[] value, int index)
- // Insert a key-value pair at index
- {
- byte[] oldBytes = fBytes;
- int valLen = (value != null) ? value.length : 0;
- int insertion = 0;
- int newLen, avLen;
-
- // locate the insertion point
- for ( int i=0; i < index && insertion < fBytes.length; i++)
- insertion += (0xFF & (fBytes[ insertion] + 1));
-
- avLen = keyBytes.length + valLen + (value != null ? 1 : 0);
- newLen = avLen + oldBytes.length + 1;
-
- fBytes = new byte[ newLen];
- System.arraycopy( oldBytes, 0, fBytes, 0, insertion);
- int secondHalfLen = oldBytes.length - insertion;
- System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen);
- fBytes[ insertion] = ( byte) avLen;
- System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length);
- if ( value != null)
- {
- fBytes[ insertion + 1 + keyBytes.length] = kAttrSep;
- System.arraycopy( value, 0, fBytes, insertion + keyBytes.length + 2, valLen);
- }
- }
-
- /** Remove a key/value pair from the TXT record. Returns index it was at, or -1 if not found. */
- public int remove( String key)
- {
- int avStart = 0;
-
- for ( int i=0; avStart < fBytes.length; i++)
- {
- int avLen = fBytes[ avStart];
- if ( key.length() <= avLen &&
- ( key.length() == avLen || fBytes[ avStart + key.length() + 1] == kAttrSep))
- {
- String s = new String( fBytes, avStart + 1, key.length());
- if ( 0 == key.compareToIgnoreCase( s))
- {
- byte[] oldBytes = fBytes;
- fBytes = new byte[ oldBytes.length - avLen - 1];
- System.arraycopy( oldBytes, 0, fBytes, 0, avStart);
- System.arraycopy( oldBytes, avStart + avLen + 1, fBytes, avStart, oldBytes.length - avStart - avLen - 1);
- return i;
- }
- }
- avStart += (0xFF & (avLen + 1));
- }
- return -1;
- }
-
- /** Return the number of keys in the TXT record. */
- public int size()
- {
- int i, avStart;
-
- for ( i=0, avStart=0; avStart < fBytes.length; i++)
- avStart += (0xFF & (fBytes[ avStart] + 1));
- return i;
- }
-
- /** Return true if key is present in the TXT record, false if not. */
- public boolean contains( String key)
- {
- String s = null;
-
- for ( int i=0; null != ( s = this.getKey( i)); i++)
- if ( 0 == key.compareToIgnoreCase( s))
- return true;
- return false;
- }
-
- /** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
- public String getKey( int index)
- {
- int avStart = 0;
-
- for ( int i=0; i < index && avStart < fBytes.length; i++)
- avStart += fBytes[ avStart] + 1;
-
- if ( avStart < fBytes.length)
- {
- int avLen = fBytes[ avStart];
- int aLen = 0;
-
- for ( aLen=0; aLen < avLen; aLen++)
- if ( fBytes[ avStart + aLen + 1] == kAttrSep)
- break;
- return new String( fBytes, avStart + 1, aLen);
- }
- return null;
- }
-
- /**
- Look up a key in the TXT record by zero-based index and return its value. <P>
- Returns null if index exceeds the total number of keys.
- Returns null if the key is present with no value.
- */
- public byte[] getValue( int index)
- {
- int avStart = 0;
- byte[] value = null;
-
- for ( int i=0; i < index && avStart < fBytes.length; i++)
- avStart += fBytes[ avStart] + 1;
-
- if ( avStart < fBytes.length)
- {
- int avLen = fBytes[ avStart];
- int aLen = 0;
-
- for ( aLen=0; aLen < avLen; aLen++)
- {
- if ( fBytes[ avStart + aLen + 1] == kAttrSep)
- {
- value = new byte[ avLen - aLen - 1];
- System.arraycopy( fBytes, avStart + aLen + 2, value, 0, avLen - aLen - 1);
- break;
- }
- }
- }
- return value;
- }
-
- /** Converts the result of getValue() to a string in the platform default character set. */
- public String getValueAsString( int index)
- {
- byte[] value = this.getValue( index);
- return value != null ? new String( value) : null;
- }
-
- /** Get the value associated with a key. Will be null if the key is not defined.
- Array will have length 0 if the key is defined with an = but no value.<P>
-
- @param forKey
- The left-hand side of the key-value pair.
- <P>
- @return The binary representation of the value.
- */
- public byte[] getValue( String forKey)
- {
- String s = null;
- int i;
-
- for ( i=0; null != ( s = this.getKey( i)); i++)
- if ( 0 == forKey.compareToIgnoreCase( s))
- return this.getValue( i);
- return null;
- }
-
- /** Converts the result of getValue() to a string in the platform default character set.<P>
-
- @param forKey
- The left-hand side of the key-value pair.
- <P>
- @return The value represented in the default platform character set.
- */
- public String getValueAsString( String forKey)
- {
- byte[] val = this.getValue( forKey);
- return val != null ? new String( val) : null;
- }
-
- /** Return the contents of the TXT record as raw bytes. */
- public byte[] getRawBytes() { return (byte[]) fBytes.clone(); }
-
- /** Return a string representation of the object. */
- public String toString()
- {
- String a, result = null;
-
- for ( int i=0; null != ( a = this.getKey( i)); i++)
- {
- String av = String.valueOf( i) + "={" + a;
- String val = this.getValueAsString( i);
- if ( val != null)
- av += "=" + val + "}";
- else
- av += "}";
- if ( result == null)
- result = av;
- else
- result = result + ", " + av;
- }
- return result != null ? result : "";
- }
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.java
deleted file mode 100644
index 8f51215165..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- BrowserApp demonstrates how to use DNS-SD to browse for and resolve services.
-
- To do:
- - display resolved TXTRecord
- */
-
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.text.*;
-import javax.swing.*;
-import javax.swing.event.*;
-
-import com.apple.dnssd.*;
-
-
-class BrowserApp implements ListSelectionListener, ResolveListener, Runnable
-{
- static BrowserApp app;
- JFrame frame;
- DomainListModel domainList;
- BrowserListModel servicesList, serviceList;
- JList domainPane, servicesPane, servicePane;
- DNSSDService servicesBrowser, serviceBrowser, domainBrowser;
- JLabel hostLabel, portLabel;
- String hostNameForUpdate;
- int portForUpdate;
-
- public BrowserApp()
- {
- frame = new JFrame("DNS-SD Service Browser");
- frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- });
-
- domainList = new DomainListModel();
- servicesList = new ServicesBrowserListModel();
- serviceList = new BrowserListModel();
-
- try {
- domainBrowser = DNSSD.enumerateDomains( DNSSD.BROWSE_DOMAINS, 0, domainList);
-
- servicesBrowser = DNSSD.browse( 0, 0, "_services._dns-sd._udp.", "", servicesList);
- serviceBrowser = null;
- }
- catch ( Exception ex) { terminateWithException( ex); }
-
- this.setupSubPanes( frame.getContentPane());
- frame.pack();
- frame.setVisible(true);
- }
-
- protected void setupSubPanes( Container parent)
- {
- parent.setLayout( new BoxLayout( parent, BoxLayout.Y_AXIS));
-
- JPanel browserRow = new JPanel();
- browserRow.setLayout( new BoxLayout( browserRow, BoxLayout.X_AXIS));
- domainPane = new JList( domainList);
- domainPane.addListSelectionListener( this);
- JScrollPane domainScroller = new JScrollPane( domainPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
- browserRow.add( domainScroller);
- servicesPane = new JList( servicesList);
- servicesPane.addListSelectionListener( this);
- JScrollPane servicesScroller = new JScrollPane( servicesPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
- browserRow.add( servicesScroller);
- servicePane = new JList( serviceList);
- servicePane.addListSelectionListener( this);
- JScrollPane serviceScroller = new JScrollPane( servicePane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
- browserRow.add( serviceScroller);
-
-/*
- JPanel buttonRow = new JPanel();
- buttonRow.setLayout( new BoxLayout( buttonRow, BoxLayout.X_AXIS));
- buttonRow.add( Box.createHorizontalGlue());
- JButton connectButton = new JButton( "Don't Connect");
- buttonRow.add( connectButton);
- buttonRow.add( Box.createRigidArea( new Dimension( 16, 0)));
-*/
-
- JPanel labelRow = new JPanel();
- labelRow.setLayout( new BoxLayout( labelRow, BoxLayout.X_AXIS));
- labelRow.add( new JLabel( " Host: "));
- hostLabel = new JLabel();
- labelRow.add( hostLabel);
- labelRow.add( Box.createRigidArea( new Dimension( 32, 0)));
- labelRow.add( new JLabel( "Port: "));
- portLabel = new JLabel();
- labelRow.add( portLabel);
- labelRow.add( Box.createHorizontalGlue());
-
- parent.add( browserRow);
- parent.add( Box.createRigidArea( new Dimension( 0, 8)));
- parent.add( labelRow);
-// parent.add( buttonRow);
- parent.add( Box.createRigidArea( new Dimension( 0, 16)));
- }
-
- public void valueChanged( ListSelectionEvent e)
- {
- try {
- if ( e.getSource() == domainPane && !e.getValueIsAdjusting())
- {
- int newSel = domainPane.getSelectedIndex();
- if ( -1 != newSel)
- {
- if ( serviceBrowser != null)
- serviceBrowser.stop();
- serviceList.removeAllElements();
- servicesBrowser = DNSSD.browse( 0, 0, "_services._dns-sd._udp.", "", servicesList);
- }
- }
- else if ( e.getSource() == servicesPane && !e.getValueIsAdjusting())
- {
- int newSel = servicesPane.getSelectedIndex();
- if ( serviceBrowser != null)
- serviceBrowser.stop();
- serviceList.removeAllElements();
- if ( -1 != newSel)
- serviceBrowser = DNSSD.browse( 0, 0, servicesList.getNthRegType( newSel), "", serviceList);
- }
- else if ( e.getSource() == servicePane && !e.getValueIsAdjusting())
- {
- int newSel = servicePane.getSelectedIndex();
-
- hostLabel.setText( "");
- portLabel.setText( "");
-
- if ( -1 != newSel)
- {
- DNSSD.resolve( 0, serviceList.getNthInterface( newSel),
- serviceList.getNthServiceName( newSel),
- serviceList.getNthRegType( newSel),
- serviceList.getNthDomain( newSel),
- this);
- }
- }
- }
- catch ( Exception ex) { terminateWithException( ex); }
- }
-
- public void run()
- {
- hostLabel.setText( hostNameForUpdate);
- portLabel.setText( String.valueOf( portForUpdate));
- }
-
- public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
- String hostName, int port, TXTRecord txtRecord)
- {
- // We want to update GUI on the AWT event dispatching thread, but we can't stop
- // the resolve from that thread, since stop() is synchronized with this callback.
- // So, we stop the resolve on this thread, then invokeAndWait on the AWT event thread.
-
- resolver.stop();
-
- hostNameForUpdate = hostName;
- portForUpdate = port;
-
- try {
- SwingUtilities.invokeAndWait(this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- service.stop();
- // handle failure here
- }
-
- protected static void terminateWithException( Exception e)
- {
- e.printStackTrace();
- System.exit( -1);
- }
-
- public static void main(String s[])
- {
- app = new BrowserApp();
- }
-}
-
-
-class BrowserListModel extends DefaultListModel implements BrowseListener, Runnable
-{
- public BrowserListModel()
- {
- addCache = new Vector();
- removeCache = new Vector();
- }
-
- /* The Browser invokes this callback when a service is discovered. */
- public void serviceFound( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- {
- addCache.add( new BrowserListElem( serviceName, domain, regType, ifIndex));
- if ( ( flags & DNSSD.MORE_COMING) == 0)
- this.scheduleOnEventThread();
- }
-
- public void serviceLost( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- {
- removeCache.add( serviceName);
- if ( ( flags & DNSSD.MORE_COMING) == 0)
- this.scheduleOnEventThread();
- }
-
- public void run()
- {
- while ( removeCache.size() > 0)
- {
- String serviceName = (String) removeCache.remove( removeCache.size() - 1);
- int matchInd = this.findMatching( serviceName); // probably doesn't handle near-duplicates well.
- if ( matchInd != -1)
- this.removeElementAt( matchInd);
- }
- while ( addCache.size() > 0)
- {
- BrowserListElem elem = (BrowserListElem) addCache.remove( addCache.size() - 1);
- if ( -1 == this.findMatching( elem.fServiceName)) // probably doesn't handle near-duplicates well.
- this.addInSortOrder( elem);
- }
- }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- // handle failure here
- }
-
- /* The list contains BrowserListElem's */
- class BrowserListElem
- {
- public BrowserListElem( String serviceName, String domain, String type, int ifIndex)
- { fServiceName = serviceName; fDomain = domain; fType = type; fInt = ifIndex; }
-
- public String toString() { return fServiceName; }
-
- public String fServiceName, fDomain, fType;
- public int fInt;
- }
-
- public String getNthServiceName( int n)
- {
- BrowserListElem sel = (BrowserListElem) this.get( n);
- return sel.fServiceName;
- }
-
- public String getNthRegType( int n)
- {
- BrowserListElem sel = (BrowserListElem) this.get( n);
- return sel.fType;
- }
-
- public String getNthDomain( int n)
- {
- BrowserListElem sel = (BrowserListElem) this.get( n);
- return sel.fDomain;
- }
-
- public int getNthInterface( int n)
- {
- BrowserListElem sel = (BrowserListElem) this.get( n);
- return sel.fInt;
- }
-
- protected void addInSortOrder( Object obj)
- {
- int i;
- for ( i = 0; i < this.size(); i++)
- if ( sCollator.compare( obj.toString(), this.getElementAt( i).toString()) < 0)
- break;
- this.add( i, obj);
- }
-
- protected int findMatching( String match)
- {
- for ( int i = 0; i < this.size(); i++)
- if ( match.equals( this.getElementAt( i).toString()))
- return i;
- return -1;
- }
-
- protected void scheduleOnEventThread()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected Vector removeCache; // list of serviceNames to remove
- protected Vector addCache; // list of BrowserListElem's to add
-
- protected static Collator sCollator;
-
- static // Initialize our static variables
- {
- sCollator = Collator.getInstance();
- sCollator.setStrength( Collator.PRIMARY);
- }
-}
-
-
-class ServicesBrowserListModel extends BrowserListModel
-{
- /* The Browser invokes this callback when a service is discovered. */
- public void serviceFound( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- // Overridden to stuff serviceName into regType and make serviceName human-readable.
- {
- regType = serviceName + ( regType.startsWith( "_udp.") ? "._udp." : "._tcp.");
- super.serviceFound( browser, flags, ifIndex, this.mapTypeToName( serviceName), regType, domain);
- }
-
- public void serviceLost( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- // Overridden to make serviceName human-readable.
- {
- super.serviceLost( browser, flags, ifIndex, this.mapTypeToName( serviceName), regType, domain);
- }
-
- protected String mapTypeToName( String type)
- // Convert a registration type into a human-readable string. Returns original string on no-match.
- {
- final String[] namedServices = {
- "_afpovertcp", "Apple File Sharing",
- "_http", "World Wide Web servers",
- "_daap", "Digital Audio Access",
- "_apple-sasl", "Apple Password Servers",
- "_distcc", "Distributed Compiler nodes",
- "_finger", "Finger servers",
- "_ichat", "iChat clients",
- "_presence", "iChat AV clients",
- "_ssh", "SSH servers",
- "_telnet", "Telnet servers",
- "_workstation", "Macintosh Manager clients",
- "_bootps", "BootP servers",
- "_xserveraid", "XServe RAID devices",
- "_eppc", "Remote AppleEvents",
- "_ftp", "FTP services",
- "_tftp", "TFTP services"
- };
-
- for ( int i = 0; i < namedServices.length; i+=2)
- if ( namedServices[i].equals( type))
- return namedServices[i + 1];
- return type;
- }
-}
-
-
-class DomainListModel extends DefaultListModel implements DomainListener
-{
- /* Called when a domain is discovered. */
- public void domainFound( DNSSDService domainEnum, int flags, int ifIndex, String domain)
- {
- if ( !this.contains( domain))
- this.addElement( domain);
- }
-
- public void domainLost( DNSSDService domainEnum, int flags, int ifIndex, String domain)
- {
- if ( this.contains( domain))
- this.removeElement( domain);
- }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- // handle failure here
- }
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.manifest b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.manifest
deleted file mode 100644
index 7c392a1908..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/BrowserApp.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: BrowserApp
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.java
deleted file mode 100644
index a1fee5c018..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- SimpleChat is a simple peer-to-peer chat program that demonstrates
- DNS-SD registration, browsing, resolving and record-querying.
-
- To do:
- - implement better coloring algorithm
- */
-
-
-import java.awt.*;
-import java.awt.event.*;
-import java.text.*;
-import java.net.*;
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
-
-import com.apple.dnssd.*;
-
-
-class SimpleChat implements ResolveListener, RegisterListener, QueryListener,
- ActionListener, ItemListener, Runnable
-{
- Document textDoc; // Holds all the chat text
- JTextField inputField; // Holds a pending chat response
- String ourName; // name used to identify this user in chat
- DNSSDService browser; // object that actively browses for other chat clients
- DNSSDService resolver; // object that resolves other chat clients
- DNSSDRegistration registration; // object that maintains our connection advertisement
- JComboBox targetPicker; // Indicates who we're talking to
- TargetListModel targetList; // and its list model
- JButton sendButton; // Will send text in inputField to target
- InetAddress buddyAddr; // and address
- int buddyPort; // and port
- DatagramPacket dataPacket; // Inbound data packet
- DatagramSocket outSocket; // Outbound data socket
- SimpleAttributeSet textAttribs;
-
- static final String kChatExampleRegType = "_p2pchat._udp";
- static final String kWireCharSet = "ISO-8859-1";
-
- public SimpleChat() throws Exception
- {
- JFrame frame = new JFrame("SimpleChat");
- frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {System.exit(0);}
- });
-
- ourName = System.getProperty( "user.name");
- targetList = new TargetListModel();
- textAttribs = new SimpleAttributeSet();
- DatagramSocket inSocket = new DatagramSocket();
- dataPacket = new DatagramPacket( new byte[ 4096], 4096);
- outSocket = new DatagramSocket();
-
- this.setupSubPanes( frame.getContentPane(), frame.getRootPane());
- frame.pack();
- frame.setVisible(true);
- inputField.requestFocusInWindow();
-
- browser = DNSSD.browse( 0, 0, kChatExampleRegType, "", new SwingBrowseListener( targetList));
-
- registration = DNSSD.register( 0, 0, ourName, kChatExampleRegType, "", "", inSocket.getLocalPort(), null, this);
-
- new ListenerThread( this, inSocket, dataPacket).start();
- }
-
- protected void setupSubPanes( Container parent, JRootPane rootPane)
- {
- parent.setLayout( new BoxLayout( parent, BoxLayout.Y_AXIS));
-
- JPanel textRow = new JPanel();
- textRow.setLayout( new BoxLayout( textRow, BoxLayout.X_AXIS));
- textRow.add( Box.createRigidArea( new Dimension( 16, 0)));
- JEditorPane textPane = new JEditorPane( "text/html", "<BR>");
- textPane.setPreferredSize( new Dimension( 400, 300));
- textPane.setEditable( false);
- JScrollPane textScroller = new JScrollPane( textPane);
- textRow.add( textScroller);
- textRow.add( Box.createRigidArea( new Dimension( 16, 0)));
- textDoc = textPane.getDocument();
-
- JPanel addressRow = new JPanel();
- addressRow.setLayout( new BoxLayout( addressRow, BoxLayout.X_AXIS));
- targetPicker = new JComboBox( targetList);
- targetPicker.addItemListener( this);
- addressRow.add( Box.createRigidArea( new Dimension( 16, 0)));
- addressRow.add( new JLabel( "Talk to: "));
- addressRow.add( targetPicker);
- addressRow.add( Box.createHorizontalGlue());
-
- JPanel buttonRow = new JPanel();
- buttonRow.setLayout( new BoxLayout( buttonRow, BoxLayout.X_AXIS));
- buttonRow.add( Box.createRigidArea( new Dimension( 16, 0)));
- inputField = new JTextField();
- // prevent inputField from hijacking <Enter> key
- inputField.getKeymap().removeKeyStrokeBinding( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0));
- buttonRow.add( inputField);
- sendButton = new JButton( "Send");
- buttonRow.add( Box.createRigidArea( new Dimension( 8, 0)));
- buttonRow.add( sendButton);
- buttonRow.add( Box.createRigidArea( new Dimension( 16, 0)));
- rootPane.setDefaultButton( sendButton);
- sendButton.addActionListener( this);
- sendButton.setEnabled( false);
-
- parent.add( Box.createRigidArea( new Dimension( 0, 16)));
- parent.add( textRow);
- parent.add( Box.createRigidArea( new Dimension( 0, 8)));
- parent.add( addressRow);
- parent.add( Box.createRigidArea( new Dimension( 0, 8)));
- parent.add( buttonRow);
- parent.add( Box.createRigidArea( new Dimension( 0, 16)));
- }
-
- public void serviceRegistered( DNSSDRegistration registration, int flags,
- String serviceName, String regType, String domain)
- {
- ourName = serviceName; // might have been renamed on collision
- }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- System.out.println( "Service reported error " + String.valueOf( errorCode));
- }
-
- public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
- String hostName, int port, TXTRecord txtRecord)
- {
- buddyPort = port;
- try {
- // Start a record query to obtain IP address from hostname
- DNSSD.queryRecord( 0, ifIndex, hostName, 1 /* ns_t_a */, 1 /* ns_c_in */,
- new SwingQueryListener( this));
- }
- catch ( Exception e) { terminateWithException( e); }
- resolver.stop();
- }
-
- public void queryAnswered( DNSSDService query, int flags, int ifIndex, String fullName,
- int rrtype, int rrclass, byte[] rdata, int ttl)
- {
- try {
- buddyAddr = InetAddress.getByAddress( rdata);
- }
- catch ( Exception e) { terminateWithException( e); }
- sendButton.setEnabled( true);
- }
-
- public void actionPerformed( ActionEvent e) // invoked when Send button is hit
- {
- try
- {
- String sendString = ourName + ": " + inputField.getText();
- byte[] sendData = sendString.getBytes( kWireCharSet);
- outSocket.send( new DatagramPacket( sendData, sendData.length, buddyAddr, buddyPort));
- StyleConstants.setForeground( textAttribs, Color.black);
- textDoc.insertString( textDoc.getLength(), inputField.getText() + "\n", textAttribs);
- inputField.setText( "");
- }
- catch ( Exception exception) { terminateWithException( exception); }
- }
-
- public void itemStateChanged( ItemEvent e) // invoked when Target selection changes
- {
- sendButton.setEnabled( false);
- if ( e.getStateChange() == ItemEvent.SELECTED)
- {
- try {
- TargetListElem sel = (TargetListElem) targetList.getSelectedItem();
- resolver = DNSSD.resolve( 0, sel.fInt, sel.fServiceName, sel.fType, sel.fDomain, this);
- }
- catch ( Exception exception) { terminateWithException( exception); }
- }
- }
-
- public void run() // invoked on event thread when inbound packet arrives
- {
- try
- {
- String inMessage = new String( dataPacket.getData(), 0, dataPacket.getLength(), kWireCharSet);
- StyleConstants.setForeground( textAttribs, this.getColorFor( dataPacket.getData(), dataPacket.getLength()));
- textDoc.insertString( textDoc.getLength(), inMessage + "\n", textAttribs);
- }
- catch ( Exception e) { terminateWithException( e); }
- }
-
- protected Color getColorFor( byte[] chars, int length)
- // Produce a mapping from a string to a color, suitable for text display
- {
- int rgb = 0;
- for ( int i=0; i < length && chars[i] != ':'; i++)
- rgb = rgb ^ ( (int) chars[i] << (i%3+2) * 8);
- return new Color( rgb & 0x007F7FFF); // mask off high bits so it is a dark color
-
-// for ( int i=0; i < length && chars[i] != ':'; i++)
-
- }
-
- protected static void terminateWithException( Exception e)
- {
- e.printStackTrace();
- System.exit( -1);
- }
-
- public static void main(String s[])
- {
- try {
- new SimpleChat();
- }
- catch ( Exception e) { terminateWithException( e); }
- }
-}
-
-
-
-class TargetListElem
-{
- public TargetListElem( String serviceName, String domain, String type, int ifIndex)
- { fServiceName = serviceName; fDomain = domain; fType = type; fInt = ifIndex; }
-
- public String toString() { return fServiceName; }
-
- public String fServiceName, fDomain, fType;
- public int fInt;
-}
-
-class TargetListModel extends DefaultComboBoxModel implements BrowseListener
-{
- /* The Browser invokes this callback when a service is discovered. */
- public void serviceFound( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- {
- TargetListElem match = this.findMatching( serviceName); // probably doesn't handle near-duplicates well.
-
- if ( match == null)
- this.addElement( new TargetListElem( serviceName, domain, regType, ifIndex));
- }
-
- /* The Browser invokes this callback when a service disappears. */
- public void serviceLost( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- {
- TargetListElem match = this.findMatching( serviceName); // probably doesn't handle near-duplicates well.
-
- if ( match != null)
- this.removeElement( match);
- }
-
- /* The Browser invokes this callback when a service disappears. */
- public void operationFailed( DNSSDService service, int errorCode)
- {
- System.out.println( "Service reported error " + String.valueOf( errorCode));
- }
-
- protected TargetListElem findMatching( String match)
- {
- for ( int i = 0; i < this.getSize(); i++)
- if ( match.equals( this.getElementAt( i).toString()))
- return (TargetListElem) this.getElementAt( i);
- return null;
- }
-
-}
-
-
-// A ListenerThread runs its owner when datagram packet p appears on socket s.
-class ListenerThread extends Thread
-{
- public ListenerThread( Runnable owner, DatagramSocket s, DatagramPacket p)
- { fOwner = owner; fSocket = s; fPacket = p; }
-
- public void run()
- {
- while ( true )
- {
- try
- {
- fSocket.receive( fPacket);
- SwingUtilities.invokeAndWait( fOwner); // process data on main thread
- }
- catch( Exception e)
- {
- break; // terminate thread
- }
- }
- }
-
- protected Runnable fOwner;
- protected DatagramSocket fSocket;
- protected DatagramPacket fPacket;
-}
-
-
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.manifest b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.manifest
deleted file mode 100644
index 45c02025c2..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SimpleChat.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: SimpleChat
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingBrowseListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingBrowseListener.java
deleted file mode 100644
index db971b2b43..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingBrowseListener.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-import javax.swing.*;
-import com.apple.dnssd.*;
-
-
-/** Use this to schedule BrowseListener callbacks via SwingUtilities.invokeAndWait(). */
-
-public class SwingBrowseListener implements Runnable, BrowseListener
-{
- /** Create a listener for DNSSD that will call your listener on the Swing/AWT event thread. */
- public SwingBrowseListener( BrowseListener listener)
- { fListener = listener; fErrorCode = 0; }
-
- /** (Clients should not call this method directly.) */
- public void operationFailed( DNSSDService service, int errorCode)
- {
- fBrowser = service;
- fErrorCode = errorCode;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void serviceFound( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
-
- {
- fBrowser = browser;
- fIsAdd = true;
- fFlags = flags;
- fIndex = ifIndex;
- fService = serviceName;
- fRegType = regType;
- fDomain = domain;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void serviceLost( DNSSDService browser, int flags, int ifIndex,
- String serviceName, String regType, String domain)
- {
- fBrowser = browser;
- fIsAdd = false;
- fFlags = flags;
- fIndex = ifIndex;
- fService = serviceName;
- fRegType = regType;
- fDomain = domain;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void run()
- {
- if ( fErrorCode != 0)
- fListener.operationFailed( fBrowser, fErrorCode);
- else if ( fIsAdd)
- fListener.serviceFound( fBrowser, fFlags, fIndex, fService, fRegType, fDomain);
- else
- fListener.serviceLost( fBrowser, fFlags, fIndex, fService, fRegType, fDomain);
- }
-
- protected void schedule()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected BrowseListener fListener;
-
- protected boolean fIsAdd;
- protected DNSSDService fBrowser;
- protected int fFlags;
- protected int fIndex;
- protected int fErrorCode;
- protected String fService;
- protected String fRegType;
- protected String fDomain;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingDomainListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingDomainListener.java
deleted file mode 100644
index b67313b7bc..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingDomainListener.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-import javax.swing.*;
-import com.apple.dnssd.*;
-
-
-/** Use this to schedule DomainListener callbacks via SwingUtilities.invokeAndWait(). */
-
-public class SwingDomainListener implements Runnable, DomainListener
-{
- /** Create a listener for DNSSD that will call your listener on the Swing/AWT event thread. */
- public SwingDomainListener( DomainListener listener)
- { fListener = listener; fErrorCode = 0; }
-
- /** (Clients should not call this method directly.) */
- public void operationFailed( DNSSDService service, int errorCode)
- {
- fEnumerator = service;
- fErrorCode = errorCode;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void domainFound( DNSSDService domainEnum, int flags, int ifIndex, String domain)
-
- {
- fEnumerator = domainEnum;
- fIsAdd = true;
- fFlags = flags;
- fIndex = ifIndex;
- fDomain = domain;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void domainLost( DNSSDService domainEnum, int flags, int ifIndex, String domain)
- {
- fEnumerator = domainEnum;
- fIsAdd = false;
- fFlags = flags;
- fIndex = ifIndex;
- fDomain = domain;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void run()
- {
- if ( fErrorCode != 0)
- fListener.operationFailed( fEnumerator, fErrorCode);
- else if ( fIsAdd)
- fListener.domainFound( fEnumerator, fFlags, fIndex, fDomain);
- else
- fListener.domainLost( fEnumerator, fFlags, fIndex, fDomain);
- }
-
- protected void schedule()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected DomainListener fListener;
-
- protected boolean fIsAdd;
- protected DNSSDService fEnumerator;
- protected int fFlags;
- protected int fIndex;
- protected int fErrorCode;
- protected String fDomain;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingQueryListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingQueryListener.java
deleted file mode 100644
index fcac75b832..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingQueryListener.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-import javax.swing.*;
-import com.apple.dnssd.*;
-
-
-/** Use this to schedule QueryListener callbacks via SwingUtilities.invokeAndWait(). */
-
-public class SwingQueryListener implements Runnable, QueryListener
-{
- /** Create a listener for DNSSD that will call your listener on the Swing/AWT event thread. */
- public SwingQueryListener( QueryListener listener)
- { fListener = listener; }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- fQuery = service;
- fErrorCode = errorCode;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void queryAnswered( DNSSDService query, int flags, int ifIndex, String fullName,
- int rrtype, int rrclass, byte[] rdata, int ttl)
- {
- fQuery = query;
- fFlags = flags;
- fIndex = ifIndex;
- fFullName = fullName;
- fType = rrtype;
- fClass = rrclass;
- fData = rdata;
- fTTL = ttl;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void run()
- {
- if ( fErrorCode != 0)
- fListener.operationFailed( fQuery, fErrorCode);
- else
- fListener.queryAnswered( fQuery, fFlags, fIndex, fFullName, fType, fClass, fData, fTTL);
- }
-
- protected void schedule()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected QueryListener fListener;
-
- protected DNSSDService fQuery;
- protected int fFlags;
- protected int fIndex;
- protected int fErrorCode;
- protected String fFullName;
- protected int fType;
- protected int fClass;
- protected byte[] fData;
- protected int fTTL;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingResolveListener.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingResolveListener.java
deleted file mode 100644
index 499da0707d..0000000000
--- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/docs/examples/src/SwingResolveListener.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: Java; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- * ("Apple") in consideration of your agreement to the following terms, and your
- * use, installation, modification or redistribution of this Apple software
- * constitutes acceptance of these terms. If you do not agree with these terms,
- * please do not use, install, modify or redistribute this Apple software.
- *
- * In consideration of your agreement to abide by the following terms, and subject
- * to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- * copyrights in this original Apple software (the "Apple Software"), to use,
- * reproduce, modify and redistribute the Apple Software, with or without
- * modifications, in source and/or binary forms; provided that if you redistribute
- * the Apple Software in its entirety and without modifications, you must retain
- * this notice and the following text and disclaimers in all such redistributions of
- * the Apple Software. Neither the name, trademarks, service marks or logos of
- * Apple Computer, Inc. may be used to endorse or promote products derived from the
- * Apple Software without specific prior written permission from Apple. Except as
- * expressly stated in this notice, no other rights or licenses, express or implied,
- * are granted by Apple herein, including but not limited to any patent rights that
- * may be infringed by your derivative works or by other works in which the Apple
- * Software may be incorporated.
- *
- * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- * COMBINATION WITH YOUR PRODUCTS.
- *
- * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- * OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ident "%Z%%M% %I% %E% SMI"
-
- */
-
-
-import javax.swing.*;
-import com.apple.dnssd.*;
-
-
-/** Use this to schedule ResolveListener callbacks via SwingUtilities.invokeAndWait(). */
-
-public class SwingResolveListener implements Runnable, ResolveListener
-{
- /** Create a listener for DNSSD that will call your listener on the Swing/AWT event thread. */
- public SwingResolveListener( ResolveListener listener)
- { fListener = listener; }
-
- public void operationFailed( DNSSDService service, int errorCode)
- {
- fResolver = service;
- fErrorCode = errorCode;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
- String hostName, int port, TXTRecord txtRecord)
- {
- fResolver = resolver;
- fFlags = flags;
- fIndex = ifIndex;
- fFullName = fullName;
- fHostName = hostName;
- fPort = port;
- fTXTRecord = txtRecord;
- this.schedule();
- }
-
- /** (Clients should not call this method directly.) */
- public void run()
- {
- if ( fErrorCode != 0)
- fListener.operationFailed( fResolver, fErrorCode);
- else
- fListener.serviceResolved( fResolver, fFlags, fIndex, fFullName, fHostName, fPort, fTXTRecord);
- }
-
- protected void schedule()
- {
- try {
- SwingUtilities.invokeAndWait( this);
- }
- catch ( Exception e)
- {
- e.printStackTrace();
- }
- }
-
- protected ResolveListener fListener;
-
- protected DNSSDService fResolver;
- protected int fFlags;
- protected int fIndex;
- protected int fErrorCode;
- protected String fFullName;
- protected String fHostName;
- protected int fPort;
- protected TXTRecord fTXTRecord;
-}
-
diff --git a/usr/src/lib/libdns_sd/java/common/JNISupport.c b/usr/src/lib/libdns_sd/java/common/JNISupport.c
deleted file mode 100644
index af4de19912..0000000000
--- a/usr/src/lib/libdns_sd/java/common/JNISupport.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2004 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 file contains the platform support for DNSSD and related Java classes.
- It is used to shim through to the underlying <dns_sd.h> API.
- */
-
-// AUTO_CALLBACKS should be set to 1 if the underlying mDNS implementation fires response
-// callbacks automatically (as in the early Windows prototypes).
-// AUTO_CALLBACKS should be set to 0 if the client must call DNSServiceProcessResult() to
-// invoke response callbacks (as is true on Mac OS X, Posix, Windows, etc.).
-// (Invoking callbacks automatically on a different thread sounds attractive, but while
-// the client gains by not needing to add an event source to its main event loop, it loses
-// by being forced to deal with concurrency and locking, which can be a bigger burden.)
-#ifndef AUTO_CALLBACKS
-#define AUTO_CALLBACKS 0
-#endif
-
-#if !AUTO_CALLBACKS
-#ifdef _WIN32
-#include <winsock2.h>
-#else //_WIN32
-#include <sys/types.h>
-#include <sys/select.h>
-#endif // _WIN32
-#endif // AUTO_CALLBACKS
-
-#include <dns_sd.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <iphlpapi.h>
-static char * win32_if_indextoname( DWORD ifIndex, char * nameBuff);
-static DWORD win32_if_nametoindex( const char * nameStr );
-#define if_indextoname win32_if_indextoname
-#define if_nametoindex win32_if_nametoindex
-#define IF_NAMESIZE MAX_ADAPTER_NAME_LENGTH
-#else // _WIN32
-#include <sys/socket.h>
-#include <net/if.h>
-#endif // _WIN32
-
-// When compiling with "-Wshadow" set, including jni.h produces the following error:
-// /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/jni.h:609: warning: declaration of 'index' shadows a global declaration
-// To work around this, we use the preprocessor to map the identifier 'index', which appears harmlessly in function prototype declarations,
-// to something 'jni_index', which doesn't conflict
-#define index jni_index
-#include "DNSSD.java.h"
-#undef index
-
-//#include <syslog.h>
-
-// convenience definition
-#ifdef __GNUC__
-#define _UNUSED __attribute__ ((unused))
-#else
-#define _UNUSED
-#endif
-
-enum {
- kInterfaceVersionOne = 1,
- kInterfaceVersionCurrent // Must match version in .jar file
-};
-
-typedef struct OpContext OpContext;
-
-struct OpContext
-{
- DNSServiceRef ServiceRef;
- JNIEnv *Env;
- jobject JavaObj;
- jobject ClientObj;
- jmethodID Callback;
- jmethodID Callback2;
-};
-
-// For AUTO_CALLBACKS, we must attach the callback thread to the Java VM prior to upcall.
-#if AUTO_CALLBACKS
-JavaVM *gJavaVM = NULL;
-#endif
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls,
- jint callerVersion)
-{
- /* Ensure that caller & interface versions match. */
- if ( callerVersion != kInterfaceVersionCurrent)
- return kDNSServiceErr_Incompatible;
-
-#if AUTO_CALLBACKS
- {
- jsize numVMs;
-
- if ( 0 != JNI_GetCreatedJavaVMs( &gJavaVM, 1, &numVMs))
- return kDNSServiceErr_BadState;
- }
-#endif
-
- // Set AppleDNSSD.hasAutoCallbacks
- {
-#if AUTO_CALLBACKS
- jboolean hasAutoC = JNI_TRUE;
-#else
- jboolean hasAutoC = JNI_FALSE;
-#endif
- jfieldID hasAutoCField = (*pEnv)->GetStaticFieldID( pEnv, cls, "hasAutoCallbacks", "Z");
- (*pEnv)->SetStaticBooleanField( pEnv, cls, hasAutoCField, hasAutoC);
- }
-
- return kDNSServiceErr_NoError;
-}
-
-
-static const char* SafeGetUTFChars( JNIEnv *pEnv, jstring str)
-// Wrapper for JNI GetStringUTFChars() that returns NULL for null str.
-{
- return str != NULL ? (*pEnv)->GetStringUTFChars( pEnv, str, 0) : NULL;
-}
-
-static void SafeReleaseUTFChars( JNIEnv *pEnv, jstring str, const char *buff)
-// Wrapper for JNI GetStringUTFChars() that handles null str.
-{
- if ( str != NULL)
- (*pEnv)->ReleaseStringUTFChars( pEnv, str, buff);
-}
-
-
-#if AUTO_CALLBACKS
-static void SetupCallbackState( JNIEnv **ppEnv)
-{
- (*gJavaVM)->AttachCurrentThread( gJavaVM, (void**) ppEnv, NULL);
-}
-
-static void TeardownCallbackState( void )
-{
- (*gJavaVM)->DetachCurrentThread( gJavaVM);
-}
-
-#else // AUTO_CALLBACKS
-
-static void SetupCallbackState( JNIEnv **ppEnv _UNUSED)
-{
- // No setup necessary if ProcessResults() has been called
-}
-
-static void TeardownCallbackState( void )
-{
- // No teardown necessary if ProcessResults() has been called
-}
-#endif // AUTO_CALLBACKS
-
-
-static OpContext *NewContext( JNIEnv *pEnv, jobject owner,
- const char *callbackName, const char *callbackSig)
-// Create and initialize a new OpContext.
-{
- OpContext *pContext = (OpContext*) malloc( sizeof *pContext);
-
- if ( pContext != NULL)
- {
- jfieldID clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner),
- "fListener", "Lcom/apple/dnssd/BaseListener;");
-
- pContext->JavaObj = (*pEnv)->NewWeakGlobalRef( pEnv, owner); // must convert local ref to global to cache;
- pContext->ClientObj = (*pEnv)->GetObjectField( pEnv, owner, clientField);
- pContext->ClientObj = (*pEnv)->NewWeakGlobalRef( pEnv, pContext->ClientObj); // must convert local ref to global to cache
- pContext->Callback = (*pEnv)->GetMethodID( pEnv,
- (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
- callbackName, callbackSig);
- pContext->Callback2 = NULL; // not always used
- }
-
- return pContext;
-}
-
-
-static void ReportError( JNIEnv *pEnv, jobject target, jobject service, DNSServiceErrorType err)
-// Invoke operationFailed() method on target with err.
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, target);
- jmethodID opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed",
- "(Lcom/apple/dnssd/DNSSDService;I)V");
-
- (*pEnv)->CallVoidMethod( pEnv, target, opFailed, service, err);
-}
-
-JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_HaltOperation( JNIEnv *pEnv, jobject pThis)
-/* Deallocate the dns_sd service browser and set the Java object's fNativeContext field to 0. */
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
-
- if ( contextField != 0)
- {
- OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
- if ( pContext != NULL)
- {
- // MUST clear fNativeContext first, BEFORE calling DNSServiceRefDeallocate()
- (*pEnv)->SetLongField(pEnv, pThis, contextField, 0);
- if ( pContext->ServiceRef != NULL)
- DNSServiceRefDeallocate( pContext->ServiceRef);
-
- (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->JavaObj);
- (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->ClientObj);
- free( pContext);
- }
- }
-}
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_BlockForData( JNIEnv *pEnv, jobject pThis)
-/* Block until data arrives, or one second passes. Returns 1 if data present, 0 otherwise. */
-{
-// BlockForData() not supported with AUTO_CALLBACKS
-#if !AUTO_CALLBACKS
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
-
- if ( contextField != 0)
- {
- OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
- if ( pContext != NULL)
- {
- fd_set readFDs;
- int sd = DNSServiceRefSockFD( pContext->ServiceRef);
- struct timeval timeout = { 1, 0 };
- FD_ZERO( &readFDs);
- FD_SET( sd, &readFDs);
-
- // Q: Why do we poll here?
- // A: Because there's no other thread-safe way to do it.
- // Mac OS X terminates a select() call if you close one of the sockets it's listening on, but Linux does not,
- // and arguably Linux is correct (See <http://www.ussg.iu.edu/hypermail/linux/kernel/0405.1/0418.html>)
- // The problem is that the Mac OS X behaviour assumes that it's okay for one thread to close a socket while
- // some other thread is monitoring that socket in select(), but the difficulty is that there's no general way
- // to make that thread-safe, because there's no atomic way to enter select() and release a lock simultaneously.
- // If we try to do this without holding any lock, then right as we jump to the select() routine,
- // some other thread could stop our operation (thereby closing the socket),
- // and then that thread (or even some third, unrelated thread)
- // could do some other DNS-SD operation (or some other operation that opens a new file descriptor)
- // and then we'd blindly resume our fall into the select() call, now blocking on a file descriptor
- // that may coincidentally have the same numerical value, but is semantically unrelated
- // to the true file descriptor we thought we were blocking on.
- // We can't stop this race condition from happening, but at least if we wake up once a second we can detect
- // when fNativeContext has gone to zero, and thereby discover that we were blocking on the wrong fd.
-
- if (select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &timeout) == 1) return(1);
- }
- }
-#endif // !AUTO_CALLBACKS
- return(0);
-}
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
-/* Call through to DNSServiceProcessResult() while data remains on socket. */
-{
-#if !AUTO_CALLBACKS // ProcessResults() not supported with AUTO_CALLBACKS
-
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
- DNSServiceErrorType err = kDNSServiceErr_BadState;
-
- if ( pContext != NULL)
- {
- int sd = DNSServiceRefSockFD( pContext->ServiceRef);
- fd_set readFDs;
- struct timeval zeroTimeout = { 0, 0 };
-
- pContext->Env = pEnv;
-
- FD_ZERO( &readFDs);
- FD_SET( sd, &readFDs);
-
- err = kDNSServiceErr_NoError;
- if (0 < select(sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
- {
- err = DNSServiceProcessResult(pContext->ServiceRef);
- // Use caution here!
- // We cannot touch any data structures associated with this operation!
- // The DNSServiceProcessResult() routine should have invoked our callback,
- // and our callback could have terminated the operation with op.stop();
- // and that means HaltOperation() will have been called, which frees pContext.
- // Basically, from here we just have to get out without touching any stale
- // data structures that could blow up on us! Particularly, any attempt
- // to loop here reading more results from the file descriptor is unsafe.
- }
- }
- return err;
-#endif // AUTO_CALLBACKS
-}
-
-
-static void DNSSD_API ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *serviceName, const char *regtype,
- const char *replyDomain, void *context)
-{
- OpContext *pContext = (OpContext*) context;
-
- SetupCallbackState( &pContext->Env);
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
- ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
- pContext->JavaObj, flags, interfaceIndex,
- (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
- (*pContext->Env)->NewStringUTF( pContext->Env, regtype),
- (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
-
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis,
- jint flags, jint ifIndex, jstring regType, jstring domain)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "serviceFound",
- "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- const char *regStr = SafeGetUTFChars( pEnv, regType);
- const char *domainStr = SafeGetUTFChars( pEnv, domain);
-
- pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
- (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
- "serviceLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-
- err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
-
- SafeReleaseUTFChars( pEnv, regType, regStr);
- SafeReleaseUTFChars( pEnv, domain, domainStr);
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-
-static void DNSSD_API ServiceResolveReply( DNSServiceRef sdRef _UNUSED, 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)
-{
- OpContext *pContext = (OpContext*) context;
- jclass txtCls;
- jmethodID txtCtor;
- jbyteArray txtBytes;
- jobject txtObj;
- jbyte *pBytes;
-
- SetupCallbackState( &pContext->Env);
-
- txtCls = (*pContext->Env)->FindClass( pContext->Env, "com/apple/dnssd/TXTRecord");
- txtCtor = (*pContext->Env)->GetMethodID( pContext->Env, txtCls, "<init>", "([B)V");
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL && txtCtor != NULL &&
- NULL != ( txtBytes = (*pContext->Env)->NewByteArray( pContext->Env, txtLen)))
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- // Since Java ints are defined to be big-endian, we canonicalize 'port' from a 16-bit
- // pattern into a number here.
- port = ( ((unsigned char*) &port)[0] << 8) | ((unsigned char*) &port)[1];
-
- // Initialize txtBytes with contents of txtRecord
- pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, txtBytes, NULL);
- memcpy( pBytes, txtRecord, txtLen);
- (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, txtBytes, pBytes, JNI_COMMIT);
-
- // Construct txtObj with txtBytes
- txtObj = (*pContext->Env)->NewObject( pContext->Env, txtCls, txtCtor, txtBytes);
- (*pContext->Env)->DeleteLocalRef( pContext->Env, txtBytes);
-
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
- pContext->JavaObj, flags, interfaceIndex,
- (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
- (*pContext->Env)->NewStringUTF( pContext->Env, hosttarget),
- port, txtObj);
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
-
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis,
- jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "serviceResolved",
- "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;ILcom/apple/dnssd/TXTRecord;)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- const char *servStr = SafeGetUTFChars( pEnv, serviceName);
- const char *regStr = SafeGetUTFChars( pEnv, regType);
- const char *domainStr = SafeGetUTFChars( pEnv, domain);
-
- err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex,
- servStr, regStr, domainStr, ServiceResolveReply, pContext);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
-
- SafeReleaseUTFChars( pEnv, serviceName, servStr);
- SafeReleaseUTFChars( pEnv, regType, regStr);
- SafeReleaseUTFChars( pEnv, domain, domainStr);
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-
-static void DNSSD_API ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags,
- DNSServiceErrorType errorCode, const char *serviceName,
- const char *regType, const char *domain, void *context)
-{
- OpContext *pContext = (OpContext*) context;
-
- SetupCallbackState( &pContext->Env);
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
- pContext->JavaObj, flags,
- (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
- (*pContext->Env)->NewStringUTF( pContext->Env, regType),
- (*pContext->Env)->NewStringUTF( pContext->Env, domain));
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis,
- jint ifIndex, jint flags, jstring serviceName, jstring regType,
- jstring domain, jstring host, jint port, jbyteArray txtRecord)
-{
- //syslog(LOG_ERR, "BR");
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- jbyte *pBytes;
- jsize numBytes;
-
- //syslog(LOG_ERR, "BR: contextField %d", contextField);
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "serviceRegistered",
- "(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- const char *servStr = SafeGetUTFChars( pEnv, serviceName);
- const char *regStr = SafeGetUTFChars( pEnv, regType);
- const char *domainStr = SafeGetUTFChars( pEnv, domain);
- const char *hostStr = SafeGetUTFChars( pEnv, host);
-
- //syslog(LOG_ERR, "BR: regStr %s", regStr);
-
- // Since Java ints are defined to be big-endian, we de-canonicalize 'port' from a
- // big-endian number into a 16-bit pattern here.
- uint16_t portBits = port;
- portBits = ( ((unsigned char*) &portBits)[0] << 8) | ((unsigned char*) &portBits)[1];
-
- pBytes = txtRecord ? (*pEnv)->GetByteArrayElements( pEnv, txtRecord, NULL) : NULL;
- numBytes = txtRecord ? (*pEnv)->GetArrayLength( pEnv, txtRecord) : 0;
-
- err = DNSServiceRegister( &pContext->ServiceRef, flags, ifIndex, servStr, regStr,
- domainStr, hostStr, portBits,
- numBytes, pBytes, ServiceRegisterReply, pContext);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
-
- if ( pBytes != NULL)
- (*pEnv)->ReleaseByteArrayElements( pEnv, txtRecord, pBytes, 0);
-
- SafeReleaseUTFChars( pEnv, serviceName, servStr);
- SafeReleaseUTFChars( pEnv, regType, regStr);
- SafeReleaseUTFChars( pEnv, domain, domainStr);
- SafeReleaseUTFChars( pEnv, host, hostStr);
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis,
- jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- jbyte *pBytes;
- jsize numBytes;
- DNSRecordRef recRef;
-
- if ( contextField != 0)
- pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
- if ( pContext == NULL || pContext->ServiceRef == NULL)
- return kDNSServiceErr_BadParam;
-
- pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
- numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
-
- err = DNSServiceAddRecord( pContext->ServiceRef, &recRef, flags, rrType, numBytes, pBytes, ttl);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
- }
-
- if ( pBytes != NULL)
- (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
-
- return err;
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis,
- jint flags, jbyteArray rData, jint ttl)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- jbyte *pBytes;
- jsize numBytes;
- DNSRecordRef recRef = NULL;
-
- if ( ownerField != 0)
- {
- jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
- jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
- if ( contextField != 0)
- pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
- }
- if ( recField != 0)
- recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
- if ( pContext == NULL || pContext->ServiceRef == NULL)
- return kDNSServiceErr_BadParam;
-
- pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
- numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
-
- err = DNSServiceUpdateRecord( pContext->ServiceRef, recRef, flags, numBytes, pBytes, ttl);
-
- if ( pBytes != NULL)
- (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
-
- return err;
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Remove( JNIEnv *pEnv, jobject pThis)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- DNSRecordRef recRef = NULL;
-
- if ( ownerField != 0)
- {
- jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
- jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
- if ( contextField != 0)
- pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
- }
- if ( recField != 0)
- recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
- if ( pContext == NULL || pContext->ServiceRef == NULL)
- return kDNSServiceErr_BadParam;
-
- err = DNSServiceRemoveRecord( pContext->ServiceRef, recRef, 0);
-
- return err;
-}
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection( JNIEnv *pEnv, jobject pThis)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "recordRegistered", "(Lcom/apple/dnssd/DNSRecord;I)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- err = DNSServiceCreateConnection( &pContext->ServiceRef);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-struct RecordRegistrationRef
-{
- OpContext *Context;
- jobject RecordObj;
-};
-typedef struct RecordRegistrationRef RecordRegistrationRef;
-
-static void DNSSD_API RegisterRecordReply( DNSServiceRef sdRef _UNUSED,
- DNSRecordRef recordRef _UNUSED, DNSServiceFlags flags,
- DNSServiceErrorType errorCode, void *context)
-{
- RecordRegistrationRef *regEnvelope = (RecordRegistrationRef*) context;
- OpContext *pContext = regEnvelope->Context;
-
- SetupCallbackState( &pContext->Env);
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
- regEnvelope->RecordObj, flags);
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
-
- (*pContext->Env)->DeleteWeakGlobalRef( pContext->Env, regEnvelope->RecordObj);
- free( regEnvelope);
-
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord( JNIEnv *pEnv, jobject pThis,
- jint flags, jint ifIndex, jstring fullname, jint rrType, jint rrClass,
- jbyteArray rData, jint ttl, jobject destObj)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
- const char *nameStr = SafeGetUTFChars( pEnv, fullname);
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- jbyte *pBytes;
- jsize numBytes;
- DNSRecordRef recRef;
- RecordRegistrationRef *regEnvelope;
-
- if ( contextField != 0)
- pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
- if ( pContext == NULL || pContext->ServiceRef == NULL || nameStr == NULL)
- return kDNSServiceErr_BadParam;
-
- regEnvelope = calloc( 1, sizeof *regEnvelope);
- if ( regEnvelope == NULL)
- return kDNSServiceErr_NoMemory;
- regEnvelope->Context = pContext;
- regEnvelope->RecordObj = (*pEnv)->NewWeakGlobalRef( pEnv, destObj); // must convert local ref to global to cache
-
- pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
- numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
-
- err = DNSServiceRegisterRecord( pContext->ServiceRef, &recRef, flags, ifIndex,
- nameStr, rrType, rrClass, numBytes, pBytes, ttl,
- RegisterRecordReply, regEnvelope);
-
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
- }
- else
- {
- if ( regEnvelope->RecordObj != NULL)
- (*pEnv)->DeleteWeakGlobalRef( pEnv, regEnvelope->RecordObj);
- free( regEnvelope);
- }
-
- if ( pBytes != NULL)
- (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
-
- SafeReleaseUTFChars( pEnv, fullname, nameStr);
-
- return err;
-}
-
-
-static void DNSSD_API ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *serviceName,
- uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
- const void *rdata, uint32_t ttl, void *context)
-{
- OpContext *pContext = (OpContext*) context;
- jbyteArray rDataObj;
- jbyte *pBytes;
-
- SetupCallbackState( &pContext->Env);
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL &&
- NULL != ( rDataObj = (*pContext->Env)->NewByteArray( pContext->Env, rdlen)))
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- // Initialize rDataObj with contents of rdata
- pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, rDataObj, NULL);
- memcpy( pBytes, rdata, rdlen);
- (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, rDataObj, pBytes, JNI_COMMIT);
-
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
- pContext->JavaObj, flags, interfaceIndex,
- (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
- rrtype, rrclass, rDataObj, ttl);
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
- jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "queryAnswered",
- "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- const char *servStr = SafeGetUTFChars( pEnv, serviceName);
-
- err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
- rrtype, rrclass, ServiceQueryReply, pContext);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
-
- SafeReleaseUTFChars( pEnv, serviceName, servStr);
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-
-static void DNSSD_API DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
- DNSServiceErrorType errorCode, const char *replyDomain, void *context)
-{
- OpContext *pContext = (OpContext*) context;
-
- SetupCallbackState( &pContext->Env);
-
- if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
- {
- if ( errorCode == kDNSServiceErr_NoError)
- {
- (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
- ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
- pContext->JavaObj, flags, interfaceIndex,
- (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
- }
- else
- ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
- }
- TeardownCallbackState();
-}
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis,
- jint flags, jint ifIndex)
-{
- jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
- OpContext *pContext = NULL;
- DNSServiceErrorType err = kDNSServiceErr_NoError;
-
- if ( contextField != 0)
- pContext = NewContext( pEnv, pThis, "domainFound",
- "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
- else
- err = kDNSServiceErr_BadParam;
-
- if ( pContext != NULL)
- {
- pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
- (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
- "domainLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
-
- err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex,
- DomainEnumReply, pContext);
- if ( err == kDNSServiceErr_NoError)
- {
- (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
- }
- }
- else
- err = kDNSServiceErr_NoMemory;
-
- return err;
-}
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED,
- jstring serviceName, jstring regtype, jstring domain, jobjectArray pOut)
-{
- DNSServiceErrorType err = kDNSServiceErr_NoError;
- const char *nameStr = SafeGetUTFChars( pEnv, serviceName);
- const char *regStr = SafeGetUTFChars( pEnv, regtype);
- const char *domStr = SafeGetUTFChars( pEnv, domain);
- char buff[ kDNSServiceMaxDomainName + 1];
-
- err = DNSServiceConstructFullName( buff, nameStr, regStr, domStr);
-
- if ( err == kDNSServiceErr_NoError)
- {
- // pOut is expected to be a String[1] array.
- (*pEnv)->SetObjectArrayElement( pEnv, pOut, 0, (*pEnv)->NewStringUTF( pEnv, buff));
- }
-
- SafeReleaseUTFChars( pEnv, serviceName, nameStr);
- SafeReleaseUTFChars( pEnv, regtype, regStr);
- SafeReleaseUTFChars( pEnv, domain, domStr);
-
- return err;
-}
-
-JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED,
- jint flags, jint ifIndex, jstring fullName,
- jint rrtype, jint rrclass, jbyteArray rdata)
-{
- jbyte *pBytes;
- jsize numBytes;
- const char *nameStr = SafeGetUTFChars( pEnv, fullName);
-
- pBytes = (*pEnv)->GetByteArrayElements( pEnv, rdata, NULL);
- numBytes = (*pEnv)->GetArrayLength( pEnv, rdata);
-
- DNSServiceReconfirmRecord( flags, ifIndex, nameStr, rrtype, rrclass, numBytes, pBytes);
-
- if ( pBytes != NULL)
- (*pEnv)->ReleaseByteArrayElements( pEnv, rdata, pBytes, 0);
-
- SafeReleaseUTFChars( pEnv, fullName, nameStr);
-}
-
-#define LOCAL_ONLY_NAME "loo"
-#define P2P_NAME "p2p"
-
-JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED,
- jint ifIndex)
-{
- char *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
-
- if (ifIndex == (jint) kDNSServiceInterfaceIndexP2P)
- p = P2P_NAME;
- else if (ifIndex != (jint) kDNSServiceInterfaceIndexLocalOnly)
- p = if_indextoname( ifIndex, nameBuff );
-
- return (*pEnv)->NewStringUTF( pEnv, p);
-}
-
-
-JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED,
- jstring ifName)
-{
- uint32_t ifIndex = kDNSServiceInterfaceIndexLocalOnly;
- const char *nameStr = SafeGetUTFChars( pEnv, ifName);
-
- if (strcmp(nameStr, P2P_NAME) == 0)
- ifIndex = kDNSServiceInterfaceIndexP2P;
- else if (strcmp(nameStr, LOCAL_ONLY_NAME))
- ifIndex = if_nametoindex( nameStr);
-
- SafeReleaseUTFChars( pEnv, ifName, nameStr);
-
- return ifIndex;
-}
-
-
-#if defined(_WIN32)
-static char*
-win32_if_indextoname( DWORD ifIndex, char * nameBuff)
-{
- PIP_ADAPTER_INFO pAdapterInfo = NULL;
- PIP_ADAPTER_INFO pAdapter = NULL;
- DWORD dwRetVal = 0;
- char * ifName = NULL;
- ULONG ulOutBufLen = 0;
-
- if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
- {
- goto exit;
- }
-
- pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
-
- if (pAdapterInfo == NULL)
- {
- goto exit;
- }
-
- dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
-
- if (dwRetVal != NO_ERROR)
- {
- goto exit;
- }
-
- pAdapter = pAdapterInfo;
- while (pAdapter)
- {
- if (pAdapter->Index == ifIndex)
- {
- // It would be better if we passed in the length of nameBuff to this
- // function, so we would have absolute certainty that no buffer
- // overflows would occur. Buffer overflows *shouldn't* occur because
- // nameBuff is of size MAX_ADAPTER_NAME_LENGTH.
- strcpy( nameBuff, pAdapter->AdapterName );
- ifName = nameBuff;
- break;
- }
-
- pAdapter = pAdapter->Next;
- }
-
-exit:
-
- if (pAdapterInfo != NULL)
- {
- free( pAdapterInfo );
- pAdapterInfo = NULL;
- }
-
- return ifName;
-}
-
-
-static DWORD
-win32_if_nametoindex( const char * nameStr )
-{
- PIP_ADAPTER_INFO pAdapterInfo = NULL;
- PIP_ADAPTER_INFO pAdapter = NULL;
- DWORD dwRetVal = 0;
- DWORD ifIndex = 0;
- ULONG ulOutBufLen = 0;
-
- if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
- {
- goto exit;
- }
-
- pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
-
- if (pAdapterInfo == NULL)
- {
- goto exit;
- }
-
- dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
-
- if (dwRetVal != NO_ERROR)
- {
- goto exit;
- }
-
- pAdapter = pAdapterInfo;
- while (pAdapter)
- {
- if (strcmp(pAdapter->AdapterName, nameStr) == 0)
- {
- ifIndex = pAdapter->Index;
- break;
- }
-
- pAdapter = pAdapter->Next;
- }
-
-exit:
-
- if (pAdapterInfo != NULL)
- {
- free( pAdapterInfo );
- pAdapterInfo = NULL;
- }
-
- return ifIndex;
-}
-#endif
-
-
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
-// NOT static -- otherwise the compiler may optimize it out
-// The "@(#) " pattern is a special prefix the "what" command looks for
-#ifndef MDNS_VERSIONSTR_NODTS
-const char VersionString_SCCS[] = "@(#) libjdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
-#else
-const char VersionString_SCCS[] = "@(#) libjdns_sd " STRINGIFY(mDNSResponderVersion);
-#endif
diff --git a/usr/src/lib/libdns_sd/java/common/mapfile-vers b/usr/src/lib/libdns_sd/java/common/mapfile-vers
deleted file mode 100644
index 01c3c548fd..0000000000
--- a/usr/src/lib/libdns_sd/java/common/mapfile-vers
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-$mapfile_version 2
-
-SYMBOL_VERSION SUNW_1.1 {
- global:
- Java_com_apple_dnssd_AppleBrowser_CreateBrowser;
- Java_com_apple_dnssd_AppleDNSRecord_Remove;
- Java_com_apple_dnssd_AppleDNSRecord_Update;
- Java_com_apple_dnssd_AppleDNSSD_ConstructName;
- Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName;
- Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex;
- Java_com_apple_dnssd_AppleDNSSD_InitLibrary;
- Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord;
- Java_com_apple_dnssd_AppleDomainEnum_BeginEnum;
- Java_com_apple_dnssd_AppleQuery_CreateQuery;
- Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection;
- Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord;
- Java_com_apple_dnssd_AppleRegistration_AddRecord;
- Java_com_apple_dnssd_AppleRegistration_BeginRegister;
- Java_com_apple_dnssd_AppleResolver_CreateResolver;
- Java_com_apple_dnssd_AppleService_BlockForData;
- Java_com_apple_dnssd_AppleService_HaltOperation;
- Java_com_apple_dnssd_AppleService_ProcessResults;
- local:
- *;
-};
diff --git a/usr/src/lib/libdns_sd/java/i386/Makefile b/usr/src/lib/libdns_sd/java/i386/Makefile
deleted file mode 100644
index 3b6c2a1943..0000000000
--- a/usr/src/lib/libdns_sd/java/i386/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-CPPFLAGS += -_gcc=-Wno-pointer-to-int-cast -_gcc=-Wno-int-to-pointer-cast
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/libdns_sd/java/sparc/Makefile b/usr/src/lib/libdns_sd/java/sparc/Makefile
deleted file mode 100644
index 3b6c2a1943..0000000000
--- a/usr/src/lib/libdns_sd/java/sparc/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-
-.KEEP_STATE:
-
-CPPFLAGS += -_gcc=-Wno-pointer-to-int-cast -_gcc=-Wno-int-to-pointer-cast
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/libdns_sd/java/sparcv9/Makefile b/usr/src/lib/libdns_sd/java/sparcv9/Makefile
deleted file mode 100644
index b645e1caed..0000000000
--- a/usr/src/lib/libdns_sd/java/sparcv9/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-#ident "%Z%%M% %I% %E% SMI"
-
-include ../Makefile.com
-include ../../../Makefile.lib.64
-
-all: $(LIBS)
-
-install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libdns_sd/sparc/Makefile b/usr/src/lib/libdns_sd/sparc/Makefile
index 9c1be5bf3a..32145a695a 100644
--- a/usr/src/lib/libdns_sd/sparc/Makefile
+++ b/usr/src/lib/libdns_sd/sparc/Makefile
@@ -21,8 +21,7 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
include ../Makefile.com
-install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/libdns_sd/sparcv9/Makefile b/usr/src/lib/libdns_sd/sparcv9/Makefile
index abae92c693..fa485a4013 100644
--- a/usr/src/lib/libdns_sd/sparcv9/Makefile
+++ b/usr/src/lib/libdns_sd/sparcv9/Makefile
@@ -21,13 +21,10 @@
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-#ident "%Z%%M% %I% %E% SMI"
include ../Makefile.com
include ../../Makefile.lib.64
-CFLAGS64 += -erroff=E_ASSIGNMENT_TYPE_MISMATCH
-
.KEEP_STATE:
all: $(LIBS)
diff --git a/usr/src/pkg/manifests/service-network-dns-mdns.mf b/usr/src/pkg/manifests/service-network-dns-mdns.mf
index 4c809b4ae7..b060539159 100644
--- a/usr/src/pkg/manifests/service-network-dns-mdns.mf
+++ b/usr/src/pkg/manifests/service-network-dns-mdns.mf
@@ -44,17 +44,6 @@ dir path=usr/lib
dir path=usr/lib/$(ARCH64)
dir path=usr/lib/inet
dir path=usr/share
-dir path=usr/share/lib
-dir path=usr/share/lib/java group=sys
-dir path=usr/share/lib/java/javadoc group=other
-dir path=usr/share/lib/java/javadoc/dnssd group=other
-dir path=usr/share/lib/java/javadoc/dnssd/api group=other
-dir path=usr/share/lib/java/javadoc/dnssd/api/com group=other
-dir path=usr/share/lib/java/javadoc/dnssd/api/com/apple group=other
-dir path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd group=other
-$(JAVA_7_ONLY)dir path=usr/share/lib/java/javadoc/dnssd/api/resources \
- group=other
-dir path=usr/share/lib/java/javadoc/dnssd/examples group=other
dir path=usr/share/man
dir path=usr/share/man/man1m
dir path=usr/share/man/man3dns_sd
@@ -63,95 +52,10 @@ file path=lib/svc/manifest/network/dns/multicast.xml group=sys mode=0444
file path=usr/bin/dns-sd mode=0555
file path=usr/include/dns_sd.h
file path=usr/lib/$(ARCH64)/libdns_sd.so.1
-file path=usr/lib/$(ARCH64)/libjdns_sd.so.1
-file path=usr/lib/$(ARCH64)/llib-ldns_sd.ln
file path=usr/lib/$(ARCH64)/nss_mdns.so.1
file path=usr/lib/inet/mdnsd mode=0555
file path=usr/lib/libdns_sd.so.1
-file path=usr/lib/libjdns_sd.so.1
-file path=usr/lib/llib-ldns_sd
-file path=usr/lib/llib-ldns_sd.ln
file path=usr/lib/nss_mdns.so.1
-file path=usr/share/lib/java/dnssd.jar group=sys
-file path=usr/share/lib/java/javadoc/dnssd/api/allclasses-frame.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/allclasses-noframe.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/BaseListener.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/BrowseListener.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSRecord.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSSD.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSSDException.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSSDRecordRegistrar.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSSDRegistration.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DNSSDService.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/DomainListener.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/QueryListener.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/RegisterListener.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/RegisterRecordListener.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/ResolveListener.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/TXTRecord.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/package-frame.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/package-summary.html \
- group=other
-file \
- path=usr/share/lib/java/javadoc/dnssd/api/com/apple/dnssd/package-tree.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/constant-values.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/deprecated-list.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/help-doc.html group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/index-all.html group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/index.html group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/overview-tree.html group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/package-list group=other
-$(JAVA_7_ONLY)file \
- path=usr/share/lib/java/javadoc/dnssd/api/resources/background.gif \
- group=other
-$(JAVA_7_ONLY)file path=usr/share/lib/java/javadoc/dnssd/api/resources/tab.gif \
- group=other
-$(JAVA_7_ONLY)file \
- path=usr/share/lib/java/javadoc/dnssd/api/resources/titlebar.gif \
- group=other
-$(JAVA_7_ONLY)file \
- path=usr/share/lib/java/javadoc/dnssd/api/resources/titlebar_end.gif \
- group=other
-$(JAVA_8_ONLY)file path=usr/share/lib/java/javadoc/dnssd/api/script.js \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/serialized-form.html \
- group=other
-file path=usr/share/lib/java/javadoc/dnssd/api/stylesheet.css group=other
-file path=usr/share/lib/java/javadoc/dnssd/examples/BrowserApp.jar group=sys
-file path=usr/share/lib/java/javadoc/dnssd/examples/SimpleChat.jar group=sys
file path=usr/share/man/man1m/dns-sd.1m
file path=usr/share/man/man1m/mdnsd.1m
file path=usr/share/man/man3dns_sd/DNSServiceBrowse.3dns_sd
@@ -174,14 +78,10 @@ legacy pkg=SUNWdsdu desc="Multicast DNS daemon and service discovery modules" \
name="Multicast DNS and Service Discovery (Usr)"
license cr_Sun license=cr_Sun
license lic_CDDL license=lic_CDDL
-license usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE \
- license=usr/src/cmd/cmd-inet/usr.lib/mdnsd/THIRDPARTYLICENSE
-license usr/src/lib/libdns_sd/THIRDPARTYLICENSE \
- license=usr/src/lib/libdns_sd/THIRDPARTYLICENSE
+license usr/src/contrib/mDNSResponder/LICENSE \
+ license=usr/src/contrib/mDNSResponder/LICENSE
link path=usr/lib/$(ARCH64)/libdns_sd.so target=libdns_sd.so.1
-link path=usr/lib/$(ARCH64)/libjdns_sd.so target=libjdns_sd.so.1
link path=usr/lib/libdns_sd.so target=libdns_sd.so.1
-link path=usr/lib/libjdns_sd.so target=libjdns_sd.so.1
link path=usr/share/man/man3dns_sd/DNSServiceAddRecord.3dns_sd \
target=DNSServiceCreateConnection.3dns_sd
link path=usr/share/man/man3dns_sd/DNSServiceRegisterRecord.3dns_sd \