diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-19 08:56:09 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-20 11:23:33 +0200 |
commit | 4c086a244624bf36865edcfa4309c333d7d7200d (patch) | |
tree | e566ffc50a6b6fdb46702ac57c8e7c4088b60b42 /mDNSResponder/mDNSShared | |
parent | mDNSResponder: Update to v765.50.9 (diff) | |
download | rtems-libbsd-4c086a244624bf36865edcfa4309c333d7d7200d.tar.bz2 |
mDNSResponder: Update to v878.1.1
The sources can be obtained via:
https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-878.1.1.tar.gz
Update #3522.
Diffstat (limited to 'mDNSResponder/mDNSShared')
-rw-r--r-- | mDNSResponder/mDNSShared/dns_sd.h | 47 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/dns_sd_internal.h | 15 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/dns_sd_private.h | 89 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/dnsextd.c | 21 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/dnssd_clientstub.c | 42 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/uds_daemon.c | 630 | ||||
-rw-r--r-- | mDNSResponder/mDNSShared/uds_daemon.h | 210 |
7 files changed, 614 insertions, 440 deletions
diff --git a/mDNSResponder/mDNSShared/dns_sd.h b/mDNSResponder/mDNSShared/dns_sd.h index 660b3707..80033920 100644 --- a/mDNSResponder/mDNSShared/dns_sd.h +++ b/mDNSResponder/mDNSShared/dns_sd.h @@ -66,7 +66,7 @@ */ #ifndef _DNS_SD_H -#define _DNS_SD_H 7655009 +#define _DNS_SD_H 8780101 #ifdef __cplusplus extern "C" { @@ -511,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. */ }; @@ -762,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. @@ -806,6 +801,12 @@ enum * 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 @@ -1131,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). @@ -1361,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: * @@ -1669,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. * @@ -1775,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. * diff --git a/mDNSResponder/mDNSShared/dns_sd_internal.h b/mDNSResponder/mDNSShared/dns_sd_internal.h new file mode 100644 index 00000000..22931f24 --- /dev/null +++ b/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/mDNSResponder/mDNSShared/dns_sd_private.h b/mDNSResponder/mDNSShared/dns_sd_private.h new file mode 100644 index 00000000..4d023686 --- /dev/null +++ b/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/mDNSResponder/mDNSShared/dnsextd.c b/mDNSResponder/mDNSShared/dnsextd.c index b55d3f42..bc89ef89 100644 --- a/mDNSResponder/mDNSShared/dnsextd.c +++ b/mDNSResponder/mDNSShared/dnsextd.c @@ -302,7 +302,7 @@ mDNSlocal TCPSocket *ConnectToServer(DaemonInfo *d) mDNSIPPort port = zeroIPPort; int fd; - TCPSocket *sock = mDNSPlatformTCPSocket( NULL, 0, &port, mDNSfalse ); + TCPSocket *sock = mDNSPlatformTCPSocket(0, &port, mDNSfalse ); if ( !sock ) { LogErr("ConnectToServer", "socket"); return NULL; } fd = mDNSPlatformTCPGetFD( sock ); if (!connect( fd, (struct sockaddr *)&d->ns_addr, sizeof(d->ns_addr))) return sock; @@ -1506,13 +1506,14 @@ HandleRequest char addrbuf[32]; TCPSocket * sock = NULL; mStatus err; - mDNSs32 lease = 0; + mDNSu32 lease = 0; + mDNSBool gotlease; if ((request->msg.h.flags.b[0] & kDNSFlag0_QROP_Mask) == kDNSFlag0_OP_Update) { int i, adds = 0, dels = 0; const mDNSu8 *ptr, *end = (mDNSu8 *)&request->msg + request->len; HdrNToH(request); - lease = GetPktLease(&mDNSStorage, &request->msg, end); + gotlease = GetPktLease(&mDNSStorage, &request->msg, end, &lease); ptr = LocateAuthorities(&request->msg, end); for (i = 0; i < request->msg.h.mDNS_numUpdates; i++) { @@ -1521,7 +1522,7 @@ HandleRequest if (lcr.r.resrec.RecordType != kDNSRecordTypePacketNegative && lcr.r.resrec.rroriginalttl) adds++;else dels++; } HdrHToN(request); - if (adds && !lease) + if (adds && !gotlease) { static const mDNSOpaque16 UpdateRefused = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, kDNSFlag1_RC_Refused } }; Log("Rejecting Update Request with %d additions but no lease", adds); @@ -3099,8 +3100,8 @@ void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const e const mDNSAddr *const dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID iid) { ( void ) m; ( void ) msg; ( void ) end; ( void ) srcaddr; ( void ) srcport; ( void ) dstaddr; ( void ) dstport; ( void ) iid; } DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const int serviceID, const mDNSAddr *addr, const mDNSIPPort port, - mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSu16 resGroupID, mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO) -{ ( void ) m; ( void ) d; ( void ) interface; ( void ) serviceID; ( void ) addr; ( void ) port; ( void ) scoped; ( void ) timeout; (void) cellIntf; + mDNSu32 scoped, mDNSu32 timeout, mDNSBool cellIntf, mDNSBool isExpensive, mDNSu16 resGroupID, mDNSBool reqA, mDNSBool reqAAAA, mDNSBool reqDO) +{ ( void ) m; ( void ) d; ( void ) interface; ( void ) serviceID; ( void ) addr; ( void ) port; ( void ) scoped; ( void ) timeout; (void) cellIntf; (void) isExpensive; (void) resGroupID; (void) reqA; (void) reqAAAA; (void) reqDO; return(NULL); } void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID) { (void)domain; (void) InterfaceID;} void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext) @@ -3108,15 +3109,15 @@ void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback mDNSs32 mDNS_Execute (mDNS *const m) { ( void ) m; return 0; } mDNSs32 mDNS_TimeNow(const mDNS *const m) { ( void ) m; return 0; } mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr) { ( void ) m; ( void ) rr; return 0; } -void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping) -{ ( void ) m; ( void ) set; ( void ) flapping; } +void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed) +{ ( void ) m; ( void ) set; ( void ) activationSpeed; } const char * const mDNS_DomainTypeNames[1] = {}; mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const domainname *dom, const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context) { ( void ) m; ( void ) question; ( void ) DomainType; ( void ) dom; ( void ) InterfaceID; ( void ) Callback; ( void ) Context; return 0; } mStatus mDNS_Register(mDNS *const m, AuthRecord *const rr) { ( void ) m; ( void ) rr; return 0; } -mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, mDNSBool flapping) -{ ( void ) m; ( void ) set; ( void ) flapping; return 0; } +mStatus mDNS_RegisterInterface(mDNS *const m, NetworkInterfaceInfo *set, InterfaceActivationSpeed activationSpeed) +{ ( void ) m; ( void ) set; ( void ) activationSpeed; return 0; } void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn) { ( void ) m; ( void ) fqdn; } void mDNS_SetFQDN(mDNS * const m) { ( void ) m; } void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr, const mDNSAddr *v6addr, const mDNSAddr *router) diff --git a/mDNSResponder/mDNSShared/dnssd_clientstub.c b/mDNSResponder/mDNSShared/dnssd_clientstub.c index 5cf4ebe9..27e90eee 100644 --- a/mDNSResponder/mDNSShared/dnssd_clientstub.c +++ b/mDNSResponder/mDNSShared/dnssd_clientstub.c @@ -35,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) @@ -195,9 +195,10 @@ 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) +#if !defined(__ppc__) && defined(SO_ISDEFUNCT) int defunct = 0; socklen_t dlen = sizeof (defunct); if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0) @@ -209,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; @@ -245,7 +246,9 @@ static int read_all(dnssd_sock_t sd, char *buf, int 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 @@ -450,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) { @@ -629,24 +632,30 @@ static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags f 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)) @@ -1215,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); @@ -1312,7 +1321,8 @@ DNSServiceErrorType DNSSD_API DNSServiceResolve ((interfaceIndex == kDNSServiceInterfaceIndexAny) || (interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) || (interfaceIndex == kDNSServiceInterfaceIndexUnicast) || - (interfaceIndex == kDNSServiceInterfaceIndexP2P))) + (interfaceIndex == kDNSServiceInterfaceIndexP2P) || + (interfaceIndex == kDNSServiceInterfaceIndexBLE))) { return kDNSServiceErr_BadParam; } @@ -2123,7 +2133,7 @@ DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord char *ptr; size_t len; ipc_msg_hdr *hdr; - DNSServiceOp *tmp; + DNSServiceOp *tmp = NULL; if (!fullname || (!rdata && rdlen)) return kDNSServiceErr_BadParam; diff --git a/mDNSResponder/mDNSShared/uds_daemon.c b/mDNSResponder/mDNSShared/uds_daemon.c index 2552c8a7..946ad162 100644 --- a/mDNSResponder/mDNSShared/uds_daemon.c +++ b/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 @@ -54,8 +55,10 @@ mDNSBool AlwaysAppendSearchDomains = mDNSfalse; #include <sys/proc_info.h> // for struct proc_bsdshortinfo #include <libproc.h> // for proc_pidinfo() #endif //LOCAL_PEEREPID -//upto 16 characters of process name (defined in <sys/proc.h> but we do not want to include that file) -#define MAXCOMLEN 16 + +#ifdef UNIT_TEST +#include "unittest.h" +#endif #if APPLE_OSX_mDNSResponder #include <WebFilterDNS/WebFilterDNS.h> @@ -84,188 +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; - 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; - -// *************************************************************************** -#if COMPILER_LIKES_PRAGMA_MARK -#pragma mark - #pragma mark - Globals #endif @@ -363,7 +184,7 @@ mDNSlocal void my_throttled_perror(char *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 { @@ -381,16 +202,16 @@ mDNSlocal void LogMcastQuestion(mDNS *const m, const DNSQuestion *const q, reque q->InterfaceID == mDNSInterface_LocalOnly ? "lo" : q->InterfaceID == mDNSInterface_P2P ? "p2p" : q->InterfaceID == mDNSInterface_BLE ? "BLE" : - q->InterfaceID == mDNSInterface_Any ? "any" : InterfaceNameForID(m, q->InterfaceID), + 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 { @@ -408,16 +229,17 @@ mDNSlocal void LogMcastService(mDNS *const m, const AuthRecord *const ar, reques 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(m, ar->resrec.InterfaceID), + 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) @@ -862,13 +684,6 @@ 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); -#if APPLE_OSX_mDNSResponder - if (applyToBLE(instance->srs.RR_SRV.resrec.InterfaceID, instance->request->flags)) - { - start_BLE_advertise(& instance->srs, instance->srs.RR_SRV.resrec.name , instance->srs.RR_SRV.resrec.rrtype, instance->request->flags); - } -#endif // APPLE_OSX_mDNSResponder - external_start_advertising_service(&instance->srs.RR_TXT.resrec, instance->request->flags); for (e = instance->srs.Extras; e; e = e->next) @@ -964,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++; @@ -1056,8 +871,8 @@ 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) { @@ -1080,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); @@ -1253,7 +1068,7 @@ mDNSlocal void connection_termination(request_state *request) 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); } @@ -1283,11 +1098,12 @@ mDNSlocal void handle_cancel_request(request_state *request) mDNSlocal mStatus handle_regrecord_request(request_state *request) { mStatus err = mStatus_BadParamErr; + AuthRecord *rr; if (request->terminate != connection_termination) { LogMsg("%3d: DNSServiceRegisterRecord(not a shared connection ref)", request->sd); return(err); } - AuthRecord *rr = read_rr_from_ipc_msg(request, 1, 1); + rr = read_rr_from_ipc_msg(request, 1, 1); if (rr) { registered_record_entry *re; @@ -1333,7 +1149,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; } @@ -1366,7 +1182,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); @@ -1400,7 +1216,6 @@ 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 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; } @@ -1413,18 +1228,13 @@ 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); + result = mDNS_AddRecordToService(&mDNSStorage, srs, extra, &extra->r.rdatastorage, ttl, request->flags); if (result) { freeL("ExtraResourceRecord/add_record_to_service", extra); return result; } - LogMcastS(&mDNSStorage, &srs->RR_PTR, request, reg_start); + LogMcastS(&srs->RR_PTR, request, reg_start); extra->ClientID = request->hdr.reg_index; if ( instance->external_advertise @@ -1461,8 +1271,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) { @@ -1552,8 +1363,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; } } @@ -1601,9 +1413,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); } @@ -1619,14 +1432,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) { @@ -1673,9 +1487,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); @@ -1822,20 +1636,6 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain 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 @@ -1891,14 +1691,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, 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 { @@ -2028,6 +1828,7 @@ mDNSlocal mDNSBool PreDefinedInterfaceIndex(mDNSu32 interfaceIndex) case kDNSServiceInterfaceIndexLocalOnly: case kDNSServiceInterfaceIndexUnicast: case kDNSServiceInterfaceIndexP2P: + case kDNSServiceInterfaceIndexBLE: return mDNStrue; default: return mDNSfalse; @@ -2190,8 +1991,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 @@ -2280,8 +2090,8 @@ mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const Resourc 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); @@ -2289,7 +2099,6 @@ validReply: 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, @@ -2303,10 +2112,7 @@ mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req) // 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]; - } + mDNSPlatformMemCopy(q->uuid, req->uuid, UUID_SIZE); q->pid = 0; } else @@ -2344,15 +2150,24 @@ 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; ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &b->domain); LogInfo("add_domain_to_browser: calling external_start_browsing_for_service()"); - external_start_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags, &b->q); + external_start_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags); } } return err; @@ -2380,10 +2195,12 @@ mDNSlocal void browse_termination_callback(request_state *info) 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); } } @@ -2617,7 +2434,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 @@ -2759,7 +2576,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request) 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); + request->sd, request->flags, interfaceIndex, request->u.browser.regtype.c, domain, request->process_id, request->pid_name); if (request->u.browser.default_domain) { @@ -2822,7 +2639,9 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con (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) { @@ -2872,10 +2691,11 @@ 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); + 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); } @@ -2931,6 +2751,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; @@ -2998,8 +2827,9 @@ 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, + 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) @@ -3012,7 +2842,7 @@ mDNSlocal mStatus handle_resolve_request(request_state *request) 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; @@ -3039,7 +2869,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; @@ -3068,7 +2898,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) @@ -3088,7 +2918,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; } @@ -3139,7 +2969,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; @@ -3165,7 +2995,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)); @@ -3289,7 +3119,7 @@ mDNSlocal mStatus SendAdditionalQuery(DNSQuestion *q, request_state *request, mS #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 @@ -3303,7 +3133,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 @@ -3312,7 +3142,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)); @@ -3348,9 +3178,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 @@ -3597,7 +3428,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)) { @@ -3661,7 +3492,7 @@ mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question, return; } #if APPLE_OSX_mDNSResponder - if (!ShouldDeliverNegativeResponse(m, question)) + if (!ShouldDeliverNegativeResponse(question)) { return; } @@ -3687,7 +3518,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. @@ -3705,12 +3536,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 @@ -3725,10 +3556,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) { @@ -3736,7 +3567,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 { @@ -3764,7 +3595,7 @@ 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 @@ -3842,6 +3673,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; @@ -3881,8 +3713,18 @@ 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) @@ -3892,11 +3734,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, q); + external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, q->flags); } } @@ -3984,7 +3826,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); } @@ -4071,10 +3913,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); @@ -4410,7 +4253,7 @@ mDNSlocal void addrinfo_termination_callback(request_state *request) 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)) @@ -4430,7 +4273,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) { @@ -4445,7 +4288,7 @@ 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)) @@ -4465,7 +4308,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) { @@ -4487,7 +4330,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. @@ -4498,12 +4341,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 } @@ -4606,6 +4449,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; @@ -4649,11 +4494,11 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request) 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, &request->u.addrinfo.q6); + external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags); } } } @@ -4705,11 +4550,11 @@ 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, &request->u.addrinfo.q4); + external_start_browsing_for_service(InterfaceID, &d, kDNSServiceType_A, flags); } } } @@ -4831,7 +4676,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 @@ -4933,6 +4778,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) @@ -5022,12 +4913,8 @@ 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 { @@ -5050,44 +4937,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: 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); @@ -5371,7 +5224,7 @@ 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) @@ -5393,8 +5246,8 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req) 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) { @@ -5595,7 +5448,7 @@ mDNSlocal char *RecordTypeName(mDNSu8 rtype) } } -mDNSlocal void LogEtcHosts(mDNS *const m) +mDNSlocal int LogEtcHosts(mDNS *const m) { mDNSBool showheader = mDNStrue; const AuthRecord *ar; @@ -5631,6 +5484,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) @@ -5674,7 +5528,7 @@ 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)) @@ -5686,7 +5540,7 @@ mDNSlocal void LogOneAuthRecord(mDNS *const m, const AuthRecord *ar, mDNSs32 now "-U-", ar->state, ar->AllowRemoteQuery ? "☠" : " ", - ARDisplayString(m, ar)); + ARDisplayString(&mDNSStorage, ar)); } else { @@ -5697,18 +5551,18 @@ mDNSlocal void LogOneAuthRecord(mDNS *const m, const AuthRecord *ar, mDNSs32 now 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 if State"); } @@ -5725,22 +5579,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) { if (ar->resrec.InterfaceID == mDNSInterface_BLE) - LogMsgNoIdent(" BLE %s", ARDisplayString(m, ar)); + LogMsgNoIdent(" BLE %s", ARDisplayString(&mDNSStorage, ar)); else - LogMsgNoIdent(" PP %s", ARDisplayString(m, ar)); + 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; @@ -5751,7 +5605,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)); } } } @@ -5759,7 +5613,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, @@ -5769,11 +5623,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; @@ -5783,13 +5637,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) { @@ -5806,7 +5660,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)); } } } @@ -5873,11 +5727,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; @@ -5892,30 +5750,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); @@ -5924,13 +5785,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>"); @@ -5947,12 +5808,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)" : ""); @@ -5980,7 +5842,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:; } } @@ -6098,7 +5960,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) @@ -6133,9 +5994,10 @@ foundparent:; LogMsgNoIdent("BonjourEnabled %d", m->BonjourEnabled); #endif // BONJOUR_ON_DEMAND -#if APPLE_OSX_mDNSResponder +#if APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR LogMsgNoIdent("EnableBLEBasedDiscovery %d", EnableBLEBasedDiscovery); -#endif // APPLE_OSX_mDNSResponder + LogMsgNoIdent("DefaultToBLETriggered %d", DefaultToBLETriggered); +#endif // APPLE_OSX_mDNSResponder && ENABLE_BLE_TRIGGERED_BONJOUR if (!m->NewQuestions) LogMsgNoIdent("NewQuestion <NONE>"); @@ -6340,7 +6202,7 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) 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; @@ -6369,7 +6231,7 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) 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); } } @@ -6395,7 +6257,11 @@ struct CompileTimeAssertionChecks_uds_daemon 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) <= 1150) ? 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/mDNSResponder/mDNSShared/uds_daemon.h b/mDNSResponder/mDNSShared/uds_daemon.h index ef98450b..dc7d9ac2 100644 --- a/mDNSResponder/mDNSShared/uds_daemon.h +++ b/mDNSResponder/mDNSShared/uds_daemon.h @@ -15,9 +15,200 @@ * 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) @@ -26,10 +217,10 @@ 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_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(mDNS *const m, mDNSBool mflag, mDNSBool start, mDNSBool mstatelog); +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 @@ -42,7 +233,7 @@ extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback call 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); +extern void RecordUpdatedNiceLabel(mDNSs32 delay); // Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X @@ -55,12 +246,12 @@ extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonDat 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(mDNS *const m, ServiceRecordSet *const srs); +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, DNSQuestion * q); +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); @@ -68,14 +259,9 @@ extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags); extern void external_connection_release(const domainname *instance); -extern void internal_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags); -extern void internal_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags); -extern void internal_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags); -extern void internal_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags); - #else // APPLE_OSX_mDNSResponder -#define external_start_browsing_for_service(A,B,C,D,E) (void)(A) +#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) @@ -92,3 +278,5 @@ extern const char mDNSResponderVersionString_SCCS[]; extern void SetDebugBoundPath(void); extern int IsDebugSocketInUse(void); #endif + +#endif /* UDS_DAEMON_H */ |