Beispiel #1
0
void PublicService::publishAsync()
{
    if(d->isRunning())
        stop();
#ifdef HAVE_DNSSD
    if(ServiceBrowser::isAvailable() == ServiceBrowser::Working)
    {
        TXTRecordRef txt;
        TXTRecordCreate(&txt, 0, 0);
        QMap< QString, QString >::ConstIterator itEnd = m_textData.end();
        for(QMap< QString, QString >::ConstIterator it = m_textData.begin(); it != itEnd; ++it)
        {
            QCString value = it.data().utf8();
            if(TXTRecordSetValue(&txt, it.key().utf8(), value.length(), value) != kDNSServiceErr_NoError)
            {
                TXTRecordDeallocate(&txt);
                emit published(false);
                return;
            }
        }
        DNSServiceRef ref;
        if(DNSServiceRegister(&ref, 0, 0, m_serviceName.utf8(), m_type.ascii(), domainToDNS(m_domain), NULL, htons(m_port), TXTRecordGetLength(&txt),
                              TXTRecordGetBytesPtr(&txt), publish_callback, reinterpret_cast< void * >(this))
           == kDNSServiceErr_NoError)
            d->setRef(ref);
        TXTRecordDeallocate(&txt);
    }
#endif
    if(!d->isRunning())
        emit published(false);
}
static int publish_main_service(struct userdata *u) {
    DNSServiceErrorType err;
    TXTRecordRef txt;

    pa_assert(u);

    if (u->main_service) {
        DNSServiceRefDeallocate(u->main_service);
        u->main_service = NULL;
    }

    TXTRecordCreate(&txt, 0, NULL);
    txt_record_server_data(u->core, &txt);

    err = DNSServiceRegister(&u->main_service,
                             0, /* flags */
                             kDNSServiceInterfaceIndexAny,
                             u->service_name,
                             SERVICE_TYPE_SERVER,
                             NULL, /* domain */
                             NULL, /* host */
                             compute_port(u),
                             TXTRecordGetLength(&txt),
                             TXTRecordGetBytesPtr(&txt),
                             NULL, NULL);

    if (err != kDNSServiceErr_NoError) {
        pa_log("%s(): DNSServiceRegister() returned err %d", __func__, err);
        return err;
    }

    TXTRecordDeallocate(&txt);

    return 0;
}
Beispiel #3
0
void CZeroconfMDNS::doStop()
{
  {
    CSingleLock lock(m_data_guard);
    CLog::Log(LOGDEBUG, "ZeroconfMDNS: Shutdown services");
    for(tServiceMap::iterator it = m_services.begin(); it != m_services.end(); ++it)
    {
      DNSServiceRefDeallocate(it->second.serviceRef);
      TXTRecordDeallocate(&it->second.txtRecordRef);
      CLog::Log(LOGDEBUG, "ZeroconfMDNS: Removed service %s", it->first.c_str());
    }
    m_services.clear();
  }
  {
    CSingleLock lock(m_data_guard);
#if defined(TARGET_WINDOWS_STORE)
    CLog::Log(LOGERROR, "ZeroconfMDNS: WSAAsyncSelect not yet supported for TARGET_WINDOWS_STORE");
#else
    WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD( m_service ), g_hWnd, BONJOUR_EVENT, 0 );
#endif //TARGET_WINDOWS

    if (m_service)
      DNSServiceRefDeallocate(m_service);
    m_service = NULL;
  }
}
Beispiel #4
0
    bool announce( const unsigned short port, const std::string& instance )
    {
#ifdef LUNCHBOX_USE_DNSSD
        if( service_ )
            return false;

        TXTRecordRef record;
        createTXTRecord_( record );

        const DNSServiceErrorType error =
            DNSServiceRegister( &service_, 0 /* flags */,
                                0 /* all interfaces */,
                                instance.empty() ? 0 : instance.c_str(),
                                name_.c_str(), 0 /* default domains */,
                                0 /* hostname */, htons( port ),
                                TXTRecordGetLength( &record ),
                                TXTRecordGetBytesPtr( &record ),
                                (DNSServiceRegisterReply)registerCBS_,
                                this );
        TXTRecordDeallocate( &record );

        if( error == kDNSServiceErr_NoError )
        {
            handleEvents_( service_ );
            return service_ != 0;
        }

        LBWARN << "DNSServiceRegister returned: " << error << std::endl;
#endif
        return false;
    }
