Esempio n. 1
0
JNIEXPORT jint JNICALL Java_avahi4j_Address(JNIEnv *e, jobject t, jlong ptr){
	AvahiAddress *address = (AvahiAddress *) (uintptr_t) ptr;

	jstring jaddress;
	jint protocol;

	// get the field IDs for both the address and protocol fields
	if (address_field==NULL){
		jclass cls = (*e)->GetObjectClass(e, t);
		address_field = (*e)->GetFieldID(e, cls, "address", "Ljava/lang/String;");
		if(address_field==NULL){
			THROW_EXCEPTION(e, JNI_EXCP, "Unable to find the address field");
			return 0;
		}
	}

	// set address member
	if(address->proto==AVAHI_PROTO_INET){
		char nice_address[AVAHI_ADDRESS_STR_MAX];
		avahi_address_snprint(nice_address, AVAHI_ADDRESS_STR_MAX, address);
		jaddress = (*e)->NewStringUTF(e,nice_address);
		(*e)->SetObjectField(e, t, address_field, jaddress);
	} else if(address->proto==AVAHI_PROTO_INET6){
		char nice_address[AVAHI_ADDRESS_STR_MAX];
		avahi_address_snprint(nice_address, AVAHI_ADDRESS_STR_MAX, address);
		jaddress = (*e)->NewStringUTF(e,nice_address);
		(*e)->SetObjectField(e, t, address_field, jaddress);
	}

	GET_JAVA_PROTO(address->proto, protocol);

	return protocol;
}
Esempio n. 2
0
/* Write host data to host file */
static int write_hosts(struct daemon_data *d) {
    struct host *h;
    int r = 0;
    assert(d);

    rs_log_info("writing zeroconf data.\n");

    if (generic_lock(d->fd, 1, 1, 1) < 0) {
        rs_log_crit("lock failed: %s\n", strerror(errno));
        return -1;
    }

    if (lseek(d->fd, 0, SEEK_SET) < 0) {
        rs_log_crit("lseek() failed: %s\n", strerror(errno));
        return -1;
    }

    if (ftruncate(d->fd, 0) < 0) {
        rs_log_crit("ftruncate() failed: %s\n", strerror(errno));
        return -1;
    }

    remove_duplicate_services(d);

    for (h = d->hosts; h; h = h->next) {
        char t[256], a[AVAHI_ADDRESS_STR_MAX];

        if (h->resolver)
            /* Not yet fully resolved */
            continue;
	if (h->address.proto == AVAHI_PROTO_INET6)
	    snprintf(t, sizeof(t), "[%s]:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus);
	else
	    snprintf(t, sizeof(t), "%s:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus);

        if (dcc_writex(d->fd, t, strlen(t)) != 0) {
            rs_log_crit("write() failed: %s\n", strerror(errno));
            goto finish;
        }
    }

    r = 0;

finish:

    generic_lock(d->fd, 1, 0, 1);
    return r;

};
Esempio n. 3
0
static void
_resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol,
		  AvahiResolverEvent event, const char *name, const char *type, const char *domain,
		  const char *host_name, const AvahiAddress *a, uint16_t port, AvahiStringList *txt,
		  AvahiLookupResultFlags flags, void *userdata) {

	BonjourBuddy *buddy;
	PurpleAccount *account = userdata;
	AvahiStringList *l;
	size_t size;
	char *key, *value;
	int ret;

	g_return_if_fail(r != NULL);

	switch (event) {
		case AVAHI_RESOLVER_FAILURE:
			purple_debug_error("bonjour", "_resolve_callback - Failure: %s\n",
				avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
			avahi_service_resolver_free(r);
			break;
		case AVAHI_RESOLVER_FOUND:
			/* create a buddy record */
			buddy = bonjour_buddy_new(name, account);

			((AvahiBuddyImplData *)buddy->mdns_impl_data)->resolver = r;

			/* Get the ip as a string */
			buddy->ip = g_malloc(AVAHI_ADDRESS_STR_MAX);
			avahi_address_snprint(buddy->ip, AVAHI_ADDRESS_STR_MAX, a);

			buddy->port_p2pj = port;

			/* Obtain the parameters from the text_record */
			clear_bonjour_buddy_values(buddy);
			l = txt;
			while (l != NULL) {
				ret = avahi_string_list_get_pair(l, &key, &value, &size);
				l = l->next;
				if (ret < 0)
					continue;
				set_bonjour_buddy_value(buddy, key, value, size);
				/* TODO: Since we're using the glib allocator, I think we
				 * can use the values instead of re-copying them */
				avahi_free(key);
				avahi_free(value);
			}

			if (!bonjour_buddy_check(buddy))
				bonjour_buddy_delete(buddy);
			else
				/* Add or update the buddy in our buddy list */
				bonjour_buddy_add_to_purple(buddy);

			break;
		default:
			purple_debug_info("bonjour", "Unrecognized Service Resolver event: %d.\n", event);
	}

}
Esempio n. 4
0
/**
* resolver: The avahi resolver
* iface: The avahi interface
* proto: The avahi protocol
* event: the avahi event
* name: name of the service
* type: must be HKP_SERVICE_TYPE
* domain: ignored
* host_name: ignored
* address: address of the service
* port: port of the service
* txt: ignored
* flags:
* data: userdata
*
* Resolves the avahi callback (AvahiServiceResolverCallback)
*
**/
static void 
resolve_callback (AvahiServiceResolver *resolver, AvahiIfIndex iface, AvahiProtocol proto, 
                  AvahiResolverEvent event, const char *name, const char *type, const char *domain,
                  const char *host_name, const AvahiAddress *address, uint16_t port, 
                  AvahiStringList *txt, AvahiLookupResultFlags flags, void *data)
{
    BastileServiceDiscovery *ssd = BASTILE_SERVICE_DISCOVERY (data);
    gchar *service_name;
    gchar *service_uri;
    gchar *ipname;
    
    g_assert (BASTILE_IS_SERVICE_DISCOVERY (ssd));


    switch(event) {
    case AVAHI_RESOLVER_FAILURE:
        g_warning ("couldn't resolve service '%s': %s", name, 
                   avahi_strerror (avahi_client_errno (ssd->priv->client)));
        break;
    
    
    case AVAHI_RESOLVER_FOUND:
        
        /* Make sure it's our type ... */
        /* XXX Is the service always guaranteed to be ascii? */
        if (g_ascii_strcasecmp (HKP_SERVICE_TYPE, type) != 0)
            break;
        
#ifndef DISCOVER_THIS_HOST
        /* And that it's local */
        if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
            break;
#endif
        
        ipname = g_new0(gchar, AVAHI_ADDRESS_STR_MAX);
        avahi_address_snprint (ipname, AVAHI_ADDRESS_STR_MAX, address);
        
        service_uri = g_strdup_printf ("hkp://%s:%d", ipname, (int)port);
        service_name = g_strdup (name);
        
        g_hash_table_replace (ssd->services, service_name, service_uri);
        g_signal_emit (ssd, signals[ADDED], 0, service_name);
    
        /* Add it to the context */
        if (!bastile_context_remote_source (SCTX_APP (), service_uri)) {
            BastileServerSource *ssrc = bastile_server_source_new (service_uri);
            g_return_if_fail (ssrc != NULL);
            bastile_context_add_source (SCTX_APP (), BASTILE_SOURCE (ssrc));
        }
    
        DEBUG_DNSSD (("DNS-SD added: %s %s\n", service_name, service_uri));
        break;
        
    default:
        break;
    };

    /* One result is enough for us */
    avahi_service_resolver_free (resolver);
}
Esempio n. 5
0
void Browser::updateService(const char *name,
                            const char *host_name,
                            const AvahiAddress *a,
                            uint16_t port,
                            AvahiStringList *txt) {
    // Find the service in our list
    Browser::Service s(name);
    auto it = std::lower_bound(services_.begin(), services_.end(), s);
    if (it == services_.end() || it->service_name != name) {
        return;
    }
    Browser::Service &svc = *it;
    auto index = createIndex(it - services_.begin(), 0);

    svc.host_name = host_name;
    char addr[AVAHI_ADDRESS_STR_MAX];
    avahi_address_snprint(addr, sizeof(addr), a);
    svc.address = addr;
    svc.port = port;
    svc.txt.clear();
    for (auto item = txt; item != nullptr; item = avahi_string_list_get_next(item)) {
        // TODO: this probably isn't actually UTF-8
        svc.txt.push_front(
            QString::fromUtf8(
                reinterpret_cast<const char*>(avahi_string_list_get_text(item)),
                avahi_string_list_get_size(item)));
    }
    Q_EMIT dataChanged(index, index);
}
Esempio n. 6
0
static void sib_controller_resolver_found( GaServiceResolver *context,
					   gint interface,
					   gint protocol,
					   gchar *name,
					   gchar *type,
					   gchar *domain,
					   gchar *host_name,
					   AvahiAddress *avahi_address,
					   gint port,
					   AvahiStringList *txt,
					   gint flags,
					   gpointer userdata)
{
  whiteboard_log_debug_fb();
  SIBController *self = (SIBController *)userdata;
  g_return_if_fail( self!= NULL);
  SIBServerData *ssdata = NULL;

  ssdata = sib_controller_get_service(self, (guchar *)name);
  if(ssdata)
    {
      
      ssdata->ip = g_new0(gchar, AVAHI_ADDRESS_STR_MAX);
      avahi_address_snprint(ssdata->ip, AVAHI_ADDRESS_STR_MAX*sizeof(gchar), avahi_address);
      ssdata->name = (guchar *)g_strdup(host_name);
      ssdata->port = port;
      whiteboard_log_debug("Service %s resolved: %s, %d\n", name, ssdata->ip, port);
      self->listener( SIBDeviceStatusAdded, ssdata, self->listener_data );
    }
  whiteboard_log_debug_fe();
}
Esempio n. 7
0
void CZeroconfBrowserAvahi::resolveCallback(
  AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event,
  const char *name, const char *type, const char *domain, const char *host_name,
  const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata )
{
  assert ( r );
  assert ( userdata );
  CZeroconfBrowserAvahi* p_instance = static_cast<CZeroconfBrowserAvahi*> ( userdata );
  switch ( event )
  {
    case AVAHI_RESOLVER_FAILURE:
      CLog::Log ( LOGERROR, "CZeroconfBrowserAvahi::resolveCallback Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror ( avahi_client_errno ( avahi_service_resolver_get_client ( r ) ) ) );
      break;
    case AVAHI_RESOLVER_FOUND:
    {
      char a[AVAHI_ADDRESS_STR_MAX];
      CLog::Log ( LOGDEBUG, "CZeroconfBrowserAvahi::resolveCallback resolved service '%s' of type '%s' in domain '%s':\n", name, type, domain );

      avahi_address_snprint ( a, sizeof ( a ), address );
      p_instance->m_resolving_service.SetIP(a);
      p_instance->m_resolving_service.SetPort(port);
      //get txt-record list
      p_instance->m_resolving_service.SetTxtRecords(GetTxtRecords(txt));
      break;
    }
  }
  avahi_service_resolver_free ( r );
  p_instance->m_resolved_event.Set();
}
Esempio n. 8
0
    void Browser::resolve_callback(AvahiServiceResolver *r,
				   AvahiIfIndex,
				   AvahiProtocol,
				   AvahiResolverEvent event,
				   const char *name,
				   const char *type,
				   const char *,
				   const char *host_name,
				   const AvahiAddress *address,
				   uint16_t port,
				   AvahiStringList *txt,
				   AvahiLookupResultFlags,
				   void *data)
    {
	assert(data);
	Browser *browser = static_cast<Browser *>(data);
	assert(r);

	switch (event) {
	case AVAHI_RESOLVER_FAILURE:
	    //cerr << "[Resolver] Failed to resolve service '" << name << "' of type '" << type << "' in domain '" << domain
	    //	 << "': " << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))) << endl;
	    break;

	case AVAHI_RESOLVER_FOUND:
	    //cerr << "[Resolver] Service '" << name << " (" << host_name << ":" << port << ")"
	    //     << "' of type '" << type <<"' in domain '" << domain << "'" << endl;

	    //cout << a->browse_services_.size() << endl;
	    browser->add_service(name, Service(type, host_name, address, port, txt));
	    // XXX cache service, broadcast

#if 0
            avahi_address_snprint(a, sizeof(a), address);
            t = avahi_string_list_to_string(txt);
            fprintf(stderr,
                    "\t%s:%u (%s)\n"
                    "\tTXT=%s\n"
                    "\tcookie is %u\n"
                    "\tis_local: %i\n"
                    "\tour_own: %i\n"
                    "\twide_area: %i\n"
                    "\tmulticast: %i\n"
                    "\tcached: %i\n",
                    host_name, port, a,
                    t,
                    avahi_string_list_get_service_cookie(txt),
                    !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
                    !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
                    !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
                    !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
                    !!(flags & AVAHI_LOOKUP_RESULT_CACHED));

            avahi_free(t);
#endif
	}

	avahi_service_resolver_free(r);
    }
static void resolve_callback(
    AvahiServiceResolver *r,
    AVAHI_GCC_UNUSED AvahiIfIndex interface,
    AVAHI_GCC_UNUSED AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const char *type,
    const char *domain,
    const char *host_name,
    const AvahiAddress *address,
    uint16_t port,
    AvahiStringList *txt,
    AvahiLookupResultFlags flags,
    AVAHI_GCC_UNUSED void* userdata) {

    assert(r);

    /* Called whenever a service has been resolved successfully or timed out */

    switch (event) {
        case AVAHI_RESOLVER_FAILURE:
            debug(2, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
            break;

        case AVAHI_RESOLVER_FOUND: {
            if (flags & AVAHI_LOOKUP_RESULT_OUR_OWN) {
              char a[AVAHI_ADDRESS_STR_MAX], *t;

//              debug(1, "avahi: service '%s' of type '%s' in domain '%s' added.", name, type, domain);
              avahi_address_snprint(a, sizeof(a), address);
              debug(1,"avahi: address advertised is: \"%s\".",a);
              /*
              t = avahi_string_list_to_string(txt);
              debug(1,
                      "\t%s:%u (%s)\n"
                      "\tTXT=%s\n"
                      "\tcookie is %u\n"
                      "\tis_local: %i\n"
                      "\tour_own: %i\n"
                      "\twide_area: %i\n"
                      "\tmulticast: %i\n"
                      "\tcached: %i\n",
                      host_name, port, a,
                      t,
                      avahi_string_list_get_service_cookie(txt),
                      !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
                      !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
                      !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
                      !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
                      !!(flags & AVAHI_LOOKUP_RESULT_CACHED));

              avahi_free(t);
              */
            }
        }
    }

    avahi_service_resolver_free(r);
}
Esempio n. 10
0
void resolve_callback(
		AvahiServiceResolver *r,
		AVAHI_GCC_UNUSED AvahiIfIndex interface,
		AVAHI_GCC_UNUSED AvahiProtocol protocol,
		AvahiResolverEvent event,
		const char *name,
		const char *type,
		const char *domain,
		const char *host_name,
		const AvahiAddress *address,
		uint16_t port,
		AvahiStringList *txt,
		AvahiLookupResultFlags flags,
		AVAHI_GCC_UNUSED void* userdata) {

	assert(r);

	/* Called whenever a service has been resolved successfully or timed out */

	switch (event) {
	case AVAHI_RESOLVER_FAILURE:
		std::cerr << "(Resolver) Failed to resolve service '" << name <<"' of type '" << type << "' in domain '" << domain << "': " << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))) << std::endl;
		break;

	case AVAHI_RESOLVER_FOUND: {
		char a[AVAHI_ADDRESS_STR_MAX], *t;

		if (!(flags & AVAHI_LOOKUP_RESULT_LOCAL)) {
			char sport[6];

			std::cerr << "Service '" << name << "' of type '" << type << "' in domain '" << domain << "':" << std::endl;

			avahi_address_snprint(a, sizeof(a), address);
			t = avahi_string_list_to_string(txt);
			std::cerr << host_name << ":" <<port << "(" << a << ")" << std::endl;
			std::cerr << "TXT=" << t << std::endl;
			std::cerr << "cookie is " << avahi_string_list_get_service_cookie(txt) << std::endl;
			std::cerr << "is_local: " << !!(flags & AVAHI_LOOKUP_RESULT_LOCAL) << std::endl;
			std::cerr << "our_own: " << !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN) << std::endl;
			std::cerr << "wide_area: " << !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA) << std::endl;
			std::cerr << "multicast: " << !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST) << std::endl;
			std::cerr << "cached: " << !!(flags & AVAHI_LOOKUP_RESULT_CACHED) << std::endl;
			sprintf(sport, "%i", port);
			mn->addHost(new Host((char *)name, (char *)a, (char *)sport, (char *)t));
			avahi_free(t);
			//todo:create new host here;
		}
		break;



	}
	}

	avahi_service_resolver_free(r);
}
Esempio n. 11
0
static void
browse_record_callback(AvahiRecordBrowser *b, AvahiIfIndex intf, AvahiProtocol proto,
                       AvahiBrowserEvent event, const char *hostname, uint16_t clazz, uint16_t type,
                       const void *rdata, size_t size, AvahiLookupResultFlags flags, void *userdata)
{
  struct mdns_record_browser *rb_data;
  AvahiAddress addr;
  char address[AVAHI_ADDRESS_STR_MAX];
  int family;
  int ret;

  rb_data = (struct mdns_record_browser *)userdata;

  if (event == AVAHI_BROWSER_CACHE_EXHAUSTED)
    DPRINTF(E_DBG, L_MDNS, "Avahi Record Browser (%s, proto %d): no more results (CACHE_EXHAUSTED)\n", hostname, proto);
  else if (event == AVAHI_BROWSER_ALL_FOR_NOW)
    DPRINTF(E_DBG, L_MDNS, "Avahi Record Browser (%s, proto %d): no more results (ALL_FOR_NOW)\n", hostname, proto);
  else if (event == AVAHI_BROWSER_FAILURE)
    DPRINTF(E_LOG, L_MDNS, "Avahi Record Browser (%s, proto %d) failure: %s\n", hostname, proto, MDNSERR);
  else if (event == AVAHI_BROWSER_REMOVE)
    return; // Not handled - record browser lifetime too short for this to happen

  if (event != AVAHI_BROWSER_NEW)
    goto out_free_record_browser;

  ret = avahi_address_make(&addr, proto, rdata, size); // Not an avahi function despite the name
  if (ret < 0)
    return;

  family = avahi_proto_to_af(proto);
  avahi_address_snprint(address, sizeof(address), &addr);

  // Avahi will sometimes give us link-local addresses in 169.254.0.0/16 or
  // fe80::/10, which (most of the time) are useless
  // - see also https://lists.freedesktop.org/archives/avahi/2012-September/002183.html
  if ((proto == AVAHI_PROTO_INET && is_v4ll(&addr.data.ipv4)) || (proto == AVAHI_PROTO_INET6 && is_v6ll(&addr.data.ipv6)))
    {
      DPRINTF(E_WARN, L_MDNS, "Ignoring announcement from %s, address %s is link-local\n", hostname, address);
      return;
    }

  DPRINTF(E_DBG, L_MDNS, "Avahi Record Browser (%s, proto %d): NEW record %s for service type '%s'\n", hostname, proto, address, rb_data->mb->type);

  // Execute callback (mb->cb) with all the data
  rb_data->mb->cb(rb_data->name, rb_data->mb->type, rb_data->domain, hostname, family, address, rb_data->port, &rb_data->txt_kv);

  // Stop record browser
 out_free_record_browser:
  keyval_clear(&rb_data->txt_kv);
  free(rb_data->name);
  free(rb_data->domain);
  free(rb_data);

  avahi_record_browser_free(b);
}
Esempio n. 12
0
void BrowseAvahi::resolve_callback(
	AvahiServiceResolver *r,
	AVAHI_GCC_UNUSED AvahiIfIndex interface,
	AVAHI_GCC_UNUSED AvahiProtocol protocol,
	AvahiResolverEvent event,
	const char *name,
	const char *type,
	const char *domain,
	const char *host_name,
	const AvahiAddress *address,
	uint16_t port,
	AvahiStringList *txt,
	AvahiLookupResultFlags flags,
	AVAHI_GCC_UNUSED void* userdata)
{
	BrowseAvahi* browseAvahi = static_cast<BrowseAvahi*>(userdata);
	assert(r);

	/* Called whenever a service has been resolved successfully or timed out */

	switch (event)
	{
		case AVAHI_RESOLVER_FAILURE:
			logE << "(Resolver) Failed to resolve service '" << name << "' of type '" << type << "' in domain '" << domain << "': " << avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))) << "\n";
			break;

		case AVAHI_RESOLVER_FOUND:
		{
			char a[AVAHI_ADDRESS_STR_MAX], *t;

			logO << "Service '" << name << "' of type '" << type << "' in domain '" << domain << "':\n";

			avahi_address_snprint(a, sizeof(a), address);
			browseAvahi->result_.host_ = host_name;
			browseAvahi->result_.ip_ = a;
			browseAvahi->result_.port_ = port;
			browseAvahi->result_.proto_ = protocol;
			browseAvahi->result_.valid_ = true;

			t = avahi_string_list_to_string(txt);
			logO << "\t" << host_name << ":" << port << " (" << a << ")\n";
			logD << "\tTXT=" << t << "\n";
			logD << "\tProto=" << (int)protocol << "\n";
			logD << "\tcookie is " << avahi_string_list_get_service_cookie(txt) << "\n";
			logD << "\tis_local: " << !!(flags & AVAHI_LOOKUP_RESULT_LOCAL) << "\n";
			logD << "\tour_own: " << !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN) << "\n";
			logD << "\twide_area: " << !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA) << "\n";
			logD << "\tmulticast: " << !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST) << "\n";
			logD << "\tcached: " << !!(flags & AVAHI_LOOKUP_RESULT_CACHED) << "\n";
			avahi_free(t);
		}
	}

	avahi_service_resolver_free(r);
}
Esempio n. 13
0
bool AvahiBrowser::get_address_port(Glib::ustring& address, int& port, Glib::ustring& name, Glib::ustring& host) {
    AvahiAddress a = AvahiAddress();
    uint16_t p = uint16_t();
    if (resolver && ga_service_resolver_get_address(resolver, &a, &p)) {
	char buf[AVAHI_ADDRESS_STR_MAX];
	address = avahi_address_snprint(buf, AVAHI_ADDRESS_STR_MAX, &a);
	port = p;
	name = found_name;
	host = found_host;
	return true;
    }
    return false;
}
Esempio n. 14
0
static void resolveCallback( AvahiServiceResolver *r,
                             AVAHI_GCC_UNUSED AvahiIfIndex interface,
                             AVAHI_GCC_UNUSED AvahiProtocol protocol,
                             AvahiResolverEvent event,
                             const char *name,
                             const char *type,
                             const char *domain,
                             const char *host_name,
                             const AvahiAddress *address,
                             uint16_t port,
                             AvahiStringList *txt,
                             AvahiLookupResultFlags flags,
                             void* userdata )
{
    TiVoUnit        *tivo = userdata;
    char             addr[AVAHI_ADDRESS_STR_MAX];
    AvahiStringList *list;
    char            *key, *value;

    assert(r);

    /* Called whenever a service has been resolved successfully, or timed out */

    switch (event)
    {
    case AVAHI_RESOLVER_FAILURE:
        logerror( "Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
                  name, type, domain, avahi_strerror( avahi_client_errno( avahi_service_resolver_get_client(r) ) ) );
        break;

    case AVAHI_RESOLVER_FOUND:
        /* now we also have the TiVo's serial number and network address */

        avahi_address_snprint( addr, sizeof(addr), address );
        tivo->address = strdup( addr );

        list = avahi_string_list_find( txt, "TSN" );
        avahi_string_list_get_pair( list, &key, &value, NULL );
        tivo->serial = strdup( value );

        avahi_free( key );
        avahi_free( value );

        loginfo( "Resolved '%s' to TSN '%s' at %s", tivo->name, tivo->serial, tivo->address );

        break;
    }

    /* all done with the resolver, so free it */
    avahi_service_resolver_free( r );
}
Esempio n. 15
0
static void
daap_mdns_resolve_browser_new_cb (
                      AvahiServiceResolver *resolv,
                      AvahiIfIndex iface,
                      AvahiProtocol proto,
                      AvahiResolverEvent event,
                      const gchar *name,
                      const gchar *type,
                      const gchar *domain,
                      const gchar *hostname,
                      const AvahiAddress *addr,
                      guint16 port,
                      AvahiStringList *text,
                      AvahiLookupResultFlags flags,
                      void *userdata)
{
	gchar ad[ADDR_LEN];
	daap_mdns_server_t *server;

	if (!resolv) {
		return;
	}

	switch (event) {
		case AVAHI_RESOLVER_FOUND:
			avahi_address_snprint (ad, sizeof (ad), addr);

			server = g_new0 (daap_mdns_server_t, 1);
			server->server_name = g_strdup (name);
			server->address = g_strdup (ad);
			server->mdns_hostname = g_strdup (hostname);
			server->port = port;

			g_static_mutex_lock (&serv_list_mut);
			g_server_list = g_slist_prepend (g_server_list, server);
			g_static_mutex_unlock (&serv_list_mut);
			break;

		case AVAHI_RESOLVER_FAILURE:
			break;

		default:
			break;
	}

	avahi_service_resolver_free (resolv);
}
void avahi_dbus_async_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, AvahiLookupResultFlags flags, void* userdata) {
    AsyncHostNameResolverInfo *i = userdata;
    DBusMessage *reply;
    
    assert(r);
    assert(i);

    reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, avahi_dbus_map_resolve_signal_name(event));
    
    if (event == AVAHI_RESOLVER_FOUND) {
        char t[AVAHI_ADDRESS_STR_MAX], *pt = t;
        int32_t i_interface, i_protocol, i_aprotocol;
        uint32_t u_flags;

        assert(a);
        assert(host_name);
        avahi_address_snprint(t, sizeof(t), a);

        i_interface = (int32_t) interface;
        i_protocol = (int32_t) protocol;
        i_aprotocol = (int32_t) a->proto;
        u_flags = (uint32_t) flags;
        
        dbus_message_append_args(
            reply,
            DBUS_TYPE_INT32, &i_interface,
            DBUS_TYPE_INT32, &i_protocol,
            DBUS_TYPE_STRING, &host_name,
            DBUS_TYPE_INT32, &i_aprotocol,
            DBUS_TYPE_STRING, &pt,
            DBUS_TYPE_UINT32, &u_flags,
            DBUS_TYPE_INVALID);
    }  else {
        assert(event == AVAHI_RESOLVER_FAILURE);
        avahi_dbus_append_server_error(reply);
    }

    dbus_message_set_destination(reply, i->client->name);  
    dbus_connection_send(server->bus, reply, NULL);
    dbus_message_unref(reply);
}
Esempio n. 17
0
void service_found(void *user_data, Avahi::Resolver *resolver,
	Avahi::Service service, AvahiLookupResultFlags flags)
{
    char caddress[AVAHI_ADDRESS_STR_MAX];


    if (flags & (AVAHI_LOOKUP_RESULT_LOCAL|AVAHI_LOOKUP_RESULT_OUR_OWN))
	return;

    avahi_address_snprint(caddress, sizeof(caddress), service.GetAddress());

#if 0
    std::cout << "Resolved " << service.GetName() << std::endl;
    std::cout << "\tFlags = " << flags << std::endl;
    std::cout << "\tType = " << service.GetType() << std::endl;
    std::cout << "\tName = " << service.GetName() << std::endl;
    std::cout << "\tDomain = " << service.GetDomain() << std::endl;
    std::cout << "\tInterface = " << service.GetInterface() << std::endl;
    std::cout << "\tProtocol = " << service.GetProtocol() << std::endl;
    std::cout << "\tHostname = " << service.GetHostName() << std::endl;
    std::cout << "\tAddress = " << caddress << std::endl;
    StringList lst = service.GetTxt();
    StringList::iterator it;
    for (it = lst.begin(); it != lst.end(); ++it)
	std::cout << "\tTXT = " << *it << std::endl;
#endif

#if 0
    service.SetName("X" + service.GetName());
    service.SetHostName("X" + service.GetHostName());
    AvahiAddress address;
    avahi_address_parse("172.16.76.2", AVAHI_PROTO_UNSPEC, &address);
    service.SetAddress(&address);
#endif
    service.SetInterface(if_nametoindex("eth1"));
    avahi->Publish(service);

    delete resolver;
}
Esempio n. 18
0
static void host_name_resolver_callback(
    AvahiHostNameResolver *r,
    AVAHI_GCC_UNUSED AvahiIfIndex interface,
    AVAHI_GCC_UNUSED AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const AvahiAddress *a,
    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
    AVAHI_GCC_UNUSED void *userdata) {

    assert(r);

    switch (event) {
        case AVAHI_RESOLVER_FOUND: {
            char address[AVAHI_ADDRESS_STR_MAX];

            avahi_address_snprint(address, sizeof(address), a);

            printf("%s\t%s\n", name, address);

            break;
        }

        case AVAHI_RESOLVER_FAILURE:

            fprintf(stderr, _("Failed to resolve host name '%s': %s\n"), name, avahi_strerror(avahi_client_errno(client)));
            break;
    }


    avahi_host_name_resolver_free(r);

    assert(n_resolving > 0);
    n_resolving--;

    if (n_resolving <= 0)
        avahi_simple_poll_quit(simple_poll);
}
Esempio n. 19
0
static void dns_server_browser_callback(
    AVAHI_GCC_UNUSED AvahiSDNSServerBrowser *b,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiBrowserEvent event,
    AVAHI_GCC_UNUSED const char *host_name,
    const AvahiAddress *a,
    uint16_t port,
    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
    void* userdata) {

    Client *c = userdata;
    char t[AVAHI_ADDRESS_STR_MAX];

    assert(c);

    if (!a)
        return;

    switch (event) {
        case AVAHI_BROWSER_FAILURE:
            client_output_printf(c, "%+i %s\n", avahi_server_errno(avahi_server), avahi_strerror(avahi_server_errno(avahi_server)));
            c->state = CLIENT_DEAD;
            break;

        case AVAHI_BROWSER_ALL_FOR_NOW:
        case AVAHI_BROWSER_CACHE_EXHAUSTED:
            break;

        case AVAHI_BROWSER_NEW:
        case AVAHI_BROWSER_REMOVE:

            avahi_address_snprint(t, sizeof(t), a);
            client_output_printf(c, "%c %i %u %s %u\n", event == AVAHI_BROWSER_NEW ? '>' : '<',  interface, protocol, t, port);
            break;
    }
}
Esempio n. 20
0
static void resolve_callback(
    AvahiServiceResolver *r,
    AVAHI_GCC_UNUSED AvahiIfIndex interface,
    AVAHI_GCC_UNUSED AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const char *type,
    const char *domain,
    const char *host_name,
    const AvahiAddress *address,
    uint16_t port,
    AvahiStringList *txt,
    AvahiLookupResultFlags flags,
    AVAHI_GCC_UNUSED void* userdata) {

    assert(r);

    /* Called whenever a service has been resolved successfully or timed out */

    switch (event) {
        case AVAHI_RESOLVER_FAILURE:
            fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
            break;

        case AVAHI_RESOLVER_FOUND: {
            char a[AVAHI_ADDRESS_STR_MAX];
            
            fprintf(stderr, "XMMS2 running on '%s@%s'\n", name, domain);
            
            avahi_address_snprint(a, sizeof(a), address);
			fprintf(stderr, "tcp://%s:%u\n", a, port);
        }
    }

    n_pending_resolvers--;
    avahi_service_resolver_free(r);
}
Esempio n. 21
0
static void host_name_resolver_callback(
    AVAHI_GCC_UNUSED AvahiSHostNameResolver *r,
    AvahiIfIndex iface,
    AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *hostname,
    const AvahiAddress *a,
    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
    void* userdata) {

    Client *c = userdata;

    assert(c);

    if (event == AVAHI_RESOLVER_FAILURE)
        client_output_printf(c, "%+i %s\n", avahi_server_errno(avahi_server), avahi_strerror(avahi_server_errno(avahi_server)));
    else if (event == AVAHI_RESOLVER_FOUND) {
        char t[AVAHI_ADDRESS_STR_MAX];
        avahi_address_snprint(t, sizeof(t), a);
        client_output_printf(c, "+ %i %u %s %s\n", iface, protocol, hostname, t);
    }

    c->state = CLIENT_DEAD;
}
Esempio n. 22
0
File: avahi.c Progetto: cjd/lyricue
void resolve_callback(
    AvahiServiceResolver *r,
    AVAHI_GCC_UNUSED AvahiIfIndex interface,
    AVAHI_GCC_UNUSED AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const char *type,
    const char *domain,
    const char *host_name,
    const AvahiAddress *address,
    uint16_t port,
    AvahiStringList *txt,
    AvahiLookupResultFlags flags,
    AVAHI_GCC_UNUSED void* userdata) {

    assert(r);

    /* Called whenever a service has been resolved successfully or timed out */

    switch (event) {
        case AVAHI_RESOLVER_FAILURE:
            l_debug("(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
            break;

        case AVAHI_RESOLVER_FOUND: {
            char a[AVAHI_ADDRESS_STR_MAX];

            avahi_address_snprint(a, sizeof(a), address);
            char *value;
            char *type = NULL;
            size_t *size=NULL;
            AvahiStringList *type_txt = avahi_string_list_find(txt,"type");
            if (type_txt != NULL){
                avahi_string_list_get_pair(type_txt,&type, &value, size);
                l_debug("Type = %s",value);
                if ((g_strcmp0(value,"miniview") == 0) || (g_strcmp0(value,"android") == 0)) {
                    char *data="data";
                    char *extra_data;
                    size_t *size2=NULL;
                    AvahiStringList *data_txt = avahi_string_list_find(txt,"data");
                    if (data_txt != NULL) {
                        avahi_string_list_get_pair(data_txt,&data, &extra_data, size2);
                        gchar *myhost = g_strdup_printf("%s:%u",hostname,server_port);
                        if (g_strcmp0(extra_data, myhost)==0) {
                            gchar *host = g_strdup_printf("%s:%u",a, port);
                            l_debug("Found miniview on %s", host);
                            if (!g_hash_table_contains(miniviews,host)) {
                                g_hash_table_insert(miniviews, g_strdup(name), host);
                            }
                        }
                        avahi_free(data);
                        avahi_free(extra_data);
                        g_free(myhost);
                    }
                }
                avahi_free(value);
                avahi_free(type);
            }
        }
    }

    avahi_service_resolver_free(r);
}
Esempio n. 23
0
struct iio_context * network_create_context(const char *host)
{
	struct addrinfo hints, *res;
	struct iio_context *ctx;
	struct iio_context_pdata *pdata;
	size_t i, len;
	int fd, ret;
	char *description;
#ifdef _WIN32
	WSADATA wsaData;

	ret = WSAStartup(MAKEWORD(2, 0), &wsaData);
	if (ret < 0) {
		ERROR("WSAStartup failed with error %i\n", ret);
		errno = -ret;
		return NULL;
	}
#endif

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

#ifdef HAVE_AVAHI
	if (!host) {
		char addr_str[AVAHI_ADDRESS_STR_MAX];
		char port_str[6];
		AvahiAddress address;
		uint16_t port = IIOD_PORT;

		memset(&address, 0, sizeof(address));

		ret = discover_host(&address, &port);
		if (ret < 0) {
			DEBUG("Unable to find host: %s\n", strerror(-ret));
			errno = -ret;
			return NULL;
		}

		avahi_address_snprint(addr_str, sizeof(addr_str), &address);
		snprintf(port_str, sizeof(port_str), "%hu", port);
		ret = getaddrinfo(addr_str, port_str, &hints, &res);
	} else
#endif
	{
		ret = getaddrinfo(host, IIOD_PORT_STR, &hints, &res);
	}

	if (ret) {
		ERROR("Unable to find host: %s\n", gai_strerror(ret));
#ifndef _WIN32
		if (ret != EAI_SYSTEM)
			errno = ret;
#endif
		return NULL;
	}

	fd = create_socket(res);
	if (fd < 0) {
		errno = fd;
		goto err_free_addrinfo;
	}

	pdata = calloc(1, sizeof(*pdata));
	if (!pdata) {
		errno = ENOMEM;
		goto err_close_socket;
	}

	pdata->fd = fd;
	pdata->addrinfo = res;

	pdata->lock = iio_mutex_create();
	if (!pdata->lock) {
		errno = ENOMEM;
		goto err_free_pdata;
	}

	pdata->iiod_client = iiod_client_new(pdata, pdata->lock,
			&network_iiod_client_ops);
	if (!pdata->iiod_client)
		goto err_destroy_mutex;

	DEBUG("Creating context...\n");
	ctx = iiod_client_create_context(pdata->iiod_client, fd);
	if (!ctx)
		goto err_destroy_iiod_client;

	/* Override the name and low-level functions of the XML context
	 * with those corresponding to the network context */
	ctx->name = "network";
	ctx->ops = &network_ops;
	ctx->pdata = pdata;

#ifdef HAVE_IPV6
	len = INET6_ADDRSTRLEN + IF_NAMESIZE + 2;
#else
	len = INET_ADDRSTRLEN + 1;
#endif

	description = malloc(len);
	if (!description) {
		ret = -ENOMEM;
		goto err_network_shutdown;
	}

	description[0] = '\0';

#ifdef HAVE_IPV6
	if (res->ai_family == AF_INET6) {
		struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
		char *ptr;
		inet_ntop(AF_INET6, &in->sin6_addr,
				description, INET6_ADDRSTRLEN);

		ptr = if_indextoname(in->sin6_scope_id, description +
				strlen(description) + 1);
		if (!ptr) {
			ret = -errno;
			ERROR("Unable to lookup interface of IPv6 address\n");
			goto err_free_description;
		}

		*(ptr - 1) = '%';
	}
#endif
	if (res->ai_family == AF_INET) {
		struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
#if (!_WIN32 || _WIN32_WINNT >= 0x600)
		inet_ntop(AF_INET, &in->sin_addr, description, INET_ADDRSTRLEN);
#else
		char *tmp = inet_ntoa(in->sin_addr);
		strncpy(description, tmp, len);
#endif
	}

	for (i = 0; i < ctx->nb_devices; i++) {
		struct iio_device *dev = ctx->devices[i];

		dev->pdata = calloc(1, sizeof(*dev->pdata));
		if (!dev->pdata) {
			ret = -ENOMEM;
			goto err_free_description;
		}

		dev->pdata->fd = -1;
#ifdef WITH_NETWORK_GET_BUFFER
		dev->pdata->memfd = -1;
#endif

		dev->pdata->lock = iio_mutex_create();
		if (!dev->pdata->lock) {
			ret = -ENOMEM;
			goto err_free_description;
		}
	}

	ret = iio_context_init(ctx);
	if (ret < 0)
		goto err_free_description;

	if (ctx->description) {
		size_t desc_len = strlen(description);
		size_t new_size = desc_len + strlen(ctx->description) + 2;
		char *ptr, *new_description = realloc(description, new_size);
		if (!new_description) {
			ret = -ENOMEM;
			goto err_free_description;
		}

		ptr = strrchr(new_description, '\0');
		snprintf(ptr, new_size - desc_len, " %s", ctx->description);
		free(ctx->description);

		ctx->description = new_description;
	} else {
		ctx->description = description;
	}

	iiod_client_set_timeout(pdata->iiod_client, fd,
			calculate_remote_timeout(DEFAULT_TIMEOUT_MS));
	return ctx;

err_free_description:
	free(description);
err_network_shutdown:
	iio_context_destroy(ctx);
	errno = -ret;
	return NULL;

err_destroy_iiod_client:
	iiod_client_destroy(pdata->iiod_client);
err_destroy_mutex:
	iio_mutex_destroy(pdata->lock);
err_free_pdata:
	free(pdata);
err_close_socket:
	close(fd);
err_free_addrinfo:
	freeaddrinfo(res);
	return NULL;
}
void avahi_dbus_async_service_resolver_callback(
    AvahiSServiceResolver *r,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const char *type,
    const char *domain,
    const char *host_name,
    const AvahiAddress *a,
    uint16_t port,
    AvahiStringList *txt,
    AvahiLookupResultFlags flags, 
    void* userdata) {

    AsyncServiceResolverInfo *i = userdata;
    DBusMessage *reply;
    
    assert(r);
    assert(i);

    reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, avahi_dbus_map_resolve_signal_name(event));
    
    if (event == AVAHI_RESOLVER_FOUND) {
        char t[AVAHI_ADDRESS_STR_MAX], *pt = t;
        int32_t i_interface, i_protocol, i_aprotocol;
        uint32_t u_flags;
    
        assert(host_name);

/*         avahi_log_debug(__FILE__": [%s] Successfully resolved service <%s.%s.%s>", i->path, name, type, domain); */
        
        if (a)
            avahi_address_snprint(t, sizeof(t), a);
        else
            t[0] = 0;

        if (!name)
            name = "";

        if (avahi_dbus_is_our_own_service(i->client, interface, protocol, name, type, domain) > 0)
            flags |= AVAHI_LOOKUP_RESULT_OUR_OWN;

        i_interface = (int32_t) interface;
        i_protocol = (int32_t) protocol;
        if (a) 
	    i_aprotocol = (int32_t) a->proto;
	else 
	    i_aprotocol = AVAHI_PROTO_UNSPEC;
        u_flags = (uint32_t) flags;

        dbus_message_append_args(
            reply,
            DBUS_TYPE_INT32, &i_interface,
            DBUS_TYPE_INT32, &i_protocol,
            DBUS_TYPE_STRING, &name,
            DBUS_TYPE_STRING, &type,
            DBUS_TYPE_STRING, &domain,
            DBUS_TYPE_STRING, &host_name,
            DBUS_TYPE_INT32, &i_aprotocol,
            DBUS_TYPE_STRING, &pt,
            DBUS_TYPE_UINT16, &port,
            DBUS_TYPE_INVALID);

        avahi_dbus_append_string_list(reply, txt);

        dbus_message_append_args(
            reply,
            DBUS_TYPE_UINT32, &u_flags,
            DBUS_TYPE_INVALID);
    }  else {
        assert(event == AVAHI_RESOLVER_FAILURE);
        avahi_dbus_append_server_error(reply);
    }

    dbus_message_set_destination(reply, i->client->name);  
    dbus_connection_send(server->bus, reply, NULL);
    dbus_message_unref(reply);
}
Esempio n. 25
0
static void 
resolve_callback(AvahiServiceResolver *r,
		 AvahiIfIndex interface,
		 AvahiProtocol protocol,
		 AvahiResolverEvent event,
		 const char *name,
		 const char *type,
		 const char *domain,
		 const char *host_name,
		 const AvahiAddress *address,
		 uint16_t port,
		 AvahiStringList *txt,
		 AvahiLookupResultFlags flags,
		 void *userdata)
{
  service_instance_t *si = userdata;
  service_aux_t *sa = si->si_opaque;
  char a[AVAHI_ADDRESS_STR_MAX];
  AvahiStringList *apath;
  char *path;
  AvahiStringList *acontents;
  char *contents;

  switch(event) {
  case AVAHI_RESOLVER_FAILURE:
    TRACE(TRACE_ERROR, "AVAHI",
	  "Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
	  name, type, domain, 
	  avahi_strerror(avahi_client_errno(sa->sa_c)));
    si_destroy(si);
    break;

  case AVAHI_RESOLVER_FOUND:

    avahi_address_snprint(a, sizeof(a), address);

    TRACE(TRACE_DEBUG, "AVAHI",
	  "Found service '%s' of type '%s' at %s:%d (%s)",
	  name, type, a, port, host_name);

    switch(sa->sa_class) {
    case SERVICE_HTSP:
      sd_add_service_htsp(si, name, a, port);
      break;

    case SERVICE_WEBDAV:
      apath = avahi_string_list_find(txt, "path");
      if(apath == NULL ||
	 avahi_string_list_get_pair(apath, NULL, &path, NULL))
        path = NULL;

      acontents = avahi_string_list_find(txt, "contents");
      if(acontents == NULL ||
	 avahi_string_list_get_pair(acontents, NULL, &contents, NULL))
        contents = NULL;
        
      sd_add_service_webdav(si, name, a, port, path, contents);
        
      if(path)
        avahi_free(path);
      break;
    }
  }
  avahi_service_resolver_free(r);
}
Esempio n. 26
0
static void resolver_cb(
        AvahiServiceResolver *r,
        AvahiIfIndex interface, AvahiProtocol protocol,
        AvahiResolverEvent event,
        const char *name, const char *type, const char *domain,
        const char *host_name, const AvahiAddress *a, uint16_t port,
        AvahiStringList *txt,
        AvahiLookupResultFlags flags,
        void *userdata) {

    struct userdata *u = userdata;
    struct tunnel *tnl;

    pa_assert(u);

    tnl = tunnel_new(interface, protocol, name, type, domain);

    if (event != AVAHI_RESOLVER_FOUND)
        pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
    else {
        char *device = NULL, *dname, *module_name, *args;
        const char *t;
        char at[AVAHI_ADDRESS_STR_MAX], cmt[PA_CHANNEL_MAP_SNPRINT_MAX];
        pa_sample_spec ss;
        pa_channel_map cm;
        AvahiStringList *l;
        pa_bool_t channel_map_set = FALSE;
        pa_module *m;

        ss = u->core->default_sample_spec;
        cm = u->core->default_channel_map;

        for (l = txt; l; l = l->next) {
            char *key, *value;
            pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);

            if (pa_streq(key, "device")) {
                pa_xfree(device);
                device = value;
                value = NULL;
            } else if (pa_streq(key, "rate"))
                ss.rate = (uint32_t) atoi(value);
            else if (pa_streq(key, "channels"))
                ss.channels = (uint8_t) atoi(value);
            else if (pa_streq(key, "format"))
                ss.format = pa_parse_sample_format(value);
            else if (pa_streq(key, "channel_map")) {
                pa_channel_map_parse(&cm, value);
                channel_map_set = TRUE;
            }

            avahi_free(key);
            avahi_free(value);
        }

        if (!channel_map_set && cm.channels != ss.channels)
            pa_channel_map_init_extend(&cm, ss.channels, PA_CHANNEL_MAP_DEFAULT);

        if (!pa_sample_spec_valid(&ss)) {
            pa_log("Service '%s' contains an invalid sample specification.", name);
            avahi_free(device);
            goto finish;
        }

        if (!pa_channel_map_valid(&cm) || cm.channels != ss.channels) {
            pa_log("Service '%s' contains an invalid channel map.", name);
            avahi_free(device);
            goto finish;
        }

        if (device)
            dname = pa_sprintf_malloc("tunnel.%s.%s", host_name, device);
        else
            dname = pa_sprintf_malloc("tunnel.%s", host_name);

        if (!pa_namereg_is_valid_name(dname)) {
            pa_log("Cannot construct valid device name from credentials of service '%s'.", dname);
            avahi_free(device);
            pa_xfree(dname);
            goto finish;
        }

        t = strstr(type, "sink") ? "sink" : "source";

        module_name = pa_sprintf_malloc("module-tunnel-%s", t);
        args = pa_sprintf_malloc("server=[%s]:%u "
                                 "%s=%s "
                                 "format=%s "
                                 "channels=%u "
                                 "rate=%u "
                                 "%s_name=%s "
                                 "channel_map=%s",
                                 avahi_address_snprint(at, sizeof(at), a), port,
                                 t, device,
                                 pa_sample_format_to_string(ss.format),
                                 ss.channels,
                                 ss.rate,
                                 t, dname,
                                 pa_channel_map_snprint(cmt, sizeof(cmt), &cm));

        pa_log_debug("Loading %s with arguments '%s'", module_name, args);

        if ((m = pa_module_load(u->core, module_name, args))) {
            tnl->module_index = m->index;
            pa_hashmap_put(u->tunnels, tnl, tnl);
            tnl = NULL;
        }

        pa_xfree(module_name);
        pa_xfree(dname);
        pa_xfree(args);
        avahi_free(device);
    }

