summaryrefslogtreecommitdiffstats
path: root/avahi-core/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'avahi-core/server.c')
-rw-r--r--avahi-core/server.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 4c55edb..dbb861d 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -564,7 +564,7 @@ static void reflect_probe(AvahiServer *s, AvahiInterface *i, AvahiRecord *r) {
avahi_interface_post_probe(j, r, 1);
}
-static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, uint16_t port, int legacy_unicast) {
+static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, uint16_t port, int legacy_unicast, int from_local_iface) {
size_t n;
int is_probe;
@@ -589,7 +589,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac
goto fail;
}
- if (!legacy_unicast)
+ if (!legacy_unicast && !from_local_iface)
reflect_query(s, i, key);
if (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT) == 0 &&
@@ -602,40 +602,44 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac
avahi_key_unref(key);
}
- /* Known Answer Suppression */
- for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) {
- AvahiRecord *record;
- int unique = 0;
+ if (!legacy_unicast) {
- if (!(record = avahi_dns_packet_consume_record(p, &unique))) {
- avahi_log_warn("Packet too short (2)");
- goto fail;
- }
-
- if (handle_conflict(s, i, record, unique, a)) {
- avahi_response_scheduler_suppress(i->response_scheduler, record, a);
- avahi_record_list_drop(s->record_list, record);
+ /* Known Answer Suppression */
+ for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) {
+ AvahiRecord *record;
+ int unique = 0;
+
+ if (!(record = avahi_dns_packet_consume_record(p, &unique))) {
+ avahi_log_warn("Packet too short (2)");
+ goto fail;
+ }
+
+ if (handle_conflict(s, i, record, unique, a)) {
+ avahi_response_scheduler_suppress(i->response_scheduler, record, a);
+ avahi_record_list_drop(s->record_list, record);
+ }
+
+ avahi_record_unref(record);
}
- avahi_record_unref(record);
- }
-
- /* Probe record */
- for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) {
- AvahiRecord *record;
- int unique = 0;
-
- if (!(record = avahi_dns_packet_consume_record(p, &unique))) {
- avahi_log_warn("Packet too short (3)");
- goto fail;
- }
-
- if (!avahi_key_is_pattern(record->key)) {
- reflect_probe(s, i, record);
- incoming_probe(s, record, i);
+ /* Probe record */
+ for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) {
+ AvahiRecord *record;
+ int unique = 0;
+
+ if (!(record = avahi_dns_packet_consume_record(p, &unique))) {
+ avahi_log_warn("Packet too short (3)");
+ goto fail;
+ }
+
+ if (!avahi_key_is_pattern(record->key)) {
+ if (!from_local_iface)
+ reflect_probe(s, i, record);
+ incoming_probe(s, record, i);
+ }
+
+ avahi_record_unref(record);
}
-
- avahi_record_unref(record);
}
if (!avahi_record_list_is_empty(s->record_list))
@@ -647,7 +651,7 @@ fail:
avahi_record_list_flush(s->record_list);
}
-static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a) {
+static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, int from_local_iface) {
unsigned n;
assert(s);
@@ -674,7 +678,8 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter
/* avahi_free(txt); */
if (handle_conflict(s, i, record, cache_flush, a)) {
- reflect_response(s, i, record, cache_flush);
+ if (!from_local_iface)
+ reflect_response(s, i, record, cache_flush);
avahi_cache_update(i->cache, record, cache_flush, a);
avahi_response_scheduler_incoming(i->response_scheduler, record, cache_flush);
}
@@ -877,10 +882,23 @@ static int is_mdns_mcast_address(const AvahiAddress *a) {
return avahi_address_cmp(a, &b) == 0;
}
+static int originates_from_local_iface(AvahiServer *s, AvahiIfIndex iface, const AvahiAddress *a, uint16_t port) {
+ assert(s);
+ assert(iface != AVAHI_IF_UNSPEC);
+ assert(a);
+
+ /* If it isn't the MDNS port it can't be generated by us */
+ if (port != AVAHI_MDNS_PORT)
+ return 0;
+
+ return avahi_interface_has_address(s->monitor, iface, a);
+}
+
static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiAddress *dest, AvahiIfIndex iface, int ttl) {
AvahiInterface *i;
AvahiAddress a;
uint16_t port;
+ int from_local_iface = 0;
assert(s);
assert(p);
@@ -907,6 +925,10 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
/* This originates from our local reflector, so let's ignore it */
return;
+ /* We don't want to reflect local traffic, so we check if this packet is generated locally. */
+ if (s->config.enable_reflector)
+ from_local_iface = originates_from_local_iface(s, iface, &a, port);
+
if (avahi_dns_packet_is_valid(p) < 0) {
avahi_log_warn("Recieved invalid packet.");
return;
@@ -935,7 +957,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
if (legacy_unicast)
reflect_legacy_unicast_query_packet(s, p, i, &a, port);
- handle_query_packet(s, p, i, &a, port, legacy_unicast);
+ handle_query_packet(s, p, i, &a, port, legacy_unicast, from_local_iface);
/* avahi_log_debug("Handled query"); */
} else {
@@ -962,7 +984,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock
return;
}
- handle_response_packet(s, p, i, &a);
+ handle_response_packet(s, p, i, &a, from_local_iface);
/* avahi_log_debug("Handled response"); */
}
}