mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-29 15:36:00 -05:00
Browse records for IPv6 addresses regardless of the underlying protocol
This commit is contained in:
parent
d8b7980fe4
commit
bcbda9bc4e
240
src/mdns_avahi.c
240
src/mdns_avahi.c
@ -536,18 +536,126 @@ browse_record_callback_v6(AvahiRecordBrowser *b, AvahiIfIndex intf, AvahiProtoco
|
|||||||
avahi_record_browser_free(b);
|
avahi_record_browser_free(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
spawn_record_browser(AvahiClient *c, AvahiIfIndex intf, AvahiProtocol proto, const char *hostname, const char *domain,
|
||||||
|
uint16_t type, struct mdns_browser *mb, const char *name, uint16_t port, AvahiStringList *txt)
|
||||||
|
{
|
||||||
|
AvahiRecordBrowser *rb;
|
||||||
|
struct mdns_record_browser *rb_data;
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
char *ptr;
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rb_data = (struct mdns_record_browser *)malloc(sizeof(struct mdns_record_browser));
|
||||||
|
if (!rb_data)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Out of memory for record browser data\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(rb_data, 0, sizeof(struct mdns_record_browser));
|
||||||
|
|
||||||
|
rb_data->mb = mb;
|
||||||
|
rb_data->port = port;
|
||||||
|
|
||||||
|
rb_data->name = strdup(name);
|
||||||
|
if (!rb_data->name)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Out of memory for service name\n");
|
||||||
|
|
||||||
|
goto out_free_rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_data->domain = strdup(domain);
|
||||||
|
if (!rb_data->domain)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Out of memory for service domain\n");
|
||||||
|
|
||||||
|
goto out_free_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (txt)
|
||||||
|
{
|
||||||
|
len = avahi_string_list_get_size(txt);
|
||||||
|
key = (char *)avahi_string_list_get_text(txt);
|
||||||
|
|
||||||
|
ptr = memchr(key, '=', len);
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
value = "";
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
value = ptr + 1;
|
||||||
|
|
||||||
|
len -= strlen(key) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = keyval_add_size(&rb_data->txt_kv, key, value, len);
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
*ptr = '=';
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not build TXT record keyval\n");
|
||||||
|
|
||||||
|
goto out_free_keyval;
|
||||||
|
}
|
||||||
|
|
||||||
|
txt = avahi_string_list_get_next(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb = NULL;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case AVAHI_DNS_TYPE_A:
|
||||||
|
rb = avahi_record_browser_new(c, intf, proto, hostname,
|
||||||
|
AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, 0,
|
||||||
|
browse_record_callback_v4, rb_data);
|
||||||
|
if (!rb)
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not create v4 record browser for host %s: %s\n",
|
||||||
|
hostname, avahi_strerror(avahi_client_errno(c)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AVAHI_DNS_TYPE_AAAA:
|
||||||
|
rb = avahi_record_browser_new(c, intf, proto, hostname,
|
||||||
|
AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, 0,
|
||||||
|
browse_record_callback_v6, rb_data);
|
||||||
|
if (!rb)
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not create v4 record browser for host %s: %s\n",
|
||||||
|
hostname, avahi_strerror(avahi_client_errno(c)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rb)
|
||||||
|
goto out_free_keyval;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_free_keyval:
|
||||||
|
keyval_clear(&rb_data->txt_kv);
|
||||||
|
free(rb_data->domain);
|
||||||
|
out_free_name:
|
||||||
|
free(rb_data->name);
|
||||||
|
out_free_rb:
|
||||||
|
free(rb_data);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtocol proto, AvahiResolverEvent event,
|
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,
|
const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *addr,
|
||||||
uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata)
|
uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata)
|
||||||
{
|
{
|
||||||
AvahiClient *c;
|
AvahiClient *c;
|
||||||
AvahiRecordBrowser *rb;
|
|
||||||
struct mdns_browser *mb;
|
struct mdns_browser *mb;
|
||||||
struct mdns_record_browser *rb_data;
|
|
||||||
char *key;
|
|
||||||
char *value;
|
|
||||||
size_t len;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mb = (struct mdns_browser *)userdata;
|
mb = (struct mdns_browser *)userdata;
|
||||||
@ -562,123 +670,25 @@ browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtoco
|
|||||||
case AVAHI_RESOLVER_FOUND:
|
case AVAHI_RESOLVER_FOUND:
|
||||||
DPRINTF(E_DBG, L_MDNS, "Avahi Resolver: resolved service '%s' type '%s' proto %d\n", name, type, proto);
|
DPRINTF(E_DBG, L_MDNS, "Avahi Resolver: resolved service '%s' type '%s' proto %d\n", name, type, proto);
|
||||||
|
|
||||||
if ((proto == AVAHI_PROTO_INET) && !(mb->flags & (MDNS_WANT_V4 | MDNS_WANT_V4LL)))
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "No IPv4 addresses requested, skipping v4 record browsing\n");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if ((proto == AVAHI_PROTO_INET6) && !(mb->flags & (MDNS_WANT_V6 | MDNS_WANT_V6LL)))
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "No IPv6 addresses requested, skipping v6 record browsing\n");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_data = (struct mdns_record_browser *)malloc(sizeof(struct mdns_record_browser));
|
|
||||||
if (!rb_data)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Out of memory for record browser data\n");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(rb_data, 0, sizeof(struct mdns_record_browser));
|
|
||||||
|
|
||||||
rb_data->mb = mb;
|
|
||||||
rb_data->port = port;
|
|
||||||
|
|
||||||
rb_data->name = strdup(name);
|
|
||||||
if (!rb_data->name)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Out of memory for service name\n");
|
|
||||||
|
|
||||||
keyval_clear(&rb_data->txt_kv);
|
|
||||||
free(rb_data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_data->domain = strdup(domain);
|
|
||||||
if (!rb_data->domain)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Out of memory for service domain\n");
|
|
||||||
|
|
||||||
keyval_clear(&rb_data->txt_kv);
|
|
||||||
free(rb_data->name);
|
|
||||||
free(rb_data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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(&rb_data->txt_kv, key, value, len);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Could not build TXT record keyval\n");
|
|
||||||
|
|
||||||
keyval_clear(&rb_data->txt_kv);
|
|
||||||
free(rb_data->name);
|
|
||||||
free(rb_data->domain);
|
|
||||||
free(rb_data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
txt = avahi_string_list_get_next(txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
c = avahi_service_resolver_get_client(r);
|
c = avahi_service_resolver_get_client(r);
|
||||||
|
|
||||||
switch (proto)
|
if (mb->flags & (MDNS_WANT_V4 | MDNS_WANT_V4LL))
|
||||||
{
|
{
|
||||||
case AVAHI_PROTO_INET:
|
ret = spawn_record_browser(c, intf, proto, hostname, domain,
|
||||||
rb = avahi_record_browser_new(c, intf, proto, hostname,
|
AVAHI_DNS_TYPE_A, mb, name, port, txt);
|
||||||
AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, 0,
|
if (ret < 0)
|
||||||
browse_record_callback_v4, rb_data);
|
DPRINTF(E_LOG, L_MDNS, "Failed to create record browser for type A\n");
|
||||||
if (!rb)
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Could not create v4 record browser for host %s: %s\n",
|
|
||||||
hostname, avahi_strerror(avahi_client_errno(c)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AVAHI_PROTO_INET6:
|
|
||||||
rb = avahi_record_browser_new(c, intf, proto, hostname,
|
|
||||||
AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, 0,
|
|
||||||
browse_record_callback_v6, rb_data);
|
|
||||||
if (!rb)
|
|
||||||
DPRINTF(E_LOG, L_MDNS, "Could not create v4 record browser for host %s: %s\n",
|
|
||||||
hostname, avahi_strerror(avahi_client_errno(c)));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DPRINTF(E_INFO, L_MDNS, "Avahi Resolver: unknown protocol %d\n", proto);
|
|
||||||
|
|
||||||
rb = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rb)
|
if (mb->flags & (MDNS_WANT_V6 | MDNS_WANT_V6LL))
|
||||||
{
|
{
|
||||||
keyval_clear(&rb_data->txt_kv);
|
ret = spawn_record_browser(c, intf, proto, hostname, domain,
|
||||||
free(rb_data->name);
|
AVAHI_DNS_TYPE_AAAA, mb, name, port, txt);
|
||||||
free(rb_data->domain);
|
if (ret < 0)
|
||||||
free(rb_data);
|
DPRINTF(E_LOG, L_MDNS, "Failed to create record browser for type A\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user