finish:

    avahi_service_resolver_free(r);

    if (tnl)
        tunnel_free(tnl);
}
Esempio n. 27
0
/*****************************************************************************
 * resolve_callback
 *****************************************************************************/
static void resolve_callback(
    AvahiServiceResolver *r,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiResolverEvent event,
    const char *name,
    const char *type,
    const char *domain,
    const char *host_name,
    const AvahiAddress *address,
    uint16_t port,
    AvahiStringList *txt,
    AvahiLookupResultFlags flags,
    void* userdata )
{
    services_discovery_t *p_sd = ( services_discovery_t* )userdata;
    services_discovery_sys_t *p_sys = p_sd->p_sys;
    
    VLC_UNUSED(interface); VLC_UNUSED(host_name);
    VLC_UNUSED(flags);

    if( event == AVAHI_RESOLVER_FAILURE )
    {
        msg_Err( p_sd,
                 "failed to resolve service '%s' of type '%s' in domain '%s'",
                 name, type, domain );
    }
    else if( event == AVAHI_RESOLVER_FOUND )
    {
        char a[128];
        char *psz_uri = NULL;
        char *psz_addr = NULL;
        AvahiStringList *asl = NULL;
        input_item_t *p_input = NULL;

        msg_Dbg( p_sd, "service '%s' of type '%s' in domain '%s'",
                 name, type, domain );

        avahi_address_snprint(a, (sizeof(a)/sizeof(a[0]))-1, address);
        if( protocol == AVAHI_PROTO_INET6 )
            if( asprintf( &psz_addr, "[%s]", a ) == -1 )
                return;

        if( txt != NULL )
            asl = avahi_string_list_find( txt, "path" );
        if( asl != NULL )
        {
            size_t size;
            char *key = NULL;
            char *value = NULL;
            if( avahi_string_list_get_pair( asl, &key, &value, &size ) == 0 &&
                value != NULL )
            {
                if( asprintf( &psz_uri, "http://%s:%d%s",
                          psz_addr != NULL ? psz_addr : a, port, value ) == -1 )
                {
                    free( psz_addr );
                    return;
                }
            }
            if( key != NULL )
                avahi_free( (void *)key );
            if( value != NULL )
                avahi_free( (void *)value );
        }
        else
        {
            if( asprintf( &psz_uri, "http://%s:%d",
                      psz_addr != NULL ? psz_addr : a, port ) == -1 )
            {
                free( psz_addr );
                return;
            }
        }

        free( psz_addr );

        if( psz_uri != NULL )
        {
            p_input = input_item_New( p_sd, psz_uri, name );
            free( psz_uri );
        }
        if( p_input != NULL )
        {
            vlc_dictionary_insert( &p_sys->services_name_to_input_item,
                name, p_input );
            services_discovery_AddItem( p_sd, p_input, NULL /* no category */ );
            vlc_gc_decref( p_input );
       }
    }

    avahi_service_resolver_free( r );
}
Esempio n. 28
0
/** Add a host/address pair */
int avahi_entry_group_add_address(
    AvahiEntryGroup *group,
    AvahiIfIndex interface,
    AvahiProtocol protocol,
    AvahiPublishFlags flags,
    const char *name,
    const AvahiAddress *a) {

    DBusMessage *message = NULL, *reply = NULL;
    int r = AVAHI_OK;
    DBusError error;
    AvahiClient *client;
    int32_t i_interface, i_protocol;
    uint32_t u_flags;
    char s_address[AVAHI_ADDRESS_STR_MAX];
    char *p_address = s_address;

    assert(name);

    client = group->client;

    if (!group->path || !avahi_client_is_connected(group->client))
        return avahi_client_set_errno(group->client, AVAHI_ERR_BAD_STATE);

    dbus_error_init(&error);

    if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, group->path, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "AddAddress"))) {
        r = avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    i_interface = (int32_t) interface;
    i_protocol = (int32_t) protocol;
    u_flags = (uint32_t) flags;

    if (!avahi_address_snprint (s_address, sizeof (s_address), a))
    {
        r = avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS);
        goto fail;
    }

    if (!dbus_message_append_args(
            message,
            DBUS_TYPE_INT32, &i_interface,
            DBUS_TYPE_INT32, &i_protocol,
            DBUS_TYPE_UINT32, &u_flags,
            DBUS_TYPE_STRING, &name,
            DBUS_TYPE_STRING, &p_address,
            DBUS_TYPE_INVALID)) {
        r = avahi_client_set_errno(group->client, AVAHI_ERR_NO_MEMORY);
        goto fail;
    }

    if (!(reply = dbus_connection_send_with_reply_and_block(client->bus, message, -1, &error)) ||
        dbus_error_is_set (&error)) {
        r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    if (!dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) ||
        dbus_error_is_set (&error)) {
        r = avahi_client_set_errno(client, AVAHI_ERR_DBUS_ERROR);
        goto fail;
    }

    dbus_message_unref(message);
    dbus_message_unref(reply);

    return AVAHI_OK;

