Пример #1
0
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;
}
nsresult
GetAddrInfoOperator::Start()
{
  nsresult rv;
  if (NS_WARN_IF(NS_FAILED(rv = MDNSResponderOperator::Start()))) {
    return rv;
  }

  nsAutoCString host;
  mServiceInfo->GetHost(host);

  LOG_I("GetAddrInfo: (%s)", host.get());

  DNSServiceRef service = nullptr;
  DNSServiceErrorType err =
    DNSServiceGetAddrInfo(&service,
                          kDNSServiceFlagsForceMulticast,
                          kDNSServiceInterfaceIndexAny,
                          kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6,
                          host.get(),
                          (DNSServiceGetAddrInfoReply)&GetAddrInfoReplyRunnable::Reply,
                          this);

  if (NS_WARN_IF(kDNSServiceErr_NoError != err)) {
    if (mListener) {
      mListener->OnResolveFailed(mServiceInfo, err);
    }
    return NS_ERROR_FAILURE;
  }

  mDeleteProtector = this;
  return ResetService(service);
}
void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
        const char *interfaceName, uint32_t protocol, const char *hostname) {
    if (VDBG) ALOGD("getAddrInfo(%d, %s %d, %s)", requestId, interfaceName, protocol, hostname);
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    if (ref == NULL) {
        ALOGE("request ID %d already in use during getAddrInfo call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during getAddrInfo call", false);
        return;
    }
    DNSServiceFlags nativeFlags = 0;
    int interfaceInt = ifaceNameToI(interfaceName);
    DNSServiceErrorType result = DNSServiceGetAddrInfo(ref, nativeFlags, interfaceInt, protocol,
            hostname, &MDnsSdListenerGetAddrInfoCallback, context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("getAddrInfo request %d got an error from DNSServiceGetAddrInfo %d", requestId,
                result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "getAddrInfo request got an error from DNSServiceGetAddrInfo", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("getAddrInfo successful");
    cli->sendMsg(ResponseCode::CommandOkay, "getAddrInfo started", false);
    return;
}
Пример #4
0
static VALUE
dnssd_service_getaddrinfo(VALUE self, VALUE _flags, VALUE _interface,
    VALUE _protocol, VALUE _host) {
  DNSServiceFlags flags = 0;
  uint32_t interface = 0;
  DNSServiceProtocol protocol = 0;
  const char *host;

  DNSServiceErrorType e;
  DNSServiceRef *client;

  dnssd_utf8_cstr(_host, host);

  protocol = (DNSServiceProtocol)NUM2ULONG(_protocol);

  if (!NIL_P(_flags))
    flags = (DNSServiceFlags)NUM2ULONG(_flags);

  if (!NIL_P(_interface))
    interface = (uint32_t)NUM2ULONG(_interface);

  get(cDNSSDService, self, DNSServiceRef, client);

  e = DNSServiceGetAddrInfo(client, flags, interface, protocol, host,
      dnssd_service_getaddrinfo_reply, (void *)self);

  dnssd_check_error_code(e);

  return self;
}
Handle<Value>
dnsServiceGetAddrInfo(Arguments const& args) {
    HandleScope scope;

    if (argumentCountMismatch(args, 7)) {
        return throwArgumentCountMismatchException(args, 7);
    }

    if ( ! ServiceRef::HasInstance(args[0])) {
        return throwTypeError("argument 1 must be a DNSServiceRef (sdRef)");
    }
    ServiceRef * serviceRef = ObjectWrap::Unwrap<ServiceRef>(args[0]->ToObject());
    if (serviceRef->IsInitialized()) {
        return throwError("DNSServiceRef is already initialized");
    }

    if ( ! args[1]->IsInt32()) {
        return throwError("argument 2 must be an integer (DNSServiceFlags)");
    }
    DNSServiceFlags flags = args[1]->ToInteger()->Int32Value();

    if ( ! args[2]->IsInt32()) {
        return throwTypeError("argument 3 must be an integer (interfaceIndex)");
    }
    uint32_t interfaceIndex = args[2]->ToInteger()->Int32Value();

    if ( ! args[3]->IsInt32()) {
        return throwTypeError("argument 4 must be an integer (DNSServiceProtocol)");
    }
    uint32_t protocol = args[3]->ToInteger()->Int32Value();

    if ( ! args[4]->IsString()) {
        return throwTypeError("argument 5 must be a string (hostname)");
    }
    String::Utf8Value hostname(args[4]->ToString());

    if ( ! args[5]->IsFunction()) {
        return throwTypeError("argument 6 must be a function (callBack)");
    }
    serviceRef->SetCallback(Local<Function>::Cast(args[5]));

    if ( ! args[6]->IsNull() && ! args[6]->IsUndefined()) {
        serviceRef->SetContext(args[6]);
    }

    DNSServiceErrorType error = DNSServiceGetAddrInfo( & serviceRef->GetServiceRef(),
            flags, interfaceIndex, protocol, *hostname, OnAddressInfo, serviceRef);

    if (error != kDNSServiceErr_NoError) {
        return throwMdnsError("dnsServiceGetAddrInfo()", error);
    }
    if ( ! serviceRef->SetSocketFlags()) {
        return throwError("Failed to set socket flags (O_NONBLOCK, FD_CLOEXEC)");
    }

    return Undefined();
}
Пример #6
0
int
lwip_dnssd_gethostbyname(const char *name, ip_addr_t *addr, u8_t addrtype, err_t *err)
{
  DNSServiceErrorType result;
  DNSServiceRef ref;
  struct addr_clbk_msg msg;
  char *p;

  /* @todo: use with IPv6 */
  LWIP_UNUSED_ARG(addrtype);

#if CONSUME_LOCAL_ONLY
  /* check if this is a .local host. If it is, then we consume the query */
  p = strstr(name, LOCAL_DOMAIN);
  if (p == NULL) {
    return 0; /* not consumed */
  }
  p += (sizeof(LOCAL_DOMAIN) - 1);
  /* check to make sure .local isn't a substring (only allow .local\0 or .local.\0) */
  if ((*p != '.' && *p != '\0') ||
      (*p == '.' && *(p + 1) != '\0')) {
    return 0; /* not consumed */
  }
#endif /* CONSUME_LOCAL_ONLY */

  msg.err = sys_sem_new(&msg.sem, 0);
  if (msg.err != ERR_OK) {
    goto query_done;
  }

  msg.err = ERR_TIMEOUT;
  result = DNSServiceGetAddrInfo(&ref, 0, 0, kDNSServiceProtocol_IPv4, name, addr_info_callback, &msg);
  if (result == kDNSServiceErr_NoError) {
    sys_arch_sem_wait(&msg.sem, GETADDR_TIMEOUT_MS);
    DNSServiceRefDeallocate(ref);

    /* We got a response */
    if (msg.err == ERR_OK) {
      struct sockaddr_in* addr_in = (struct sockaddr_in *)&msg.addr;
      if (addr_in->sin_family == AF_INET) {
        inet_addr_to_ip4addr(ip_2_ip4(addr), &addr_in->sin_addr);
      } else {
        /* @todo add IPv6 support */
        msg.err = ERR_VAL;
      }
    }
  }
  sys_sem_free(&msg.sem);

/* Query has been consumed and is finished */
query_done:
*err = msg.err;
return 1;
}
Пример #7
0
static int
mdns_addr_lookup_start(struct mdns_resolver *rs, uint32_t interfaceIndex,
                       const char *hosttarget, uint16_t port, uint16_t txtLen,
                       const unsigned char *txtRecord)
{
  struct mdns_addr_lookup *lu;
  DNSServiceErrorType err;
  char key[256];
  int i;
  uint8_t valueLen;
  const char *value;
  int ret;

  lu = calloc(1, sizeof(*lu));
  if (!lu)
    {
      DPRINTF(E_LOG, L_MDNS, "Out of memory creating address lookup.\n");
      return -1;
    }
  lu->port = port;
  lu->rs = rs;

  for (i=0; TXTRecordGetItemAtIndex(txtLen, txtRecord, i, sizeof(key),
                                    key, &valueLen, (const void **)&value)
         != kDNSServiceErr_Invalid; i++)
    {
      ret = keyval_add_size(&lu->txt_kv, key, value, valueLen);
      if (ret < 0)
        {
          DPRINTF(E_LOG, L_MDNS, "Could not build TXT record keyval\n");
          return mdns_addr_lookup_free(lu);
        }
    }

  lu->sdref = mdns_sdref_main;
  err = DNSServiceGetAddrInfo(&lu->sdref, kDNSServiceFlagsShareConnection,
                              interfaceIndex, rs->mb->protocol, hosttarget,
                              mdns_lookup_callback, lu);
  if (err != kDNSServiceErr_NoError)
    {
      DPRINTF(E_LOG, L_MDNS, "Failed to create service resolver.\n");
      lu->sdref = NULL;
      return mdns_addr_lookup_free(lu);
    }

  /* resolver now owns the lookup */
  lu->next = rs->lookups;
  rs->lookups = lu;

  return 0;
}
Пример #8
0
STDMETHODIMP CDNSSD::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IGetAddrInfoListener *listener, IDNSSDService **service)
{
	CComObject<CDNSSDService>	*	object			= NULL;
	DNSServiceRef					sref			= NULL;
	std::string						hostNameUTF8;
	DNSServiceErrorType				err				= 0;
	HRESULT							hr				= 0;
	BOOL							ok;

	// Initialize
	*service = NULL;

	// Convert BSTR params to utf8
	ok = BSTRToUTF8( hostName, hostNameUTF8 );
	require_action( ok, exit, err = kDNSServiceErr_BadParam );

	try
	{
		object = new CComObject<CDNSSDService>();
	}
	catch ( ... )
	{
		object = NULL;
	}

	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
	hr = object->FinalConstruct();
	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );
	object->AddRef();

	err = DNSServiceGetAddrInfo( &sref, flags, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );
	require_noerr( err, exit );

	object->SetServiceRef( sref );
	object->SetListener( listener );

	err = object->Run();
	require_noerr( err, exit );

	*service = object;

exit:

	if ( err && object )
	{
		object->Release();
	}

	return err;
}
Пример #9
0
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());
}
Пример #10
0
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));
}