diff options
Diffstat (limited to 'mDNSResponder/mDNSShared/uds_daemon.c')
-rw-r--r-- | mDNSResponder/mDNSShared/uds_daemon.c | 683 |
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]; }; |