Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions libmdnsd/mdnsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <stdbool.h>
#include <time.h>
#include <errno.h>
#include <ifaddrs.h>

#define SPRIME 109 /* Size of query/publish hashes */
#define LPRIME 1009 /* Size of cache hash */
Expand Down Expand Up @@ -675,6 +676,34 @@ static int _r_out(mdns_daemon_t *d, struct message *m, mdns_record_t **list)
return ret;
}

/* Check if an IPv4 address belongs to this host (any interface) */
static bool _is_local_ipv4(mdns_daemon_t *d, struct in_addr ip)
{
/* Always consider the primary configured address as local */
if (ip.s_addr == d->addr.s_addr)
return true;

struct ifaddrs *ifa = NULL;

if (getifaddrs(&ifa) != 0)
return false;

for (struct ifaddrs *it = ifa; it; it = it->ifa_next) {
if (!it->ifa_addr)
continue;
if (it->ifa_addr->sa_family != AF_INET)
continue;

struct sockaddr_in *sin = (struct sockaddr_in *)it->ifa_addr;
if (sin->sin_addr.s_addr == ip.s_addr) {
freeifaddrs(ifa);
return true;
}
}

freeifaddrs(ifa);
return false;
}

mdns_daemon_t *mdnsd_new(int class, int frame)
{
Expand Down Expand Up @@ -869,6 +898,10 @@ int mdnsd_in(mdns_daemon_t *d, struct message *m, struct in_addr ip, unsigned sh

gettimeofday(&d->now, 0);

/* Ignore packets originated from any of our local IPv4 addresses */
if (_is_local_ipv4(d, ip))
return 0;

if (m->header.qr == 0) {
/* Process each query */
for (i = 0; i < m->qdcount; i++) {
Expand All @@ -883,7 +916,7 @@ int mdnsd_in(mdns_daemon_t *d, struct message *m, struct in_addr ip, unsigned sh
if (!r)
continue;

/* Service enumeratio/discovery prepeare to send all matching records */
/* Service enumeration/discovery prepeare to send all matching records */
if (!strcmp(m->qd[i].name, DISCO_NAME)) {
d->disco = 1;
while (r) {
Expand Down Expand Up @@ -961,9 +994,6 @@ int mdnsd_in(mdns_daemon_t *d, struct message *m, struct in_addr ip, unsigned sh
INFO("Got Answer: Name: %s, Type: %d", m->an[i].name, m->an[i].type);
r = _r_next(d, NULL, m->an[i].name, m->an[i].type);
if (r && r->unique && r->modified && _a_match(&m->an[i], &r->rr)) {
/* double check, is this actually from us, looped back? */
if (ip.s_addr == d->addr.s_addr)
continue;
_conflict(d, r);
}

Expand Down
Loading