diff options
author | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2011-01-26 09:50:33 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2011-01-26 09:56:25 +0100 |
commit | 2abadb22447f8d693c4cc7bae00b8cf869b625fa (patch) | |
tree | 9f69ed784956b23446cf9f6ea37caee7518f5e46 /src/resolver.c | |
parent | c04a2f0f523c6f27966182283710f67d3fdcc1e3 (diff) | |
download | connman-2abadb22447f8d693c4cc7bae00b8cf869b625fa.tar.gz connman-2abadb22447f8d693c4cc7bae00b8cf869b625fa.tar.bz2 connman-2abadb22447f8d693c4cc7bae00b8cf869b625fa.zip |
resolver: Only support resolv.conf and dnsproxy
Remove resolver module support.
Diffstat (limited to 'src/resolver.c')
-rw-r--r-- | src/resolver.c | 400 |
1 files changed, 155 insertions, 245 deletions
diff --git a/src/resolver.c b/src/resolver.c index 6ee4d483..42be0304 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -36,7 +36,6 @@ #define RESOLVER_FLAG_PUBLIC (1 << 0) struct entry_data { - struct connman_resolver *resolver; char *interface; char *domain; char *server; @@ -45,99 +44,187 @@ struct entry_data { }; static GSList *entry_list = NULL; -static GSList *resolver_list = NULL; +static connman_bool_t dnsproxy_enabled = FALSE; -static void remove_entries(GSList *entries) +struct resolvfile_entry { + char *interface; + char *domain; + char *server; +}; + +static GList *resolvfile_list = NULL; + +static void resolvfile_remove_entries(GList *entries) { - GSList *list; + GList *list; for (list = entries; list; list = list->next) { - struct entry_data *entry = list->data; - struct connman_resolver *resolver = entry->resolver; - - entry_list = g_slist_remove(entry_list, entry); + struct resolvfile_entry *entry = list->data; - if (resolver && resolver->remove) - resolver->remove(entry->interface, entry->domain, - entry->server); + resolvfile_list = g_list_remove(resolvfile_list, entry); - if (entry->timeout) - g_source_remove(entry->timeout); g_free(entry->server); g_free(entry->domain); g_free(entry->interface); g_free(entry); } - g_slist_free(entries); + g_list_free(entries); } -static gint compare_priority(gconstpointer a, gconstpointer b) +static int resolvfile_export(void) { - const struct connman_resolver *resolver1 = a; - const struct connman_resolver *resolver2 = b; + GList *list; + GString *content; + int fd, err; + unsigned int count; + mode_t old_umask; - return resolver2->priority - resolver1->priority; -} + content = g_string_new("# Generated by Connection Manager\n"); -/** - * connman_resolver_register: - * @resolver: resolver module - * - * Register a new resolver module - * - * Returns: %0 on success - */ -int connman_resolver_register(struct connman_resolver *resolver) -{ - GSList *list; + /* + * Domains and nameservers are added in reverse so that the most + * recently appended entry is the primary one. No more than + * MAXDNSRCH/MAXNS entries are used. + */ - DBG("resolver %p name %s", resolver, resolver->name); + for (count = 0, list = g_list_last(resolvfile_list); + list && (count < MAXDNSRCH); + list = g_list_previous(list)) { + struct resolvfile_entry *entry = list->data; - resolver_list = g_slist_insert_sorted(resolver_list, resolver, - compare_priority); + if (!entry->domain) + continue; - if (resolver->append == NULL) - return 0; + if (count == 0) + g_string_append_printf(content, "search "); - for (list = entry_list; list; list = list->next) { - struct entry_data *entry = list->data; + g_string_append_printf(content, "%s ", entry->domain); + count++; + } + + if (count) + g_string_append_printf(content, "\n"); + + for (count = 0, list = g_list_last(resolvfile_list); + list && (count < MAXNS); + list = g_list_previous(list)) { + struct resolvfile_entry *entry = list->data; - if (entry->resolver) + if (!entry->server) continue; - if (resolver->append(entry->interface, entry->domain, - entry->server) == 0) - entry->resolver = resolver; + g_string_append_printf(content, "nameserver %s\n", + entry->server); + count++; } - return 0; + old_umask = umask(022); + + fd = open("/etc/resolv.conf", O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + err = -errno; + goto done; + } + + if (ftruncate(fd, 0) < 0) { + err = -errno; + goto failed; + } + + err = 0; + + if (write(fd, content->str, content->len) < 0) + err = -errno; + +failed: + close(fd); + +done: + g_string_free(content, TRUE); + umask(old_umask); + + return err; } -/** - * connman_resolver_unregister: - * @resolver: resolver module - * - * Remove a previously registered resolver module - */ -void connman_resolver_unregister(struct connman_resolver *resolver) +int __connman_resolvfile_append(const char *interface, const char *domain, + const char *server) { - GSList *list, *matches = NULL; + struct resolvfile_entry *entry; + + DBG("interface %s server %s", interface, server); + + if (interface == NULL) + return -ENOENT; - DBG("resolver %p name %s", resolver, resolver->name); + entry = g_try_new0(struct resolvfile_entry, 1); + if (entry == NULL) + return -ENOMEM; - resolver_list = g_slist_remove(resolver_list, resolver); + entry->interface = g_strdup(interface); + entry->domain = g_strdup(domain); + entry->server = g_strdup(server); - for (list = entry_list; list; list = list->next) { - struct entry_data *entry = list->data; + resolvfile_list = g_list_append(resolvfile_list, entry); - if (entry->resolver != resolver) + return resolvfile_export(); +} + +int __connman_resolvfile_remove(const char *interface, const char *domain, + const char *server) +{ + GList *list, *matches = NULL; + + DBG("interface %s server %s", interface, server); + + for (list = resolvfile_list; list; list = g_list_next(list)) { + struct resolvfile_entry *entry = list->data; + + if (interface != NULL && + g_strcmp0(entry->interface, interface) != 0) continue; - matches = g_slist_append(matches, entry); + if (domain != NULL && g_strcmp0(entry->domain, domain) != 0) + continue; + + if (g_strcmp0(entry->server, server) != 0) + continue; + + matches = g_list_append(matches, entry); } - remove_entries(matches); + resolvfile_remove_entries(matches); + + return resolvfile_export(); +} + +static void remove_entries(GSList *entries) +{ + GSList *list; + + for (list = entries; list; list = list->next) { + struct entry_data *entry = list->data; + + entry_list = g_slist_remove(entry_list, entry); + + if (dnsproxy_enabled == TRUE) { + __connman_dnsproxy_remove(entry->interface, entry->domain, + entry->server); + } else { + __connman_resolvfile_remove(entry->interface, entry->domain, + entry->server); + } + + if (entry->timeout) + g_source_remove(entry->timeout); + g_free(entry->server); + g_free(entry->domain); + g_free(entry->interface); + g_free(entry); + } + + g_slist_free(entries); } static gboolean resolver_expire_cb(gpointer user_data) @@ -159,7 +246,6 @@ static int append_resolver(const char *interface, const char *domain, unsigned int flags) { struct entry_data *entry; - GSList *list; DBG("interface %s domain %s server %s lifetime %d flags %d", interface, domain, server, lifetime, flags); @@ -182,17 +268,10 @@ static int append_resolver(const char *interface, const char *domain, entry_list = g_slist_append(entry_list, entry); - for (list = resolver_list; list; list = list->next) { - struct connman_resolver *resolver = list->data; - - if (resolver->append == NULL) - continue; - - if (resolver->append(interface, domain, server) == 0) { - entry->resolver = resolver; - break; - } - } + if (dnsproxy_enabled == TRUE) + __connman_dnsproxy_append(interface, domain, server); + else + __connman_resolvfile_append(interface, domain, server); return 0; } @@ -206,7 +285,7 @@ static int append_resolver(const char *interface, const char *domain, * Append resolver server address to current list */ int connman_resolver_append(const char *interface, const char *domain, - const char *server) + const char *server) { DBG("interface %s domain %s server %s", interface, domain, server); @@ -358,190 +437,21 @@ int connman_resolver_remove_public_server(const char *server) */ void connman_resolver_flush(void) { - GSList *list; - - for (list = resolver_list; list; list = list->next) { - struct connman_resolver *resolver = list->data; - - if (resolver->flush == NULL) - continue; - - resolver->flush(); - } + if (dnsproxy_enabled == TRUE) + __connman_dnsproxy_flush(); return; } -struct resolvfile_entry { - char *interface; - char *domain; - char *server; -}; - -static GList *resolvfile_list = NULL; - -static void resolvfile_remove_entries(GList *entries) -{ - GList *list; - - for (list = entries; list; list = list->next) { - struct resolvfile_entry *entry = list->data; - - resolvfile_list = g_list_remove(resolvfile_list, entry); - - g_free(entry->server); - g_free(entry->domain); - g_free(entry->interface); - g_free(entry); - } - - g_list_free(entries); -} - -static int resolvfile_export(void) -{ - GList *list; - GString *content; - int fd, err; - unsigned int count; - mode_t old_umask; - - content = g_string_new("# Generated by Connection Manager\n"); - - /* - * Domains and nameservers are added in reverse so that the most - * recently appended entry is the primary one. No more than - * MAXDNSRCH/MAXNS entries are used. - */ - - for (count = 0, list = g_list_last(resolvfile_list); - list && (count < MAXDNSRCH); - list = g_list_previous(list)) { - struct resolvfile_entry *entry = list->data; - - if (!entry->domain) - continue; - - if (count == 0) - g_string_append_printf(content, "search "); - - g_string_append_printf(content, "%s ", entry->domain); - count++; - } - - if (count) - g_string_append_printf(content, "\n"); - - for (count = 0, list = g_list_last(resolvfile_list); - list && (count < MAXNS); - list = g_list_previous(list)) { - struct resolvfile_entry *entry = list->data; - - if (!entry->server) - continue; - - g_string_append_printf(content, "nameserver %s\n", - entry->server); - count++; - } - - old_umask = umask(022); - - fd = open("/etc/resolv.conf", O_RDWR | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) { - err = -errno; - goto done; - } - - if (ftruncate(fd, 0) < 0) { - err = -errno; - goto failed; - } - - err = 0; - - if (write(fd, content->str, content->len) < 0) - err = -errno; - -failed: - close(fd); - -done: - g_string_free(content, TRUE); - umask(old_umask); - - return err; -} - -static int resolvfile_append(const char *interface, const char *domain, - const char *server) +int __connman_resolver_init(connman_bool_t dnsproxy) { - struct resolvfile_entry *entry; + DBG("dnsproxy %d", dnsproxy); - DBG("interface %s server %s", interface, server); - - if (interface == NULL) - return -ENOENT; - - entry = g_try_new0(struct resolvfile_entry, 1); - if (entry == NULL) - return -ENOMEM; - - entry->interface = g_strdup(interface); - entry->domain = g_strdup(domain); - entry->server = g_strdup(server); - - resolvfile_list = g_list_append(resolvfile_list, entry); - - return resolvfile_export(); -} - -static int resolvfile_remove(const char *interface, const char *domain, - const char *server) -{ - GList *list, *matches = NULL; - - DBG("interface %s server %s", interface, server); - - for (list = resolvfile_list; list; list = g_list_next(list)) { - struct resolvfile_entry *entry = list->data; - - if (interface != NULL && - g_strcmp0(entry->interface, interface) != 0) - continue; - - if (domain != NULL && g_strcmp0(entry->domain, domain) != 0) - continue; - - if (g_strcmp0(entry->server, server) != 0) - continue; - - matches = g_list_append(matches, entry); - } - - resolvfile_remove_entries(matches); - - return resolvfile_export(); -} - -static struct connman_resolver resolvfile_resolver = { - .name = "resolvfile", - .priority = CONNMAN_RESOLVER_PRIORITY_LOW, - .append = resolvfile_append, - .remove = resolvfile_remove, -}; - -int __connman_resolver_init(void) -{ - DBG(""); - - return connman_resolver_register(&resolvfile_resolver); + dnsproxy_enabled = dnsproxy; + return 0; } void __connman_resolver_cleanup(void) { DBG(""); - - connman_resolver_unregister(&resolvfile_resolver); } |