bool CZeroconfBrowserOSX::doResolveService(CZeroconfBrowser::ZeroconfService &fr_service, double f_timeout) { bool ret = false; CFStringRef type = CFStringCreateWithCString(NULL, fr_service.GetType().c_str(), kCFStringEncodingUTF8); CFStringRef name = CFStringCreateWithCString(NULL, fr_service.GetName().c_str(), kCFStringEncodingUTF8); CFStringRef domain = CFStringCreateWithCString(NULL, fr_service.GetDomain().c_str(), kCFStringEncodingUTF8); CFNetServiceRef service = CFNetServiceCreate (NULL, domain, type, name, 0); if (CFNetServiceResolveWithTimeout(service, f_timeout, NULL) ) { std::string ip; int port = 0; ret = CopyFirstIPv4Address(service, ip, port); fr_service.SetIP(ip); fr_service.SetPort(port); //get txt-record list fr_service.SetTxtRecords(GetTxtRecords(service)); } CFRelease(type); CFRelease(name); CFRelease(domain); CFRelease(service); return ret; }
void DNSSD_API CZeroconfBrowserWIN::ResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, /* In network byte order */ uint16_t txtLen, const unsigned char *txtRecord, void *context ) { if (errorCode) { CLog::Log(LOGERROR, "ZeroconfBrowserWIN: ResolveCallback failed with error = %ld", (int) errorCode); return; } DNSServiceErrorType err; CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap; CStdString strIP; CZeroconfBrowser::ZeroconfService* service = (CZeroconfBrowser::ZeroconfService*) context; if(!CDNSNameCache::Lookup(hosttarget, strIP)) { CLog::Log(LOGERROR, "ZeroconfBrowserWIN: Could not resolve hostname %s",hosttarget); return; } service->SetIP(strIP); for(uint16_t i = 0; i < TXTRecordGetCount(txtLen, txtRecord); ++i) { char key[256]; uint8_t valueLen; const void *value; std::string strvalue; err = TXTRecordGetItemAtIndex(txtLen, txtRecord,i ,sizeof(key) , key, &valueLen, &value); if(err != kDNSServiceErr_NoError) continue; if(value != NULL && valueLen > 0) strvalue.append((const char *)value, valueLen); recordMap.insert(std::make_pair(key, strvalue)); } service->SetTxtRecords(recordMap); service->SetPort(ntohs(port)); }
bool CZeroconfBrowserAndroid::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout) { jni::CJNINsdServiceInfo service; service.setServiceName(fr_service.GetName()); service.setServiceType(fr_service.GetType()); CZeroconfBrowserAndroidResolve resolver; m_manager.resolveService(service, resolver); if (!resolver.m_resolutionDone.WaitMSec(f_timeout * 1000)) { CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve Timeout error"); return false; } if (resolver.m_errorCode != -1) { CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve returned (error = %ld)", resolver.m_errorCode); return false; } fr_service.SetHostname(resolver.m_retServiceInfo.getHost().getHostName()); fr_service.SetIP(resolver.m_retServiceInfo.getHost().getHostAddress()); fr_service.SetPort(resolver.m_retServiceInfo.getPort()); CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap; jni::CJNISet<jni::jhstring> txtKey = resolver.m_retServiceInfo.getAttributes().keySet(); jni::CJNIIterator<jni::jhstring> it = txtKey.iterator(); while (it.hasNext()) { jni::jhstring k = it.next(); jni::jhbyteArray v = resolver.m_retServiceInfo.getAttributes().get(k); std::string key = jni::jcast<std::string>(k); std::vector<char> vv = jni::jcast<std::vector<char>>(v); std::string value = std::string(vv.begin(), vv.end()); CLog::Log(LOGDEBUG, "ZeroconfBrowserAndroid: TXT record %s = %s (%d)", key.c_str(), value.c_str(), vv.size()); recordMap.insert(std::make_pair(key, value)); } fr_service.SetTxtRecords(recordMap); return (!fr_service.GetIP().empty()); }
void DNSSD_API AddrinfoCallback(DNSServiceRef sdref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { if (errorCode) { CLog::Log(LOGERROR, "ZeroconfBrowserWIN: AddrinfoCallback failed with error = %ld", (int) errorCode); return; } DNSServiceErrorType err; CStdString strIP; CZeroconfBrowser::ZeroconfService* service = (CZeroconfBrowser::ZeroconfService*) context; char addr[256] = ""; if (address && address->sa_family == AF_INET) { const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr; snprintf(addr, sizeof(addr), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]); } strIP = addr; service->SetIP(strIP); }
bool CZeroconfBrowserMDNS::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout) { DNSServiceErrorType err; DNSServiceRef sdRef = NULL; //start resolving m_resolving_service = fr_service; m_resolved_event.Reset(); err = DNSServiceResolve(&sdRef, 0, kDNSServiceInterfaceIndexAny, fr_service.GetName(), fr_service.GetType(), fr_service.GetDomain(), ResolveCallback, this); if( err != kDNSServiceErr_NoError ) { if (sdRef) DNSServiceRefDeallocate(sdRef); CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: DNSServiceResolve returned (error = %ld)", (int) err); return false; } err = DNSServiceProcessResult(sdRef); if (err != kDNSServiceErr_NoError) CLog::Log(LOGERROR, "ZeroconfBrowserMDNS::doResolveService DNSServiceProcessResult returned (error = %ld)", (int) err); #if defined(HAS_MDNS_EMBEDDED) // when using the embedded mdns service the call to DNSServiceProcessResult // above will not block until the resolving was finished - instead we have to // wait for resolve to return or timeout m_resolved_event.WaitMSec(f_timeout * 1000); #endif //HAS_MDNS_EMBEDDED fr_service = m_resolving_service; if (sdRef) DNSServiceRefDeallocate(sdRef); // resolve the hostname if (!fr_service.GetHostname().empty()) { CStdString strIP; // use mdns resolving m_addrinfo_event.Reset(); sdRef = NULL; err = DNSServiceGetAddrInfo(&sdRef, 0, kDNSServiceInterfaceIndexAny, kDNSServiceProtocol_IPv4, fr_service.GetHostname(), GetAddrInfoCallback, this); if (err != kDNSServiceErr_NoError) CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: DNSServiceGetAddrInfo returned (error = %ld)", (int) err); err = DNSServiceProcessResult(sdRef); if (err != kDNSServiceErr_NoError) CLog::Log(LOGERROR, "ZeroconfBrowserMDNS::doResolveService DNSServiceProcessResult returned (error = %ld)", (int) err); #if defined(HAS_MDNS_EMBEDDED) // when using the embedded mdns service the call to DNSServiceProcessResult // above will not block until the resolving was finished - instead we have to // wait for resolve to return or timeout // give it 2 secs for resolving (resolving in mdns is cached and queued // in timeslices off 1 sec m_addrinfo_event.WaitMSec(2000); #endif //HAS_MDNS_EMBEDDED fr_service = m_resolving_service; if (sdRef) DNSServiceRefDeallocate(sdRef); // fall back to our resolver if (fr_service.GetIP().empty()) { CLog::Log(LOGWARNING, "ZeroconfBrowserMDNS: Could not resolve hostname %s falling back to CDNSNameCache", fr_service.GetHostname().c_str()); if (CDNSNameCache::Lookup(fr_service.GetHostname(), strIP)) fr_service.SetIP(strIP); else CLog::Log(LOGERROR, "ZeroconfBrowserMDNS: Could not resolve hostname %s", fr_service.GetHostname().c_str()); } } return (!fr_service.GetIP().empty()); }
void DNSSD_API CZeroconfBrowserWIN::ResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, /* In network byte order */ uint16_t txtLen, const unsigned char *txtRecord, void *context ) { if (errorCode) { CLog::Log(LOGERROR, "ZeroconfBrowserWIN: ResolveCallback failed with error = %ld", (int) errorCode); return; } DNSServiceErrorType err; CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap; CStdString strIP; CZeroconfBrowser::ZeroconfService* service = (CZeroconfBrowser::ZeroconfService*) context; #if defined(__VIDONME_MEDIACENTER__) { DNSServiceErrorType err; DNSServiceRef sdRef = NULL; err = DNSServiceGetAddrInfo(&sdRef, kDNSServiceFlagsReturnIntermediates, kDNSServiceInterfaceIndexAny,kDNSServiceProtocol_IPv4, hosttarget, AddrinfoCallback, service); if( err != kDNSServiceErr_NoError ) { if (sdRef) DNSServiceRefDeallocate(sdRef); CLog::Log(LOGERROR, "ZeroconfBrowserWIN: DNSServiceGetAddrInfo returned (error = %ld)", (int) err); return; } err = DNSServiceProcessResult(sdRef); if (err != kDNSServiceErr_NoError) CLog::Log(LOGERROR, "ZeroconfBrowserWIN::doGetAddrInfoService DNSServiceProcessResult returned (error = %ld)", (int) err); if (sdRef) DNSServiceRefDeallocate(sdRef); } #else if(!CDNSNameCache::Lookup(hosttarget, strIP)) { CLog::Log(LOGERROR, "ZeroconfBrowserWIN: Could not resolve hostname %s",hosttarget); return; } service->SetIP(strIP); #endif for(uint16_t i = 0; i < TXTRecordGetCount(txtLen, txtRecord); ++i) { char key[256]; uint8_t valueLen; const void *value; std::string strvalue; err = TXTRecordGetItemAtIndex(txtLen, txtRecord,i ,sizeof(key) , key, &valueLen, &value); if(err != kDNSServiceErr_NoError) continue; if(value != NULL && valueLen > 0) strvalue.append((const char *)value, valueLen); recordMap.insert(std::make_pair(key, strvalue)); } service->SetTxtRecords(recordMap); service->SetPort(ntohs(port)); }