X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fresolver.c;h=8bfea3ce34bd3343ac05ad9e1dc381a4ecdd23f9;hb=f2a9f93bbb2df62e3b3246ea253f8aaae29234d2;hp=6a64938842c5e1565e2df0268ea3a04d6ff2172d;hpb=6aa4055ef0544ae85457c25c510fe3db04949c43;p=platform%2Fupstream%2Fconnman.git diff --git a/src/resolver.c b/src/resolver.c index 6a64938..8bfea3c 100755 --- a/src/resolver.c +++ b/src/resolver.c @@ -23,7 +23,6 @@ #include #endif -#define _GNU_SOURCE #include #include #include @@ -35,6 +34,19 @@ #include "connman.h" +/* + * Just to avoid build failure due to missing STATEDIR + */ +#if defined TIZEN_EXT +#ifdef STATEDIR +#undef STATEDIR +#endif +#define STATEDIR "/etc" +#endif + +#define RESOLV_CONF_STATEDIR STATEDIR"/resolv.conf" +#define RESOLV_CONF_ETC "/etc/resolv.conf" + #define RESOLVER_FLAG_PUBLIC (1 << 0) /* @@ -81,9 +93,22 @@ static void resolvfile_remove_entries(GList *entries) g_list_free(entries); } -static int resolvfile_export(void) +static bool already_exported(GList *export_list, const char *str) { GList *list; + + for (list = export_list; list; list = g_list_next(list)) { + const char *str0 = list->data; + if (g_strcmp0(str0, str) == 0) + return true; + } + + return false; +} + +static int resolvfile_export(void) +{ + GList *list, *export_list; GString *content; int fd, err; unsigned int count; @@ -97,44 +122,68 @@ static int resolvfile_export(void) * MAXDNSRCH/MAXNS entries are used. */ - for (count = 0, list = g_list_last(resolvfile_list); + export_list = NULL; + for (count = 0, list = g_list_first(resolvfile_list); list && (count < MAXDNSRCH); - list = g_list_previous(list)) { + list = g_list_next(list)) { struct resolvfile_entry *entry = list->data; if (!entry->domain) continue; + if (already_exported(export_list, entry->domain)) + continue; + if (count == 0) g_string_append_printf(content, "search "); g_string_append_printf(content, "%s ", entry->domain); + + export_list = g_list_append(export_list, entry->domain); + count++; } + g_list_free(export_list); + if (count) g_string_append_printf(content, "\n"); - for (count = 0, list = g_list_last(resolvfile_list); + export_list = NULL; + for (count = 0, list = g_list_first(resolvfile_list); list && (count < MAXNS); - list = g_list_previous(list)) { + list = g_list_next(list)) { struct resolvfile_entry *entry = list->data; if (!entry->server) continue; - g_string_append_printf(content, "nameserver %s\n", - entry->server); + if (already_exported(export_list, entry->server)) + continue; + + g_string_append_printf(content, "nameserver %s\n", entry->server); + + export_list = g_list_append(export_list, entry->server); + count++; } + g_list_free(export_list); old_umask = umask(022); - fd = open("/etc/resolv.conf", O_RDWR | O_CREAT | O_CLOEXEC, + fd = open(RESOLV_CONF_STATEDIR, O_RDWR | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { - err = -errno; - goto done; + connman_warn_once("Cannot create "RESOLV_CONF_STATEDIR" " + "falling back to "RESOLV_CONF_ETC); + + fd = open(RESOLV_CONF_ETC, O_RDWR | O_CREAT | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if (fd < 0) { + err = -errno; + goto done; + } } if (ftruncate(fd, 0) < 0) { @@ -162,7 +211,7 @@ int __connman_resolvfile_append(int index, const char *domain, { struct resolvfile_entry *entry; - DBG("index %d server %s", index, server); + DBG("index %d domain %s server %s", index, domain, server); if (index < 0) return -ENOENT; @@ -185,7 +234,7 @@ int __connman_resolvfile_remove(int index, const char *domain, { GList *list, *matches = NULL; - DBG("index %d server %s", index, server); + DBG("index %d domain %s server %s", index, domain, server); for (list = resolvfile_list; list; list = g_list_next(list)) { struct resolvfile_entry *entry = list->data; @@ -207,7 +256,7 @@ int __connman_resolvfile_remove(int index, const char *domain, return resolvfile_export(); } -static void append_fallback_nameservers(void) +void __connman_resolver_append_fallback_nameservers(void) { GSList *list; @@ -284,7 +333,7 @@ static void remove_entries(GSList *entries) g_slist_free(entries); - append_fallback_nameservers(); + __connman_resolver_append_fallback_nameservers(); } static gboolean resolver_expire_cb(gpointer user_data) @@ -301,8 +350,14 @@ static gboolean resolver_expire_cb(gpointer user_data) struct connman_service *service; service = __connman_service_lookup_from_index(entry->index); if (service) +#if defined TIZEN_EXT + __connman_service_nameserver_remove(service, + entry->server, true, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_remove(service, entry->server, true); +#endif } remove_entries(list); @@ -356,6 +411,11 @@ static int append_resolver(int index, const char *domain, if (!server && !domain) return -EINVAL; +#ifdef TIZEN_EXT + if (g_strcmp0(server, "0.0.0.0") == 0) + return -EINVAL; +#endif + entry = g_try_new0(struct entry_data, 1); if (!entry) return -ENOMEM; @@ -378,18 +438,6 @@ static int append_resolver(int index, const char *domain, entry->timeout = g_timeout_add_seconds(interval, resolver_refresh_cb, entry); - - /* - * We update the service only for those nameservers - * that are automagically added via netlink (lifetime > 0) - */ - if (server && entry->index >= 0) { - struct connman_service *service; - service = __connman_service_lookup_from_index(entry->index); - if (service) - __connman_service_nameserver_append(service, - server, true); - } } if (entry->index >= 0 && entry->server) @@ -402,6 +450,24 @@ static int append_resolver(int index, const char *domain, else __connman_resolvfile_append(entry->index, domain, server); + /* + * We update the service only for those nameservers + * that are automagically added via netlink (lifetime > 0) + */ + if (server && entry->index >= 0 && lifetime) { + struct connman_service *service; + service = __connman_service_lookup_from_index(entry->index); + if (service) +#if defined TIZEN_EXT + __connman_service_nameserver_append(service, + server, true, + CONNMAN_IPCONFIG_TYPE_ALL); +#else + __connman_service_nameserver_append(service, + server, true); +#endif + } + return 0; } @@ -600,6 +666,28 @@ int __connman_resolver_redo_servers(int index) entry->server); } + /* + * We want to re-add all search domains back to search + * domain lists as they just got removed for RDNSS IPv6-servers + * (above). + * Removal of search domains is not necessary + * as there can be only one instance of each search domain + * in the each dns-servers search domain list. + */ + + for (list = entry_list; list; list = list->next) { + struct entry_data *entry = list->data; + + if (entry->index != index) + continue; + + if (entry->server) + continue; + + __connman_dnsproxy_append(entry->index, entry->domain, + NULL); + } + return 0; } @@ -619,6 +707,14 @@ static void free_resolvfile(gpointer data) g_free(entry); } +int __connman_resolver_set_mdns(int index, bool enabled) +{ + if (!dnsproxy_enabled) + return -ENOTSUP; + + return __connman_dnsproxy_set_mdns(index, enabled); +} + int __connman_resolver_init(gboolean dnsproxy) { int i; @@ -626,6 +722,14 @@ int __connman_resolver_init(gboolean dnsproxy) DBG("dnsproxy %d", dnsproxy); + /* get autoip nameservers */ + ns = __connman_inet_get_pnp_nameservers(NULL); + for (i = 0; ns && ns[i]; i += 1) { + DBG("pnp server %s", ns[i]); + append_resolver(i, NULL, ns[i], 86400, 0); + } + g_strfreev(ns); + if (!dnsproxy) return 0;