Beispiel #5
0
int OTAClass::beginArduinoMdnsService(char *device_name, uint16_t port) {

    int ret = -1;

    mdns_buf = (unsigned char *) malloc (DEFAULT_OTA_MDNS_BUF);
    txtRecord = malloc (sizeof(TXTRecordRef));

    do {
        if (mDNSResponderInit() != 0) {
            OTA_PRINTF("Fail to init mDNS service\r\n");
            break;
        }

        TXTRecordCreate((TXTRecordRef *)txtRecord, DEFAULT_OTA_MDNS_BUF, mdns_buf);

        TXTRecordSetValue((TXTRecordRef *)txtRecord, "board",       strlen("ameba_rtl8195a"), "ameba_rtl8195a");
        TXTRecordSetValue((TXTRecordRef *)txtRecord, "auth_upload", strlen("no"),             "no");
        TXTRecordSetValue((TXTRecordRef *)txtRecord, "tcp_check",   strlen("no"),             "no");
        TXTRecordSetValue((TXTRecordRef *)txtRecord, "ssh_upload",  strlen("no"),             "no");

        mdns_service_id = mDNSRegisterService(device_name, "_arduino._tcp", "local", port, (TXTRecordRef *)txtRecord);

        TXTRecordDeallocate((TXTRecordRef *)txtRecord);

        ret = 0;
    } while (0);

    if (ret < 0) {
        OTA_PRINTF("Fail to begin Arduino mDNS service\r\n");
    }

    return ret;
}
Beispiel #6
0
static void
dnssdFreeTxtRecord(cupsd_txt_t *txt)	/* I - TXT record */
{
#  ifdef HAVE_DNSSD
  TXTRecordDeallocate(txt);

#  else /* HAVE_AVAHI */
  avahi_string_list_free(*txt);
  *txt = NULL;
#  endif /* HAVE_DNSSD */
}
Beispiel #7
0
void _YMmDNSServiceFree(YMTypeRef o_)
{
    __ym_mdns_service_t *s = (__ym_mdns_service_t *)o_;
    if ( s->type )
        YMRelease(s->type);
    if ( s->name )
        YMRelease(s->name);
    if ( s->txtRecord ) {
        TXTRecordDeallocate((TXTRecordRef *)s->txtRecord);
        free(s->txtRecord);
    }
}
static void example_mdns_thread(void *param)
{
    DNSServiceRef dnsServiceRef = NULL;
    TXTRecordRef txtRecord;
    unsigned char txt_buf[100];	// use fixed buffer for text record to prevent malloc/free

    // Delay to wait for IP by DHCP
    vTaskDelay(10000);

    printf("\nmDNS Init\n");
    if(mDNSResponderInit() == 0) {
        printf("mDNS Register service\n");
        TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
        TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content"), "text1_content");
        TXTRecordSetValue(&txtRecord, "text2", strlen("text2_content"), "text2_content");
        dnsServiceRef = mDNSRegisterService("ameba", "_service1._tcp", "local", 5000, &txtRecord);
        TXTRecordDeallocate(&txtRecord);
        printf("wait for 30s ... \n");
        vTaskDelay(30*1000);

        printf("mDNS Update service\n");
        TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
        TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content_new"), "text1_content_new");
        mDNSUpdateService(dnsServiceRef, &txtRecord, 0);
        TXTRecordDeallocate(&txtRecord);
        printf("wait for 30s ... \n");
        vTaskDelay(30*1000);

        if(dnsServiceRef)
            mDNSDeregisterService(dnsServiceRef);

        // deregister service before mdns deinit is not necessary
        // mDNS deinit will also deregister all services
        printf("mDNS Deinit\n");
        mDNSResponderDeinit();
    }

    vTaskDelete(NULL);
}
Beispiel #9
0
//methods to implement for concrete implementations
bool CZeroconfWIN::doPublishService(const std::string& fcr_identifier,
                      const std::string& fcr_type,
                      const std::string& fcr_name,
                      unsigned int f_port,
                      std::map<std::string, std::string> txt)
{
  DNSServiceRef netService = NULL;
  TXTRecordRef txtRecord;
  TXTRecordCreate(&txtRecord, 0, NULL);

  CLog::Log(LOGDEBUG, "CZeroconfWIN::doPublishService identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port);

  //add txt records
  if(!txt.empty())
  {
    for(std::map<std::string, std::string>::const_iterator it = txt.begin(); it != txt.end(); ++it)
    {
      CLog::Log(LOGDEBUG, "CZeroconfWIN: key:%s, value:%s",it->first.c_str(),it->second.c_str());
      uint8_t txtLen = (uint8_t)strlen(it->second.c_str());
      TXTRecordSetValue(&txtRecord, it->first.c_str(), txtLen, it->second.c_str());
    }
  }

  DNSServiceErrorType err = DNSServiceRegister(&netService, 0, 0, fcr_name.c_str(), fcr_type.c_str(), NULL, NULL, htons(f_port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), registerCallback, NULL);

  if(err != kDNSServiceErr_ServiceNotRunning)
    DNSServiceProcessResult(netService);
  
  if (err != kDNSServiceErr_NoError)
  {
    // Something went wrong so lets clean up.
    if (netService)
      DNSServiceRefDeallocate(netService);

    CLog::Log(LOGERROR, "CZeroconfWIN::doPublishService CFNetServiceRegister returned (error = %ld)\n", (int) err);
    if(err == kDNSServiceErr_ServiceNotRunning)
    {
      CLog::Log(LOGERROR, "CZeroconfWIN: Zeroconf can't be started probably because Apple's Bonjour Service isn't installed. You can get it by either installing Itunes or Apple's Bonjour Print Service for Windows (http://support.apple.com/kb/DL999)");
      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, "Failed to start zeroconf", "Is Apple's Bonjour Service installed? See log for more info.", 10000, true);
    }
  } 
  else
  {
    CSingleLock lock(m_data_guard);
    m_services.insert(make_pair(fcr_identifier, netService));
  }

  TXTRecordDeallocate(&txtRecord);

  return err == kDNSServiceErr_NoError;
}
void PublicService::publishAsync()
{
	K_D;
	if (d->isRunning()) stop();
	TXTRecordRef txt;
	TXTRecordCreate(&txt,0,0);
	QMap<QString,QByteArray>::ConstIterator itEnd = d->m_textData.end();
	for (QMap<QString,QByteArray>::ConstIterator it = d->m_textData.begin(); it!=itEnd ; ++it) {
		if (TXTRecordSetValue(&txt,it.key().toUtf8(),it.value().length(),it.value())!=kDNSServiceErr_NoError) {
			TXTRecordDeallocate(&txt);
			emit published(false);
			return;
		}
	}
	DNSServiceRef ref;
	QString fullType=d->m_type;
	Q_FOREACH(const QString &subtype, d->m_subtypes) fullType+=','+subtype;
	if (DNSServiceRegister(&ref,0,0,d->m_serviceName.toUtf8(),fullType.toAscii().constData(),domainToDNS(d->m_domain),NULL,
	    htons(d->m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback,
	    reinterpret_cast<void*>(d)) == kDNSServiceErr_NoError) d->setRef(ref);
	TXTRecordDeallocate(&txt);
	if (!d->isRunning()) emit published(false);
}
Beispiel #11
0
static int
mdns_service_free(struct mdns_service *s)
{
  if(! s)
    return -1;

  /* free sdref, then everything else */
  if(s->sdref)
    DNSServiceRefDeallocate(s->sdref);
  TXTRecordDeallocate(&(s->txtRecord));
  free(s);

  return -1;
}
Beispiel #12
0
bool CZeroconfMDNS::doRemoveService(const std::string& fcr_ident)
{
  CSingleLock lock(m_data_guard);
  tServiceMap::iterator it = m_services.find(fcr_ident);
  if(it != m_services.end())
  {
    DNSServiceRefDeallocate(it->second.serviceRef);
    TXTRecordDeallocate(&it->second.txtRecordRef);
    m_services.erase(it);
    CLog::Log(LOGDEBUG, "ZeroconfMDNS: Removed service %s", fcr_ident.c_str());
    return true;
  }
  else
    return false;
}
Beispiel #13
0
//methods to implement for concrete implementations
bool CZeroconfWIN::doPublishService(const std::string& fcr_identifier,
                      const std::string& fcr_type,
                      const std::string& fcr_name,
                      unsigned int f_port,
                      std::map<std::string, std::string> txt)
{
  DNSServiceRef netService = NULL;
  TXTRecordRef txtRecord;
  TXTRecordCreate(&txtRecord, 0, NULL);

  CLog::Log(LOGDEBUG, __FUNCTION__ " identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port);

  //add txt records
  if(!txt.empty())
  {
    for(std::map<std::string, std::string>::const_iterator it = txt.begin(); it != txt.end(); ++it)
    {
      CLog::Log(LOGDEBUG, "ZeroconfWIN: key:%s, value:%s",it->first.c_str(),it->second.c_str());
      uint8_t txtLen = (uint8_t)strlen(it->second.c_str());
      TXTRecordSetValue(&txtRecord, it->first.c_str(), txtLen, it->second.c_str());
    }
  }

  DNSServiceErrorType err = DNSServiceRegister(&netService, 0, 0, fcr_name.c_str(), fcr_type.c_str(), NULL, NULL, htons(f_port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), registerCallback, NULL);
  
  if (err != kDNSServiceErr_NoError)
  {
    // Something went wrong so lets clean up.
    if (netService)
      DNSServiceRefDeallocate(netService);

    CLog::Log(LOGERROR, __FUNCTION__ " DNSServiceRegister returned (error = %ld)", (int) err);
  } 
  else
  {
    err = DNSServiceProcessResult(netService);

    if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, __FUNCTION__ " DNSServiceProcessResult returned (error = %ld)", (int) err);

    CSingleLock lock(m_data_guard);
    m_services.insert(make_pair(fcr_identifier, netService));
  }

  TXTRecordDeallocate(&txtRecord);

  return err == kDNSServiceErr_NoError;
}
Beispiel #14
0
    void updateRecord_()
    {
        if( !service_ )
            return;

        TXTRecordRef record;

        createTXTRecord_( record );
        const DNSServiceErrorType error =
            DNSServiceUpdateRecord( service_, 0, 0,
                                    TXTRecordGetLength( &record ),
                                    TXTRecordGetBytesPtr( &record ), -1 );
        TXTRecordDeallocate( &record );
        if( error != kDNSServiceErr_NoError )
            LBWARN << "DNSServiceUpdateRecord error: " << error << std::endl;
    }
Beispiel #15
0
void CZeroconfMDNS::doStop()
{
  {
    CSingleLock lock(m_data_guard);
    CLog::Log(LOGDEBUG, "ZeroconfMDNS: Shutdown services");
    for(tServiceMap::iterator it = m_services.begin(); it != m_services.end(); ++it)
    {
      DNSServiceRefDeallocate(it->second.serviceRef);
      TXTRecordDeallocate(&it->second.txtRecordRef);
      CLog::Log(LOGDEBUG, "ZeroconfMDNS: Removed service %s", it->first.c_str());
    }
    m_services.clear();
  }
  {
    CSingleLock lock(m_data_guard);

    if (m_service)
      DNSServiceRefDeallocate(m_service);
    m_service = NULL;
  }
}
Beispiel #16
0
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
    const char *r;
    TXTRecordRef ref;
    uint8_t l;
    const void *p;
    char k[256];

    TXTRecordCreate(&ref, 0, NULL);

    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "foo", 7, "lennart");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "waldo", 5, "rocks");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "quux", 9, "the_house");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "yeah", 0, NULL);
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "waldo", 6, "rocked");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordRemoveValue(&ref, "foo");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordRemoveValue(&ref, "waldo");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "kawumm", 6, "bloerb");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "one", 1, "1");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "two", 1, "2");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    TXTRecordSetValue(&ref, "three", 1, "3");
    hexdump(TXTRecordGetBytesPtr(&ref), TXTRecordGetLength(&ref));

    assert(TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "two"));
    assert(!TXTRecordContainsKey(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "four"));

    r = TXTRecordGetValuePtr(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), "kawumm", &l);

    hexdump(r, l);

    assert(TXTRecordGetCount(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref)) == 6);

    TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 2, sizeof(k), k, &l, &p);

    fprintf(stderr, "key=<%s>\n", k);

    hexdump(p, l);

    assert(TXTRecordGetItemAtIndex(TXTRecordGetLength(&ref), TXTRecordGetBytesPtr(&ref), 20, sizeof(k), k, &l, &p) == kDNSServiceErr_Invalid);

    TXTRecordDeallocate(&ref);
}
Beispiel #17
0
/*
 * This function tries to register the AFP DNS
 * SRV service type.
 */
