Support specifying instance name in JSON file
[project/mdnsd.git] / cache.c
diff --git a/cache.c b/cache.c
index 0e92137b391a2ea37f1e5716c1683d75aeaa68ba..7d2aa8fdba2d467320c74cc4db53990dfc9db01c 100644 (file)
--- a/cache.c
+++ b/cache.c
@@ -76,11 +76,12 @@ cache_gc_timer(struct uloop_timeout *timeout)
        struct cache_service *s, *t;
 
        avl_for_each_element_safe(&records, r, avl, p) {
-               if (!cache_is_expired(r->time, r->ttl, 100))
+               if (!cache_is_expired(r->time, r->ttl, r->refresh))
                        continue;
-               /* Records other and A(AAA) are handled as services */
+               /* Records other than A(AAA) are handled as services */
                if (r->type != TYPE_A && r->type != TYPE_AAAA) {
-                       cache_record_free(r);
+                       if (cache_is_expired(r->time, r->ttl, 100))
+                               cache_record_free(r);
                        continue;
                }
                if (r->refresh >= 100) {
@@ -88,7 +89,7 @@ cache_gc_timer(struct uloop_timeout *timeout)
                        continue;
                }
                r->refresh += 50;
-               dns_send_question(r->iface, r->record, r->type, 0);
+               dns_send_question(r->iface, (struct sockaddr *)&r->from, r->record, r->type, 0);
        }
 
        avl_for_each_element_safe(&services, s, avl, t) {
@@ -101,7 +102,7 @@ cache_gc_timer(struct uloop_timeout *timeout)
                        continue;
                }
                s->refresh += 50;
-               dns_send_question(s->iface, s->entry, TYPE_PTR, 0);
+               dns_send_question(s->iface, NULL, s->entry, TYPE_PTR, 0);
        }
 
        uloop_timeout_set(timeout, 10000);
@@ -140,7 +141,7 @@ cache_update(void)
 
        vlist_for_each_element(&interfaces, iface, node)
                avl_for_each_element(&services, s, avl)
-                       dns_send_question(iface, s->entry, TYPE_PTR, 0);
+                       dns_send_question(iface, NULL, s->entry, TYPE_PTR, 0);
 }
 
 static struct cache_service*
@@ -180,7 +181,7 @@ cache_service(struct interface *iface, char *entry, int hlen, int ttl)
        avl_insert(&services, &s->avl);
 
        if (!hlen)
-               dns_send_question(iface, entry, TYPE_PTR, iface->multicast);
+               dns_send_question(iface, NULL, entry, TYPE_PTR, iface->multicast);
 
        return s;
 }
@@ -241,8 +242,9 @@ cache_host_is_known(char *record)
        return 0;
 }
 
-void
-cache_answer(struct interface *iface, uint8_t *base, int blen, char *name, struct dns_answer *a, uint8_t *rdata, int flush)
+void cache_answer(struct interface *iface, struct sockaddr *from, uint8_t *base,
+                 int blen, char *name, struct dns_answer *a, uint8_t *rdata,
+                 int flush)
 {
        struct dns_srv_data *dsd = (struct dns_srv_data *) rdata;
        struct cache_record *r;
@@ -336,9 +338,11 @@ cache_answer(struct interface *iface, uint8_t *base, int blen, char *name, struc
                if (!a->ttl) {
                        DBG(1, "D -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl);
                        r->time = now + 1 - r->ttl;
+                       r->refresh = 100;
                } else {
                        r->ttl = a->ttl;
                        r->time = now;
+                       r->refresh = 50;
                        DBG(1, "A -> %s %s ttl:%d\n", dns_type_string(r->type), r->record, r->ttl);
                }
                return;
@@ -359,6 +363,11 @@ cache_answer(struct interface *iface, uint8_t *base, int blen, char *name, struc
        r->rdlength = dlen;
        r->time = now;
        r->iface = iface;
+       if (iface->v6)
+               memcpy(&r->from, from, sizeof(struct sockaddr_in6));
+       else
+               memcpy(&r->from, from, sizeof(struct sockaddr_in));
+       r->refresh = 50;
 
        if (tlen)
                r->txt = memcpy(txt_ptr, rdata_buffer, tlen);