From d195ac7ddd53ac457c282581783ef5cd756b9608 Mon Sep 17 00:00:00 2001
From: David Kerr
Date: Sat, 2 Jul 2016 14:05:24 -0400
Subject: [PATCH 1/7] Add service types to database for audio streaming, device
info, amazon fire and qnap nas devices.
---
service-type-database/service-types | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/service-type-database/service-types b/service-type-database/service-types
index 6e7e2cd98..4bbf52a3f 100644
--- a/service-type-database/service-types
+++ b/service-type-database/service-types
@@ -139,6 +139,7 @@ _realplayfavs._tcp:RealPlayer Shared Favorites
_realplayfavs._tcp[it]:RealPlayer - Preferiti Condivisi
_raop._tcp:AirTunes Remote Audio
+_airplay._tcp:AirPlay Remote Video
_rtsp._tcp:RTSP Realtime Streaming Server
_rtp._udp:RTP Realtime Streaming Server
@@ -216,6 +217,10 @@ _adobe-vc._tcp:Adobe Version Cue
_home-sharing._tcp:Apple Home Sharing
+_amzn-wplay._tcp:Amazon Fire TV
+
+_qdiscover._tcp:QNAP NAS
+
# Other
@@ -231,3 +236,6 @@ _tp-https._tcp:Thousand Parsec Server (Secure HTTP Tunnel)
_shifter._tcp:Window Shifter
_libvirt._tcp:Virtual Machine Manager
+
+_device-info._tcp:Device Info
+
From d9caeb59739c4e8af6b0dfbffff8e4ed365d3beb Mon Sep 17 00:00:00 2001
From: David Kerr
Date: Sat, 2 Jul 2016 18:14:24 -0400
Subject: [PATCH 2/7] Adds support for filtering reflector advertisements This
enhancement is provided courtesy of James Rudd
and http://jrudd.org/2014/08/avahi-reflector-filtering-patch/
Allows Avahi-Daemon to filter which advertisements are added to the cache to be reflected to different networks.
It checks incoming service names against a list defined in avahi-daemon.conf [reflector] reflect-filters.
The list can be types of services or can contain hostnames to match.
For example if we only allow AirPlay and AirTunes to be reflected between VLANs, so have "_airplay._tcp.local,_raop._tcp.local" set.
For AirPrint set "_printer._tcp.local,_ipp._tcp.local,_pdl-datastream._tcp.local"
Remember to set firewall to permit traffic between LANs for the corresponding ports.
The patch will block the PTR and SRV advertisements but will still allow A records for machine name lookup.
All locally published services are still published even if they do not match the filter.
The filter also blocks local programs from seeing advertised programs so it is recommend to only enable it on a dedicated bonjour reflector server.
---
avahi-core/core.h | 1 +
avahi-core/server.c | 48 ++++++++++++++++++++++++++++-
avahi-daemon/avahi-daemon.conf | 1 +
avahi-daemon/main.c | 12 ++++++++
man/avahi-daemon.conf.5.xml.in | 10 ++++++
service-type-database/service-types | 1 -
6 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/avahi-core/core.h b/avahi-core/core.h
index f50c6128a..1ebd27a00 100644
--- a/avahi-core/core.h
+++ b/avahi-core/core.h
@@ -56,6 +56,7 @@ typedef struct AvahiServerConfig {
int use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */
int enable_reflector; /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */
int reflect_ipv; /**< if enable_reflector is 1, enable/disable reflecting between IPv4 and IPv6 */
+ AvahiStringList *reflect_filters; /**< if enable_reflector is 1, will only add services containing one of these strings */
int add_service_cookie; /**< Add magic service cookie to all locally generated records implicitly */
int enable_wide_area; /**< Enable wide area support */
AvahiAddress wide_area_servers[AVAHI_WIDE_AREA_SERVERS_MAX]; /** Unicast DNS server to use for wide area lookup */
diff --git a/avahi-core/server.c b/avahi-core/server.c
index a2cb19a83..1a91907dd 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -674,6 +674,40 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
}
if (!avahi_key_is_pattern(record->key)) {
+ // Filter services that will be cached. Allow all local services
+ if (!from_local_iface && s->config.enable_reflector && s->config.reflect_filters != NULL){
+ AvahiStringList *l;
+ int match = 0;
+
+ if (record->key->type == AVAHI_DNS_TYPE_PTR){
+ // Need to match DNS pointer target with filter
+ for (l = s->config.reflect_filters; l; l = l->next) {
+ if (strstr( record->data.ptr.name, (char*) l->text) != NULL) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (! match){
+ //avahi_log_info("Reject Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
+ return;
+ }
+ }
+ else if (record->key->type == AVAHI_DNS_TYPE_SRV || record->key->type == AVAHI_DNS_TYPE_TXT){
+ // Need to match key name with filter
+ for (l = s->config.reflect_filters; l; l = l->next) {
+ if (strstr( record->key->name, (char*) l->text) != NULL) {
+ match = 1;
+ break;
+ }
+ }
+
+ if (! match){
+ //avahi_log_info("Reject Key [%s] iface [%d]", record->key->name, from_local_iface);
+ return;
+ }
+ }
+ }
if (handle_conflict(s, i, record, cache_flush)) {
if (!from_local_iface && !avahi_record_is_link_local_address(record))
@@ -1589,6 +1623,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
c->use_iff_running = 0;
c->enable_reflector = 0;
c->reflect_ipv = 0;
+ c->reflect_filters = NULL;
c->add_service_cookie = 0;
c->enable_wide_area = 0;
c->n_wide_area_servers = 0;
@@ -1611,13 +1646,14 @@ void avahi_server_config_free(AvahiServerConfig *c) {
avahi_free(c->host_name);
avahi_free(c->domain_name);
avahi_string_list_free(c->browse_domains);
+ avahi_string_list_free(c->reflect_filters);
avahi_string_list_free(c->allow_interfaces);
avahi_string_list_free(c->deny_interfaces);
}
AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c) {
char *d = NULL, *h = NULL;
- AvahiStringList *browse = NULL, *allow = NULL, *deny = NULL;
+ AvahiStringList *browse = NULL, *allow = NULL, *deny = NULL, *reflect = NULL ;
assert(ret);
assert(c);
@@ -1652,12 +1688,22 @@ AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiS
return NULL;
}
+ if (!(reflect = avahi_string_list_copy(c->reflect_filters)) && c->reflect_filters) {
+ avahi_string_list_free(allow);
+ avahi_string_list_free(browse);
+ avahi_string_list_free(deny);
+ avahi_free(h);
+ avahi_free(d);
+ return NULL;
+ }
+
*ret = *c;
ret->host_name = h;
ret->domain_name = d;
ret->browse_domains = browse;
ret->allow_interfaces = allow;
ret->deny_interfaces = deny;
+ ret->reflect_filters = reflect;
return ret;
}
diff --git a/avahi-daemon/avahi-daemon.conf b/avahi-daemon/avahi-daemon.conf
index 95166f802..2c6c1fcc5 100644
--- a/avahi-daemon/avahi-daemon.conf
+++ b/avahi-daemon/avahi-daemon.conf
@@ -57,6 +57,7 @@ publish-workstation=no
[reflector]
#enable-reflector=no
#reflect-ipv=no
+#reflect-filters=_airplay._tcp.local,_raop._tcp.local
[rlimits]
#rlimit-as=
diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c
index 10cb41e7e..346338fb9 100644
--- a/avahi-daemon/main.c
+++ b/avahi-daemon/main.c
@@ -826,6 +826,18 @@ static int load_config_file(DaemonConfig *c) {
c->server_config.enable_reflector = is_yes(p->value);
else if (strcasecmp(p->key, "reflect-ipv") == 0)
c->server_config.reflect_ipv = is_yes(p->value);
+ else if (strcasecmp(p->key, "reflect-filters") == 0) {
+ char **e, **t;
+
+ avahi_string_list_free(c->server_config.reflect_filters);
+ c->server_config.reflect_filters = NULL;
+ e = avahi_split_csv(p->value);
+
+ for (t = e; *t; t++)
+ c->server_config.reflect_filters = avahi_string_list_add(c->server_config.reflect_filters, *t);
+
+ avahi_strfreev(e);
+ }
else {
avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name);
goto finish;
diff --git a/man/avahi-daemon.conf.5.xml.in b/man/avahi-daemon.conf.5.xml.in
index 2d15017a1..dd91e60d3 100644
--- a/man/avahi-daemon.conf.5.xml.in
+++ b/man/avahi-daemon.conf.5.xml.in
@@ -327,6 +327,16 @@
enabled, avahi-daemon will forward mDNS traffic between IPv4
and IPv6, which is usually not recommended. Defaults to "no".
+
+
diff --git a/service-type-database/service-types b/service-type-database/service-types
index 4bbf52a3f..0b99d403f 100644
--- a/service-type-database/service-types
+++ b/service-type-database/service-types
@@ -238,4 +238,3 @@ _shifter._tcp:Window Shifter
_libvirt._tcp:Virtual Machine Manager
_device-info._tcp:Device Info
-
From c8723de8100cac0449514e095caa45eb6af416c6 Mon Sep 17 00:00:00 2001
From: David Kerr
Date: Sun, 3 Jul 2016 21:46:11 -0400
Subject: [PATCH 3/7] Uncommented the info messages and changed them to debug
messages. Added debug message for matches as well as rejects. I have found
that it is extremely useful to see what mDNS-SD messages are matched or
rejected in order to debug service discovery and therefore it is best if
these messages can be turned on with the --debug flag as necessary.
---
avahi-core/server.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 1a91907dd..018429ccf 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -689,9 +689,11 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
}
if (! match){
- //avahi_log_info("Reject Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
+ avahi_log_debug("Reject Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
return;
}
+ else
+ avahi_log_debug("Match Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
}
else if (record->key->type == AVAHI_DNS_TYPE_SRV || record->key->type == AVAHI_DNS_TYPE_TXT){
// Need to match key name with filter
@@ -703,9 +705,11 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
}
if (! match){
- //avahi_log_info("Reject Key [%s] iface [%d]", record->key->name, from_local_iface);
+ avahi_log_debug("Reject Key [%s] iface [%d]", record->key->name, from_local_iface);
return;
}
+ else
+ avahi_log_debug("Match Key [%s] iface [%d]", record->key->name, from_local_iface);
}
}
From 2e42c6416327c256ab70940c7341caf3830d5c24 Mon Sep 17 00:00:00 2001
From: David Kerr
Date: Fri, 24 Feb 2017 23:43:33 -0500
Subject: [PATCH 4/7] suppress warning message that avahi_server_add_address()
failed when disable-publishing=yes is set in conf file. Fixes lathiat/avahi
issue #38
---
avahi-core/iface.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/avahi-core/iface.c b/avahi-core/iface.c
index 39a860ae7..a68a4b900 100644
--- a/avahi-core/iface.c
+++ b/avahi-core/iface.c
@@ -74,7 +74,10 @@ void avahi_interface_address_update_rrs(AvahiInterfaceAddress *a, int remove_rrs
avahi_log_info("Registering new address record for %s on %s.%s.", t, a->interface->hardware->name, p == AVAHI_PROTO_UNSPEC ? "*" : avahi_proto_to_string(p));
if (avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, p, 0, NULL, &a->address) < 0) {
- avahi_log_warn(__FILE__": avahi_server_add_address() failed: %s", avahi_strerror(m->server->error));
+ if (!m->server->config.disable_publishing || m->server->error != AVAHI_ERR_NOT_PERMITTED) {
+ /* suppress warning if disable_publishing set as this is expected state */
+ avahi_log_warn(__FILE__": avahi_server_add_address() failed: %s", avahi_strerror(m->server->error));
+ }
avahi_s_entry_group_free(a->entry_group);
a->entry_group = NULL;
return;
From 659a7df2c51b2c4dbf227c465ea89ef52ec54432 Mon Sep 17 00:00:00 2001
From: wisd0me
Date: Wed, 25 Sep 2019 15:38:21 +0700
Subject: [PATCH 5/7] reflect-filters logic bugfix
This commit fixes the bug, when there is multiple records in the
response (usually there are), and first record does not correspond to
any of the configured services - originally, packet was getting dropped.
With this fix current record is skipped, and the code looks further.
---
avahi-core/server.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 018429ccf..622658f39 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -690,7 +690,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
if (! match){
avahi_log_debug("Reject Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
- return;
+ goto unref;
}
else
avahi_log_debug("Match Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
@@ -706,7 +706,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
if (! match){
avahi_log_debug("Reject Key [%s] iface [%d]", record->key->name, from_local_iface);
- return;
+ goto unref;
}
else
avahi_log_debug("Match Key [%s] iface [%d]", record->key->name, from_local_iface);
@@ -721,6 +721,7 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
}
}
+ unref:
avahi_record_unref(record);
}
From 6dabb000cc4206ecbf30d016c0a4625c5eae2930 Mon Sep 17 00:00:00 2001
From: wisd0me
Date: Wed, 25 Sep 2019 15:51:53 +0700
Subject: [PATCH 6/7] formatting fixed
---
avahi-core/server.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 622658f39..7dcfb7b14 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -674,37 +674,37 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
}
if (!avahi_key_is_pattern(record->key)) {
- // Filter services that will be cached. Allow all local services
- if (!from_local_iface && s->config.enable_reflector && s->config.reflect_filters != NULL){
+ /* Filter services that will be cached. Allow all local services */
+ if (!from_local_iface && s->config.enable_reflector && s->config.reflect_filters != NULL) {
AvahiStringList *l;
int match = 0;
- if (record->key->type == AVAHI_DNS_TYPE_PTR){
- // Need to match DNS pointer target with filter
+ if (record->key->type == AVAHI_DNS_TYPE_PTR) {
+ /* Need to match DNS pointer target with filter */
for (l = s->config.reflect_filters; l; l = l->next) {
- if (strstr( record->data.ptr.name, (char*) l->text) != NULL) {
+ if (strstr(record->data.ptr.name, (char*) l->text) != NULL) {
match = 1;
break;
}
}
- if (! match){
+ if (!match) {
avahi_log_debug("Reject Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
goto unref;
}
else
avahi_log_debug("Match Ptr SRC [%s] Dest [%s]", record->key->name, record->data.ptr.name);
}
- else if (record->key->type == AVAHI_DNS_TYPE_SRV || record->key->type == AVAHI_DNS_TYPE_TXT){
- // Need to match key name with filter
+ else if (record->key->type == AVAHI_DNS_TYPE_SRV || record->key->type == AVAHI_DNS_TYPE_TXT) {
+ /* Need to match key name with filter */
for (l = s->config.reflect_filters; l; l = l->next) {
- if (strstr( record->key->name, (char*) l->text) != NULL) {
+ if (strstr(record->key->name, (char*) l->text) != NULL) {
match = 1;
break;
}
}
- if (! match){
+ if (!match) {
avahi_log_debug("Reject Key [%s] iface [%d]", record->key->name, from_local_iface);
goto unref;
}
From 0538cf4c483edd01fecf6287109dbf9e538dd7d5 Mon Sep 17 00:00:00 2001
From: David Kerr
Date: Thu, 26 Sep 2019 08:39:34 -0400
Subject: [PATCH 7/7] bugfix free avahi record before returning from function.
---
avahi-core/server.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 250af412b..cbb389f53 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -1208,6 +1208,7 @@ static void register_hinfo(AvahiServer *s) {
if (avahi_server_add(s, s->hinfo_entry_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_PUBLISH_UNIQUE, r) < 0) {
avahi_log_warn("Failed to add HINFO RR: %s", avahi_strerror(s->error));
+ avahi_record_unref(r);
return;
}
}