chiark / gitweb /
resolved: flush cache each time we change to a different DNS server
authorLennart Poettering <lennart@poettering.net>
Fri, 1 Aug 2014 16:09:07 +0000 (18:09 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 1 Aug 2014 16:10:01 +0000 (18:10 +0200)
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-scope.h
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-link.c
src/resolve/resolved-link.h
src/resolve/resolved-manager.c
src/resolve/resolved-manager.h

index 42a2fc4c774c3fbc923acc6f8075626c3901d703..291d0356be83011cac7ad940e2847d9ad7a3d8cb 100644 (file)
@@ -85,7 +85,7 @@ DnsScope* dns_scope_free(DnsScope *s) {
         return NULL;
 }
 
         return NULL;
 }
 
-DnsServer *dns_scope_get_server(DnsScope *s) {
+DnsServer *dns_scope_get_dns_server(DnsScope *s) {
         assert(s);
 
         if (s->protocol != DNS_PROTOCOL_DNS)
         assert(s);
 
         if (s->protocol != DNS_PROTOCOL_DNS)
@@ -133,7 +133,7 @@ int dns_scope_send(DnsScope *s, DnsPacket *p) {
                 if (DNS_PACKET_QDCOUNT(p) > 1)
                         return -ENOTSUP;
 
                 if (DNS_PACKET_QDCOUNT(p) > 1)
                         return -ENOTSUP;
 
-                srv = dns_scope_get_server(s);
+                srv = dns_scope_get_dns_server(s);
                 if (!srv)
                         return -ESRCH;
 
                 if (!srv)
                         return -ESRCH;
 
@@ -197,7 +197,7 @@ int dns_scope_tcp_socket(DnsScope *s, int family, const union in_addr_union *add
         if (family == AF_UNSPEC) {
                 DnsServer *srv;
 
         if (family == AF_UNSPEC) {
                 DnsServer *srv;
 
-                srv = dns_scope_get_server(s);
+                srv = dns_scope_get_dns_server(s);
                 if (!srv)
                         return -ESRCH;
 
                 if (!srv)
                         return -ESRCH;
 
@@ -384,7 +384,7 @@ int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union
         if (s->link)
                 return !!link_find_dns_server(s->link,  family, address);
         else
         if (s->link)
                 return !!link_find_dns_server(s->link,  family, address);
         else
-                return manager_known_dns_server(s->manager, family, address);
+                return !!manager_find_dns_server(s->manager, family, address);
 }
 
 static int dns_scope_make_reply_packet(
 }
 
 static int dns_scope_make_reply_packet(
index 8f420683443c9abf3ceab2dfe5a9e57a0445fed1..313c6178dd03d34eccabbc67b0a30c82c689dae8 100644 (file)
@@ -70,7 +70,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, const char *domain);
 int dns_scope_good_key(DnsScope *s, DnsResourceKey *key);
 int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union *address);
 
 int dns_scope_good_key(DnsScope *s, DnsResourceKey *key);
 int dns_scope_good_dns_server(DnsScope *s, int family, const union in_addr_union *address);
 
-DnsServer *dns_scope_get_server(DnsScope *s);
+DnsServer *dns_scope_get_dns_server(DnsScope *s);
 void dns_scope_next_dns_server(DnsScope *s);
 
 int dns_scope_llmnr_membership(DnsScope *s, bool b);
 void dns_scope_next_dns_server(DnsScope *s);
 
 int dns_scope_llmnr_membership(DnsScope *s, bool b);
index 2c413370ea003a4d2aac8d209d73660fe5f28e7a..30d9c8b34ed90fcccefc7a3ef6549e4acbb5b23e 100644 (file)
@@ -64,7 +64,7 @@ int dns_server_new(
         if (type != DNS_SERVER_FALLBACK &&
             s->manager->current_dns_server &&
             s->manager->current_dns_server->type == DNS_SERVER_FALLBACK)
         if (type != DNS_SERVER_FALLBACK &&
             s->manager->current_dns_server &&
             s->manager->current_dns_server->type == DNS_SERVER_FALLBACK)
-                s->manager->current_dns_server = NULL;
+                manager_set_dns_server(s->manager, NULL);
 
         if (ret)
                 *ret = s;
 
         if (ret)
                 *ret = s;
@@ -88,10 +88,10 @@ DnsServer* dns_server_free(DnsServer *s)  {
         }
 
         if (s->link && s->link->current_dns_server == s)
         }
 
         if (s->link && s->link->current_dns_server == s)
-                s->link->current_dns_server = NULL;
+                link_set_dns_server(s->link, NULL);
 
         if (s->manager && s->manager->current_dns_server == s)
 
         if (s->manager && s->manager->current_dns_server == s)
-                s->manager->current_dns_server = NULL;
+                manager_set_dns_server(s->manager, NULL);
 
         free(s);
 
 
         free(s);
 
index faa1de9143a275b525d77b0a6f5aecbbb0ab5bcc..48da432a1200f94fb2b6105801e790aa24eaae8d 100644 (file)
@@ -465,12 +465,19 @@ int dns_transaction_go(DnsTransaction *t) {
         t->cached = dns_answer_unref(t->cached);
         t->cached_rcode = 0;
 
         t->cached = dns_answer_unref(t->cached);
         t->cached_rcode = 0;
 
-        /* First, let's try the cache */
+        /* Before trying the cache, let's make sure we figured out a
+         * server to use. Should this cause a change of server this
+         * might flush the cache. */
+        dns_scope_get_dns_server(t->scope);
+
+        /* Let's then prune all outdated entries */
         dns_cache_prune(&t->scope->cache);
         dns_cache_prune(&t->scope->cache);
+
         r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
         if (r < 0)
                 return r;
         if (r > 0) {
         r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
         if (r < 0)
                 return r;
         if (r > 0) {
+                log_debug("Cache hit!");
                 if (t->cached_rcode == DNS_RCODE_SUCCESS)
                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
                 else
                 if (t->cached_rcode == DNS_RCODE_SUCCESS)
                         dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
                 else
@@ -478,6 +485,8 @@ int dns_transaction_go(DnsTransaction *t) {
                 return 0;
         }
 
                 return 0;
         }
 
+        log_debug("Cache miss!");
+
         /* Otherwise, we need to ask the network */
         r = dns_transaction_make_packet(t);
         if (r == -EDOM) {
         /* Otherwise, we need to ask the network */
         r = dns_transaction_make_packet(t);
         if (r == -EDOM) {
index 7418ea1ed99111951713b39b1672e2090c260c02..2c02f0947305e1acf4d880ea99d6352e3e9fe715 100644 (file)
@@ -248,7 +248,7 @@ DnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *
         return NULL;
 }
 
         return NULL;
 }
 
-static DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
+DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
         assert(l);
 
         if (l->current_dns_server == s)
         assert(l);
 
         if (l->current_dns_server == s)
@@ -259,10 +259,13 @@ static DnsServer* link_set_dns_server(Link *l, DnsServer *s) {
 
                 in_addr_to_string(s->family, &s->address, &ip);
                 log_info("Switching to DNS server %s for interface %s.", strna(ip), l->name);
 
                 in_addr_to_string(s->family, &s->address, &ip);
                 log_info("Switching to DNS server %s for interface %s.", strna(ip), l->name);
-        } else
-                log_info("No DNS server set for interface %s.", l->name);
+        }
 
         l->current_dns_server = s;
 
         l->current_dns_server = s;
+
+        if (l->unicast_scope)
+                dns_cache_flush(&l->unicast_scope->cache);
+
         return s;
 }
 
         return s;
 }
 
index d29311e04929cf237204f86480a1031b6b4f41f3..38bb39271002fbceb33aac663eb48c71381bed3d 100644 (file)
@@ -77,6 +77,8 @@ int link_update_monitor(Link *l);
 bool link_relevant(Link *l, int family);
 LinkAddress* link_find_address(Link *l, int family, const union in_addr_union *in_addr);
 void link_add_rrs(Link *l, bool force_remove);
 bool link_relevant(Link *l, int family);
 LinkAddress* link_find_address(Link *l, int family, const union in_addr_union *in_addr);
 void link_add_rrs(Link *l, bool force_remove);
+
+DnsServer* link_set_dns_server(Link *l, DnsServer *s);
 DnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr);
 DnsServer* link_get_dns_server(Link *l);
 void link_next_dns_server(Link *l);
 DnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr);
 DnsServer* link_get_dns_server(Link *l);
 void link_next_dns_server(Link *l);
index ba2380d68287dd9c1df085fef52b40cecb6f6015..5ed7a9fd1c62b659c2bdd9f95e5b216eb3f47d29 100644 (file)
@@ -1053,7 +1053,7 @@ int manager_send(Manager *m, int fd, int ifindex, int family, const union in_add
         return -EAFNOSUPPORT;
 }
 
         return -EAFNOSUPPORT;
 }
 
