#include "dnssd_clientlib.h" #include "DNSCommon.h" #include "mDNSDebug.h" extern mDNS mDNSStorage; int DNSServiceRefSockFD(DNSServiceRef sdRef) { (void)sdRef; // Unused return (0); } DNSServiceErrorType DNSServiceProcessResult(DNSServiceRef sdRef) { (void)sdRef; // Unused return (kDNSServiceErr_NoError); } void DNSServiceRefDeallocate(DNSServiceRef sdRef) { mDNS_DirectOP *op = (mDNS_DirectOP *)sdRef; //LogMsg("DNSServiceRefDeallocate"); if (op->disposefn != NULL) { op->disposefn(op); } } // Domain Enumeration // Not yet implemented, so don't include in stub library // We DO include it in the actual Extension, so that if a later client compiled to use this // is run against this Extension, it will get a reasonable error code instead of just // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link) #if !MDNS_BUILDINGSTUBLIBRARY DNSServiceErrorType DNSServiceEnumerateDomains ( DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceDomainEnumReply callback, void *context /* may be NULL */ ) { (void)sdRef; // Unused (void)flags; // Unused (void)interfaceIndex; // Unused (void)callback; // Unused (void)context; // Unused return (kDNSServiceErr_Unsupported); } #endif // Register Service mDNSlocal void FreeDNSServiceRegistration(mDNS_DirectOP_Register *x) { while (x->s.Extras) { ExtraResourceRecord *extras = x->s.Extras; x->s.Extras = x->s.Extras->next; if (extras->r.resrec.rdata != &extras->r.rdatastorage) { mDNSPlatformMemFree(extras->r.resrec.rdata); } mDNSPlatformMemFree(extras); } if (x->s.RR_TXT.resrec.rdata != &x->s.RR_TXT.rdatastorage) { mDNSPlatformMemFree(x->s.RR_TXT.resrec.rdata); } if (x->s.SubTypes) { mDNSPlatformMemFree(x->s.SubTypes); } mDNSPlatformMemFree(x); } static void DNSServiceRegisterDispose(mDNS_DirectOP *op) { mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register *)op; x->autorename = mDNSfalse; //// If mDNS_DeregisterService() returns mStatus_NoError, that means that the service was found in the list, ////is sending its goodbye packet, and we'll get an mStatus_MemFree message when we can free the memory. ////If mDNS_DeregisterService() returns an error, it means that the service had already been removed from //// the list, so we should go ahead and free the memory right now if (mDNS_DeregisterService(&mDNSStorage, &x->s) != mStatus_NoError) { FreeDNSServiceRegistration(x); } } mDNSlocal void RegCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus result) { mDNS_DirectOP_Register *x = (mDNS_DirectOP_Register *)sr->ServiceContext; domainlabel name; domainname type, dom; char namestr[MAX_DOMAIN_LABEL + 1]; // Unescaped name: up to 63 bytes plus C-string terminating NULL. char typestr[MAX_ESCAPED_DOMAIN_NAME]; char domstr [MAX_ESCAPED_DOMAIN_NAME]; if (!DeconstructServiceName(sr->RR_SRV.resrec.name, &name, &type, &dom)) { return; } if (!ConvertDomainLabelToCString_unescaped(&name, namestr)) { return; } if (!ConvertDomainNameToCString(&type, typestr)) { return; } if (!ConvertDomainNameToCString(&dom, domstr)) { return; } if (result == mStatus_NoError) { if (x->callback) { x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context); } } else if (result == mStatus_NameConflict) { if (x->autoname) { mDNS_RenameAndReregisterService(m, sr, mDNSNULL); } else if (x->callback) { x->callback((DNSServiceRef)x, 0, result, namestr, typestr, domstr, x->context); } } else if (result == mStatus_MemFree) { if (x->autorename) { x->autorename = mDNSfalse; x->name = mDNSStorage.nicelabel; mDNS_RenameAndReregisterService(m, &x->s, &x->name); } else { FreeDNSServiceRegistration(x); } } } DNSServiceErrorType DNSServiceRegister ( DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *name, /* may be NULL */ const char *regtype, const char *domain, /* may be NULL */ const char *host, /* may be NULL */ uint16_t notAnIntPort, uint16_t txtLen, const void *txtRecord, /* may be NULL */ DNSServiceRegisterReply callback, /* may be NULL */ void *context /* may be NULL */ ) { mStatus err = mStatus_NoError; const char *errormsg = "Unknown"; domainlabel n; domainname t, d, h, srv; mDNSIPPort port; unsigned int size = sizeof(RDataBody); AuthRecord *SubTypes = mDNSNULL; mDNSu32 NumSubTypes = 0; mDNS_DirectOP_Register *x; (void)flags; // Unused (void)interfaceIndex; // Unused ////Check parameters if (!name) { name = ""; } if (!name[0]) { n = mDNSStorage.nicelabel; } else if (!MakeDomainLabelFromLiteralString(&n, name)) { errormsg = "Bad Instance Name"; goto badparam; } if (!regtype || !*regtype || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type"; goto badparam; } if (!MakeDomainNameFromDNSNameString(&d, (domain && *domain) ? domain : "local.")) { errormsg = "Bad Domain"; goto badparam; } if (!MakeDomainNameFromDNSNameString(&h, (host && *host) ? host : "")) { errormsg = "Bad Target Host"; goto badparam; } if (!ConstructServiceName(&srv, &n, &t, &d)) { errormsg = "Bad Name"; goto badparam; } port.NotAnInteger = notAnIntPort; //// Allocate memory, and handle failure if (size < txtLen) { size = txtLen; } x = (mDNS_DirectOP_Register *)mDNSPlatformMemAllocate(sizeof(*x) - sizeof(RDataBody) + size); if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } //// Set up object x->disposefn = DNSServiceRegisterDispose; x->callback = callback; x->context = context; x->autoname = (!name[0]); x->autorename = mDNSfalse; x->name = n; x->host = h; //// Do the operation err = mDNS_RegisterService(&mDNSStorage, &x->s, &x->name, &t, &d, // Name, type, domain &x->host, port, // Host and port txtRecord, txtLen, // TXT data, length SubTypes, NumSubTypes, // Subtypes mDNSInterface_Any, // Interface ID RegCallback, x, 0); // Callback, context, flags if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_RegisterService"; goto fail; } ////Succeeded: Wrap up and return *sdRef = (DNSServiceRef)x; return (mStatus_NoError); badparam: err = mStatus_BadParamErr; fail: LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err); return (err); } //************************************************************************************************************* // Add / Update / Remove records from existing Registration // Not yet implemented, so don't include in stub library // We DO include it in the actual Extension, so that if a later client compiled to use this // is run against this Extension, it will get a reasonable error code instead of just // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link) #if !MDNS_BUILDINGSTUBLIBRARY DNSServiceErrorType DNSServiceAddRecord ( DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags, uint16_t rrtype, uint16_t rdlen, const void *rdata, uint32_t ttl ) { (void)sdRef; // Unused (void)RecordRef; // Unused (void)flags; // Unused (void)rrtype; // Unused (void)rdlen; // Unused (void)rdata; // Unused (void)ttl; // Unused return (kDNSServiceErr_Unsupported); } DNSServiceErrorType DNSServiceUpdateRecord ( DNSServiceRef sdRef, DNSRecordRef RecordRef, /* may be NULL */ DNSServiceFlags flags, uint16_t rdlen, const void *rdata, uint32_t ttl ) { (void)sdRef; // Unused (void)RecordRef; // Unused (void)flags; // Unused (void)rdlen; // Unused (void)rdata; // Unused (void)ttl; // Unused return (kDNSServiceErr_Unsupported); } DNSServiceErrorType DNSServiceRemoveRecord ( DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags ) { (void)sdRef; // Unused (void)RecordRef; // Unused (void)flags; // Unused return (kDNSServiceErr_Unsupported); } #endif // Browse for services static void DNSServiceBrowseDispose(mDNS_DirectOP *op) { mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse *)op; ////LogMsg("DNSServiceBrowseDispose"); mDNS_StopBrowse(&mDNSStorage, &x->q); mDNSPlatformMemFree(x); } mDNSlocal void FoundInstance(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord) { DNSServiceFlags flags = AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0; domainlabel name; domainname type, domain; char cname[MAX_DOMAIN_LABEL + 1]; // Unescaped name: up to 63 bytes plus C-string terminating NULL. char ctype[MAX_ESCAPED_DOMAIN_NAME]; char cdom [MAX_ESCAPED_DOMAIN_NAME]; mDNS_DirectOP_Browse *x = (mDNS_DirectOP_Browse *)question->QuestionContext; (void)m; // Unused if (answer->rrtype != kDNSType_PTR) { LogMsg("FoundInstance: Should not be called with rrtype %d (not a PTR record)", answer->rrtype); return; } if (!DeconstructServiceName(&answer->rdata->u.name, &name, &type, &domain)) { LogMsg("FoundInstance: %##s PTR %##s received from network is not valid DNS-SD service pointer", answer->name->c, answer->rdata->u.name.c); return; } ConvertDomainLabelToCString_unescaped(&name, cname); ConvertDomainNameToCString(&type, ctype); ConvertDomainNameToCString(&domain, cdom); if (x->callback) { x->callback((DNSServiceRef)x, flags, 0, 0, cname, ctype, cdom, x->context); } } DNSServiceErrorType DNSServiceBrowse ( DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *regtype, const char *domain, /* may be NULL */ DNSServiceBrowseReply callback, void *context /* may be NULL */ ) { mStatus err = mStatus_NoError; const char *errormsg = "Unknown"; domainname t, d; mDNS_DirectOP_Browse *x; (void)flags; // Unused (void)interfaceIndex; // Unused //Check parameters if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Illegal regtype"; goto badparam; } if (!MakeDomainNameFromDNSNameString(&d, *domain ? domain : "local.")) { errormsg = "Illegal domain"; goto badparam; } ////Allocate memory, and handle failure x = (mDNS_DirectOP_Browse *)mDNSPlatformMemAllocate(sizeof(*x)); if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } ////Set up object x->disposefn = DNSServiceBrowseDispose; x->callback = callback; x->context = context; x->q.QuestionContext = x; ////Do the operation err = mDNS_StartBrowse(&mDNSStorage, &x->q, &t, &d, mDNSInterface_Any, (flags & kDNSServiceFlagsForceMulticast) != 0, FoundInstance, x); if (err) { mDNSPlatformMemFree(x); errormsg = "mDNS_StartBrowse"; goto fail; } ////Succeeded: Wrap up and return *sdRef = (DNSServiceRef)x; return (mStatus_NoError); badparam: err = mStatus_BadParamErr; fail: LogMsg("DNSServiceBrowse(\"%s\", \"%s\") failed: %s (%ld)", regtype, domain, errormsg, err); return (err); } // Resolve Service Info static void DNSServiceResolveDispose(mDNS_DirectOP *op) { mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve *)op; if (x->qSRV.ThisQInterval >= 0) { mDNS_StopQuery(&mDNSStorage, &x->qSRV); } if (x->qTXT.ThisQInterval >= 0) { mDNS_StopQuery(&mDNSStorage, &x->qTXT); } mDNSPlatformMemFree(x); } static void FoundServiceInfo(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord) { mDNS_DirectOP_Resolve *x = (mDNS_DirectOP_Resolve *)question->QuestionContext; (void)m; // Unused if (!AddRecord) { if (answer->rrtype == kDNSType_SRV && x->SRV == answer) { x->SRV = mDNSNULL; } if (answer->rrtype == kDNSType_TXT && x->TXT == answer) { x->TXT = mDNSNULL; } } else { if (answer->rrtype == kDNSType_SRV) { x->SRV = answer; } if (answer->rrtype == kDNSType_TXT) { x->TXT = answer; } if (x->SRV && x->TXT && x->callback) { char fullname[MAX_ESCAPED_DOMAIN_NAME], targethost[MAX_ESCAPED_DOMAIN_NAME]; ConvertDomainNameToCString(answer->name, fullname); ConvertDomainNameToCString(&x->SRV->rdata->u.srv.target, targethost); x->callback((DNSServiceRef)x, 0, 0, kDNSServiceErr_NoError, fullname, targethost, x->SRV->rdata->u.srv.port.NotAnInteger, x->TXT->rdlength, (unsigned char *)x->TXT->rdata->u.txt.c, x->context); } } } 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.ReturnIntermed = mDNSfalse; x->qSRV.SuppressUnusable = mDNSfalse; x->qSRV.SearchListIndex = 0; x->qSRV.AppendSearchDomains = 0; x->qSRV.RetryWithSearchDomains = mDNSfalse; x->qSRV.TimeoutQuestion = 0; x->qSRV.WakeOnResolve = 0; x->qSRV.qnameOrig = mDNSNULL; 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.ReturnIntermed = mDNSfalse; x->qTXT.SuppressUnusable = mDNSfalse; x->qTXT.SearchListIndex = 0; x->qTXT.AppendSearchDomains = 0; x->qTXT.RetryWithSearchDomains = mDNSfalse; x->qTXT.TimeoutQuestion = 0; x->qTXT.WakeOnResolve = 0; x->qTXT.qnameOrig = mDNSNULL; 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); } // Connection-oriented calls // Not yet implemented, so don't include in stub library // We DO include it in the actual Extension, so that if a later client compiled to use this // is run against this Extension, it will get a reasonable error code instead of just // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link) #if !MDNS_BUILDINGSTUBLIBRARY DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef) { (void)sdRef; // Unused return (kDNSServiceErr_Unsupported); } DNSServiceErrorType DNSServiceRegisterRecord ( DNSServiceRef sdRef, DNSRecordRef *RecordRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, DNSServiceRegisterRecordReply callback, void *context /* may be NULL */ ) { (void)sdRef; // Unused (void)RecordRef; // Unused (void)flags; // Unused (void)interfaceIndex; // Unused (void)fullname; // Unused (void)rrtype; // Unused (void)rrclass; // Unused (void)rdlen; // Unused (void)rdata; // Unused (void)ttl; // Unused (void)callback; // Unused (void)context; // Unused return (kDNSServiceErr_Unsupported); } #endif static void DNSServiceQueryRecordDispose(mDNS_DirectOP *op) { mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord *)op; if (x->q.ThisQInterval >= 0) { mDNS_StopQuery(&mDNSStorage, &x->q); } mDNSPlatformMemFree(x); } mDNSlocal void DNSServiceQueryRecordResponse(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord) { mDNS_DirectOP_QueryRecord *x = (mDNS_DirectOP_QueryRecord *)question->QuestionContext; char fullname[MAX_ESCAPED_DOMAIN_NAME]; (void)m; // Unused ConvertDomainNameToCString(answer->name, fullname); x->callback((DNSServiceRef)x, AddRecord ? kDNSServiceFlagsAdd : (DNSServiceFlags)0, 0, kDNSServiceErr_NoError, fullname, answer->rrtype, answer->rrclass, answer->rdlength, answer->rdata->u.data, answer->rroriginalttl, x->context); } DNSServiceErrorType DNSServiceQueryRecord ( DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, const char *fullname, uint16_t rrtype, uint16_t rrclass, DNSServiceQueryRecordReply callback, void *context /* may be NULL */ ) { mStatus err = mStatus_NoError; const char *errormsg = "Unknown"; mDNS_DirectOP_QueryRecord *x; (void)flags; // Unused (void)interfaceIndex; // Unused //// Allocate memory, and handle failure x = (mDNS_DirectOP_QueryRecord *)mDNSPlatformMemAllocate(sizeof(*x)); if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } //// Set up object x->disposefn = DNSServiceQueryRecordDispose; x->callback = callback; x->context = context; x->q.ThisQInterval = -1; // So that DNSServiceResolveDispose() knows whether to cancel this question x->q.InterfaceID = mDNSInterface_Any; x->q.Target = zeroAddr; MakeDomainNameFromDNSNameString(&x->q.qname, fullname); x->q.qtype = rrtype; x->q.qclass = rrclass; x->q.LongLived = (flags & kDNSServiceFlagsLongLivedQuery) != 0; x->q.ExpectUnique = mDNSfalse; x->q.ForceMCast = (flags & kDNSServiceFlagsForceMulticast) != 0; x->q.ReturnIntermed = (flags & kDNSServiceFlagsReturnIntermediates) != 0; x->q.SuppressUnusable = (flags & kDNSServiceFlagsSuppressUnusable) != 0; x->q.SearchListIndex = 0; x->q.AppendSearchDomains = 0; x->q.RetryWithSearchDomains = mDNSfalse; x->q.WakeOnResolve = 0; x->q.qnameOrig = mDNSNULL; x->q.QuestionCallback = DNSServiceQueryRecordResponse; x->q.QuestionContext = x; err = mDNS_StartQuery(&mDNSStorage, &x->q); if (err) { DNSServiceResolveDispose((mDNS_DirectOP *)x); errormsg = "mDNS_StartQuery"; goto fail; } //// Succeeded: Wrap up and return *sdRef = (DNSServiceRef)x; return (mStatus_NoError); fail: LogMsg("DNSServiceQueryRecord(\"%s\", %d, %d) failed: %s (%ld)", fullname, rrtype, rrclass, errormsg, err); return (err); } //static void DNSServiceGetAddrInfoDispose(mDNS_DirectOP *op) //{ // mDNS_DirectOP_GetAddrInfo *x = (mDNS_DirectOP_GetAddrInfo*)op; // if (x->aQuery) DNSServiceRefDeallocate(x->aQuery); // mDNSPlatformMemFree(x); //} // //static void DNSServiceGetAddrInfoResponse( // DNSServiceRef inRef, // DNSServiceFlags inFlags, // uint32_t inInterfaceIndex, // DNSServiceErrorType inErrorCode, // const char * inFullName, // uint16_t inRRType, // uint16_t inRRClass, // uint16_t inRDLen, // const void * inRData, // uint32_t inTTL, // void * inContext ) //{ // mDNS_DirectOP_GetAddrInfo * x = (mDNS_DirectOP_GetAddrInfo*)inContext; // struct sockaddr_in sa4; // // mDNSPlatformMemZero(&sa4, sizeof(sa4)); // if (inErrorCode == kDNSServiceErr_NoError && inRRType == kDNSServiceType_A) // { // sa4.sin_family = AF_INET; // mDNSPlatformMemCopy(&sa4.sin_addr.s_addr, inRData, 4); // } // // x->callback((DNSServiceRef)x, inFlags, inInterfaceIndex, inErrorCode, inFullName, // (const struct sockaddr *) &sa4, inTTL, x->context); //} //DNSServiceErrorType DNSServiceGetAddrInfo( // DNSServiceRef * outRef, // DNSServiceFlags inFlags, // uint32_t inInterfaceIndex, // DNSServiceProtocol inProtocol, // const char * inHostName, // DNSServiceGetAddrInfoReply inCallback, // void * inContext ) //{ // const char * errormsg = "Unknown"; // DNSServiceErrorType err; // mDNS_DirectOP_GetAddrInfo * x; // /// Allocate memory, and handle failure // x = (mDNS_DirectOP_GetAddrInfo *)mDNSPlatformMemAllocate(sizeof(*x)); // if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; } // // Set up object // x->disposefn = DNSServiceGetAddrInfoDispose; // x->callback = inCallback; // x->context = inContext; // x->aQuery = mDNSNULL; // ///Start the query. // (It would probably be more efficient to code this using mDNS_StartQuery directly, //instead of wrapping DNSServiceQueryRecord, which then unnecessarily allocates //more memory and then just calls through to mDNS_StartQuery. -- SC June 2010) // err = DNSServiceQueryRecord(&x->aQuery, inFlags, inInterfaceIndex, inHostName, kDNSServiceType_A, // kDNSServiceClass_IN, DNSServiceGetAddrInfoResponse, x); // if (err) { DNSServiceGetAddrInfoDispose((mDNS_DirectOP*)x); errormsg = "DNSServiceQueryRecord"; goto fail; } // // *outRef = (DNSServiceRef)x; // return(mStatus_NoError); // //fail: // LogMsg("DNSServiceGetAddrInfo(\"%s\", %d) failed: %s (%ld)", inHostName, inProtocol, errormsg, err); // return(err); //} // DNSServiceReconfirmRecord // Not yet implemented, so don't include in stub library // We DO include it in the actual Extension, so that if a later client compiled to use this // is run against this Extension, it will get a reasonable error code instead of just // failing to launch (Strong Link) or calling an unresolved symbol and crashing (Weak Link) #if !MDNS_BUILDINGSTUBLIBRARY DNSServiceErrorType DNSServiceReconfirmRecord ( DNSServiceFlags flags, uint32_t interfaceIndex, const char *fullname, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata ) { (void)flags; // Unused (void)interfaceIndex; // Unused (void)fullname; // Unused (void)rrtype; // Unused (void)rrclass; // Unused (void)rdlen; // Unused (void)rdata; // Unused return (kDNSServiceErr_Unsupported); } #endif