---
src/connman.h | 10 +++++++
src/resolver.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 906483a..46c6a61 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -145,6 +145,16 @@ 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_register_notifier(const char *interface,
+ gpointer user_data,
+ void (*nameserver_added) (const char *interface,
+ gpointer user_data,
+ const char *nameserver),
+ void (*nameserver_removed) (const char *interface,
+ gpointer user_data,
+ const char *nameserver));
+void __connman_resolver_unregister_notifier(const char *interface);
+
void __connman_storage_migrate(void);
GKeyFile *__connman_storage_open_global();
GKeyFile *__connman_storage_load_global();
diff --git a/src/resolver.c b/src/resolver.c
index 68fa4f7..1d5c61e 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -54,6 +54,22 @@ struct resolvfile_entry {
};
static GList *resolvfile_list = NULL;
+static GHashTable *notifier_hash = NULL;
+
+/*
+ * Notifier notifies the caller about all nameservers
+ * that have a lifetime and were append via netlink
+ */
+struct notifier_data {
+ gchar *interface;
+ gpointer user_data;
+ void (*nameserver_added) (const char *interface,
+ gpointer user_data,
+ const char *nameserver);
+ void (*nameserver_removed) (const char *interface,
+ gpointer user_data,
+ const char *nameserver);
+};
static void resolvfile_remove_entries(GList *entries)
{
@@ -231,12 +247,21 @@ static void remove_entries(GSList *entries)
static gboolean resolver_expire_cb(gpointer user_data)
{
struct entry_data *entry = user_data;
+ struct notifier_data *data;
GSList *list;
DBG("interface %s domain %s server %s",
entry->interface, entry->domain, entry->server);
list = g_slist_append(NULL, entry);
+
+ if (entry->interface != NULL) {
+ data = g_hash_table_lookup(notifier_hash, entry->interface);
+ if (data != NULL)
+ data->nameserver_removed(data->interface,
+ data->user_data, entry->server);
+ }
+
remove_entries(list);
return FALSE;
@@ -304,6 +329,7 @@ int connman_resolver_append(const char *interface, const
char *domain,
int connman_resolver_append_lifetime(const char *interface, const char *domain,
const char *server, unsigned int lifetime)
{
+ struct notifier_data *data;
GSList *list;
DBG("interface %s domain %s server %s lifetime %d",
@@ -327,6 +353,13 @@ int connman_resolver_append_lifetime(const char
*interface, const char *domain,
return 0;
}
+ if (interface != NULL) {
+ data = g_hash_table_lookup(notifier_hash, interface);
+ if (data != NULL)
+ data->nameserver_added(data->interface,
+ data->user_data, server);
+ }
+
return append_resolver(interface, domain, server, lifetime, 0);
}
@@ -443,6 +476,46 @@ void connman_resolver_flush(void)
return;
}
+static void notify_value_free(gpointer user_data)
+{
+ struct notifier_data *data = user_data;
+
+ g_free(data->interface);
+ g_free(data);
+}
+
+int __connman_resolver_register_notifier(const char *interface,
+ gpointer user_data,
+ void (*nameserver_added) (const char *interface,
+ gpointer user_data,
+ const char *nameserver),
+ void (*nameserver_removed) (const char *interface,
+ gpointer user_data,
+ const char *nameserver))
+{
+ struct notifier_data *data;
+ gchar *iface;
+
+ data = g_try_new(struct notifier_data, 1);
+ if (data == NULL)
+ return -ENOMEM;
+
+ data->user_data = user_data;
+ data->nameserver_added = nameserver_added;
+ data->nameserver_removed = nameserver_removed;
+ data->interface = g_strdup(interface);
+
+ iface = g_strdup(interface);
+
+ g_hash_table_replace(notifier_hash, iface, data);
+ return 0;
+}
+
+void __connman_resolver_unregister_notifier(const char *interface)
+{
+ g_hash_table_remove(notifier_hash, interface);
+}
+
int __connman_resolver_init(connman_bool_t dnsproxy)
{
DBG("dnsproxy %d", dnsproxy);
@@ -450,6 +523,9 @@ int __connman_resolver_init(connman_bool_t dnsproxy)
if (dnsproxy == FALSE)
return 0;
+ notifier_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, notify_value_free);
+
if (__connman_dnsproxy_init() < 0) {
/* Fall back to resolv.conf */
return 0;
@@ -466,4 +542,7 @@ void __connman_resolver_cleanup(void)
if (dnsproxy_enabled == TRUE)
__connman_dnsproxy_cleanup();
+
+ g_hash_table_destroy(notifier_hash);
+ notifier_hash = NULL;
}
--
1.7.1
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman