---
 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

Reply via email to