static void register_stuff(const AFPObj *obj) {
    uint                                        port;
    const struct vol                *volume;
    char                                        name[MAXINSTANCENAMELEN+1];
    DNSServiceErrorType         error;
    TXTRecordRef                        txt_adisk;
    TXTRecordRef                        txt_devinfo;
    char                                        tmpname[256];

    // If we had already registered, then we will unregister and re-register
    if(svc_refs) unregister_stuff();

    /* Register our service, prepare the TXT record */
    TXTRecordCreate(&txt_adisk, 0, NULL);
    if( 0 > TXTRecordPrintf(&txt_adisk, "sys", "waMa=0,adVF=0x100") ) {
        LOG ( log_error, logtype_afpd, "Could not create Zeroconf TXTRecord for sys");
        goto fail;
    }

    /* Build AFP volumes list */
    int i = 0;

    for (volume = getvolumes(); volume; volume = volume->v_next) {

        if (convert_string(CH_UCS2, CH_UTF8_MAC, volume->v_u8mname, -1, tmpname, 255) <= 0) {
            LOG ( log_error, logtype_afpd, "Could not set Zeroconf volume name for TimeMachine");
            goto fail;
        }

        if (volume->v_flags & AFPVOL_TM) {
            if (volume->v_uuid) {
                LOG(log_info, logtype_afpd, "Registering volume '%s' with UUID: '%s' for TimeMachine",
                    volume->v_localname, volume->v_uuid);
                if( 0 > TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1,adVU=%s",
                                   tmpname, volume->v_uuid) ) {
                    LOG ( log_error, logtype_afpd, "Could not set Zeroconf TXTRecord for dk%u", i);
                    goto fail;
                }
            } else {
                LOG(log_warning, logtype_afpd, "Registering volume '%s' for TimeMachine. But UUID is invalid.",
                    volume->v_localname);
                if( 0 > TXTRecordKeyPrintf(&txt_adisk, "dk%u", i++, "adVN=%s,adVF=0xa1", tmpname) ) {
                    LOG ( log_error, logtype_afpd, "Could not set Zeroconf TXTRecord for dk%u", i);
                    goto fail;
                }
            }
        }
    }

    /* AFP_DNS_SERVICE_TYPE */
    svc_ref_count = 1;
    if (i) {
        /* ADISK_SERVICE_TYPE */
        svc_ref_count++;
    }
    if (obj->options.mimicmodel) {
        /* DEV_INFO_SERVICE_TYPE */
        svc_ref_count++;
    }

    // Allocate the memory to store our service refs
    svc_refs = calloc(svc_ref_count, sizeof(DNSServiceRef));
    assert(svc_refs);
    svc_ref_count = 0;

    port = atoi(obj->options.port);

    if (convert_string(obj->options.unixcharset,
                       CH_UTF8,
                       obj->options.hostname,
                       -1,
                       name,
                       MAXINSTANCENAMELEN) <= 0) {
        LOG(log_error, logtype_afpd, "Could not set Zeroconf instance name");
        goto fail;
    }

    error = DNSServiceRegister(&svc_refs[svc_ref_count++],
                               0,               // no flags
                               0,               // all network interfaces
                               name,
                               AFP_DNS_SERVICE_TYPE,
                               "",            // default domains
                               NULL,            // default host name
                               htons(port),
                               0,               // length of TXT
                               NULL,            // no TXT
                               RegisterReply,           // callback
                               NULL);       // no context
    if (error != kDNSServiceErr_NoError) {
        LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
            AFP_DNS_SERVICE_TYPE, error);
        goto fail;
    }

    if (i) {
        error = DNSServiceRegister(&svc_refs[svc_ref_count++],
                                   0,               // no flags
                                   0,               // all network interfaces
                                   name,
                                   ADISK_SERVICE_TYPE,
                                   "",            // default domains
                                   NULL,            // default host name
                                   htons(port),
                                   TXTRecordGetLength(&txt_adisk),
                                   TXTRecordGetBytesPtr(&txt_adisk),
                                   RegisterReply,           // callback
                                   NULL);       // no context
        if (error != kDNSServiceErr_NoError) {
            LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
                ADISK_SERVICE_TYPE, error);
            goto fail;
        }
    }

    if (obj->options.mimicmodel) {
        LOG(log_info, logtype_afpd, "Registering server as model '%s'",
            obj->options.mimicmodel);
        TXTRecordCreate(&txt_devinfo, 0, NULL);
        if ( 0 > TXTRecordPrintf(&txt_devinfo, "model", obj->options.mimicmodel) ) {
            LOG ( log_error, logtype_afpd, "Could not create Zeroconf TXTRecord for model");
            goto fail;
        }

        error = DNSServiceRegister(&svc_refs[svc_ref_count++],
                                   0,               // no flags
                                   0,               // all network interfaces
                                   name,
                                   DEV_INFO_SERVICE_TYPE,
                                   "",            // default domains
                                   NULL,            // default host name
                                   /*
                                    * We would probably use port 0 zero, but we can't, from man DNSServiceRegister:
                                    *   "A value of 0 for a port is passed to register placeholder services.
                                    *    Place holder services are not found  when browsing, but other
                                    *    clients cannot register with the same name as the placeholder service."
                                    * We therefor use port 9 which is used by the adisk service type.
                                    */
                                   htons(9),
                                   TXTRecordGetLength(&txt_devinfo),
                                   TXTRecordGetBytesPtr(&txt_devinfo),
                                   RegisterReply,           // callback
                                   NULL);       // no context
        TXTRecordDeallocate(&txt_devinfo);
        if (error != kDNSServiceErr_NoError) {
            LOG(log_error, logtype_afpd, "Failed to add service: %s, error=%d",
                DEV_INFO_SERVICE_TYPE, error);
            goto fail;
        }
    } /* if (config->obj.options.mimicmodel) */

    /*
     * Now we can create the thread that will poll for the results
     * and handle the calling of the callbacks
     */
    if(pthread_create(&poller, NULL, polling_thread, NULL) != 0) {
        LOG(log_error, logtype_afpd, "Unable to start mDNS polling thread");
        goto fail;
    }

