Пример #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);
}
Пример #2
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;
}
Пример #3
0
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;
}
Пример #4
0
STDMETHODIMP CTXTRecord::SetValue(BSTR key, VARIANT value)
{
	std::string			keyUTF8;
	ByteArray			valueArray;
	BOOL				ok;
	DNSServiceErrorType	err;
	HRESULT				hr = S_OK;

	if ( !m_allocated )
	{
		TXTRecordCreate( &m_tref, 0, NULL );
		m_allocated = TRUE;
	}

	ok = BSTRToUTF8( key, keyUTF8 );
	require_action( ok, exit, hr = S_FALSE );

	ok = VariantToByteArray( &value, valueArray );
	require_action( ok, exit, hr = S_FALSE );

	err = TXTRecordSetValue( &m_tref, keyUTF8.c_str(), ( uint8_t ) valueArray.size(), &valueArray[ 0 ] );
	require_action( !err, exit, hr = S_FALSE );

exit:

	return hr;
}
Пример #5
0
int
mdns_register(char *name, char *regtype, int port, char **txt)
{
  struct mdns_service *s;
  DNSServiceErrorType err;
  int i;
  char *eq;

  DPRINTF(E_DBG, L_MDNS, "Adding mDNS service '%s.%s'\n", name, regtype);

  s = calloc(1, sizeof(*s));
  if (!s)
    {
      DPRINTF(E_LOG, L_MDNS, "Out of memory registering service.\n");
      return -1;
    }
  TXTRecordCreate(&(s->txtRecord), 0, NULL);

  for (i = 0; txt && txt[i]; i++)
    {
      if ((eq = strchr(txt[i], '=')))
        {
          *eq = '\0';
          eq++;
          err = TXTRecordSetValue(&(s->txtRecord), txt[i], strlen(eq) * sizeof(char), eq);
          *(--eq) = '=';
          if (err != kDNSServiceErr_NoError)
            {
              DPRINTF(E_LOG, L_MDNS, "Could not set TXT record value\n");
              return mdns_service_free(s);
            }
        }
    }

  s->sdref = mdns_sdref_main;
  err = DNSServiceRegister(&(s->sdref), kDNSServiceFlagsShareConnection, 0,
                           name, regtype, NULL, NULL, htons(port),
                           TXTRecordGetLength(&(s->txtRecord)),
                           TXTRecordGetBytesPtr(&(s->txtRecord)),
                           mdns_register_callback, NULL);

  if (err != kDNSServiceErr_NoError)
    {
      DPRINTF(E_LOG, L_MDNS, "Error registering service '%s.%s'\n",
              name, regtype);
      s->sdref = NULL;
      return mdns_service_free(s);
    }

  s->next = mdns_services;
  mdns_services = s;

  return 0;
}
Пример #6
0
 void createTXTRecord_( TXTRecordRef& record )
 {
     TXTRecordCreate( &record, 0, 0 );
     for( ValueMapCIter i = data_.begin(); i != data_.end(); ++i )
     {
         const std::string& key = i->first;
         const std::string& value = i->second;
         const uint8_t valueSize = value.length() > 255 ?
                                       255 : uint8_t( value.length( ));
         TXTRecordSetValue( &record, key.c_str(), valueSize, value.c_str( ));
     }
 }
