mDNSlocal mStatus mDNS_RegisterProxyHost(mDNS *m, ProxyHost *p) { char buffer[32]; mDNS_SetupResourceRecord(&p->RR_A, mDNSNULL, mDNSInterface_Any, kDNSType_A, 60, kDNSRecordTypeUnique, AuthRecordAny, HostNameCallback, p); mDNS_SetupResourceRecord(&p->RR_PTR, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 60, kDNSRecordTypeKnownUnique, AuthRecordAny, HostNameCallback, p); p->RR_A.namestorage.c[0] = 0; AppendDomainLabel(&p->RR_A.namestorage, &p->hostlabel); AppendLiteralLabelString(&p->RR_A.namestorage, "local"); // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.", p->ip.b[3], p->ip.b[2], p->ip.b[1], p->ip.b[0]); MakeDomainNameFromDNSNameString(&p->RR_PTR.namestorage, buffer); p->RR_PTR.ForceMCast = mDNStrue; // This PTR points to our dot-local name, so don't ever try to write it into a uDNS server p->RR_A.resrec.rdata->u.ipv4 = p->ip; AssignDomainName(&p->RR_PTR.resrec.rdata->u.name, p->RR_A.resrec.name); mDNS_Register(m, &p->RR_A); mDNS_Register(m, &p->RR_PTR); debugf("Made Proxy Host Records for %##s", p->RR_A.resrec.name->c); return(mStatus_NoError); }
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr) { int len; domainname *name; ResourceRecord *nsec3rr; if (rr->rdlength < MCAST_NSEC3_RDLENGTH) { LogMsg("CopyNSEC3ResourceRecord: rdlength %d smaller than MCAST_NSEC3_RDLENGTH %d", rr->rdlength, MCAST_NSEC3_RDLENGTH); return mDNSNULL; } // Allocate space for the name and the rdata along with the ResourceRecord len = DomainNameLength(rr->name); nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData)); if (!nsec3rr) return mDNSNULL; *nsec3rr = *rr; name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord)); nsec3rr->name = (const domainname *)name; AssignDomainName(name, rr->name); nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len); mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength); si->nsec3RR = nsec3rr; return nsec3rr; }
mDNSlocal OSStatus mDNSResponderSetAvail(mDNS *m, AuthRecord *rr, ServiceRecordSet *sr) { // 1. Initialize required fields of AuthRecord // 2. Set name of subtype PTR record to our special subtype name denoting "available" instances // 3. Set target of subtype PTR record to point to our SRV record (exactly the same as the main service PTR record) // 4. And register it mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 2*3600, kDNSRecordTypeShared, AvailCallback, &availRec2Active); MakeDomainNameFromDNSNameString(rr->resrec.name, "a._sub._raop._tcp.local."); AssignDomainName(&rr->resrec.rdata->u.name, sr->RR_SRV.resrec.name); return(mDNS_Register(m, rr)); }
mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const mDNSu8 *AnonData, int len, mDNSu32 salt) { ResourceRecord *rr; int dlen; domainname *name; // We are just allocating an RData which has StandardAuthRDSize if (StandardAuthRDSize < MCAST_NSEC3_RDLENGTH) { LogMsg("ConstructNSEC3Record: StandardAuthRDSize %d smaller than MCAST_NSEC3_RDLENGTH %d", StandardAuthRDSize, MCAST_NSEC3_RDLENGTH); return mDNSNULL; } dlen = DomainNameLength(service); // Allocate space for the name and RData. rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + dlen + sizeof(RData)); if (!rr) return mDNSNULL; name = (domainname *)((mDNSu8 *)rr + sizeof(ResourceRecord)); rr->RecordType = kDNSRecordTypePacketAuth; rr->InterfaceID = mDNSInterface_Any; rr->name = (const domainname *)name; rr->rrtype = kDNSType_NSEC3; rr->rrclass = kDNSClass_IN; rr->rroriginalttl = kStandardTTL; rr->rDNSServer = mDNSNULL; rr->rdlength = MCAST_NSEC3_RDLENGTH; rr->rdestimate = MCAST_NSEC3_RDLENGTH; rr->rdata = (RData *)((mDNSu8 *)rr->name + dlen); AssignDomainName(name, service); if (!InitializeNSEC3Record(rr, AnonData, len, salt)) { mDNSPlatformMemFree(rr); return mDNSNULL; } return rr; }
mDNSlocal void AddTrustAnchor(mDNS *const m, const domainname *zone, mDNSu16 keytag, mDNSu8 alg, mDNSu8 digestType, int diglen, mDNSu8 *digest) { TrustAnchor *ta, *tmp; mDNSu32 t = (mDNSu32) time(NULL); // Check for duplicates tmp = m->TrustAnchors; while (tmp) { if (SameDomainName(zone, &tmp->zone) && tmp->rds.keyTag == keytag && tmp->rds.alg == alg && tmp->rds.digestType == digestType && !memcmp(tmp->rds.digest, digest, diglen)) { LogMsg("AddTrustAnchors: Found a duplicate"); return; } tmp = tmp->next; } ta = (TrustAnchor *)mDNSPlatformMemAllocate(sizeof(TrustAnchor)); if (!ta) { LogMsg("AddTrustAnchor: malloc failure ta"); return; } ta->rds.keyTag = keytag; ta->rds.alg = alg; ta->rds.digestType = digestType; ta->rds.digest = digest; ta->digestLen = diglen; ta->validFrom = t; ta->validUntil = t + TEST_TA_EXPIRE_INTERVAL; AssignDomainName(&ta->zone, zone); ta->next = mDNSNULL; LinkTrustAnchor(m, ta); }
mDNSlocal void StartInsecureProof(mDNS * const m, DNSSECVerifier *dv) { domainname trigger; DNSSECVerifier *prevdv = mDNSNULL; // Remember the name that triggered the insecure proof AssignDomainName(&trigger, &dv->q.qname); while (dv->parent) { prevdv = dv; dv = dv->parent; } if (prevdv) { prevdv->parent = mDNSNULL; FreeDNSSECVerifier(m, prevdv); } // For Optional DNSSEC, we are opportunistically verifying dnssec. We don't care // if something results in bogus as we still want to deliver results to the // application e.g., CNAME processing results in bogus because the path is broken, // but we still want to follow CNAMEs so that we can deliver the final results to // the application. if (dv->ValidationRequired == DNSSEC_VALIDATION_SECURE_OPTIONAL) { LogDNSSEC("StartInsecureProof: Aborting insecure proof for %##s (%s)", dv->q.qname.c, DNSTypeName(dv->q.qtype)); dv->DVCallback(m, dv, DNSSEC_Bogus); return; } LogDNSSEC("StartInsecureProof for %##s (%s)", dv->q.qname.c, DNSTypeName(dv->q.qtype)); // Don't start the insecure proof again after we finish the one that we start here by // setting InsecureProofDone. dv->InsecureProofDone = 1; ProveInsecure(m, dv, mDNSNULL, &trigger); return; }
DNSServiceErrorType DNSServiceResolve ( DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, const char *regtype, const char *domain, DNSServiceResolveReply callback, void *context /* may be NULL */ ) { mStatus err = mStatus_NoError; const char *errormsg = "Unknown"; domainlabel n; domainname t, d, srv; mDNS_DirectOP_Resolve *x; (void)flags; // Unused (void)interfaceIndex; // Unused // Check parameters if (!name[0] || !MakeDomainLabelFromLiteralString(&n, name )) { errormsg = "Bad Instance Name"; goto badparam; } if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type"; goto badparam; } if (!domain[0] || !MakeDomainNameFromDNSNameString(&d, domain )) { errormsg = "Bad Domain"; goto badparam; } if (!ConstructServiceName(&srv, &n, &t, &d)) { errormsg = "Bad Name"; goto badparam; } // Allocate memory, and handle failure x = (mDNS_DirectOP_Resolve *)mDNSPlatformMemAllocate(sizeof(*x)); if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } // Set up object x->disposefn = DNSServiceResolveDispose; x->callback = callback; x->context = context; x->SRV = mDNSNULL; x->TXT = mDNSNULL; x->qSRV.ThisQInterval = -1; // So that DNSServiceResolveDispose() knows whether to cancel this question x->qSRV.InterfaceID = mDNSInterface_Any; x->qSRV.Target = zeroAddr; AssignDomainName(&x->qSRV.qname, &srv); x->qSRV.qtype = kDNSType_SRV; x->qSRV.qclass = kDNSClass_IN; x->qSRV.LongLived = mDNSfalse; x->qSRV.ExpectUnique = mDNStrue; x->qSRV.ForceMCast = mDNSfalse; x->qSRV.QuestionCallback = FoundServiceInfo; x->qSRV.QuestionContext = x; x->qTXT.ThisQInterval = -1; // So that DNSServiceResolveDispose() knows whether to cancel this question x->qTXT.InterfaceID = mDNSInterface_Any; x->qTXT.Target = zeroAddr; AssignDomainName(&x->qTXT.qname, &srv); x->qTXT.qtype = kDNSType_TXT; x->qTXT.qclass = kDNSClass_IN; x->qTXT.LongLived = mDNSfalse; x->qTXT.ExpectUnique = mDNStrue; x->qTXT.ForceMCast = mDNSfalse; x->qTXT.QuestionCallback = FoundServiceInfo; x->qTXT.QuestionContext = x; err = mDNS_StartQuery(&mDNSStorage, &x->qSRV); if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qSRV"; goto fail; } err = mDNS_StartQuery(&mDNSStorage, &x->qTXT); if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qTXT"; goto fail; } // Succeeded: Wrap up and return *sdRef = (DNSServiceRef)x; return(mStatus_NoError); badparam: err = mStatus_BadParamErr; fail: LogMsg("DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", name, regtype, domain, errormsg, err); return(err); }