Skip to content

Commit

Permalink
Add a new setting to specify the interface the service should be prov…
Browse files Browse the repository at this point in the history
…ided on.
  • Loading branch information
mikebrady committed Feb 5, 2017
1 parent 5c42d82 commit 2cab35c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 30 deletions.
2 changes: 2 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ typedef struct {
char *configfile;
char *regtype; // The regtype is the service type followed by the protocol, separated by a dot, by
// default “_raop._tcp.”.
char *interface; // a string containg the interface name, or NULL if nothing specified
int interface_index; // only valid if the interface string is non-NULL
double audio_backend_buffer_desired_length; // this will be the length in seconds of the
// audio backend buffer -- the DAC buffer for ALSA
double audio_backend_latency_offset; // this will be the offset in seconds to compensate for any
Expand Down
9 changes: 7 additions & 2 deletions mdns_avahi.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,21 @@ static void register_service(AvahiClient *c) {
return;

int ret;
AvahiIfIndex selected_interface;
if (config.interface!=NULL)
selected_interface = config.interface_index;
else
selected_interface = AVAHI_IF_UNSPEC;
#ifdef CONFIG_METADATA
if (config.metadata_enabled) {
ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name,
ret = avahi_entry_group_add_service(group, selected_interface, AVAHI_PROTO_UNSPEC, 0, name,
config.regtype, NULL, NULL, port,
MDNS_RECORD_WITH_METADATA, NULL);
if (ret == 0)
debug(1, "avahi: request to add \"%s\" service with metadata", config.regtype);
} else {
#endif
ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name,
ret = avahi_entry_group_add_service(group, selected_interface, AVAHI_PROTO_UNSPEC, 0, name,
config.regtype, NULL, NULL, port,
MDNS_RECORD_WITHOUT_METADATA, NULL);
if (ret == 0)
Expand Down
56 changes: 31 additions & 25 deletions mdns_tinysvcmdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,21 @@ static int mdns_tinysvcmdns_register(char *apname, int port) {

// Look for an ipv4/ipv6 non-loopback interface to use as the main one.
for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) {
if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;

mdnsd_set_hostname(svr, hostname, main_ip); // TTL should be 120 seconds
break;
} else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr &&
ifa->ifa_addr->sa_family == AF_INET6) {
struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;

mdnsd_set_hostname_v6(svr, hostname, addr); // TTL should be 120 seconds
break;
// only check for the named interface, if specified
if ((config.interface==NULL) || (strcmp(config.interface,ifa->ifa_name)==0)) {

if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
uint32_t main_ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;

mdnsd_set_hostname(svr, hostname, main_ip); // TTL should be 120 seconds
break;
} else if (!(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr &&
ifa->ifa_addr->sa_family == AF_INET6) {
struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;

mdnsd_set_hostname_v6(svr, hostname, addr); // TTL should be 120 seconds
break;
}
}
}

Expand All @@ -92,20 +96,22 @@ static int mdns_tinysvcmdns_register(char *apname, int port) {
// Skip the first one, it was already added by set_hostname
for (ifa = ifa->ifa_next; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_flags & IFF_LOOPBACK) // Skip loop-back interfaces
continue;

switch (ifa->ifa_addr->sa_family) {
case AF_INET: { // ipv4
uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); // TTL should be 120 seconds
mdnsd_add_rr(svr, a_e);
} break;
case AF_INET6: { // ipv6
struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
struct rr_entry *aaaa_e =
rr_create_aaaa(create_nlabel(hostname), addr); // TTL should be 120 seconds
mdnsd_add_rr(svr, aaaa_e);
} break;
continue;
// only check for the named interface, if specified
if ((config.interface==NULL) || (strcmp(config.interface,ifa->ifa_name)==0)) {
switch (ifa->ifa_addr->sa_family) {
case AF_INET: { // ipv4
uint32_t ip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
struct rr_entry *a_e = rr_create_a(create_nlabel(hostname), ip); // TTL should be 120 seconds
mdnsd_add_rr(svr, a_e);
} break;
case AF_INET6: { // ipv6
struct in6_addr *addr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
struct rr_entry *aaaa_e =
rr_create_aaaa(create_nlabel(hostname), addr); // TTL should be 120 seconds
mdnsd_add_rr(svr, aaaa_e);
} break;
}
}
}

Expand Down
48 changes: 45 additions & 3 deletions shairport.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <net/if.h>
#include <unistd.h>

#include "config.h"
Expand Down Expand Up @@ -490,7 +491,45 @@ int parse_options(int argc, char **argv) {
die("Invalid playback_mode choice \"%s\". It should be \"stereo\" (default), \"mono\", "
"\"reverse stereo\", \"both left\", \"both right\"");
}





/* Get the interface to listen on, if specified Default is all interfaces */
/* we keep the interface name and the index */

if (config_lookup_string(config.cfg, "general.interface", &str))
config.interface = strdup(str);

if (config_lookup_string(config.cfg, "general.interface", &str)) {
int specified_interface_found = 0;

struct if_nameindex *if_ni, *i;

if_ni = if_nameindex();
if (if_ni == NULL) {
debug(1,"Can't get a list of interface names.");
} else {
for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) {
// printf("%u: %s\n", i->if_index, i->if_name);
if (strcmp(i->if_name,str)==0) {
config.interface_index = i->if_index;
specified_interface_found = 1;
}
}

}

if_freenameindex(if_ni);

if (specified_interface_found==0) {
inform("The mdns service interface \"%s\" was not found, so the setting has been ignored.",config.interface);
free(config.interface);
config.interface = NULL;
config.interface_index = 0;
}
}

/* Get the regtype -- the service type and protocol, separated by a dot. Default is
* "_raop._tcp" */
if (config_lookup_string(config.cfg, "general.regtype", &str))
Expand Down Expand Up @@ -762,7 +801,6 @@ void shairport_startup_complete(void) {
const char *pid_file_proc(void) {
#ifdef HAVE_ASPRINTF
static char *fn = NULL;
free(fn);
asprintf(&fn, "%s/%s.pid", PIDDIR, daemon_pid_file_ident ? daemon_pid_file_ident : "unknown");
#else
static char fn[8192];
Expand All @@ -777,6 +815,7 @@ const char *pid_file_proc(void) {
void exit_function() {
if (config.cfg)
config_destroy(config.cfg);
// probably should be freeing malloc'ed memory here, including strdup-created strings...
}

int main(int argc, char **argv) {
Expand Down Expand Up @@ -1146,7 +1185,10 @@ int main(int argc, char **argv) {
debug(1, "zeroconf regtype is \"%s\".", config.regtype);
debug(1, "decoders_supported field is %d.", config.decoders_supported);
debug(1, "use_apple_decoder is %d.", config.use_apple_decoder);

if (config.interface)
debug(1, "mdns service interface \"%s\" requested.",config.interface);
else
debug(1, "no special mdns service interface was requested.");
char *realConfigPath = realpath(config.configfile, NULL);
if (realConfigPath) {
debug(1, "configuration file name \"%s\" resolves to \"%s\".", config.configfile,
Expand Down

0 comments on commit 2cab35c

Please sign in to comment.