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; }
/* 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; };
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); } }
/** * 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); }
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); }
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(); }
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(); }
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); }
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); }
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); }
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); }
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; }
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 ); }
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); }
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; }
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); }
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; } }
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); }
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; }
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); }
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); }
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); }
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); }
/***************************************************************************** * 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 ); }
/** 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; }
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); }
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); }