summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSShared/uds_daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSShared/uds_daemon.c')
-rw-r--r--mDNSResponder/mDNSShared/uds_daemon.c683
1 files changed, 409 insertions, 274 deletions
diff --git a/mDNSResponder/mDNSShared/uds_daemon.c b/mDNSResponder/mDNSShared/uds_daemon.c
index be89f319..0102453f 100644
--- a/mDNSResponder/mDNSShared/uds_daemon.c
+++ b/mDNSResponder/mDNSShared/uds_daemon.c
@@ -48,17 +48,18 @@ mDNSBool AlwaysAppendSearchDomains = mDNSfalse;
#endif
#endif
-#ifdef LOCAL_PEERPID
-#include <sys/un.h> // for LOCAL_PEERPID
+#ifdef LOCAL_PEEREPID
+#include <sys/un.h> // for LOCAL_PEEREPID
#include <sys/socket.h> // for getsockopt
#include <sys/proc_info.h> // for struct proc_bsdshortinfo
#include <libproc.h> // for proc_pidinfo()
-#endif //LOCAL_PEERPID
+#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
#if APPLE_OSX_mDNSResponder
#include <WebFilterDNS/WebFilterDNS.h>
+#include "BLE.h"
#if !NO_WCF
@@ -225,7 +226,8 @@ struct request_state
DNSServiceFlags flags;
DNSQuestion q_all;
DNSQuestion q_default;
- } enumeration;
+ DNSQuestion q_autoall;
+ } enumeration;
struct
{
DNSQuestion q;
@@ -271,11 +273,19 @@ typedef struct reply_state
mDNSexport mDNS mDNSStorage;
mDNSexport const char ProgramName[] = "mDNSResponder";
+#if defined(USE_TCP_LOOPBACK)
+static char* boundPath = NULL;
+#else
+static char* boundPath = MDNS_UDS_SERVERPATH;
+#endif
+#if DEBUG
+#define MDNS_UDS_SERVERPATH_DEBUG "/var/tmp/mDNSResponder"
+#endif
static dnssd_sock_t listenfd = dnssd_InvalidSocket;
static request_state *all_requests = NULL;
-#ifdef LOCAL_PEERPID
+#ifdef LOCAL_PEEREPID
struct proc_bsdshortinfo proc;
-#endif //LOCAL_PEERPID
+#endif //LOCAL_PEEREPID
mDNSlocal void set_peer_pid(request_state *request);
mDNSlocal void LogMcastClientInfo(request_state *req);
mDNSlocal void GetMcastClients(request_state *req);
@@ -284,6 +294,13 @@ static mDNSu32 i_mcount; // sets mcount when McastLogging is enabled(PROF sign
static mDNSu32 n_mrecords; // tracks the current active mcast records for McastLogging
static mDNSu32 n_mquests; // tracks the current active mcast questions for McastLogging
+
+#if TARGET_OS_EMBEDDED
+mDNSu32 curr_num_regservices = 0;
+mDNSu32 max_num_regservices = 0;
+#endif
+
+
// Note asymmetry here between registration and browsing.
// For service registrations we only automatically register in domains that explicitly appear in local configuration data
// (so AutoRegistrationDomains could equally well be called SCPrefRegDomains)
@@ -340,9 +357,9 @@ mDNSlocal void my_perror(char *errmsg)
mDNSlocal void my_throttled_perror(char *err_msg)
{
static int uds_throttle_count = 0;
- if ((uds_throttle_count++ % 250) == 0)
+ if ((uds_throttle_count++ % 250) == 0)
my_perror(err_msg);
-}
+}
// LogMcastQuestion/LogMcastQ should be called after the DNSQuestion struct is initialized(especially for q->TargetQID)
// Hence all calls are made after mDNS_StartQuery()/mDNS_StopQuery()/mDNS_StopBrowse() is called.
@@ -360,9 +377,11 @@ mDNSlocal void LogMcastQuestion(mDNS *const m, const DNSQuestion *const q, reque
{
mcount--;
}
- LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Question" : "-Question", q->qname.c, DNSTypeName(q->qtype),
- q->InterfaceID == mDNSInterface_LocalOnly ? "lo" : q->InterfaceID == mDNSInterface_P2P ? "p2p" :
- q->InterfaceID == mDNSInterface_Any ? "any" : InterfaceNameForID(m, q->InterfaceID),
+ LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Question" : "-Question", q->qname.c, DNSTypeName(q->qtype),
+ q->InterfaceID == mDNSInterface_LocalOnly ? "lo" :
+ q->InterfaceID == mDNSInterface_P2P ? "p2p" :
+ q->InterfaceID == mDNSInterface_BLE ? "BLE" :
+ q->InterfaceID == mDNSInterface_Any ? "any" : InterfaceNameForID(m, q->InterfaceID),
req->process_id, req->pid_name);
LogMcastStateInfo(m, mflag, mDNSfalse, mDNSfalse);
}
@@ -386,8 +405,10 @@ mDNSlocal void LogMcastService(mDNS *const m, const AuthRecord *const ar, reques
mcount--;
}
LogMcast("%s: %##s (%s) (%s) Client(%d)[%s]", status ? "+Service" : "-Service", ar->resrec.name->c, DNSTypeName(ar->resrec.rrtype),
- ar->resrec.InterfaceID == mDNSInterface_LocalOnly ? "lo" : ar->resrec.InterfaceID == mDNSInterface_P2P ? "p2p" :
- ar->resrec.InterfaceID == mDNSInterface_Any ? "all" : InterfaceNameForID(m, ar->resrec.InterfaceID),
+ ar->resrec.InterfaceID == mDNSInterface_LocalOnly ? "lo" :
+ ar->resrec.InterfaceID == mDNSInterface_P2P ? "p2p" :
+ ar->resrec.InterfaceID == mDNSInterface_BLE ? "BLE" :
+ ar->resrec.InterfaceID == mDNSInterface_Any ? "all" : InterfaceNameForID(m, ar->resrec.InterfaceID),
req->process_id, req->pid_name);
LogMcastStateInfo(m, mflag, mDNSfalse, mDNSfalse);
}
@@ -407,13 +428,13 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
{
request_state *req, *r;
for (req = all_requests; req; req=req->next)
- {
+ {
if (req->primary) // If this is a subbordinate operation, check that the parent is in the list
- {
- for (r = all_requests; r && r != req; r=r->next)
- if (r == req->primary)
+ {
+ for (r = all_requests; r && r != req; r=r->next)
+ if (r == req->primary)
goto foundpar;
- }
+ }
// For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
GetMcastClients(req);
foundpar:;
@@ -432,28 +453,28 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
// wrong value if MulticastLogging is disabled and then re-enabled
LogMcastNoIdent("--- START MCAST STATE LOG ---");
if (!all_requests)
- {
+ {
mcount = 0;
LogMcastNoIdent("<None>");
- }
- else
- {
+ }
+ else
+ {
request_state *req, *r;
for (req = all_requests; req; req=req->next)
- {
+ {
if (req->primary) // If this is a subbordinate operation, check that the parent is in the list
- {
- for (r = all_requests; r && r != req; r=r->next)
- if (r == req->primary)
+ {
+ for (r = all_requests; r && r != req; r=r->next)
+ if (r == req->primary)
goto foundparent;
LogMcastNoIdent("%3d: Orphan operation; parent not found in request list", req->sd);
- }
+ }
// For non-subbordinate operations, and subbordinate operations that have lost their parent, write out their info
LogMcastClientInfo(req);
foundparent:;
}
if(!mcount) // To initially set mcount
- mcount = i_mcount;
+ mcount = i_mcount;
}
if (mcount == 0)
{
@@ -461,7 +482,7 @@ mDNSexport void LogMcastStateInfo(mDNS *const m, mDNSBool mflag, mDNSBool start,
LogMcastNoIdent("--- MCOUNT[%d]: IMPKTNUM[%d] ---", mcount, i_mpktnum);
}
if (mflag)
- LogMcastNoIdent("--- MCOUNT[%d]: CMPKTNUM[%d] - IMPKTNUM[%d] = [%d]PKTS ---", mcount, m->MPktNum, i_mpktnum, (m->MPktNum - i_mpktnum));
+ LogMcastNoIdent("--- MCOUNT[%d]: CMPKTNUM[%d] - IMPKTNUM[%d] = [%d]PKTS ---", mcount, m->MPktNum, i_mpktnum, (m->MPktNum - i_mpktnum));
LogMcastNoIdent("--- END MCAST STATE LOG ---");
}
}
@@ -507,6 +528,24 @@ mDNSlocal void abort_request(request_state *req)
req->terminate = (req_termination_fn) ~0;
}
+#if DEBUG
+mDNSexport void SetDebugBoundPath(void)
+{
+#if !defined(USE_TCP_LOOPBACK)
+ boundPath = MDNS_UDS_SERVERPATH_DEBUG;
+#endif
+}
+
+mDNSexport int IsDebugSocketInUse(void)
+{
+#if !defined(USE_TCP_LOOPBACK)
+ return !strcmp(boundPath, MDNS_UDS_SERVERPATH_DEBUG);
+#else
+ return mDNSfalse;
+#endif
+}
+#endif
+
mDNSlocal void AbortUnlinkAndFree(request_state *req)
{
request_state **p = &all_requests;
@@ -611,9 +650,7 @@ mDNSlocal mStatus GenerateNTDResponse(const domainname *const servicename, const
}
}
-// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
-// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
-mDNSlocal void GenerateBonjourBrowserResponse(const domainname *const servicename, const mDNSInterfaceID id,
+mDNSlocal void GenerateBrowseReply(const domainname *const servicename, const mDNSInterfaceID id,
request_state *const request, reply_state **const rep, reply_op_t op, DNSServiceFlags flags, mStatus err)
{
char namestr[MAX_DOMAIN_LABEL+1];
@@ -665,7 +702,7 @@ mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, i
mDNSu16 rdlen = get_uint16(&request->msgptr, request->msgend);
const char *rdata = get_rdata (&request->msgptr, request->msgend, rdlen);
mDNSu32 ttl = GetTTL ? get_uint32(&request->msgptr, request->msgend) : 0;
- int storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ size_t storage_size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
AuthRecord *rr;
mDNSInterfaceID InterfaceID;
AuthRecType artype;
@@ -691,7 +728,7 @@ mDNSlocal AuthRecord *read_rr_from_ipc_msg(request_state *request, int GetTTL, i
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
if (InterfaceID == mDNSInterface_LocalOnly)
artype = AuthRecordLocalOnly;
- else if (InterfaceID == mDNSInterface_P2P)
+ else if (InterfaceID == mDNSInterface_P2P || InterfaceID == mDNSInterface_BLE)
artype = AuthRecordP2P;
else if ((InterfaceID == mDNSInterface_Any) && (flags & kDNSServiceFlagsIncludeP2P)
&& (flags & kDNSServiceFlagsIncludeAWDL))
@@ -782,12 +819,14 @@ mDNSlocal mDNSBool AuthorizedDomain(const request_state * const request, const d
#pragma mark - external helpers
#endif
-mDNSlocal mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags)
+mDNSexport mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags)
{
#if APPLE_OSX_mDNSResponder
- if ( ((InterfaceID == mDNSInterface_Any) && (flags & (kDNSServiceFlagsIncludeP2P | kDNSServiceFlagsIncludeAWDL)) && IsLocalDomain(domain))
- || mDNSPlatformInterfaceIsD2D(InterfaceID))
+ // Only call D2D layer routines if request applies to a D2D interface and the domain is "local".
+ if ( (((InterfaceID == mDNSInterface_Any) && (flags & (kDNSServiceFlagsIncludeP2P | kDNSServiceFlagsIncludeAWDL | kDNSServiceFlagsAutoTrigger)))
+ || mDNSPlatformInterfaceIsD2D(InterfaceID) || (InterfaceID == mDNSInterface_BLE))
+ && IsLocalDomain(domain))
{
return mDNStrue;
}
@@ -822,6 +861,14 @@ 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)
@@ -1014,6 +1061,9 @@ mDNSlocal void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, m
}
else if (result == mStatus_MemFree)
{
+#if TARGET_OS_EMBEDDED
+ curr_num_regservices--;
+#endif
if (instance->request && instance->renameonmemfree)
{
external_stop_advertising_helper(instance);
@@ -1148,24 +1198,24 @@ mDNSlocal void set_peer_pid(request_state *request)
socklen_t len = sizeof(p);
request->pid_name[0] = '\0';
request->process_id = -1;
-#ifdef LOCAL_PEERPID
- if (request->sd < 0)
+#ifdef LOCAL_PEEREPID
+ if (request->sd < 0)
return;
- // to extract the pid value
- if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEERPID, &p, &len) != 0)
+ // to extract the effective pid value
+ if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREPID, &p, &len) != 0)
return;
// to extract the process name from the pid value
if (proc_pidinfo(p, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
return;
- mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
+ mDNSPlatformStrLCopy(request->pid_name, proc.pbsi_comm, sizeof(request->pid_name));
request->process_id = p;
- debugf("set_peer_pid: Client PEERPID is %d %s", p, request->pid_name);
-#else // !LOCAL_PEERPID
+ debugf("set_peer_pid: Client PEEREPID is %d %s", p, request->pid_name);
+#else // !LOCAL_PEEREPID
len = 0;
LogInfo("set_peer_pid: Not Supported on this version of OS");
if (request->sd < 0)
return;
-#endif // LOCAL_PEERPID
+#endif // LOCAL_PEEREPID
}
mDNSlocal void connection_termination(request_state *request)
@@ -1196,7 +1246,7 @@ mDNSlocal void connection_termination(request_state *request)
{
registered_record_entry *ptr = request->u.reg_recs;
LogOperation("%3d: DNSServiceRegisterRecord(%u %s) STOP PID[%d](%s)", request->sd, ptr->key, RRDisplayString(&mDNSStorage, &ptr->rr->resrec), request->process_id, request->pid_name);
- request->u.reg_recs = request->u.reg_recs->next;
+ request->u.reg_recs = request->u.reg_recs->next;
ptr->rr->RecordContext = NULL;
if (ptr->external_advertise)
{
@@ -1248,7 +1298,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
}
// allocate registration entry, link into list
re = mallocL("registered_record_entry", sizeof(registered_record_entry));
- if (!re)
+ if (!re)
FatalError("ERROR: malloc");
re->key = request->hdr.reg_index;
re->rr = rr;
@@ -1259,7 +1309,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
rr->RecordCallback = regrecord_callback;
re->origInterfaceID = rr->resrec.InterfaceID;
- if (rr->resrec.InterfaceID == mDNSInterface_P2P)
+ if (rr->resrec.InterfaceID == mDNSInterface_P2P)
rr->resrec.InterfaceID = mDNSInterface_Any;
#if 0
if (!AuthorizedDomain(request, rr->resrec.name, AutoRegistrationDomains)) return (mStatus_NoError);
@@ -1267,7 +1317,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
if (rr->resrec.rroriginalttl == 0)
rr->resrec.rroriginalttl = DefaultTTLforRRType(rr->resrec.rrtype);
- LogOperation("%3d: DNSServiceRegisterRecord(%u %s) START PID[%d](%s)", request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec),
+ LogOperation("%3d: DNSServiceRegisterRecord(%u %s) START PID[%d](%s)", request->sd, re->key, RRDisplayString(&mDNSStorage, &rr->resrec),
request->process_id, request->pid_name);
err = mDNS_Register(&mDNSStorage, rr);
@@ -1279,7 +1329,7 @@ mDNSlocal mStatus handle_regrecord_request(request_state *request)
}
else
{
- LogMcastS(&mDNSStorage, rr, request, reg_start);
+ LogMcastS(&mDNSStorage, rr, request, reg_start);
re->next = request->u.reg_recs;
request->u.reg_recs = re;
}
@@ -1291,17 +1341,17 @@ mDNSlocal void UpdateDeviceInfoRecord(mDNS *const m);
mDNSlocal void regservice_termination_callback(request_state *request)
{
- if (!request)
- {
- LogMsg("regservice_termination_callback context is NULL");
- return;
+ if (!request)
+ {
+ LogMsg("regservice_termination_callback context is NULL");
+ return;
}
while (request->u.servicereg.instances)
{
service_instance *p = request->u.servicereg.instances;
request->u.servicereg.instances = request->u.servicereg.instances->next;
// only safe to free memory if registration is not valid, i.e. deregister fails (which invalidates p)
- LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP PID[%d](%s)", request->sd, p->srs.RR_SRV.resrec.name->c,
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) STOP PID[%d](%s)", request->sd, p->srs.RR_SRV.resrec.name->c,
mDNSVal16(p->srs.RR_SRV.resrec.rdata->u.srv.port), request->process_id, request->pid_name);
external_stop_advertising_helper(p);
@@ -1320,9 +1370,9 @@ mDNSlocal void regservice_termination_callback(request_state *request)
}
}
if (request->u.servicereg.txtdata)
- {
- freeL("service_info txtdata", request->u.servicereg.txtdata);
- request->u.servicereg.txtdata = NULL;
+ {
+ freeL("service_info txtdata", request->u.servicereg.txtdata);
+ request->u.servicereg.txtdata = NULL;
}
if (request->u.servicereg.autoname)
{
@@ -1347,7 +1397,7 @@ mDNSlocal mStatus add_record_to_service(request_state *request, service_instance
ServiceRecordSet *srs = &instance->srs;
mStatus result;
mDNSu32 coreFlags = 0; // translate to corresponding mDNSCore flag definitions
- int size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ size_t size = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
ExtraResourceRecord *extra = mallocL("ExtraResourceRecord", sizeof(*extra) - sizeof(RDataBody) + size);
if (!extra) { my_perror("ERROR: malloc"); return mStatus_NoMemoryErr; }
@@ -1363,15 +1413,15 @@ mDNSlocal mStatus add_record_to_service(request_state *request, service_instance
coreFlags |= coreFlagIncludeP2P;
if (request->flags & kDNSServiceFlagsIncludeAWDL)
coreFlags |= coreFlagIncludeAWDL;
-
+
result = mDNS_AddRecordToService(&mDNSStorage, srs, extra, &extra->r.rdatastorage, ttl, coreFlags);
- if (result)
- {
- freeL("ExtraResourceRecord/add_record_to_service", extra);
- return result;
+ if (result)
+ {
+ freeL("ExtraResourceRecord/add_record_to_service", extra);
+ return result;
}
LogMcastS(&mDNSStorage, &srs->RR_PTR, request, reg_start);
-
+
extra->ClientID = request->hdr.reg_index;
if ( instance->external_advertise
&& callExternalHelpers(request->u.servicereg.InterfaceID, &instance->domain, request->flags))
@@ -1437,14 +1487,7 @@ mDNSlocal void update_callback(mDNS *const m, AuthRecord *const rr, RData *oldrd
if (external_advertise)
{
ResourceRecord ext = rr->resrec;
- DNSServiceFlags flags = 0;
-
- // Since we don't have a copy of the flags value used when the record was registered,
- // we'll have to derive it from the ARType field.
- if (rr->ARType == AuthRecordAnyIncludeP2P)
- flags |= kDNSServiceFlagsIncludeP2P;
- else if (rr->ARType == AuthRecordAnyIncludeAWDL)
- flags |= kDNSServiceFlagsIncludeAWDL;
+ DNSServiceFlags flags = deriveD2DFlagsFromAuthRecType(rr->ARType);
if (ext.rdlength == oldrdlen && mDNSPlatformMemSame(&ext.rdata->u, &oldrd->u, oldrdlen)) goto exit;
SetNewRData(&ext, oldrd, oldrdlen);
@@ -1459,7 +1502,7 @@ exit:
mDNSlocal mStatus update_record(AuthRecord *rr, mDNSu16 rdlen, const char *rdata, mDNSu32 ttl, const mDNSBool *const external_advertise)
{
mStatus result;
- const int rdsize = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
+ const size_t rdsize = rdlen > sizeof(RDataBody) ? rdlen : sizeof(RDataBody);
RData *newrd = mallocL("RData/update_record", sizeof(RData) - sizeof(RDataBody) + rdsize);
if (!newrd) FatalError("ERROR: malloc");
newrd->MaxRDLength = (mDNSu16) rdsize;
@@ -1709,7 +1752,7 @@ mDNSexport mDNSs32 ChopSubTypes(char *regtype, char **AnonData)
mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData)
{
AuthRecord *st = mDNSNULL;
- //
+ //
// "p" is pointing at the regtype e.g., _http._tcp followed by ":<AnonData>" indicated
// by AnonData being non-NULL which is in turn follwed by ",<SubTypes>" indicated by
// NumSubTypes being non-zero. We need to skip the initial regtype to get to the actual
@@ -1757,7 +1800,7 @@ mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **Ano
if (!MakeDomainNameFromDNSNameString(&st[i].namestorage, p))
{
freeL("ServiceSubTypes", st);
- if (*AnonData)
+ if (AnonData && *AnonData)
freeL("AnonymousData", *AnonData);
return(mDNSNULL);
}
@@ -1771,7 +1814,7 @@ mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **Ano
mDNSlocal mStatus register_service_instance(request_state *request, const domainname *domain)
{
service_instance **ptr, *instance;
- const int extra_size = (request->u.servicereg.txtlen > sizeof(RDataBody)) ? (request->u.servicereg.txtlen - sizeof(RDataBody)) : 0;
+ size_t extra_size = (request->u.servicereg.txtlen > sizeof(RDataBody)) ? (request->u.servicereg.txtlen - sizeof(RDataBody)) : 0;
const mDNSBool DomainIsLocal = SameDomainName(domain, &localdomain);
mStatus result;
mDNSInterfaceID interfaceID = request->u.servicereg.InterfaceID;
@@ -1828,14 +1871,14 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
char *AnonData = mDNSNULL;
instance->subtypes = AllocateSubTypes(request->u.servicereg.num_subtypes, request->u.servicereg.type_as_string, &AnonData);
if (AnonData)
- instance->srs.AnonData = (const mDNSu8 *)AnonData;
+ instance->srs.AnonData = (const mDNSu8 *)AnonData;
}
if (request->u.servicereg.num_subtypes && !instance->subtypes)
- {
- unlink_and_free_service_instance(instance);
- instance = NULL;
- FatalError("ERROR: malloc");
+ {
+ unlink_and_free_service_instance(instance);
+ instance = NULL;
+ FatalError("ERROR: malloc");
}
result = mDNS_RegisterService(&mDNSStorage, &instance->srs,
@@ -1849,7 +1892,7 @@ mDNSlocal mStatus register_service_instance(request_state *request, const domain
if (!result)
{
*ptr = instance; // Append this to the end of our request->u.servicereg.instances list
- LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED", instance->request->sd,
+ LogOperation("%3d: DNSServiceRegister(%##s, %u) ADDED", instance->request->sd,
instance->srs.RR_SRV.resrec.name->c, mDNSVal16(request->u.servicereg.port));
LogMcastS(&mDNSStorage, &instance->srs.RR_SRV, request, reg_start);
}
@@ -1867,10 +1910,6 @@ mDNSlocal void udsserver_default_reg_domain_changed(const DNameListElem *const d
{
request_state *request;
-#if APPLE_OSX_mDNSResponder
- machserver_automatic_registration_domain_changed(&d->name, add);
-#endif // APPLE_OSX_mDNSResponder
-
LogMsg("%s registration domain %##s", add ? "Adding" : "Removing", d->name.c);
for (request = all_requests; request; request = request->next)
{
@@ -2045,7 +2084,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
request->u.servicereg.instances = NULL;
request->u.servicereg.txtlen = 0;
request->u.servicereg.txtdata = NULL;
- mDNSPlatformStrCopy(request->u.servicereg.type_as_string, type_as_string);
+ mDNSPlatformStrLCopy(request->u.servicereg.type_as_string, type_as_string, sizeof(request->u.servicereg.type_as_string));
if (request->msgptr + 2 > request->msgend) request->msgptr = NULL;
else
@@ -2148,7 +2187,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
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, 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
@@ -2160,6 +2199,12 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
request->terminate = regservice_termination_callback;
err = register_service_instance(request, &d);
+
+#if TARGET_OS_EMBEDDED
+ ++curr_num_regservices;
+ if (curr_num_regservices > max_num_regservices)
+ max_num_regservices = curr_num_regservices;
+#endif
#if 0
err = AuthorizedDomain(request, &d, AutoRegistrationDomains) ? register_service_instance(request, &d) : mStatus_NoError;
@@ -2179,7 +2224,7 @@ mDNSlocal mStatus handle_regservice_request(request_state *request)
}
return(err);
-
+
bad_param:
freeL("handle_regservice_request (txtdata)", request->u.servicereg.txtdata);
request->u.servicereg.txtdata = NULL;
@@ -2207,14 +2252,21 @@ mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const Resourc
flags |= kDNSServiceFlagsThresholdReached;
}
+ // if returning a negative answer, then use question's name in reply
+ if (answer->RecordType == kDNSRecordTypePacketNegative)
+ {
+ GenerateBrowseReply(&question->qname, answer->InterfaceID, req, &rep, browse_reply_op, flags, kDNSServiceErr_NoSuchRecord);
+ goto validReply;
+ }
+
if (GenerateNTDResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError) != mStatus_NoError)
{
if (SameDomainName(&req->u.browser.regtype, (const domainname*)"\x09_services\x07_dns-sd\x04_udp"))
{
// Special support to enable the DNSServiceBrowse call made by Bonjour Browser
// Remove after Bonjour Browser is updated to use DNSServiceQueryRecord instead of DNSServiceBrowse
- GenerateBonjourBrowserResponse(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
- goto bonjourbrowserhack;
+ GenerateBrowseReply(&answer->rdata->u.name, answer->InterfaceID, req, &rep, browse_reply_op, flags, mStatus_NoError);
+ goto validReply;
}
LogMsg("%3d: FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer",
@@ -2222,7 +2274,7 @@ mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const Resourc
return;
}
-bonjourbrowserhack:
+validReply:
LogOperation("%3d: DNSServiceBrowse(%##s, %s) RESULT %s %d: %s",
req->sd, question->qname.c, DNSTypeName(question->qtype), AddRecord ? "Add" : "Rmv",
@@ -2231,6 +2283,36 @@ bonjourbrowserhack:
append_reply(req, rep);
}
+mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
+{
+ int i;
+ q->euid = req->uid;
+ // The policy is either based on pid or UUID. Pass a zero pid
+ // to the "core" if the UUID is valid. If we always pass the pid,
+ // then the "core" needs to determine whether the uuid is valid
+ // by examining all the 16 bytes at the time of the policy
+ // check and also when setting the delegate socket option. Also, it
+ // requires that we zero out the uuid wherever the question is
+ // initialized to make sure that it is not interpreted as valid.
+ // To prevent these intrusive changes, just pass a zero pid to indicate
+ // that pid is not valid when uuid is valid. In future if we need the
+ // pid in the question, we will reevaluate this strategy.
+ if (req->validUUID)
+ {
+ for (i = 0; i < UUID_SIZE; i++)
+ {
+ q->uuid[i] = req->uuid[i];
+ }
+ q->pid = 0;
+ }
+ else
+ {
+ q->pid = req->process_id;
+ }
+
+ //debugf("SetQuestionPolicy: q->euid[%d] q->pid[%d] uuid is valid : %s", q->euid, q->pid, req->validUUID ? "true" : "false");
+}
+
mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d)
{
browser_t *b, *p;
@@ -2244,8 +2326,10 @@ mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d
b = mallocL("browser_t", sizeof(*b));
if (!b) return mStatus_NoMemoryErr;
+ mDNSPlatformMemZero(b, sizeof(*b));
AssignDomainName(&b->domain, d);
- err = mDNS_StartBrowse(&mDNSStorage, &b->q, &info->u.browser.regtype, d, info->u.browser.AnonData, info->u.browser.interface_id, info->flags,
+ SetQuestionPolicy(&b->q, info);
+ err = mDNS_StartBrowse(&mDNSStorage, &b->q, &info->u.browser.regtype, d, info->u.browser.AnonData, info->u.browser.interface_id, info->flags,
info->u.browser.ForceMCast, (info->flags & kDNSServiceFlagsBackgroundTrafficClass) != 0, FoundInstance, info);
if (err)
{
@@ -2256,7 +2340,7 @@ 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,
+ 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 (callExternalHelpers(info->u.browser.interface_id, &b->domain, info->flags))
@@ -2264,7 +2348,7 @@ mDNSlocal mStatus add_domain_to_browser(request_state *info, const domainname *d
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);
+ external_start_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags, &b->q);
}
}
return err;
@@ -2284,18 +2368,18 @@ mDNSlocal void browse_termination_callback(request_state *info)
{
browser_t *ptr = info->u.browser.browsers;
- if (callExternalHelpers(info->u.browser.interface_id, &ptr->domain, info->flags))
+ if (callExternalHelpers(ptr->q.InterfaceID, &ptr->domain, ptr->q.flags))
{
domainname tmp;
ConstructServiceName(&tmp, NULL, &info->u.browser.regtype, &ptr->domain);
LogInfo("browse_termination_callback: calling external_stop_browsing_for_service()");
- external_stop_browsing_for_service(info->u.browser.interface_id, &tmp, kDNSType_PTR, info->flags);
+ external_stop_browsing_for_service(ptr->q.InterfaceID, &tmp, kDNSType_PTR, ptr->q.flags);
}
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(&mDNSStorage, &ptr->q, info, q_stop);
freeL("browser_t/browse_termination_callback", ptr);
}
}
@@ -2305,10 +2389,6 @@ mDNSlocal void udsserver_automatic_browse_domain_changed(const DNameListElem *co
request_state *request;
debugf("udsserver_automatic_browse_domain_changed: %s default browse domain %##s", add ? "Adding" : "Removing", d->name.c);
-#if APPLE_OSX_mDNSResponder
- machserver_automatic_browse_domain_changed(&d->name, add);
-#endif // APPLE_OSX_mDNSResponder
-
for (request = all_requests; request; request = request->next)
{
if (request->terminate != browse_termination_callback) continue; // Not a browse operation
@@ -2665,7 +2745,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
if (!MakeDomainNameFromDNSNameString(&temp, regtype)) return(mStatus_BadParamErr);
// For over-long service types, we only allow domain "local"
- if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrCopy(domain, "local.");
+ if (temp.c[0] > 15 && domain[0] == 0) mDNSPlatformStrLCopy(domain, "local.", sizeof(domain));
// Set up browser info
request->u.browser.ForceMCast = (flags & kDNSServiceFlagsForceMulticast) != 0;
@@ -2674,7 +2754,7 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
request->u.browser.default_domain = !domain[0];
request->u.browser.browsers = NULL;
- LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\", \"%s\") START PID[%d](%s)",
+ LogOperation("%3d: DNSServiceBrowse(%X, %d, \"%##s\", \"%s\") START PID[%d](%s)",
request->sd, request->flags, interfaceIndex, request->u.browser.regtype.c, domain, request->process_id, request->pid_name);
if (request->u.browser.default_domain)
@@ -2730,10 +2810,12 @@ mDNSlocal mStatus handle_browse_request(request_state *request)
mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
size_t len = 0;
- char fullname[MAX_ESCAPED_DOMAIN_NAME], target[MAX_ESCAPED_DOMAIN_NAME];
+ char fullname[MAX_ESCAPED_DOMAIN_NAME], target[MAX_ESCAPED_DOMAIN_NAME] = "0";
char *data;
reply_state *rep;
request_state *req = question->QuestionContext;
+ const DNSServiceErrorType error =
+ (answer->RecordType == kDNSRecordTypePacketNegative) ? kDNSServiceErr_NoSuchRecord : kDNSServiceErr_NoError;
(void)m; // Unused
LogOperation("%3d: DNSServiceResolve(%##s) %s %s", req->sd, question->qname.c, AddRecord ? "ADD" : "RMV", RRDisplayString(m, answer));
@@ -2751,7 +2833,9 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con
if (!req->u.resolve.txt || !req->u.resolve.srv) return; // only deliver result to client if we have both answers
ConvertDomainNameToCString(answer->name, fullname);
- ConvertDomainNameToCString(&req->u.resolve.srv->rdata->u.srv.target, target);
+
+ if (answer->RecordType != kDNSRecordTypePacketNegative)
+ ConvertDomainNameToCString(&req->u.resolve.srv->rdata->u.srv.target, target);
// calculate reply length
len += sizeof(DNSServiceFlags);
@@ -2766,7 +2850,7 @@ mDNSlocal void resolve_result_callback(mDNS *const m, DNSQuestion *question, con
rep = create_reply(resolve_reply_op, len, req);
rep->rhdr->flags = dnssd_htonl(0);
rep->rhdr->ifi = dnssd_htonl(mDNSPlatformInterfaceIndexfromInterfaceID(m, answer->InterfaceID, mDNSfalse));
- rep->rhdr->error = dnssd_htonl(kDNSServiceErr_NoError);
+ rep->rhdr->error = dnssd_htonl(error);
data = (char *)&rep->rhdr[1];
@@ -2788,7 +2872,7 @@ mDNSlocal void resolve_termination_callback(request_state *request)
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qtxt);
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
LogMcastQ(&mDNSStorage, &request->u.resolve.qsrv, request, q_stop);
- if (request->u.resolve.external_advertise)
+ if (request->u.resolve.external_advertise)
external_stop_resolving_service(request->u.resolve.qsrv.InterfaceID, &request->u.resolve.qsrv.qname, request->flags);
}
@@ -2858,8 +2942,6 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qsrv.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
request->u.resolve.qsrv.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
request->u.resolve.qsrv.SuppressUnusable = mDNSfalse;
- request->u.resolve.qsrv.DenyOnCellInterface = mDNSfalse;
- request->u.resolve.qsrv.DenyOnExpInterface = mDNSfalse;
request->u.resolve.qsrv.SearchListIndex = 0;
request->u.resolve.qsrv.AppendSearchDomains = 0;
request->u.resolve.qsrv.RetryWithSearchDomains = mDNSfalse;
@@ -2887,8 +2969,6 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
request->u.resolve.qtxt.ForceMCast = (flags & kDNSServiceFlagsForceMulticast ) != 0;
request->u.resolve.qtxt.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0;
request->u.resolve.qtxt.SuppressUnusable = mDNSfalse;
- request->u.resolve.qtxt.DenyOnCellInterface = mDNSfalse;
- request->u.resolve.qtxt.DenyOnExpInterface = mDNSfalse;
request->u.resolve.qtxt.SearchListIndex = 0;
request->u.resolve.qtxt.AppendSearchDomains = 0;
request->u.resolve.qtxt.RetryWithSearchDomains = mDNSfalse;
@@ -2914,15 +2994,15 @@ mDNSlocal mStatus handle_resolve_request(request_state *request)
#endif
// ask the questions
- LogOperation("%3d: DNSServiceResolve(%X %d %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex,
- request->u.resolve.qsrv.qname.c, request->process_id, request->pid_name);
+ LogOperation("%3d: DNSServiceResolve(%X %d %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex,
+ request->u.resolve.qsrv.qname.c, request->process_id, request->pid_name);
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qsrv);
-
+
if (!err)
{
err = mDNS_StartQuery(&mDNSStorage, &request->u.resolve.qtxt);
if (err)
- {
+ {
mDNS_StopQuery(&mDNSStorage, &request->u.resolve.qsrv);
}
else
@@ -3198,7 +3278,7 @@ mDNSlocal mStatus SendAdditionalQuery(DNSQuestion *q, request_state *request, mS
(void) q;
(void) request;
(void) err;
-
+
return mStatus_NoError;
#endif // !UNICAST_DISABLED
}
@@ -3279,7 +3359,7 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
rep = create_reply(req->hdr.op == query_request ? query_reply_op : addrinfo_reply_op, len, req);
if (AddRecord)
- flags |= kDNSServiceFlagsAdd;
+ flags |= kDNSServiceFlagsAdd;
if (question->ValidationStatus != 0)
{
error = kDNSServiceErr_NoError;
@@ -3304,7 +3384,7 @@ mDNSlocal void queryrecord_result_reply(mDNS *const m, request_state *req, DNSQu
}
}
}
-
+
rep->rhdr->flags = dnssd_htonl(flags);
// Call mDNSPlatformInterfaceIndexfromInterfaceID, but suppressNetworkChange (last argument). Otherwise, if the
// InterfaceID is not valid, then it simulates a "NetworkChanged" which in turn makes questions
@@ -3622,7 +3702,7 @@ 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);
+ request->sd, 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
@@ -3686,40 +3766,11 @@ mDNSlocal void queryrecord_termination_callback(request_state *request)
#endif // APPLE_OSX_mDNSResponder
}
-mDNSlocal void SetQuestionPolicy(DNSQuestion *q, request_state *req)
-{
- int i;
- q->euid = req->uid;
- // The policy is either based on pid or UUID. Pass a zero pid
- // to the "core" if the UUID is valid. If we always pass the pid,
- // then the "core" needs to determine whether the uuid is valid
- // by examining all the 16 bytes at the time of the policy
- // check and also when setting the delegate socket option. Also, it
- // requires that we zero out the uuid wherever the question is
- // initialized to make sure that it is not interpreted as valid.
- // To prevent these intrusive changes, just pass a zero pid to indicate
- // that pid is not valid when uuid is valid. In future if we need the
- // pid in the question, we will reevaluate this strategy.
- if (req->validUUID)
- {
- for (i = 0; i < UUID_SIZE; i++)
- {
- q->uuid[i] = req->uuid[i];
- }
- q->pid = 0;
- }
- else
- {
- q->pid = req->process_id;
- }
-
- //debugf("SetQuestionPolicy: q->euid[%d] q->pid[%d] uuid is valid : %s", q->euid, q->pid, req->validUUID ? "true" : "false");
-}
-
mDNSlocal mStatus handle_queryrecord_request(request_state *request)
{
DNSQuestion *const q = &request->u.queryrecord.q;
char name[256];
+ size_t nameLen;
mDNSu16 rrtype, rrclass;
mStatus err;
@@ -3731,6 +3782,9 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
+ if (interfaceIndex > 1)
+ LogMsg("handle_queryrecord_request: interfaceIndex %d is currently inactive requested by client[%d][%s]",
+ interfaceIndex, request->process_id, request->pid_name);
// If it's one of the specially defined inteface index values, just return an error.
// Also, caller should return an error immediately if lo0 (index 1) is not configured
// into the current active interfaces. See background in Radar 21967160.
@@ -3774,8 +3828,6 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
q->TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
q->WakeOnResolve = 0;
q->UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
- q->DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular) != 0;
- q->DenyOnExpInterface = (flags & kDNSServiceFlagsDenyExpensive) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
q->ValidationRequired = DNSSEC_VALIDATION_SECURE;
else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
@@ -3793,7 +3845,7 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
//Turn off dnssec validation for local domains and Question Types: RRSIG/ANY(ANY Type is not supported yet)
if ((IsLocalDomain(&q->qname)) || (q->qtype == kDNSServiceType_RRSIG) || (q->qtype == kDNSServiceType_ANY))
q->ValidationRequired = 0;
-
+
// Don't append search domains for fully qualified domain names including queries
// such as e.g., "abc." that has only one label. We convert all names to FQDNs as internally
// we only deal with FQDNs. Hence, we cannot look at qname to figure out whether we should
@@ -3803,9 +3855,10 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
// argument "AlwaysAppendSearchDomains", then we do it for any query which is not fully qualified.
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set.
- if ((!(q->ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(q->ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && (rrtype == kDNSType_A || rrtype == kDNSType_AAAA) && name[strlen(name) - 1] != '.' &&
- (AlwaysAppendSearchDomains || CountLabels(&q->qname) == 1))
+ nameLen = strlen(name);
+ if ((!(q->ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(q->ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && (rrtype == kDNSType_A || rrtype == kDNSType_AAAA) && ((nameLen == 0) || (name[nameLen - 1] != '.')) &&
+ (AlwaysAppendSearchDomains || CountLabels(&q->qname) == 1))
{
q->AppendSearchDomains = 1;
q->AppendLocalSearchDomains = 1;
@@ -3825,13 +3878,13 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
SetQuestionPolicy(q, request);
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, flags, interfaceIndex, q->qname.c, DNSTypeName(q->qtype), request->process_id, request->pid_name);
err = mDNS_StartQuery(&mDNSStorage, q);
-
+
if (err)
- {
+ {
LogMsg("%3d: ERROR: DNSServiceQueryRecord %##s %s mDNS_StartQuery: %d", request->sd, q->qname.c, DNSTypeName(q->qtype), (int)err);
- }
+ }
else
{
request->terminate = queryrecord_termination_callback;
@@ -3839,7 +3892,7 @@ mDNSlocal mStatus handle_queryrecord_request(request_state *request)
if (callExternalHelpers(q->InterfaceID, &q->qname, flags))
{
LogInfo("handle_queryrecord_request: calling external_start_browsing_for_service()");
- external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, flags);
+ external_start_browsing_for_service(q->InterfaceID, &q->qname, q->qtype, flags, q);
}
}
@@ -3888,7 +3941,8 @@ mDNSlocal void enum_termination_callback(request_state *request)
else
{
LogInfo("%3d: DNSServiceEnumeration Cancel WAB Browse PID[%d](%s)", request->sd, request->process_id, request->pid_name);
- uDNS_StopWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY);
+ uDNS_StopWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY | UDNS_WAB_LBROWSE_QUERY);
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_autoall);
}
mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_default);
@@ -3955,6 +4009,7 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
// necessary context can be reached from the callbacks
request->u.enumeration.q_all.QuestionContext = request;
request->u.enumeration.q_default.QuestionContext = request;
+ if (!reg) request->u.enumeration.q_autoall.QuestionContext = request;
// if the caller hasn't specified an explicit interface, we use local-only to get the system-wide list.
if (!InterfaceID) InterfaceID = mDNSInterface_LocalOnly;
@@ -3968,7 +4023,16 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
{
err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_default, t_default, NULL, InterfaceID, enum_result_callback, request);
if (err) mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
- else request->terminate = enum_termination_callback;
+ else if (!reg)
+ {
+ err = mDNS_GetDomains(&mDNSStorage, &request->u.enumeration.q_autoall, mDNS_DomainTypeBrowseAutomatic, NULL, InterfaceID, enum_result_callback, request);
+ if (err)
+ {
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_all);
+ mDNS_StopGetDomains(&mDNSStorage, &request->u.enumeration.q_default);
+ }
+ }
+ if (!err) request->terminate = enum_termination_callback;
}
if (!err)
{
@@ -3978,10 +4042,10 @@ mDNSlocal mStatus handle_enum_request(request_state *request)
LogInfo("%3d: DNSServiceEnumerateDomains Start WAB Registration PID[%d](%s)", request->sd, request->process_id, request->pid_name);
uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_REG_QUERY);
}
- else
+ else
{
LogInfo("%3d: DNSServiceEnumerateDomains Start WAB Browse PID[%d](%s)", request->sd, request->process_id, request->pid_name);
- uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY);
+ uDNS_StartWABQueries(&mDNSStorage, UDNS_WAB_BROWSE_QUERY | UDNS_WAB_LBROWSE_QUERY);
}
}
@@ -4045,7 +4109,7 @@ mDNSlocal mStatus handle_release_request(request_state *request)
LogOperation("%3d: PeerConnectionRelease(%X %##s) START PID[%d](%s)",
request->sd, flags, instance.c, request->process_id, request->pid_name);
-
+
external_connection_release(&instance);
return(err);
}
@@ -4054,7 +4118,7 @@ mDNSlocal mStatus handle_release_request(request_state *request)
mDNSlocal mStatus handle_release_request(request_state *request)
{
- (void) request;
+ (void) request;
return mStatus_UnsupportedErr;
}
@@ -4116,11 +4180,14 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
{
len = sizeof(pid);
if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREPID, &request->process_id, &len) != 0)
+ {
+ LogMsg("handle_connection_delegate_request: getsockopt for LOCAL_PEEREPID failed errno:%d / %s", errno, strerror(errno));
return;
+ }
// to extract the process name from the pid value
if (proc_pidinfo(request->process_id, PROC_PIDT_SHORTBSDINFO, 1, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) == 0)
return;
- mDNSPlatformStrCopy(request->pid_name, proc.pbsi_comm);
+ mDNSPlatformStrLCopy(request->pid_name, proc.pbsi_comm, sizeof(request->pid_name));
debugf("handle_connection_delegate_request: process id %d, name %s", request->process_id, request->pid_name);
}
#endif
@@ -4129,7 +4196,10 @@ mDNSlocal void handle_connection_delegate_request(request_state *request)
{
len = UUID_SIZE;
if (getsockopt(request->sd, SOL_LOCAL, LOCAL_PEEREUUID, request->uuid, &len) != 0)
+ {
+ LogMsg("handle_connection_delegate_request: getsockopt for LOCAL_PEEREUUID failed errno:%d / %s", errno, strerror(errno));
return;
+ }
request->validUUID = mDNStrue;
}
#endif
@@ -4197,7 +4267,7 @@ mDNSlocal void handle_getpid_request(request_state *request)
}
}
}
-
+
pi.err = 0;
pi.pid = pid;
send_all(request->sd, (const char *)&pi, sizeof(PIDInfo));
@@ -4216,8 +4286,8 @@ mDNSlocal void port_mapping_termination_callback(request_state *request)
{
LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) STOP PID[%d](%s)", request->sd,
DNSServiceProtocol(request->u.pm.NATinfo.Protocol),
- mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
- request->process_id, request->pid_name);
+ mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
+ request->process_id, request->pid_name);
mDNS_StopNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
}
@@ -4309,8 +4379,8 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
request->u.pm.NATinfo.clientContext = request;
LogOperation("%3d: DNSServiceNATPortMappingCreate(%X, %u, %u, %d) START PID[%d](%s)", request->sd,
- protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
- request->process_id, request->pid_name);
+ protocol, mDNSVal16(request->u.pm.NATinfo.IntPort), mDNSVal16(request->u.pm.ReqExt), request->u.pm.NATinfo.NATLease,
+ request->process_id, request->pid_name);
err = mDNS_StartNATOperation(&mDNSStorage, &request->u.pm.NATinfo);
if (err) LogMsg("ERROR: mDNS_StartNATOperation: %d", (int)err);
else request->terminate = port_mapping_termination_callback;
@@ -4327,13 +4397,19 @@ mDNSlocal mStatus handle_port_mapping_request(request_state *request)
mDNSlocal void addrinfo_termination_callback(request_state *request)
{
LogOperation("%3d: DNSServiceGetAddrInfo(%##s) STOP PID[%d](%s)", request->sd, request->u.addrinfo.q4.qname.c,
- request->process_id, request->pid_name);
+ request->process_id, request->pid_name);
if (request->u.addrinfo.q4.QuestionContext)
{
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q4);
LogMcastQ(&mDNSStorage, &request->u.addrinfo.q4, request, q_stop);
request->u.addrinfo.q4.QuestionContext = mDNSNULL;
+
+ if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, request->flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_A record");
+ external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q4.qname, kDNSServiceType_A, request->flags);
+ }
}
if (request->u.addrinfo.q4.qnameOrig)
{
@@ -4363,6 +4439,12 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q6);
LogMcastQ(&mDNSStorage, &request->u.addrinfo.q6, request, q_stop);
request->u.addrinfo.q6.QuestionContext = mDNSNULL;
+
+ if (callExternalHelpers(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, request->flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ external_stop_browsing_for_service(request->u.addrinfo.interface_id, &request->u.addrinfo.q6.qname, kDNSServiceType_AAAA, request->flags);
+ }
}
if (request->u.addrinfo.q6.qnameOrig)
{
@@ -4421,13 +4503,14 @@ mDNSlocal void addrinfo_termination_callback(request_state *request)
mDNSlocal mStatus handle_addrinfo_request(request_state *request)
{
char hostname[256];
+ size_t hostnameLen;
domainname d;
mStatus err = 0;
mDNSs32 serviceIndex = -1; // default unscoped value for ServiceID is -1
mDNSInterfaceID InterfaceID;
-
+
DNSServiceFlags flags = get_flags(&request->msgptr, request->msgend);
-
+
mDNSu32 interfaceIndex = get_uint32(&request->msgptr, request->msgend);
if (flags & kDNSServiceFlagsServiceIndex)
@@ -4439,7 +4522,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
serviceIndex = interfaceIndex;
interfaceIndex = 0;
}
-
+
mDNSPlatformMemZero(&request->u.addrinfo, sizeof(request->u.addrinfo));
InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
@@ -4448,6 +4531,9 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
// interface is not currently in our list.
if (interfaceIndex && !InterfaceID)
{
+ if (interfaceIndex > 1)
+ LogMsg("handle_addrinfo_request: interfaceIndex %d is currently inactive requested by client[%d][%s]",
+ interfaceIndex, request->process_id, request->pid_name);
// If it's one of the specially defined inteface index values, just return an error.
if (PreDefinedInterfaceIndex(interfaceIndex))
{
@@ -4455,7 +4541,7 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
return(mStatus_BadParamErr);
}
- // Otherwise, use the specified interface index value and the registration will
+ // Otherwise, use the specified interface index value and the request will
// be applied to that interface when it comes up.
InterfaceID = (mDNSInterfaceID)(uintptr_t)interfaceIndex;
LogInfo("handle_addrinfo_request: query pending for interface index %d", interfaceIndex);
@@ -4500,8 +4586,6 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
request->u.addrinfo.q4.TimeoutQuestion = request->u.addrinfo.q6.TimeoutQuestion = (flags & kDNSServiceFlagsTimeout ) != 0;
request->u.addrinfo.q4.WakeOnResolve = request->u.addrinfo.q6.WakeOnResolve = 0;
request->u.addrinfo.q4.UseBackgroundTrafficClass = request->u.addrinfo.q6.UseBackgroundTrafficClass = (flags & kDNSServiceFlagsBackgroundTrafficClass) != 0;
- request->u.addrinfo.q4.DenyOnCellInterface = request->u.addrinfo.q6.DenyOnCellInterface = (flags & kDNSServiceFlagsDenyCellular) != 0;
- request->u.addrinfo.q4.DenyOnExpInterface = request->u.addrinfo.q6.DenyOnExpInterface = (flags & kDNSServiceFlagsDenyExpensive) != 0;
if ((flags & kDNSServiceFlagsValidate) != 0)
request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = DNSSEC_VALIDATION_SECURE;
else if ((flags & kDNSServiceFlagsValidateOptional) != 0)
@@ -4521,13 +4605,18 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
if (IsLocalDomain(&d))
request->u.addrinfo.q4.ValidationRequired = request->u.addrinfo.q6.ValidationRequired = 0;
+ hostnameLen = strlen(hostname);
+
+ LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)",
+ request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
+
if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv6)
{
request->u.addrinfo.q6.qtype = kDNSServiceType_AAAA;
request->u.addrinfo.q6.SearchListIndex = 0;
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set
- if ((!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
+ if ((!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q6.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && ((hostnameLen == 0) || (hostname[hostnameLen - 1] != '.')) && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
{
request->u.addrinfo.q6.AppendSearchDomains = 1;
request->u.addrinfo.q6.AppendLocalSearchDomains = 1;
@@ -4550,9 +4639,14 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
err = SendAdditionalQuery(&request->u.addrinfo.q6, request, err);
#endif // APPLE_OSX_mDNSResponder
if (!err)
- {
+ {
request->terminate = addrinfo_termination_callback;
LogMcastQ(&mDNSStorage, &request->u.addrinfo.q6, request, q_start);
+ 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);
+ }
}
}
@@ -4565,8 +4659,8 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
// "AlwaysAppendSearchDomains", then we do it for any query which is not fully qualified.
// For DNSSEC questions, append search domains only if kDNSServiceFlagsValidateOptional is set.
- if ((!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
- && hostname[strlen(hostname) - 1] != '.' && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
+ if ((!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_SECURE)) && (!(request->u.addrinfo.q4.ValidationRequired == DNSSEC_VALIDATION_INSECURE))
+ && ((hostnameLen == 0) || (hostname[hostnameLen - 1] != '.')) && (AlwaysAppendSearchDomains || CountLabels(&d) == 1))
{
request->u.addrinfo.q4.AppendSearchDomains = 1;
request->u.addrinfo.q4.AppendLocalSearchDomains = 1;
@@ -4585,11 +4679,17 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
LogMsg("ERROR: mDNS_StartQuery: %d", (int)err);
request->u.addrinfo.q4.QuestionContext = mDNSNULL;
if (request->u.addrinfo.protocol & kDNSServiceProtocol_IPv6)
- {
- // If we started a query for IPv6, we need to cancel it
+ {
+ // If we started a query for IPv6, we need to cancel it
mDNS_StopQuery(&mDNSStorage, &request->u.addrinfo.q6);
request->u.addrinfo.q6.QuestionContext = mDNSNULL;
- }
+
+ if (callExternalHelpers(InterfaceID, &d, flags))
+ {
+ LogInfo("addrinfo_termination_callback: calling external_stop_browsing_for_service() for kDNSServiceType_AAAA record");
+ external_stop_browsing_for_service(InterfaceID, &d, kDNSServiceType_AAAA, flags);
+ }
+ }
}
#if APPLE_OSX_mDNSResponder
err = SendAdditionalQuery(&request->u.addrinfo.q4, request, err);
@@ -4598,10 +4698,14 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
{
request->terminate = addrinfo_termination_callback;
LogMcastQ(&mDNSStorage, &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);
+ }
+ }
}
- LogOperation("%3d: DNSServiceGetAddrInfo(%X, %d, %d, %##s) START PID[%d](%s)", request->sd, flags, interfaceIndex, request->u.addrinfo.protocol, d.c, request->process_id, request->pid_name);
return(err);
}
@@ -4614,10 +4718,10 @@ mDNSlocal mStatus handle_addrinfo_request(request_state *request)
mDNSlocal request_state *NewRequest(void)
{
request_state **p = &all_requests;
- while (*p)
+ while (*p)
p=&(*p)->next;
*p = mallocL("request_state", sizeof(request_state));
- if (!*p)
+ if (!*p)
FatalError("ERROR: malloc");
mDNSPlatformMemZero(*p, sizeof(request_state));
return(*p);
@@ -4758,7 +4862,7 @@ mDNSlocal void read_msg(request_state *req)
get_string(&req->msgptr, req->msgend, ctrl_path, MAX_CTLPATH); // path is first element in message buffer
mDNSPlatformMemZero(&cliaddr, sizeof(cliaddr));
cliaddr.sun_family = AF_LOCAL;
- mDNSPlatformStrCopy(cliaddr.sun_path, ctrl_path);
+ mDNSPlatformStrLCopy(cliaddr.sun_path, ctrl_path, sizeof(cliaddr.sun_path));
// If the error return path UDS name is empty string, that tells us
// that this is a new version of the library that's going to pass us
// the error return path socket via sendmsg/recvmsg
@@ -4771,8 +4875,8 @@ mDNSlocal void read_msg(request_state *req)
#endif
req->errsd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(req->errsd))
- {
+ if (!dnssd_SocketValid(req->errsd))
+ {
my_throttled_perror("ERROR: socket");
req->ts = t_error;
return;
@@ -4838,22 +4942,22 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
for (;;)
{
read_msg(req);
- if (req->ts == t_morecoming)
+ if (req->ts == t_morecoming)
+ return;
+ if (req->ts == t_terminated || req->ts == t_error)
+ {
+ AbortUnlinkAndFree(req);
return;
- if (req->ts == t_terminated || req->ts == t_error)
- {
- AbortUnlinkAndFree(req);
- return;
}
- if (req->ts != t_complete)
- {
- LogMsg("request_callback: req->ts %d != t_complete PID[%d][%s]", req->ts, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
+ if (req->ts != t_complete)
+ {
+ LogMsg("request_callback: req->ts %d != t_complete PID[%d][%s]", req->ts, req->process_id, req->pid_name);
+ AbortUnlinkAndFree(req);
+ return;
}
if (req->hdr.version != VERSION)
{
- LogMsg("request_callback: ERROR: client IPC version %d incompatible with daemon IPC version %d PID[%d][%s]",
+ LogMsg("request_callback: ERROR: client IPC version %d incompatible with daemon IPC version %d PID[%d][%s]",
req->hdr.version, VERSION, req->process_id, req->pid_name);
AbortUnlinkAndFree(req);
return;
@@ -4881,24 +4985,24 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
case send_bpf: // Same as cancel_request below
case cancel_request: min_size = 0; break;
case release_request: min_size += sizeof(mDNSu32) + 3 /* type, type, domain */; break;
- default: LogMsg("request_callback: ERROR: validate_message - unsupported req type: %d PID[%d][%s]",
- req->hdr.op, req->process_id, req->pid_name);
+ default: LogMsg("request_callback: ERROR: validate_message - unsupported req type: %d PID[%d][%s]",
+ req->hdr.op, req->process_id, req->pid_name);
min_size = -1; break;
}
if ((mDNSs32)req->data_bytes < min_size)
- {
- LogMsg("request_callback: Invalid message %d bytes; min for %d is %d PID[%d][%s]",
- req->data_bytes, req->hdr.op, min_size, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
+ {
+ LogMsg("request_callback: Invalid message %d bytes; min for %d is %d PID[%d][%s]",
+ req->data_bytes, req->hdr.op, min_size, req->process_id, req->pid_name);
+ AbortUnlinkAndFree(req);
+ return;
}
if (LightweightOp(req->hdr.op) && !req->terminate)
- {
- LogMsg("request_callback: Reg/Add/Update/Remove %d require existing connection PID[%d][%s]",
- req->hdr.op, req->process_id, req->pid_name);
- AbortUnlinkAndFree(req);
- return;
+ {
+ LogMsg("request_callback: Reg/Add/Update/Remove %d require existing connection PID[%d][%s]",
+ req->hdr.op, req->process_id, req->pid_name);
+ AbortUnlinkAndFree(req);
+ return;
}
// If req->terminate is already set, this means this operation is sharing an existing connection
@@ -4929,6 +5033,7 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
if (req->process_id)
{
newreq->process_id = req->process_id;
+ mDNSPlatformStrLCopy(newreq->pid_name, req->pid_name, (mDNSu32)sizeof(newreq->pid_name));
}
else
{
@@ -4948,7 +5053,7 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
err = mStatus_ServiceNotRunning;
}
else
- {
+ {
switch(req->hdr.op)
{
// These are all operations that have their own first-class request_state object
@@ -4983,7 +5088,7 @@ mDNSlocal void request_callback(int fd, short filter, void *info)
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]",
+ 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;
}
}
@@ -5032,7 +5137,7 @@ mDNSlocal void connect_callback(int fd, short filter, void *info)
if (!dnssd_SocketValid(sd))
{
- if (dnssd_errno != dnssd_EWOULDBLOCK)
+ if (dnssd_errno != dnssd_EWOULDBLOCK)
my_throttled_perror("ERROR: accept");
return;
}
@@ -5063,9 +5168,9 @@ mDNSlocal void connect_callback(int fd, short filter, void *info)
#if APPLE_OSX_mDNSResponder
struct xucred x;
socklen_t xucredlen = sizeof(x);
- if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION)
+ if (getsockopt(sd, 0, LOCAL_PEERCRED, &x, &xucredlen) >= 0 && x.cr_version == XUCRED_VERSION)
request->uid = x.cr_uid; // save the effective userid of the client
- else
+ else
my_perror("ERROR: getsockopt, LOCAL_PEERCRED");
debugf("LOCAL_PEERCRED %d %u %u %d", xucredlen, x.cr_version, x.cr_uid, x.cr_ngroups);
@@ -5110,7 +5215,7 @@ mDNSlocal mDNSBool uds_socket_setup(dnssd_sock_t skt)
return mDNSfalse;
}
else
- {
+ {
LogOperation("%3d: Listening for incoming Unix Domain Socket client requests", skt);
mDNSStorage.uds_listener_skt = skt;
}
@@ -5168,19 +5273,19 @@ mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count)
#else
{
mode_t mask = umask(0);
- unlink(MDNS_UDS_SERVERPATH); // OK if this fails
+ unlink(boundPath); // OK if this fails
laddr.sun_family = AF_LOCAL;
#ifndef NOT_HAVE_SA_LEN
// According to Stevens (section 3.2), there is no portable way to
// determine whether sa_len is defined on a particular platform.
laddr.sun_len = sizeof(struct sockaddr_un);
#endif
- if (strlen(MDNS_UDS_SERVERPATH) >= sizeof(laddr.sun_path))
+ if (strlen(boundPath) >= sizeof(laddr.sun_path))
{
LogMsg("ERROR: MDNS_UDS_SERVERPATH must be < %d characters", (int)sizeof(laddr.sun_path));
goto error;
}
- mDNSPlatformStrCopy(laddr.sun_path, MDNS_UDS_SERVERPATH);
+ mDNSPlatformStrLCopy(laddr.sun_path, boundPath, sizeof(laddr.sun_path));
ret = bind(listenfd, (struct sockaddr *) &laddr, sizeof(laddr));
umask(mask);
if (ret < 0)
@@ -5260,7 +5365,7 @@ mDNSexport int udsserver_exit(void)
// Currently, we're unable to remove /var/run/mdnsd because we've changed to userid "nobody"
// to give up unnecessary privilege, but we need to be root to remove this Unix Domain Socket.
// It would be nice if we could find a solution to this problem
- if (unlink(MDNS_UDS_SERVERPATH))
+ if (unlink(boundPath))
debugf("Unable to remove %s", MDNS_UDS_SERVERPATH);
#endif
}
@@ -5273,9 +5378,9 @@ mDNSexport int udsserver_exit(void)
mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
{
char prefix[16];
- if (req->primary)
+ if (req->primary)
mDNS_snprintf(prefix, sizeof(prefix), " -> ");
- else
+ else
mDNS_snprintf(prefix, sizeof(prefix), "%3d:", req->sd);
if (!req->terminate)
@@ -5287,8 +5392,8 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
request_state *r;
for (p = req->u.reg_recs; p; p=p->next) num_records++;
for (r = req->next; r; r=r->next) if (r->primary == req) num_ops++;
- LogMsgNoIdent("%s DNSServiceCreateConnection: %d registered record%s, %d kDNSServiceFlagsShareConnection operation%s PID[%d](%s)",
- prefix, num_records, num_records != 1 ? "s" : "", num_ops, num_ops != 1 ? "s" : "",
+ LogMsgNoIdent("%s DNSServiceCreateConnection: %d registered record%s, %d kDNSServiceFlagsShareConnection operation%s PID[%d](%s)",
+ prefix, num_records, num_records != 1 ? "s" : "", num_ops, num_ops != 1 ? "s" : "",
req->process_id, req->pid_name);
for (p = req->u.reg_recs; p; p=p->next)
LogMsgNoIdent(" -> DNSServiceRegisterRecord 0x%08X %2d %3d %s PID[%d](%s)",
@@ -5336,7 +5441,7 @@ mDNSlocal void LogClientInfo(mDNS *const m, request_state *req)
mDNSVal16(req->u.pm.NATinfo.ExternalPort),
req->u.pm.NATinfo.NATLease,
req->u.pm.NATinfo.Lifetime,
- req->process_id, req->pid_name);
+ req->process_id, req->pid_name);
else if (req->terminate == addrinfo_termination_callback)
LogMsgNoIdent("%s DNSServiceGetAddrInfo 0x%08X %2d %s%s %##s PID[%d](%s)",
prefix, req->flags, req->interfaceIndex,
@@ -5354,18 +5459,18 @@ mDNSlocal void GetMcastClients(request_state *req)
int num_records = 0, num_ops = 0;
const registered_record_entry *p;
request_state *r;
- for (p = req->u.reg_recs; p; p=p->next)
+ for (p = req->u.reg_recs; p; p=p->next)
num_records++;
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
num_ops++;
for (p = req->u.reg_recs; p; p=p->next)
{
if (!AuthRecord_uDNS(p->rr))
n_mrecords++;
}
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
GetMcastClients(r);
}
else if (req->terminate == regservice_termination_callback)
@@ -5374,7 +5479,7 @@ mDNSlocal void GetMcastClients(request_state *req)
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
{
if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
- n_mrecords++;
+ n_mrecords++;
}
}
else if (req->terminate == browse_termination_callback)
@@ -5417,19 +5522,19 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
int num_records = 0, num_ops = 0;
const registered_record_entry *p;
request_state *r;
- for (p = req->u.reg_recs; p; p=p->next)
+ for (p = req->u.reg_recs; p; p=p->next)
num_records++;
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
num_ops++;
for (p = req->u.reg_recs; p; p=p->next)
{
if (!AuthRecord_uDNS(p->rr))
- LogMcastNoIdent("R: -> DNSServiceRegisterRecord: %##s %s PID[%d](%s)", p->rr->resrec.name->c,
+ LogMcastNoIdent("R: -> DNSServiceRegisterRecord: %##s %s PID[%d](%s)", p->rr->resrec.name->c,
DNSTypeName(p->rr->resrec.rrtype), req->process_id, req->pid_name, i_mcount++);
}
- for (r = req->next; r; r=r->next)
- if (r->primary == req)
+ for (r = req->next; r; r=r->next)
+ if (r->primary == req)
LogMcastClientInfo(r);
}
else if (req->terminate == regservice_termination_callback)
@@ -5437,8 +5542,8 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
service_instance *ptr;
for (ptr = req->u.servicereg.instances; ptr; ptr = ptr->next)
{
- if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
- LogMcastNoIdent("R: DNSServiceRegister: %##s %u/%u PID[%d](%s)", ptr->srs.RR_SRV.resrec.name->c, mDNSVal16(req->u.servicereg.port),
+ if (!AuthRecord_uDNS(&ptr->srs.RR_SRV))
+ LogMcastNoIdent("R: DNSServiceRegister: %##s %u/%u PID[%d](%s)", ptr->srs.RR_SRV.resrec.name->c, mDNSVal16(req->u.servicereg.port),
SRS_PORT(&ptr->srs), req->process_id, req->pid_name, i_mcount++);
}
}
@@ -5461,7 +5566,7 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
else if (req->terminate == queryrecord_termination_callback)
{
if ((mDNSOpaque16IsZero(req->u.queryrecord.q.TargetQID)) && (req->u.queryrecord.q.ThisQInterval > 0))
- LogMcastNoIdent("Q: DNSServiceQueryRecord %##s %s PID[%d](%s)", req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype),
+ LogMcastNoIdent("Q: DNSServiceQueryRecord %##s %s PID[%d](%s)", req->u.queryrecord.q.qname.c, DNSTypeName(req->u.queryrecord.q.qtype),
req->process_id, req->pid_name, i_mcount++);
}
else if (req->terminate == addrinfo_termination_callback)
@@ -5476,7 +5581,7 @@ mDNSlocal void LogMcastClientInfo(request_state *req)
{
return;
}
-
+
}
mDNSlocal char *RecordTypeName(mDNSu8 rtype)
@@ -5549,9 +5654,14 @@ mDNSlocal void LogLocalOnlyAuthRecords(mDNS *const m)
// Print a maximum of 400 records
if (ar->ARType == AuthRecordLocalOnly)
- LogMsgNoIdent(" %s LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ LogMsgNoIdent(" %s LO %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
else if (ar->ARType == AuthRecordP2P)
- LogMsgNoIdent(" %s PP %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ {
+ if (ar->resrec.InterfaceID == mDNSInterface_BLE)
+ LogMsgNoIdent(" %s BLE %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ else
+ LogMsgNoIdent(" %s PP %s", RecordTypeName(ar->resrec.RecordType), ARDisplayString(m, ar));
+ }
}
}
@@ -5573,21 +5683,23 @@ mDNSlocal void LogOneAuthRecord(mDNS *const m, const AuthRecord *ar, mDNSs32 now
char anstr[256];
if (AuthRecord_uDNS(ar))
{
- LogMsgNoIdent("%7d %7d %7d %7d %s %s",
+ LogMsgNoIdent("%7d %7d %7d %-7s %4d %s %s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
(ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond,
ar->expire ? (ar->expire - now) / mDNSPlatformOneSecond : 0,
+ "-U-",
ar->state,
ar->AllowRemoteQuery ? "☠" : " ",
ARDisplayString(m, ar));
}
else
{
- LogMsgNoIdent("%7d %7d %7d %7s %s %s%s",
+ LogMsgNoIdent("%7d %7d %7d %-7s 0x%02X %s %s%s",
ar->ThisAPInterval / mDNSPlatformOneSecond,
ar->AnnounceCount ? (ar->LastAPTime + ar->ThisAPInterval - now) / mDNSPlatformOneSecond : 0,
ar->TimeExpire ? (ar->TimeExpire - now) / mDNSPlatformOneSecond : 0,
ifname ? ifname : "ALL",
+ ar->resrec.RecordType,
ar->AllowRemoteQuery ? "☠" : " ",
ARDisplayString(m, ar), AnonInfoToString(ar->resrec.AnonInfo, anstr, sizeof(anstr)));
}
@@ -5603,7 +5715,7 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
const char *const ifname = InterfaceNameForID(m, ar->resrec.InterfaceID);
if ((ar->WakeUp.HMAC.l[0] != 0) == (proxy != mDNSNULL))
{
- if (showheader) { showheader = mDNSfalse; LogMsgNoIdent(" Int Next Expire State"); }
+ if (showheader) { showheader = mDNSfalse; LogMsgNoIdent(" Int Next Expire if State"); }
if (proxy) (*proxy)++;
if (!mDNSPlatformMemSame(&owner, &ar->WakeUp, sizeof(owner)))
{
@@ -5625,7 +5737,10 @@ mDNSlocal void LogAuthRecords(mDNS *const m, const mDNSs32 now, AuthRecord *Reso
}
else if (ar->ARType == AuthRecordP2P)
{
- LogMsgNoIdent(" PP %s", ARDisplayString(m, ar));
+ if (ar->resrec.InterfaceID == mDNSInterface_BLE)
+ LogMsgNoIdent(" BLE %s", ARDisplayString(m, ar));
+ else
+ LogMsgNoIdent(" PP %s", ARDisplayString(m, ar));
}
else
{
@@ -5731,7 +5846,7 @@ mDNSlocal char *AnonDataToString(const mDNSu8 *ad, int adlen, char *adstr, int a
mDNSexport void LogMDNSStatistics(mDNS *const m)
{
LogMsgNoIdent("--- MDNS Statistics ---");
-
+
LogMsgNoIdent("Name Conflicts %u", m->mDNSStats.NameConflicts);
LogMsgNoIdent("KnownUnique Name Conflicts %u", m->mDNSStats.KnownUniqueNameConflicts);
LogMsgNoIdent("Duplicate Query Suppressions %u", m->mDNSStats.DupQuerySuppressions);
@@ -5849,10 +5964,11 @@ mDNSexport void udsserver_info(mDNS *const m)
LogMsgNoIdent("%lu question%s; %lu active", CacheUsed, CacheUsed > 1 ? "s" : "", CacheActive);
}
- LogMsgNoIdent("----- Local-Only Questions -----");
+ LogMsgNoIdent("----- LocalOnly, P2P Questions -----");
if (!m->LocalOnlyQuestions) LogMsgNoIdent("<None>");
else for (q = m->LocalOnlyQuestions; q; q=q->next)
- LogMsgNoIdent(" %5d %-6s%##s%s",
+ LogMsgNoIdent(" %3s %5d %-6s%##s%s",
+ q->InterfaceID == mDNSInterface_LocalOnly ? "LO ": q->InterfaceID == mDNSInterface_BLE ? "BLE": "P2P",
q->CurrentAnswers, DNSTypeName(q->qtype), q->qname.c, q->DuplicateOf ? " (dup)" : "");
LogMsgNoIdent("---- Active UDS Client Requests ----");
@@ -5872,7 +5988,7 @@ mDNSexport void udsserver_info(mDNS *const m)
foundparent:;
}
}
-
+
LogMsgNoIdent("-------- NAT Traversals --------");
LogMsgNoIdent("ExtAddress %.4a Retry %d Interval %d",
&m->ExtAddress,
@@ -5965,7 +6081,7 @@ foundparent:;
}
}
LogInfo("--- Trust Anchors ---");
- if (!m->TrustAnchors)
+ if (!m->TrustAnchors)
{
LogInfo("<None>");
}
@@ -6017,6 +6133,14 @@ foundparent:;
LogMsgNoIdent("---- Task Scheduling Timers ----");
+#if BONJOUR_ON_DEMAND
+ LogMsgNoIdent("BonjourEnabled %d", m->BonjourEnabled);
+#endif // BONJOUR_ON_DEMAND
+
+#if APPLE_OSX_mDNSResponder
+ LogMsgNoIdent("EnableBLEBasedDiscovery %d", EnableBLEBasedDiscovery);
+#endif // APPLE_OSX_mDNSResponder
+
if (!m->NewQuestions)
LogMsgNoIdent("NewQuestion <NONE>");
else
@@ -6058,6 +6182,11 @@ foundparent:;
LogTimer("m->NextCacheCheck ", m->NextCacheCheck);
LogTimer("m->NextScheduledSPS ", m->NextScheduledSPS);
LogTimer("m->NextScheduledKA ", m->NextScheduledKA);
+
+#if BONJOUR_ON_DEMAND
+ LogTimer("m->NextBonjourDisableTime ", m->NextBonjourDisableTime);
+#endif // BONJOUR_ON_DEMAND
+
LogTimer("m->NextScheduledSPRetry ", m->NextScheduledSPRetry);
LogTimer("m->DelaySleep ", m->DelaySleep);
@@ -6186,15 +6315,16 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
if (r->u.resolve.ReportTime && now - r->u.resolve.ReportTime >= 0)
{
r->u.resolve.ReportTime = 0;
- LogMsgNoIdent("Client application bug PID[%d](%s) : DNSServiceResolve(%##s) active for over two minutes. "
- "This places considerable burden on the network.", r->process_id, r->pid_name, r->u.resolve.qsrv.qname.c);
+ // if client received results and resolve still active
+ if (r->u.resolve.txt && r->u.resolve.srv)
+ LogMsgNoIdent("Client application PID[%d](%s) has received results for DNSServiceResolve(%##s) yet remains active over two minutes.", r->process_id, r->pid_name, r->u.resolve.qsrv.qname.c);
}
// Note: Only primary req's have reply lists, not subordinate req's.
while (r->replies) // Send queued replies
{
transfer_state result;
- if (r->replies->next)
+ if (r->replies->next)
r->replies->rhdr->flags |= dnssd_htonl(kDNSServiceFlagsMoreComing);
result = send_msg(r); // Returns t_morecoming if buffer full because client is not reading
if (result == t_complete)
@@ -6206,7 +6336,12 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
r->unresponsiveness_reports = 0;
continue;
}
- else if (result == t_terminated || result == t_error)
+ else if (result == t_terminated)
+ {
+ LogInfo("%3d: Could not write data to client PID[%d](%s) because connection is terminated by the client", r->sd, r->process_id, r->pid_name);
+ abort_request(r);
+ }
+ else if (result == t_error)
{
LogMsg("%3d: Could not write data to client PID[%d](%s) because of error - aborting connection", r->sd, r->process_id, r->pid_name);
LogClientInfo(&mDNSStorage, r);
@@ -6217,21 +6352,21 @@ mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent)
if (r->replies) // If we failed to send everything, check our time_blocked timer
{
- if (nextevent - now > mDNSPlatformOneSecond)
+ if (nextevent - now > mDNSPlatformOneSecond)
nextevent = now + mDNSPlatformOneSecond;
- if (mDNSStorage.SleepState != SleepState_Awake)
+ if (mDNSStorage.SleepState != SleepState_Awake)
r->time_blocked = 0;
- else if (!r->time_blocked)
+ else if (!r->time_blocked)
r->time_blocked = NonZeroTime(now);
else if (now - r->time_blocked >= 10 * mDNSPlatformOneSecond * (r->unresponsiveness_reports+1))
{
int num = 0;
struct reply_state *x = r->replies;
- while (x)
- {
- num++;
- x=x->next;
+ while (x)
+ {
+ num++;
+ x=x->next;
}
LogMsg("%3d: Could not write data to client PID[%d](%s) after %ld seconds, %d repl%s waiting",
r->sd, r->process_id, r->pid_name, (now - r->time_blocked) / mDNSPlatformOneSecond, num, num == 1 ? "y" : "ies");
@@ -6261,10 +6396,10 @@ struct CompileTimeAssertionChecks_uds_daemon
// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
// other overly-large structures instead of having a pointer to them, can inadvertently
// cause structure sizes (and therefore memory usage) to balloon unreasonably.
- char sizecheck_request_state [(sizeof(request_state) <= 2000) ? 1 : -1];
+ char sizecheck_request_state [(sizeof(request_state) <= 2954) ? 1 : -1];
char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <= 60) ? 1 : -1];
char sizecheck_service_instance [(sizeof(service_instance) <= 6552) ? 1 : -1];
- char sizecheck_browser_t [(sizeof(browser_t) <= 1128) ? 1 : -1];
+ char sizecheck_browser_t [(sizeof(browser_t) <= 1150) ? 1 : -1];
char sizecheck_reply_hdr [(sizeof(reply_hdr) <= 12) ? 1 : -1];
char sizecheck_reply_state [(sizeof(reply_state) <= 64) ? 1 : -1];
};