-bool manager_known_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
+DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
         DnsServer *s;
 
         assert(m);
         DnsServer *s;
 
         assert(m);
@@ -1061,16 +1061,16 @@ bool manager_known_dns_server(Manager *m, int family, const union in_addr_union
 
         LIST_FOREACH(servers, s, m->dns_servers)
                 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
 
         LIST_FOREACH(servers, s, m->dns_servers)
                 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
-                        return true;
+                        return s;
 
         LIST_FOREACH(servers, s, m->fallback_dns_servers)
                 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
 
         LIST_FOREACH(servers, s, m->fallback_dns_servers)
                 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
-                        return true;
+                        return s;
 
 
-        return false;
+        return NULL;
 }
 
 }
 
-static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
+DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
         assert(m);
 
         if (m->current_dns_server == s)
         assert(m);
 
         if (m->current_dns_server == s)
@@ -1081,10 +1081,13 @@ static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
 
                 in_addr_to_string(s->family, &s->address, &ip);
                 log_info("Switching to system DNS server %s.", strna(ip));
 
                 in_addr_to_string(s->family, &s->address, &ip);
                 log_info("Switching to system DNS server %s.", strna(ip));
-        } else
-                log_info("No system DNS server set.");
+        }
 
         m->current_dns_server = s;
 
         m->current_dns_server = s;
+
+        if (m->unicast_scope)
+                dns_cache_flush(&m->unicast_scope->cache);
+
         return s;
 }
 
         return s;
 }
 
index 7bb18c0d666ada6286a50023cc8d39f606ae40b4..31d670da44e9804f301d6224e130c0e6abb76dff 100644 (file)
@@ -117,7 +117,8 @@ Manager* manager_free(Manager *m);
 int manager_read_resolv_conf(Manager *m);
 int manager_write_resolv_conf(Manager *m);
 
 int manager_read_resolv_conf(Manager *m);
 int manager_write_resolv_conf(Manager *m);
 
-bool manager_known_dns_server(Manager *m, int family, const union in_addr_union *in_addr);
+DnsServer *manager_set_dns_server(Manager *m, DnsServer *s);
+DnsServer *manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr);
 DnsServer *manager_get_dns_server(Manager *m);
 void manager_next_dns_server(Manager *m);
 
 DnsServer *manager_get_dns_server(Manager *m);
 void manager_next_dns_server(Manager *m);