fail:
    TXTRecordDeallocate(&txt_adisk);
    return;
}
Beispiel #18
0
TxtRecordRef::~TxtRecordRef() {
    TXTRecordDeallocate( & ref_);
}
 ~scopedTXTRecord() {
     if (recordPtr != NULL) {
         TXTRecordDeallocate(recordPtr);
     }
 }
static int publish_service(struct service *s) {
    int r = -1;
    TXTRecordRef txt;
    DNSServiceErrorType err;
    const char *name = NULL, *t;
    pa_proplist *proplist = NULL;
    pa_sample_spec ss;
    pa_channel_map map;
    char cm[PA_CHANNEL_MAP_SNPRINT_MAX], tmp[64];
    enum service_subtype subtype;

    const char * const subtype_text[] = {
        [SUBTYPE_HARDWARE] = "hardware",
        [SUBTYPE_VIRTUAL] = "virtual",
        [SUBTYPE_MONITOR] = "monitor"
    };

    pa_assert(s);

    if (s->service) {
        DNSServiceRefDeallocate(s->service);
        s->service = NULL;
    }

    TXTRecordCreate(&txt, 0, NULL);

    txt_record_server_data(s->userdata->core, &txt);

    get_service_data(s, &ss, &map, &name, &proplist, &subtype);
    TXTRecordSetValue(&txt, "device", strlen(name), name);

    snprintf(tmp, sizeof(tmp), "%u", ss.rate);
    TXTRecordSetValue(&txt, "rate", strlen(tmp), tmp);

    snprintf(tmp, sizeof(tmp), "%u", ss.channels);
    TXTRecordSetValue(&txt, "channels", strlen(tmp), tmp);

    t = pa_sample_format_to_string(ss.format);
    TXTRecordSetValue(&txt, "format", strlen(t), t);

    t = pa_channel_map_snprint(cm, sizeof(cm), &map);
    TXTRecordSetValue(&txt, "channel_map", strlen(t), t);

    t = subtype_text[subtype];
    TXTRecordSetValue(&txt, "subtype", strlen(t), t);

    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_DESCRIPTION)))
        TXTRecordSetValue(&txt, "description", strlen(t), t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_ICON_NAME)))
        TXTRecordSetValue(&txt, "icon-name", strlen(t), t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_VENDOR_NAME)))
        TXTRecordSetValue(&txt, "vendor-name", strlen(t), t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_PRODUCT_NAME)))
        TXTRecordSetValue(&txt, "product-name", strlen(t), t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_CLASS)))
        TXTRecordSetValue(&txt, "class", strlen(t), t);
    if ((t = pa_proplist_gets(proplist, PA_PROP_DEVICE_FORM_FACTOR)))
        TXTRecordSetValue(&txt, "form-factor", strlen(t), t);

    err = DNSServiceRegister(&s->service,
                             0,         /* flags */
                             kDNSServiceInterfaceIndexAny,
                             s->service_name,
                             pa_sink_isinstance(s->device) ? SERVICE_TYPE_SINK : SERVICE_TYPE_SOURCE,
                             NULL,      /* domain */
                             NULL,      /* host */
                             compute_port(s->userdata),
                             TXTRecordGetLength(&txt),
                             TXTRecordGetBytesPtr(&txt),
                             dns_service_register_reply, s);

    if (err != kDNSServiceErr_NoError) {
        pa_log("DNSServiceRegister() returned err %d", err);
        goto finish;
    }

    pa_log_debug("Successfully registered Bonjour services for >%s<.", s->service_name);
    return 0;

