From 829f870603a6f6860f45bb1ee20113f3a44e2beb Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Tue, 7 Aug 2018 16:47:30 +0200 Subject: [PATCH] Fix #13: Check if IP address changed since last run, update A records Signed-off-by: Joachim Nilsson --- libmdnsd/mdnsd.c | 37 +++++++++++++++++++++++++++++++++---- src/mdnsd.c | 16 ++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/libmdnsd/mdnsd.c b/libmdnsd/mdnsd.c index d1a7d81..3069448 100644 --- a/libmdnsd/mdnsd.c +++ b/libmdnsd/mdnsd.c @@ -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; @@ -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 */ @@ -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; } @@ -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 @@ -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; } @@ -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)) @@ -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) diff --git a/src/mdnsd.c b/src/mdnsd.c index 40064fd..b998887 100644 --- a/src/mdnsd.c +++ b/src/mdnsd.c @@ -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; @@ -202,6 +203,7 @@ int main(int argc, char *argv[]) switch (c) { case 'a': inet_aton(optarg, &ina); + autoip = 0; break; case 'h': @@ -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)); @@ -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));