fail:

    if (dbus_error_is_set(&error)) {
        r = avahi_client_set_dbus_error(client, &error);
        dbus_error_free(&error);
    }

    if (message)
        dbus_message_unref(message);

    if (reply)
        dbus_message_unref(reply);

    return r;
}
Esempio n. 29
0
static void resolver_cb(
        AvahiServiceResolver *r,
        AvahiIfIndex interface, AvahiProtocol protocol,
        AvahiResolverEvent event,
        const char *name, const char *type, const char *domain,
        const char *host_name, const AvahiAddress *a, uint16_t port,
        AvahiStringList *txt,
        AvahiLookupResultFlags flags,
        void *userdata) {
    struct userdata *u = userdata;
    struct tunnel *tnl;
    char *device = NULL, *nicename, *dname, *vname, *args;
    char *tp = NULL, *et = NULL, *cn = NULL;
    char *ch = NULL, *ss = NULL, *sr = NULL;
    char *t = NULL;
    char at[AVAHI_ADDRESS_STR_MAX];
    AvahiStringList *l;
    pa_module *m;

    pa_assert(u);

    tnl = tunnel_new(interface, protocol, name, type, domain);

    if (event != AVAHI_RESOLVER_FOUND) {
        pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
        goto finish;
    }

    if ((nicename = strstr(name, "@"))) {
        ++nicename;
        if (strlen(nicename) > 0) {
            pa_log_debug("Found RAOP: %s", nicename);
            nicename = pa_escape(nicename, "\"'");
        } else
            nicename = NULL;
    }

    for (l = txt; l; l = l->next) {
        char *key, *value;
        pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);

        pa_log_debug("Found key: '%s' with value: '%s'", key, value);
        if (pa_streq(key, "device")) {
            device = value;
            value = NULL;
        } else if (pa_streq(key, "tp")) {
            /* Transport protocol:
             *  - TCP = only TCP,
             *  - UDP = only UDP,
             *  - TCP,UDP = both supported (UDP should be prefered) */
            pa_xfree(tp);
            if (pa_str_in_list(value, ",", "UDP"))
                tp = pa_xstrdup("UDP");
            else if (pa_str_in_list(value, ",", "TCP"))
                tp = pa_xstrdup("TCP");
            else
                tp = pa_xstrdup(value);
        } else if (pa_streq(key, "et")) {
            /* Supported encryption types:
             *  - 0 = none,
             *  - 1 = RSA,
             *  - 2 = FairPlay,
             *  - 3 = MFiSAP,
             *  - 4 = FairPlay SAPv2.5. */
            pa_xfree(et);
            if (pa_str_in_list(value, ",", "1"))
                et = pa_xstrdup("RSA");
            else
                et = pa_xstrdup("none");
        } else if (pa_streq(key, "cn")) {
            /* Suported audio codecs:
             *  - 0 = PCM,
             *  - 1 = ALAC,
             *  - 2 = AAC,
             *  - 3 = AAC ELD. */
            pa_xfree(cn);
            if (pa_str_in_list(value, ",", "1"))
                cn = pa_xstrdup("ALAC");
            else
                cn = pa_xstrdup("PCM");
        } else if (pa_streq(key, "md")) {
            /* Supported metadata types:
             *  - 0 = text,
             *  - 1 = artwork,
             *  - 2 = progress. */
        } else if (pa_streq(key, "pw")) {
            /* Requires password ? (true/false) */
        } else if (pa_streq(key, "ch")) {
            /* Number of channels */
            pa_xfree(ch);
            ch = pa_xstrdup(value);
        } else if (pa_streq(key, "ss")) {
            /* Sample size */
            pa_xfree(ss);
            ss = pa_xstrdup(value);
        } else if (pa_streq(key, "sr")) {
            /* Sample rate */
            pa_xfree(sr);
            sr = pa_xstrdup(value);
        }

        avahi_free(key);
        avahi_free(value);
    }

    if (device)
        dname = pa_sprintf_malloc("raop_output.%s.%s", host_name, device);
    else
        dname = pa_sprintf_malloc("raop_output.%s", host_name);

    if (!(vname = pa_namereg_make_valid_name(dname))) {
        pa_log("Cannot construct valid device name from '%s'.", dname);
        avahi_free(device);
        pa_xfree(dname);
        pa_xfree(tp);
        pa_xfree(et);
        pa_xfree(cn);
        pa_xfree(ch);
        pa_xfree(ss);
        pa_xfree(sr);
        goto finish;
    }

    avahi_free(device);
    pa_xfree(dname);

    avahi_address_snprint(at, sizeof(at), a);
    if (nicename) {
        args = pa_sprintf_malloc("server=[%s]:%u "
                                 "sink_name=%s "
                                 "sink_properties='device.description=\"%s (%s:%u)\"'",
                                 at, port,
                                 vname,
                                 nicename, at, port);
        pa_xfree(nicename);
    } else {
        args = pa_sprintf_malloc("server=[%s]:%u "
                                 "sink_name=%s"
                                 "sink_properties='device.description=\"%s:%u\"'",
                                 at, port,
                                 vname,
                                 at, port);
    }

    if (tp != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s protocol=%s", args, tp);
        pa_xfree(tp);
        pa_xfree(t);
    }
    if (et != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s encryption=%s", args, et);
        pa_xfree(et);
        pa_xfree(t);
    }
    if (cn != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s codec=%s", args, cn);
        pa_xfree(cn);
        pa_xfree(t);
    }
    if (ch != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s channels=%s", args, ch);
        pa_xfree(ch);
        pa_xfree(t);
    }
    if (ss != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s format=%s", args, ss);
        pa_xfree(ss);
        pa_xfree(t);
    }
    if (sr != NULL) {
        t = args;
        args = pa_sprintf_malloc("%s rate=%s", args, sr);
        pa_xfree(sr);
        pa_xfree(t);
    }

    pa_log_debug("Loading module-raop-sink with arguments '%s'", args);

    if ((m = pa_module_load(u->core, "module-raop-sink", args))) {
        tnl->module_index = m->index;
        pa_hashmap_put(u->tunnels, tnl, tnl);
        tnl = NULL;
    }

    pa_xfree(vname);
    pa_xfree(args);

finish:
    avahi_service_resolver_free(r);

    if (tnl)
        tunnel_free(tnl);
}
Esempio n. 30
0
static void
browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtocol proto, AvahiResolverEvent event,
			const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *addr,
			uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata)
{
  char address[AVAHI_ADDRESS_STR_MAX + IF_NAMESIZE + 2];
  char ifname[IF_NAMESIZE];
  struct keyval txt_kv;
  struct mdns_browser *mb;
  char *key;
  char *value;
  size_t len;
  int family;
  int ll;
  int ret;

  mb = (struct mdns_browser *)userdata;

  switch (event)
    {
      case AVAHI_RESOLVER_FAILURE:
	DPRINTF(E_LOG, L_MDNS, "Avahi Resolver failure: service '%s' type '%s': %s\n", name, type,
		avahi_strerror(avahi_client_errno(mdns_client)));
	break;

      case AVAHI_RESOLVER_FOUND:
	DPRINTF(E_DBG, L_MDNS, "Avahi Resolver: resolved service '%s' type '%s' proto %d\n", name, type, proto);

	// KK - if I reject 192.168.* my AirTunes get rejected.
	// How does avahi passes multiple IP addresses?
	// ll = is_link_local(addr);
	ll = 0;

	switch (proto)
	  {
	    case AVAHI_PROTO_INET:
		    avahi_record_browser_new()
	      if (ll)
		{
		  family = AF_UNSPEC;

		  DPRINTF(E_DBG, L_MDNS, "Discarding IPv4 LL address\n");
		  break;
		}

	      family = AF_INET;
	      avahi_address_snprint(address, sizeof(address), addr);
	      break;

	    case AVAHI_PROTO_INET6:
	      avahi_address_snprint(address, sizeof(address), addr);

	      if (ll)
		{
		  DPRINTF(E_DBG, L_MDNS, "Appending interface name to IPv6 LL address\n");

		  if (!if_indextoname(intf, ifname))
		    {
		      DPRINTF(E_LOG, L_MDNS, "Could not map interface index %d to a name\n", intf);

		      family = AF_UNSPEC;
		      break;
		    }

		  len = strlen(address);
		  ret = snprintf(address + len, sizeof(address) - len, "%%%s", ifname);
		  if ((ret < 0) || (ret > sizeof(address) - len))
		    {
		      DPRINTF(E_LOG, L_MDNS, "Buffer too short for scoped IPv6 LL\n");

		      family = AF_UNSPEC;
		      break;
		    }

		  DPRINTF(E_DBG, L_MDNS, "Scoped IPv6 LL: %s\n", address);
		}

	      family = AF_INET6;
	      break;

	    default:
	      DPRINTF(E_INFO, L_MDNS, "Avahi Resolver: unknown protocol %d\n", proto);

	      family = AF_UNSPEC;
	      break;
	  }

	if (family == AF_UNSPEC)
	  break;

	memset(&txt_kv, 0, sizeof(struct keyval));

	while (txt)
	  {
	    len = avahi_string_list_get_size(txt);
	    key = (char *)avahi_string_list_get_text(txt);

	    value = memchr(key, '=', len);
	    if (!value)
	      {
		value = "";
		len = 0;
	      }
	    else
	      {
		*value = '\0';
		value++;

		len -= strlen(key) + 1;
	      }

	    ret = keyval_add_size(&txt_kv, key, value, len);
	    if (ret < 0)
	      {
		DPRINTF(E_LOG, L_MDNS, "Could not build TXT record keyval\n");

		goto out_clear_txt_kv;
	      }

	    txt = avahi_string_list_get_next(txt);
	  }

	/* Execute callback (mb->cb) with all the data */
	mb->cb(name, type, domain, hostname, family, address, port, &txt_kv);

    out_clear_txt_kv:
	keyval_clear(&txt_kv);
	break;
    }

  avahi_service_resolver_free(r);
}