[mdns] CNAME record so we have fixed uri for OAuth redirects
- also refactor mdns_avahi
This commit is contained in:
parent
33c22a59b9
commit
90ecc61ed7
10
src/mdns.h
10
src/mdns.h
|
@ -37,6 +37,16 @@ mdns_deinit(void);
|
||||||
int
|
int
|
||||||
mdns_register(char *name, char *type, int port, char **txt);
|
mdns_register(char *name, char *type, int port, char **txt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register a CNAME record, it will be an alias for hostname
|
||||||
|
* Call only from the main thread!
|
||||||
|
*
|
||||||
|
* @in name The CNAME alias, e.g. "forked-daapd.local"
|
||||||
|
* @return 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
mdns_cname(char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start a service browser, a callback will be made when the service changes state
|
* Start a service browser, a callback will be made when the service changes state
|
||||||
* Call only from the main thread!
|
* Call only from the main thread!
|
||||||
|
|
165
src/mdns_avahi.c
165
src/mdns_avahi.c
|
@ -33,6 +33,7 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
|
|
||||||
|
@ -351,8 +352,15 @@ struct mdns_record_browser {
|
||||||
int port;
|
int port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum publish
|
||||||
|
{
|
||||||
|
MDNS_PUBLISH_SERVICE,
|
||||||
|
MDNS_PUBLISH_CNAME,
|
||||||
|
};
|
||||||
|
|
||||||
struct mdns_group_entry
|
struct mdns_group_entry
|
||||||
{
|
{
|
||||||
|
enum publish publish;
|
||||||
char *name;
|
char *name;
|
||||||
char *type;
|
char *type;
|
||||||
int port;
|
int port;
|
||||||
|
@ -620,13 +628,100 @@ entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_U
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
_create_services(void)
|
create_group_entry(struct mdns_group_entry *ge, int commit)
|
||||||
{
|
{
|
||||||
struct mdns_group_entry *pentry;
|
char hostname[HOST_NAME_MAX + 1];
|
||||||
|
char rdata[HOST_NAME_MAX + 6 + 1]; // Includes room for ".local" and 0-terminator
|
||||||
|
int count;
|
||||||
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Creating service group\n");
|
if (!mdns_group)
|
||||||
|
{
|
||||||
|
mdns_group = avahi_entry_group_new(mdns_client, entry_group_callback, NULL);
|
||||||
|
if (!mdns_group)
|
||||||
|
{
|
||||||
|
DPRINTF(E_WARN, L_MDNS, "Could not create Avahi EntryGroup: %s\n", MDNSERR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ge->publish == MDNS_PUBLISH_SERVICE)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_MDNS, "Adding service %s/%s\n", ge->name, ge->type);
|
||||||
|
|
||||||
|
ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
|
||||||
|
ge->name, ge->type,
|
||||||
|
NULL, NULL, ge->port, ge->txt);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not add mDNS service %s/%s: %s\n", ge->name, ge->type, avahi_strerror(ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ge->publish == MDNS_PUBLISH_CNAME)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_MDNS, "Adding CNAME record %s\n", ge->name);
|
||||||
|
|
||||||
|
ret = gethostname(hostname, HOST_NAME_MAX);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, gethostname failed\n", ge->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, gethostname does not guarantee 0-termination
|
||||||
|
ret = snprintf(rdata, sizeof(rdata), ".%s.local", hostname);
|
||||||
|
if (!(ret > 0 && ret < sizeof(rdata)))
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not add CNAME %s, hostname is invalid\n", ge->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to dns string: .forked-daapd.local -> \12forked-daapd\6local
|
||||||
|
count = 0;
|
||||||
|
for (i = ret - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (rdata[i] == '.')
|
||||||
|
{
|
||||||
|
rdata[i] = count;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ret + 1 should be the string length of rdata incl. 0-terminator
|
||||||
|
ret = avahi_entry_group_add_record(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
|
||||||
|
AVAHI_PUBLISH_USE_MULTICAST | AVAHI_PUBLISH_ALLOW_MULTIPLE,
|
||||||
|
ge->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_CNAME,
|
||||||
|
AVAHI_DEFAULT_TTL, rdata, ret + 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not add CNAME record %s: %s\n", ge->name, avahi_strerror(ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!commit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = avahi_entry_group_commit(mdns_group);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Could not commit mDNS services: %s\n", MDNSERR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_all_group_entries(void)
|
||||||
|
{
|
||||||
|
struct mdns_group_entry *ge;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!group_entries)
|
if (!group_entries)
|
||||||
{
|
{
|
||||||
|
@ -634,32 +729,17 @@ _create_services(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mdns_group == NULL)
|
if (mdns_group)
|
||||||
|
avahi_entry_group_reset(mdns_group);
|
||||||
|
|
||||||
|
DPRINTF(E_INFO, L_MDNS, "Re-registering mDNS groups (services and records)\n");
|
||||||
|
|
||||||
|
for (ge = group_entries; ge; ge = ge->next)
|
||||||
{
|
{
|
||||||
mdns_group = avahi_entry_group_new(mdns_client, entry_group_callback, NULL);
|
create_group_entry(ge, 0);
|
||||||
if (!mdns_group)
|
if (!mdns_group)
|
||||||
{
|
|
||||||
DPRINTF(E_WARN, L_MDNS, "Could not create Avahi EntryGroup: %s\n", MDNSERR);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pentry = group_entries;
|
|
||||||
while (pentry)
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Re-registering %s/%s\n", pentry->name, pentry->type);
|
|
||||||
|
|
||||||
ret = avahi_entry_group_add_service_strlst(mdns_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0,
|
|
||||||
pentry->name, pentry->type,
|
|
||||||
NULL, NULL, pentry->port, pentry->txt);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_WARN, L_MDNS, "Could not add mDNS services: %s\n", avahi_strerror(ret));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pentry = pentry->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = avahi_entry_group_commit(mdns_group);
|
ret = avahi_entry_group_commit(mdns_group);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -678,7 +758,7 @@ client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void *
|
||||||
case AVAHI_CLIENT_S_RUNNING:
|
case AVAHI_CLIENT_S_RUNNING:
|
||||||
DPRINTF(E_LOG, L_MDNS, "Avahi state change: Client running\n");
|
DPRINTF(E_LOG, L_MDNS, "Avahi state change: Client running\n");
|
||||||
if (!mdns_group)
|
if (!mdns_group)
|
||||||
_create_services();
|
create_all_group_entries();
|
||||||
|
|
||||||
for (mb = browser_list; mb; mb = mb->next)
|
for (mb = browser_list; mb; mb = mb->next)
|
||||||
{
|
{
|
||||||
|
@ -806,8 +886,6 @@ mdns_register(char *name, char *type, int port, char **txt)
|
||||||
AvahiStringList *txt_sl;
|
AvahiStringList *txt_sl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Adding mDNS service %s/%s\n", name, type);
|
|
||||||
|
|
||||||
ge = calloc(1, sizeof(struct mdns_group_entry));
|
ge = calloc(1, sizeof(struct mdns_group_entry));
|
||||||
if (!ge)
|
if (!ge)
|
||||||
{
|
{
|
||||||
|
@ -815,6 +893,7 @@ mdns_register(char *name, char *type, int port, char **txt)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ge->publish = MDNS_PUBLISH_SERVICE;
|
||||||
ge->name = strdup(name);
|
ge->name = strdup(name);
|
||||||
ge->type = strdup(type);
|
ge->type = strdup(type);
|
||||||
ge->port = port;
|
ge->port = port;
|
||||||
|
@ -835,14 +914,30 @@ mdns_register(char *name, char *type, int port, char **txt)
|
||||||
ge->next = group_entries;
|
ge->next = group_entries;
|
||||||
group_entries = ge;
|
group_entries = ge;
|
||||||
|
|
||||||
if (mdns_group)
|
create_all_group_entries(); // TODO why is this required?
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Resetting mDNS group\n");
|
return 0;
|
||||||
avahi_entry_group_reset(mdns_group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MDNS, "Creating service group\n");
|
int
|
||||||
_create_services();
|
mdns_cname(char *name)
|
||||||
|
{
|
||||||
|
struct mdns_group_entry *ge;
|
||||||
|
|
||||||
|
ge = calloc(1, sizeof(struct mdns_group_entry));
|
||||||
|
if (!ge)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_MDNS, "Out of memory for mDNS CNAME\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ge->publish = MDNS_PUBLISH_CNAME;
|
||||||
|
ge->name = strdup(name);
|
||||||
|
|
||||||
|
ge->next = group_entries;
|
||||||
|
group_entries = ge;
|
||||||
|
|
||||||
|
create_all_group_entries();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue