[mdns] Make connection test optional and only do it for Airplay (fixes #602)
Some remotes don't respond as expected to the test. Retune will give connection refused, because the test is made too quickly, before the service is running. Even if we delay the test it won't work because Retune crashes. Since the false mdns advertisements are only seen on Airplay, we only do the test there.
This commit is contained in:
parent
07e46d75c8
commit
df7456dc39
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
enum mdns_options
|
||||||
|
{
|
||||||
|
// Test connection to device and only call back if successful
|
||||||
|
MDNS_CONNECTION_TEST = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (* mdns_browse_cb)(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt);
|
typedef void (* mdns_browse_cb)(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -54,10 +60,11 @@ mdns_cname(char *name);
|
||||||
* @in type Type of service to look for, e.g. "_raop._tcp"
|
* @in type Type of service to look for, e.g. "_raop._tcp"
|
||||||
* @in family AF_INET to browse for ipv4 services, AF_INET6 for ipv6,
|
* @in family AF_INET to browse for ipv4 services, AF_INET6 for ipv6,
|
||||||
AF_UNSPEC for both
|
AF_UNSPEC for both
|
||||||
|
* @in flags See mdns_options (only supported by Avahi implementation)
|
||||||
* @in cb Callback when service state changes (e.g. appears/disappears)
|
* @in cb Callback when service state changes (e.g. appears/disappears)
|
||||||
* @return 0 on success, -1 on error
|
* @return 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mdns_browse(char *type, int family, mdns_browse_cb cb);
|
mdns_browse(char *type, int family, mdns_browse_cb cb, enum mdns_options flags);
|
||||||
|
|
||||||
#endif /* !__MDNS_H__ */
|
#endif /* !__MDNS_H__ */
|
||||||
|
|
|
@ -348,6 +348,7 @@ struct mdns_browser
|
||||||
char *type;
|
char *type;
|
||||||
AvahiProtocol protocol;
|
AvahiProtocol protocol;
|
||||||
mdns_browse_cb cb;
|
mdns_browse_cb cb;
|
||||||
|
enum mdns_options flags;
|
||||||
|
|
||||||
struct mdns_browser *next;
|
struct mdns_browser *next;
|
||||||
};
|
};
|
||||||
|
@ -567,7 +568,7 @@ connection_test(int family, const char *address, const char *address_log, int po
|
||||||
// a connection to the address
|
// a connection to the address
|
||||||
// - see also https://lists.freedesktop.org/archives/avahi/2012-September/002183.html
|
// - see also https://lists.freedesktop.org/archives/avahi/2012-September/002183.html
|
||||||
static int
|
static int
|
||||||
address_check(AvahiProtocol proto, const char *hostname, const AvahiAddress *addr, int port)
|
address_check(AvahiProtocol proto, const char *hostname, const AvahiAddress *addr, int port, enum mdns_options flags)
|
||||||
{
|
{
|
||||||
char address[AVAHI_ADDRESS_STR_MAX];
|
char address[AVAHI_ADDRESS_STR_MAX];
|
||||||
char address_log[AVAHI_ADDRESS_STR_MAX + 2];
|
char address_log[AVAHI_ADDRESS_STR_MAX + 2];
|
||||||
|
@ -588,6 +589,9 @@ address_check(AvahiProtocol proto, const char *hostname, const AvahiAddress *add
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(flags & MDNS_CONNECTION_TEST))
|
||||||
|
return 0; // All done
|
||||||
|
|
||||||
ret = connection_test(family, address, address_log, port);
|
ret = connection_test(family, address, address_log, port);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
@ -633,7 +637,7 @@ browse_record_callback(AvahiRecordBrowser *b, AvahiIfIndex intf, AvahiProtocol p
|
||||||
|
|
||||||
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);
|
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);
|
||||||
|
|
||||||
ret = address_check(proto, hostname, &addr, rb_data->port);
|
ret = address_check(proto, hostname, &addr, rb_data->port, rb_data->mb->flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -714,7 +718,7 @@ browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtoco
|
||||||
// devices (e.g. ApEx 1 gen) will include multiple records, and we need to
|
// devices (e.g. ApEx 1 gen) will include multiple records, and we need to
|
||||||
// filter out those records that won't work (notably link-local). The value of
|
// filter out those records that won't work (notably link-local). The value of
|
||||||
// *addr given by browse_resolve_callback is just the first record.
|
// *addr given by browse_resolve_callback is just the first record.
|
||||||
ret = address_check(proto, hostname, addr, port);
|
ret = address_check(proto, hostname, addr, port, mb->flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
CHECK_NULL(L_MDNS, rb_data = calloc(1, sizeof(struct mdns_record_browser)));
|
CHECK_NULL(L_MDNS, rb_data = calloc(1, sizeof(struct mdns_record_browser)));
|
||||||
|
@ -1156,22 +1160,18 @@ mdns_cname(char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mdns_browse(char *type, int family, mdns_browse_cb cb)
|
mdns_browse(char *type, int family, mdns_browse_cb cb, enum mdns_options flags)
|
||||||
{
|
{
|
||||||
struct mdns_browser *mb;
|
struct mdns_browser *mb;
|
||||||
AvahiServiceBrowser *b;
|
AvahiServiceBrowser *b;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Adding service browser for type %s\n", type);
|
DPRINTF(E_DBG, L_MDNS, "Adding service browser for type %s\n", type);
|
||||||
|
|
||||||
mb = calloc(1, sizeof(struct mdns_browser));
|
CHECK_NULL(L_MDNS, mb = calloc(1, sizeof(struct mdns_browser)));
|
||||||
if (!mb)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Out of memory for new mdns browser\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mb->protocol = avahi_af_to_proto(family);
|
mb->protocol = avahi_af_to_proto(family);
|
||||||
mb->type = strdup(type);
|
mb->type = strdup(type);
|
||||||
|
mb->flags = flags;
|
||||||
mb->cb = cb;
|
mb->cb = cb;
|
||||||
|
|
||||||
mb->next = browser_list;
|
mb->next = browser_list;
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct mdns_browser
|
||||||
struct mdns_resolver *resolvers;
|
struct mdns_resolver *resolvers;
|
||||||
char *regtype;
|
char *regtype;
|
||||||
/* references */
|
/* references */
|
||||||
|
enum mdns_options flags;
|
||||||
mdns_browse_cb cb;
|
mdns_browse_cb cb;
|
||||||
DNSServiceProtocol protocol;
|
DNSServiceProtocol protocol;
|
||||||
void *res_uuid;
|
void *res_uuid;
|
||||||
|
@ -871,20 +872,16 @@ mdns_browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mdns_browse(char *regtype, int family, mdns_browse_cb cb)
|
mdns_browse(char *regtype, int family, mdns_browse_cb cb, enum mdns_options flags)
|
||||||
{
|
{
|
||||||
struct mdns_browser *mb;
|
struct mdns_browser *mb;
|
||||||
DNSServiceErrorType err;
|
DNSServiceErrorType err;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Adding service browser for type %s\n", regtype);
|
DPRINTF(E_DBG, L_MDNS, "Adding service browser for type %s\n", regtype);
|
||||||
|
|
||||||
mb = calloc(1, sizeof(*mb));
|
CHECK_NULL(L_MDNS, mb = calloc(1, sizeof(*mb)));
|
||||||
if (!mb)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Out of memory creating service browser.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mb->flags = flags;
|
||||||
mb->cb = cb;
|
mb->cb = cb;
|
||||||
|
|
||||||
/* flags are ignored in DNS-SD implementation */
|
/* flags are ignored in DNS-SD implementation */
|
||||||
|
|
|
@ -1774,7 +1774,7 @@ cast_init(void)
|
||||||
else
|
else
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
|
|
||||||
ret = mdns_browse("_googlecast._tcp", family, cast_device_cb);
|
ret = mdns_browse("_googlecast._tcp", family, cast_device_cb, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_CAST, "Could not add mDNS browser for Chromecast devices\n");
|
DPRINTF(E_LOG, L_CAST, "Could not add mDNS browser for Chromecast devices\n");
|
||||||
|
|
|
@ -5025,7 +5025,7 @@ raop_init(void)
|
||||||
else
|
else
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
|
|
||||||
ret = mdns_browse("_raop._tcp", family, raop_device_cb);
|
ret = mdns_browse("_raop._tcp", family, raop_device_cb, MDNS_CONNECTION_TEST);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "Could not add mDNS browser for AirPlay devices\n");
|
DPRINTF(E_LOG, L_RAOP, "Could not add mDNS browser for AirPlay devices\n");
|
||||||
|
|
|
@ -818,7 +818,7 @@ remote_pairing_init(void)
|
||||||
#endif /* HAVE_EVENTFD */
|
#endif /* HAVE_EVENTFD */
|
||||||
|
|
||||||
// No ipv6 for remote at the moment
|
// No ipv6 for remote at the moment
|
||||||
ret = mdns_browse("_touch-remote._tcp", AF_INET, touch_remote_cb);
|
ret = mdns_browse("_touch-remote._tcp", AF_INET, touch_remote_cb, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_FATAL, L_REMOTE, "Could not browse for Remote services\n");
|
DPRINTF(E_FATAL, L_REMOTE, "Could not browse for Remote services\n");
|
||||||
|
|
Loading…
Reference in New Issue