Skip to content

Commit

Permalink
Fix #13: Check if IP address changed since last run, update A records
Browse files Browse the repository at this point in the history
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
  • Loading branch information
troglobit committed Aug 7, 2018
1 parent cb586c5 commit 829f870
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
37 changes: 33 additions & 4 deletions libmdnsd/mdnsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct cached {
struct mdns_record {
struct mdns_answer rr;
char unique; /* # of checks performed to ensure */
int modified; /* Ignore conflicts after update at runtime */
int tries;
void (*conflict)(char *, int, void *);
void *arg;
Expand Down Expand Up @@ -262,6 +263,8 @@ static void _r_push(mdns_record_t **list, mdns_record_t *r)
/* Force any r out right away, if valid */
static void _r_publish(mdns_daemon_t *d, mdns_record_t *r)
{
r->modified = 1;

if (r->unique && r->unique < 5)
return; /* Probing already */

Expand Down Expand Up @@ -373,7 +376,8 @@ static void _r_done(mdns_daemon_t *d, mdns_record_t *r)
if (d->published[i] == r)
d->published[i] = r->next;
else {
for (cur = d->published[i]; cur && cur->next != r; cur = cur->next) ;
for (cur = d->published[i]; cur && cur->next != r; cur = cur->next)
;
if (cur)
cur->next = r->next;
}
Expand Down Expand Up @@ -570,6 +574,7 @@ static int _r_out(mdns_daemon_t *d, struct message *m, mdns_record_t **list)

_a_copy(m, &r->rr);

r->modified = 0; /* If updated we've now sent the update. */
if (r->rr.ttl == 0) {
/*
* also remove from other lists, because record
Expand Down Expand Up @@ -603,6 +608,30 @@ mdns_daemon_t *mdnsd_new(int class, int frame)

void mdnsd_set_address(mdns_daemon_t *d, struct in_addr addr)
{
int i;

if (!memcmp(&d->addr, &addr, sizeof(d->addr)))
return; /* No change */

for (i = 0; i < SPRIME; i++) {
mdns_record_t *r, *next;

r = d->published[i];
while (r != 0) {
next = r->next;

if (r->rr.type == QTYPE_A) {
mdnsd_set_raw(d, r, (char *)&addr, 4);
// mdnsd_set_ip(d, r, mdnsd_get_address(d));

/* Republish, IP changed */
_r_push(&d->a_pause, r);
}

r = next;
}
}

d->addr = addr;
}

Expand Down Expand Up @@ -744,7 +773,7 @@ int mdnsd_in(mdns_daemon_t *d, struct message *m, unsigned long int ip, unsigned
r_next = _r_next(d, r, m->qd[i].name, m->qd[i].type);

/* probing state, check for conflicts */
if (r->unique && r->unique < 5) {
if (r->unique && r->unique < 5 && !r->modified) {
/* Check all to-be answers against our own */
for (j = 0; j < m->nscount; j++) {
if (m->qd[i].type != m->an[j].type || strcmp(m->qd[i].name, m->an[j].name))
Expand Down Expand Up @@ -797,8 +826,8 @@ int mdnsd_in(mdns_daemon_t *d, struct message *m, unsigned long int ip, unsigned
}

INFO("Got Answer: Name: %s, Type: %d", m->an[i].name, m->an[i].type);
if ((r = _r_next(d, 0, m->an[i].name, m->an[i].type)) != 0 &&
r->unique && _a_match(&m->an[i], &r->rr) == 0)
r = _r_next(d, 0, m->an[i].name, m->an[i].type);
if (r != 0 && r->unique && !r->modified && _a_match(&m->an[i], &r->rr) == 0)
_conflict(d, r);

if (d->received_callback)
Expand Down
16 changes: 10 additions & 6 deletions src/mdnsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ int main(int argc, char *argv[])
char *path;
char address[20];
int persistent = 0;
int autoip = 1;
int ttl = 255;
int c, sd, rc;

Expand All @@ -202,6 +203,7 @@ int main(int argc, char *argv[])
switch (c) {
case 'a':
inet_aton(optarg, &ina);
autoip = 0;
break;

case 'h':
Expand Down Expand Up @@ -255,12 +257,6 @@ int main(int argc, char *argv[])
}
}

if (!ina.s_addr) {
if (!getaddr(iface, address, sizeof(address)))
errx(1, "Cannot find default interface, use -a ADDRESS");
inet_aton(address, &ina);
}

d = mdnsd_new(QCLASS_IN, 1000);
if (!d) {
ERR("Failed creating daemon context: %s", strerror(errno));
Expand Down Expand Up @@ -294,6 +290,14 @@ int main(int argc, char *argv[])
}
}

/* Check if IP address changed, needed to update A records */
if (autoip && iface) {
if (!getaddr(iface, address, sizeof(address)))
errx(1, "Cannot find default interface, use -a ADDRESS");
inet_aton(address, &ina);
mdnsd_set_address(d, ina);
}

rc = mdnsd_step(d, sd, FD_ISSET(sd, &fds), true, &tv);
if (rc == 1) {
ERR("Failed reading from socket %d: %s", errno, strerror(errno));
Expand Down

0 comments on commit 829f870

Please sign in to comment.