finish:

    /* Remove this service */
    if (r < 0)
        service_free(s);

    TXTRecordDeallocate(&txt);

    return r;
}
Beispiel #21
0
void cmd_mdns(int argc, char **argv)
{
	static DNSServiceRef dnsServiceRef = NULL;
	static char hostname[32];

	if(argc == 1) goto error;

	if(strcmp(argv[1], "init") == 0) {
		WACPersistentConfig_t config;
		WACPlatformReadConfig(&config);
		if((config.name_len > 0) && (config.name_len < 32)) {
			strcpy(hostname, config.name);
		}
		else {
			uint8_t *mac = LwIP_GetMAC(&xnetif[0]);
			sprintf(hostname, "AMEBA%02x%02x%02x", mac[3], mac[4], mac[5]);
		}
		netif_set_hostname(&xnetif[0], hostname);

		if(mDNSResponderInit() == 0)
			printf("mDNS initialized\n");
		else
			printf("mDNS init failed\n");
	}
	else if(strcmp(argv[1], "deinit") == 0) {
		mDNSResponderDeinit();
		printf("mDNS de-initialized\n");
	}
	else if(strcmp(argv[1], "reg") == 0) {
		if(argc != 5) {
			printf("Usage: mdns reg NAME TYPE PORT\n");
			return;
		}

		if(atoi(argv[4]) == 0)
			printf("mDNS service incorrect port\n");

		if(dnsServiceRef) {
			mDNSDeregisterService(dnsServiceRef);
			dnsServiceRef = NULL;
		}

		if((dnsServiceRef = mDNSRegisterService(argv[2], argv[3], "local", atoi(argv[4]), NULL)) != NULL)
			printf("mDNS service %s.%s registered\n", argv[2], argv[3]);
		else
			printf("mDNS service %s.%s register failed\n", argv[2], argv[3]);
	}
	else if(strcmp(argv[1], "dereg") == 0) {
		if(dnsServiceRef) {
			mDNSDeregisterService(dnsServiceRef);
			dnsServiceRef = NULL;
			printf("mDNS service de-registered\n");
		}
		else {
			printf("mDNS no service\n");
		}
	}
	else if(strcmp(argv[1], "update") == 0) {
		if(argc != 5) {
			printf("Usage: mdns update TXT_KEY TXT_VALUE TTL\n");
			return;
		}

		if(dnsServiceRef) {
			TXTRecordRef txtRecord;
			unsigned char txt_buf[100];
			TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
			TXTRecordSetValue(&txtRecord, argv[2], strlen(argv[3]), argv[3]);
			mDNSUpdateService(dnsServiceRef, &txtRecord, atoi(argv[4]));
			TXTRecordDeallocate(&txtRecord);
			printf("mDNS service updated\n");
		}
		else {
			printf("mDNS no service\n");
		}
	}
	// For BCT mDNS manual name change test
	else if(strcmp(argv[1], "name_test") == 0) {
		char *new_name = "New - Bonjour Service Name";
		printf("Rename HAP service to \"%s\"._hap._tcp.local. %s\n", 
		       new_name, (RenameHAPBonjourService(new_name) == 0) ? "success":"fail");
	}
	else {
error:
		printf("Usage: mdns init|deinit|reg|dereg|name_test\n");
	}
}
Beispiel #22
0
//methods to implement for concrete implementations
bool CZeroconfWIN::doPublishService(const std::string& fcr_identifier,
                      const std::string& fcr_type,
                      const std::string& fcr_name,
                      unsigned int f_port,
                      const std::vector<std::pair<std::string, std::string> >& txt)
{
  DNSServiceRef netService = NULL;
  TXTRecordRef txtRecord;
  DNSServiceErrorType err;
  TXTRecordCreate(&txtRecord, 0, NULL);

  if(m_service == NULL)
  {
    err = DNSServiceCreateConnection(&m_service);
    if (err != kDNSServiceErr_NoError)
    {
      CLog::Log(LOGERROR, "ZeroconfWIN: DNSServiceCreateConnection failed with error = %ld", (int) err);
      return false;
    }
    err = WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD( m_service ), g_hWnd, BONJOUR_EVENT, FD_READ | FD_CLOSE );
    if (err != kDNSServiceErr_NoError)
      CLog::Log(LOGERROR, "ZeroconfWIN: WSAAsyncSelect failed with error = %ld", (int) err);
  }

  CLog::Log(LOGDEBUG, "ZeroconfWIN: identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port);

  //add txt records
  if(!txt.empty())
  {
    for(std::vector<std::pair<std::string, std::string> >::const_iterator it = txt.begin(); it != txt.end(); ++it)
    {
      CLog::Log(LOGDEBUG, "ZeroconfWIN: key:%s, value:%s",it->first.c_str(),it->second.c_str());
      uint8_t txtLen = (uint8_t)strlen(it->second.c_str());
      TXTRecordSetValue(&txtRecord, it->first.c_str(), txtLen, it->second.c_str());
    }
  }

  {
    CSingleLock lock(m_data_guard);
    netService = m_service;
    err = DNSServiceRegister(&netService, kDNSServiceFlagsShareConnection, 0, fcr_name.c_str(), fcr_type.c_str(), NULL, NULL, htons(f_port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), registerCallback, NULL);
  }

  if (err != kDNSServiceErr_NoError)
  {
    // Something went wrong so lets clean up.
    if (netService)
      DNSServiceRefDeallocate(netService);

    CLog::Log(LOGERROR, "ZeroconfWIN: DNSServiceRegister returned (error = %ld)", (int) err);
  }
  else
  {
    CSingleLock lock(m_data_guard);
    m_services.insert(make_pair(fcr_identifier, netService));
  }

  TXTRecordDeallocate(&txtRecord);

  return err == kDNSServiceErr_NoError;
}
nsresult
RegisterOperator::Start()
{
  nsresult rv;

  rv = MDNSResponderOperator::Start();
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  uint16_t port;
  if (NS_WARN_IF(NS_FAILED(rv = mServiceInfo->GetPort(&port)))) {
    return rv;
  }
  nsAutoCString type;
  if (NS_WARN_IF(NS_FAILED(rv = mServiceInfo->GetServiceType(type)))) {
    return rv;
  }

  TXTRecordRef txtRecord;
  char buf[TXT_BUFFER_SIZE] = { 0 };
  TXTRecordCreate(&txtRecord, TXT_BUFFER_SIZE, buf);

  nsCOMPtr<nsIPropertyBag2> attributes;
  if (NS_FAILED(rv = mServiceInfo->GetAttributes(getter_AddRefs(attributes)))) {
    LOG_I("register: no attributes");
  } else {
    nsCOMPtr<nsISimpleEnumerator> enumerator;
    if (NS_WARN_IF(NS_FAILED(rv =
        attributes->GetEnumerator(getter_AddRefs(enumerator))))) {
      return rv;
    }

    bool hasMoreElements;
    while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) &&
           hasMoreElements) {
      nsCOMPtr<nsISupports> element;
      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(element))));
      nsCOMPtr<nsIProperty> property = do_QueryInterface(element);
      MOZ_ASSERT(property);

      nsAutoString name;
      nsCOMPtr<nsIVariant> value;
      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(property->GetName(name)));
      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(property->GetValue(getter_AddRefs(value))));

      nsAutoCString str;
      if (NS_WARN_IF(NS_FAILED(value->GetAsACString(str)))) {
        continue;
      }

      TXTRecordSetValue(&txtRecord,
                        /* it's safe because key name is ASCII only. */
                        NS_LossyConvertUTF16toASCII(name).get(),
                        str.Length(),
                        str.get());
    }
  }

  nsAutoCString host;
  nsAutoCString name;
  nsAutoCString domain;

  DNSServiceRef service = nullptr;
  DNSServiceErrorType err =
    DNSServiceRegister(&service,
                       0,
                       0,
                       NS_SUCCEEDED(mServiceInfo->GetServiceName(name)) ?
                         name.get() : nullptr,
                       type.get(),
                       NS_SUCCEEDED(mServiceInfo->GetDomainName(domain)) ?
                         domain.get() : nullptr,
                       NS_SUCCEEDED(mServiceInfo->GetHost(host)) ?
                         host.get() : nullptr,
                       NativeEndian::swapToNetworkOrder(port),
                       TXTRecordGetLength(&txtRecord),
                       TXTRecordGetBytesPtr(&txtRecord),
                       &RegisterReplyRunnable::Reply,
                       this);
  NS_WARN_IF(kDNSServiceErr_NoError != err);

  TXTRecordDeallocate(&txtRecord);

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

  return ResetService(service);
}