Пример #7
0
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);
}
Пример #8
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;
}
Пример #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, __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;
}
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);
}
Пример #11
0
bool YMmDNSServiceSetTXTRecord( YMmDNSServiceRef s_, YMmDNSTxtRecordKeyPair *keyPairs[], size_t nPairs )
{
    __ym_mdns_service_t *s = (__ym_mdns_service_t *)s_;
    
    if ( keyPairs == NULL || nPairs == 0 )
        return false;
    
    size_t idx;
    
    TXTRecordRef *txtRecord = (TXTRecordRef *)YMALLOC(sizeof(TXTRecordRef));
    TXTRecordCreate(txtRecord, 0, NULL);
    for ( idx = 0; idx < nPairs; idx++ ) {
        YMmDNSTxtRecordKeyPair **_keyPairs = (YMmDNSTxtRecordKeyPair **)keyPairs;
        const char *key = YMSTR(_keyPairs[idx]->key);
        const uint8_t *value = _keyPairs[idx]->value;
        uint8_t valueLen = _keyPairs[idx]->valueLen;
        
        TXTRecordSetValue(txtRecord, key, valueLen, value);
    }
    
    s->txtRecord = (uint8_t *)txtRecord;
    
    return true;
}
Пример #12
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;
}
Пример #13
0
static cupsd_txt_t			/* O - TXT record */
dnssdBuildTxtRecord(
    cupsd_printer_t *p,			/* I - Printer information */
    int             for_lpd)		/* I - 1 = LPD, 0 = IPP */
{
  int		i,			/* Looping var */
		count;			/* Count of key/value pairs */
  char		admin_hostname[256],	/* .local hostname for admin page */
		adminurl_str[256],	/* URL for the admin page */
		type_str[32],		/* Type to string buffer */
		state_str[32],		/* State to string buffer */
		rp_str[1024],		/* Queue name string buffer */
		air_str[1024],		/* auth-info-required string buffer */
		*keyvalue[32][2];	/* Table of key/value pairs */
  cupsd_txt_t	txt;			/* TXT record */


 /*
  * Load up the key value pairs...
  */

  count = 0;

  if (!for_lpd || (BrowseLocalProtocols & BROWSE_LPD))
  {
    keyvalue[count  ][0] = "txtvers";
    keyvalue[count++][1] = "1";

    keyvalue[count  ][0] = "qtotal";
    keyvalue[count++][1] = "1";

    keyvalue[count  ][0] = "rp";
    keyvalue[count++][1] = rp_str;
    if (for_lpd)
      strlcpy(rp_str, p->name, sizeof(rp_str));
    else
      snprintf(rp_str, sizeof(rp_str), "%s/%s",
	       (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
	       p->name);

    keyvalue[count  ][0] = "ty";
    keyvalue[count++][1] = p->make_model ? p->make_model : "Unknown";

    if (strstr(DNSSDHostName, ".local"))
      strlcpy(admin_hostname, DNSSDHostName, sizeof(admin_hostname));
    else
      snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.",
               DNSSDHostName);
    httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
#  ifdef HAVE_SSL
		     "https",
#  else
		     "http",
#  endif /* HAVE_SSL */
		     NULL, admin_hostname, DNSSDPort, "/%s/%s",
		     (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
		     p->name);
    keyvalue[count  ][0] = "adminurl";
    keyvalue[count++][1] = adminurl_str;

    if (p->location)
    {
      keyvalue[count  ][0] = "note";
      keyvalue[count++][1] = p->location;
    }

    keyvalue[count  ][0] = "priority";
    keyvalue[count++][1] = for_lpd ? "100" : "0";

    keyvalue[count  ][0] = "product";
    keyvalue[count++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";

    keyvalue[count  ][0] = "pdl";
    keyvalue[count++][1] = p->pdl ? p->pdl : "application/postscript";

    if (get_auth_info_required(p, air_str, sizeof(air_str)))
    {
      keyvalue[count  ][0] = "air";
      keyvalue[count++][1] = air_str;
    }

    keyvalue[count  ][0] = "UUID";
    keyvalue[count++][1] = p->uuid + 9;

  #ifdef HAVE_SSL
    keyvalue[count  ][0] = "TLS";
    keyvalue[count++][1] = "1.2";
  #endif /* HAVE_SSL */

    if (p->type & CUPS_PRINTER_FAX)
    {
      keyvalue[count  ][0] = "Fax";
      keyvalue[count++][1] = "T";
      keyvalue[count  ][0] = "rfo";
      keyvalue[count++][1] = rp_str;
    }

    if (p->type & CUPS_PRINTER_COLOR)
    {
      keyvalue[count  ][0] = "Color";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_DUPLEX)
    {
      keyvalue[count  ][0] = "Duplex";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_STAPLE)
    {
      keyvalue[count  ][0] = "Staple";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_COPIES)
    {
      keyvalue[count  ][0] = "Copies";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_COLLATE)
    {
      keyvalue[count  ][0] = "Collate";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_PUNCH)
    {
      keyvalue[count  ][0] = "Punch";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_BIND)
    {
      keyvalue[count  ][0] = "Bind";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_SORT)
    {
      keyvalue[count  ][0] = "Sort";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F";
    }

    if (p->type & CUPS_PRINTER_MFP)
    {
      keyvalue[count  ][0] = "Scan";
      keyvalue[count++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F";
    }

    snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE);
    snprintf(state_str, sizeof(state_str), "%d", p->state);

    keyvalue[count  ][0] = "printer-state";
    keyvalue[count++][1] = state_str;

    keyvalue[count  ][0] = "printer-type";
    keyvalue[count++][1] = type_str;
  }

 /*
  * Then pack them into a proper txt record...
  */

#  ifdef HAVE_DNSSD
  TXTRecordCreate(&txt, 0, NULL);

  for (i = 0; i < count; i ++)
  {
    size_t len = strlen(keyvalue[i][1]);

    if (len < 256)
      TXTRecordSetValue(&txt, keyvalue[i][0], (uint8_t)len, keyvalue[i][1]);
  }

#  else
  for (i = 0, txt = NULL; i < count; i ++)
    txt = avahi_string_list_add_printf(txt, "%s=%s", keyvalue[i][0],
                                       keyvalue[i][1]);
#  endif /* HAVE_DNSSD */

  return (txt);
}
Пример #14
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;
}
Пример #15
0
int 
player_sd_register(player_sd_t* sd, 
                   const char* name, 
                   player_devaddr_t addr)
{
  DNSServiceErrorType sdErr;
  char recordval[PLAYER_SD_TXT_MAXLEN];
  int i,j;
  player_sd_mdns_t* mdns = (player_sd_mdns_t*)(sd->sdRef);
  player_sd_mdns_dev_t* dev;
  char nameBuf[PLAYER_SD_NAME_MAXLEN];

  // Find a spot for this device
  for(i=0;i<mdns->mdnsDevs_len;i++)
  {
    if(!mdns->mdnsDevs[i].valid)
      break;
  }
  if(i==mdns->mdnsDevs_len)
  {
    // Make the list bigger
    if(!mdns->mdnsDevs_len)
      mdns->mdnsDevs_len = PLAYER_SD_MDNS_DEVS_LEN_INITIAL;
    else
      mdns->mdnsDevs_len *= PLAYER_SD_MDNS_DEVS_LEN_MULTIPLIER;
    mdns->mdnsDevs = 
            (player_sd_mdns_dev_t*)realloc(mdns->mdnsDevs,
                                           (mdns->mdnsDevs_len * 
                                            sizeof(player_sd_mdns_dev_t)));
    assert(mdns->mdnsDevs);
    for(j=i;j<mdns->mdnsDevs_len;j++)
      mdns->mdnsDevs[j].valid = 0;
  }

  dev = mdns->mdnsDevs + i;
  dev->fail = 0;
  memset(dev->sdDev.name,0,sizeof(dev->sdDev.name));
  strncpy(dev->sdDev.name,name,sizeof(dev->sdDev.name)-1);
  memset(dev->sdDev.hostname,0,sizeof(dev->sdDev.hostname));
  packedaddr_to_dottedip(dev->sdDev.hostname,sizeof(dev->sdDev.hostname),
                         addr.host);
  dev->sdDev.robot = addr.robot;
  dev->sdDev.interf = addr.interf;
  dev->sdDev.index = addr.index;
  dev->nameIdx = 1;

  TXTRecordCreate(&(dev->txtRecord),sizeof(dev->txtBuf),dev->txtBuf);
  memset(recordval,0,sizeof(recordval));
  snprintf(recordval, sizeof(recordval), "%s:%u",
           interf_to_str(addr.interf), addr.index);
  if((sdErr = TXTRecordSetValue(&(dev->txtRecord),
                                "device",
                                strlen(recordval),
                                recordval)))
  {
    PLAYER_ERROR1("TXTRecordSetValue returned error: %d", sdErr);
    return(-1);
  }

  memset(nameBuf,0,sizeof(nameBuf));
  strncpy(nameBuf,name,sizeof(nameBuf)-1);
  sdErr = kDNSServiceErr_NameConflict;

  // Avahi can return the kDNSServiceErr_NameConflict immediately.
  while(sdErr == kDNSServiceErr_NameConflict)
  {
    sdErr = DNSServiceRegister(&(dev->regRef), 
                               0,
                               0,
                               nameBuf,
                               PLAYER_SD_SERVICENAME,
                               NULL,
                               NULL,
                               addr.robot,
                               TXTRecordGetLength(&(dev->txtRecord)),
                               TXTRecordGetBytesPtr(&(dev->txtRecord)),
                               registerCB,
                               (void*)dev);

    if(sdErr == kDNSServiceErr_NameConflict)
    {
      // Pick a new name
      memset(nameBuf,0,sizeof(nameBuf));
      snprintf(nameBuf,sizeof(nameBuf),"%s (%d)",
               name,dev->nameIdx++);
    }
  }

  if(sdErr != kDNSServiceErr_NoError)
  {
    PLAYER_ERROR1("DNSServiceRegister returned error: %d", sdErr);
    return(-1);
  }
  else
  {
    dev->valid = 1;
    if(strcmp(nameBuf,name))
      PLAYER_WARN2("Changing service name of %s to %s\n",
                   name,nameBuf);
    PLAYER_MSG1(2,"Registration of %s successful", name);
    return(0);
  }
}
Пример #16
0
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);
}
Пример #17
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);
}
 void initialize() {
     recordPtr = &record;
     TXTRecordCreate(recordPtr, 0, NULL);
 }
Пример #19
0
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;
}
Пример #20
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");
	}
}