summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/connman.h1
-rw-r--r--src/resolver.c33
-rw-r--r--src/rtnl.c14
3 files changed, 48 insertions, 0 deletions
diff --git a/src/connman.h b/src/connman.h
index 97e5437f..be3a2c12 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -196,6 +196,7 @@ int __connman_resolver_init(connman_bool_t dnsproxy);
void __connman_resolver_cleanup(void);
int __connman_resolvfile_append(const char *interface, const char *domain, const char *server);
int __connman_resolvfile_remove(const char *interface, const char *domain, const char *server);
+int __connman_resolver_redo_servers(const char *interface);
void __connman_storage_migrate(void);
GKeyFile *__connman_storage_open_global();
diff --git a/src/resolver.c b/src/resolver.c
index 9796717f..cead9c32 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -468,6 +468,39 @@ void connman_resolver_flush(void)
return;
}
+int __connman_resolver_redo_servers(const char *interface)
+{
+ GSList *list;
+
+ if (dnsproxy_enabled == FALSE)
+ return 0;
+
+ DBG("interface %s", interface);
+
+ if (interface == NULL)
+ return -EINVAL;
+
+ for (list = entry_list; list; list = list->next) {
+ struct entry_data *entry = list->data;
+
+ if (entry->timeout == 0 ||
+ g_strcmp0(entry->interface, interface) != 0)
+ continue;
+
+ /*
+ * We remove the server, and then re-create so that it will
+ * use proper source addresses when sending DNS queries.
+ */
+ __connman_dnsproxy_remove(entry->interface, entry->domain,
+ entry->server);
+
+ __connman_dnsproxy_append(entry->interface, entry->domain,
+ entry->server);
+ }
+
+ return 0;
+}
+
static void free_entry(gpointer data)
{
struct entry_data *entry = data;
diff --git a/src/rtnl.c b/src/rtnl.c
index 39afb12b..251d9cd9 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -601,6 +601,20 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen,
__connman_ipconfig_newaddr(index, family, label,
prefixlen, ip_string);
+
+ if (family == AF_INET6) {
+ /*
+ * Re-create RDNSS configured servers if there are any
+ * for this interface. This is done because we might
+ * have now properly configured interface with proper
+ * autoconfigured address.
+ */
+ char *interface = connman_inet_ifname(index);
+
+ __connman_resolver_redo_servers(interface);
+
+ g_free(interface);
+ }
}
static void process_deladdr(unsigned char family, unsigned char prefixlen,