static void DNSSD_API KprZeroconfPlatformResolveCallBack(DNSServiceRef resolveRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hostname, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { FskErr err = kFskErrNone; KprZeroconfBrowser self = context; KprZeroconfPlatformBrowser browser = self->platform; KprZeroconfPlatformService resolver = KprZeroconfPlatformServiceFind(browser->services, resolveRef); if (!resolver || (errorCode != kDNSServiceErr_NoError)) { FskInstrumentedItemPrintfDebug(browser, "KprZeroconfPlatformResolveCallBack returned %d\n", errorCode); } else { DNSServiceErrorType error; DNSServiceRef serviceRef; KprZeroconfPlatformService service = NULL; FskInstrumentedItemPrintfDebug(browser, "RESOLVE: %s %s is at %s:%d", self->serviceType, resolver->name, hostname, ntohs(port)); error = DNSServiceGetAddrInfo(&serviceRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, hostname, KprZeroconfPlatformGetAddrInfoCallBack, self); if (error != kDNSServiceErr_NoError) { bailIfError(kFskErrNetworkErr); } bailIfError(KprZeroconfPlatformServiceNew(&service, resolver->owner, serviceRef, resolver->name, ntohs(port))); if (txtLen > 1) { bailIfError(FskMemPtrNewClear(txtLen, &service->txt)); FskStrNCopy(service->txt, (const char*)txtRecord, txtLen); } FskListAppend(&browser->services, service); FskListRemove(&browser->services, resolver); KprZeroconfPlatformServiceDispose(resolver); } bail: return; }
void DNSSD_API KprZeroconfPlatformGetAddrInfoCallBack(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { KprZeroconfBrowser self = context; KprZeroconfPlatformBrowser browser = self->platform; KprZeroconfPlatformService service = KprZeroconfPlatformServiceFind(browser->services, serviceRef); char* serviceType = self->serviceType; if (!self->serviceType) { serviceType = service->owner->name; } if (!service || (errorCode != kDNSServiceErr_NoError)) { FskInstrumentedItemPrintfDebug(browser, "KprZeroconfPlatformResolveCallBack returned %d\n", errorCode); } else { KprZeroconfServiceInfo serviceInfo = NULL; #if TARGET_OS_WIN32 char ip[256]; if (address && address->sa_family == AF_INET) { const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr; snprintf(ip, sizeof(ip), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]); } #else char ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(((struct sockaddr_in *)address)->sin_addr), ip, INET_ADDRSTRLEN); #endif FskInstrumentedItemPrintfDebug(browser, "GETADDRINFO: %s %s is at %s -> %s:%d", self->serviceType, service->name, hostname, ip, service->port); KprZeroconfServiceInfoNew(&serviceInfo, serviceType, service->name, hostname, ip, service->port, service->txt); KprZeroconfBrowserServiceUp(self, serviceInfo); FskListRemove(&browser->services, service); KprZeroconfPlatformServiceDispose(service); } }
void DNSSD_API KprZeroconfPlatformAdvertisementProcess(DNSServiceRef ref, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char* name, const char* type, const char* domain, void* context) { KprZeroconfAdvertisement self = context; if (errorCode != kDNSServiceErr_NoError) { FskInstrumentedItemPrintfDebug((KprZeroconfPlatformAdvertisement)(self->platform), "KprZeroconfPlatformResolveCallBack returned %d\n", errorCode); } else { KprZeroconfServiceInfo serviceInfo = NULL; FskInstrumentedItemPrintfDebug((KprZeroconfPlatformAdvertisement)(self->platform), "Advertisement: %s %s %s", name, type, domain); KprZeroconfServiceInfoNew(&serviceInfo, type, name, NULL, NULL, 0, NULL); KprZeroconfAdvertisementServiceRegistered(self, serviceInfo); } }
FskErr KprZeroconfPlatformAdvertisementStart(KprZeroconfAdvertisement self) { FskErr err = kFskErrNone; char* txt = NULL; UInt32 size = 0, offset = 0, length; KprZeroconfPlatformAdvertisement advertisement = self->platform; if (!advertisement->service) { DNSServiceErrorType error; DNSServiceRef serviceRef; FskAssociativeArrayIterator iterator = FskAssociativeArrayIteratorNew(self->txt); FskInstrumentedItemPrintfDebug(advertisement, "DNSServiceRegister %s %s %d\n", self->serviceName, self->serviceType, self->port); while (iterator) { UInt32 nameLength = FskStrLen(iterator->name); UInt32 valueLength = FskStrLen(iterator->value); length = nameLength + 1 + valueLength; if (length <= 255) { size += length + 1; err = txt ? FskMemPtrRealloc(size + 1, &txt) : FskMemPtrNew(size + 1, &txt); if (err) size -= length + 1; else { txt[offset++] = (char)length; FskStrCopy(txt + offset, iterator->name); offset += nameLength; txt[offset++] = '='; FskStrCopy(txt + offset, iterator->value); offset += valueLength; txt[offset] = 0; } } iterator = FskAssociativeArrayIteratorNext(iterator); } FskAssociativeArrayIteratorDispose(iterator); error = DNSServiceRegister(&serviceRef, 0, 0, self->serviceName, self->serviceType, "", NULL, // use default host name htons(self->port), txt ? FskStrLen(txt) : 0, txt, KprZeroconfPlatformAdvertisementProcess, self); if (error != kDNSServiceErr_NoError) { FskInstrumentedItemPrintfDebug(advertisement, "DNSServiceRegister error %d\n", error); bailIfError(kFskErrNetworkErr); } bailIfError(KprZeroconfPlatformServiceNew(&advertisement->service, NULL, serviceRef, NULL, 0)); } bail: FskMemPtrDispose(txt); return err; }
void KprZeroconfBrowserServiceDown(KprZeroconfBrowser self, KprZeroconfServiceInfo service) { if (!self) self = KprZeroconfBrowserFind(NULL, service->type); if (!self) return; FskInstrumentedItemPrintfDebug(self, "%p - KprZeroconfBrowserServiceDown %s %s - %p %p", self, service->type, service->name, KprShellGetThread(gShell), FskThreadGetCurrent()); if (self->serviceDownCallback) (*self->serviceDownCallback)(self, service); KprZeroconfServiceInfoDispose(service); }
static void DNSSD_API KprZeroconfPlatformWildcardCallback(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* name, const char* type, const char* domain, void* context) { FskErr err = kFskErrNone; KprZeroconfBrowser self = context; KprZeroconfPlatformBrowser browser = self->platform; char* ptr = NULL; char* serviceType = NULL; if (errorCode != kDNSServiceErr_NoError) { FskInstrumentedItemPrintfDebug(browser, "KprZeroconfPlatformWildcardCallback returned %d\n", errorCode); } else if (flags & kDNSServiceFlagsAdd) { char* ptr = FskStrStr(type, "local."); if (ptr) { *ptr = 0; bailIfError(FskMemPtrNew(FskStrLen(name) + FskStrLen(type) + 2, &serviceType)); FskStrCopy(serviceType, name); FskStrCat(serviceType, "."); FskStrCat(serviceType, type); if (!KprZeroconfPlatformServiceFindType(browser->types, serviceType)) { KprZeroconfPlatformService service = NULL; DNSServiceErrorType error; FskInstrumentedItemPrintfDebug(browser, "WILDCARD: %d %s", interfaceIndex, serviceType); error = DNSServiceBrowse(&serviceRef, 0, 0, serviceType, NULL, KprZeroconfPlatformBrowseCallback, self); if (error != kDNSServiceErr_NoError) { bailIfError(kFskErrNetworkErr); } bailIfError(KprZeroconfPlatformServiceNew(&service, NULL, serviceRef, serviceType, 0)); FskListAppend(&browser->types, service); } } } bail: if (ptr) *ptr = 'l'; FskMemPtrDispose(serviceType); return; }
static void DNSSD_API KprZeroconfPlatformBrowseCallback(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char* name, const char* type, const char* domain, void* context) { FskErr err = kFskErrNone; KprZeroconfBrowser self = context; KprZeroconfPlatformBrowser browser = self->platform; char* serviceType = self->serviceType; KprZeroconfPlatformService service = NULL; if (!serviceType) { service = KprZeroconfPlatformServiceFind(browser->types, serviceRef); if (service) serviceType = service->name; } if (!serviceType || (errorCode != kDNSServiceErr_NoError)) { FskInstrumentedItemPrintfDebug(browser, "KprZeroconfPlatformBrowseCallback returned %d\n", errorCode); } else if (flags & kDNSServiceFlagsAdd) { DNSServiceErrorType error; DNSServiceRef resolveRef; KprZeroconfPlatformService resolver = NULL; FskInstrumentedItemPrintfDebug(browser, "ADD: %d %s %s %s", interfaceIndex, name, type, domain); error = DNSServiceResolve(&resolveRef, kDNSServiceFlagsForceMulticast, interfaceIndex, name, type, domain, KprZeroconfPlatformResolveCallBack, self); if (error != kDNSServiceErr_NoError) { bailIfError(kFskErrNetworkErr); } bailIfError(KprZeroconfPlatformServiceNew(&resolver, service, resolveRef, name, 0)); FskListAppend(&browser->services, resolver); } else { KprZeroconfServiceInfo serviceInfo = NULL; KprZeroconfServiceInfoNew(&serviceInfo, type, name, NULL, NULL, 0, NULL); KprZeroconfBrowserServiceDown(self, serviceInfo); FskInstrumentedItemPrintfDebug(browser, "REMOVE: %d %s %s %s", interfaceIndex, name, type, domain); } bail: return; }