From: Patrik Flykt Date: Wed, 21 Nov 2012 14:25:11 +0000 (+0200) Subject: core: Use interface index instead of interface name X-Git-Tag: 1.10~191 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=99e49dd2add20aecafe79b24effb4b87353449f9;p=platform%2Fupstream%2Fconnman.git core: Use interface index instead of interface name Service and network code use only interface indexes. Convert the rest of the code using interface names to use interface indexes instead. The files affected are: include/resolver.h src/connman.h src/dnsproxy.c src/resolver.c src/rtnl.c src/service.c src/tethering.c As the network and service code used interface indexes, the interface name had to be looked up via a SIOCGIFNAME ioctl when needed. If a service was removed due to the interface and network being taken down, the lookup wouldn't work. This caused DNS servers to be left behind with broken sockets since removing the DNS servers was done using the interface name. --- diff --git a/include/resolver.h b/include/resolver.h index 5dcf6982..57cb2870 100644 --- a/include/resolver.h +++ b/include/resolver.h @@ -32,13 +32,13 @@ extern "C" { * @short_description: Functions for registering resolver modules */ -int connman_resolver_append(const char *interface, const char *domain, +int connman_resolver_append(int index, const char *domain, const char *server); -int connman_resolver_append_lifetime(const char *interface, const char *domain, +int connman_resolver_append_lifetime(int index, const char *domain, const char *server, unsigned int lifetime); -int connman_resolver_remove(const char *interface, const char *domain, +int connman_resolver_remove(int index, const char *domain, const char *server); -int connman_resolver_remove_all(const char *interface); +int connman_resolver_remove_all(int index); void connman_resolver_flush(void); diff --git a/src/connman.h b/src/connman.h index 2472dab0..613d1dc9 100644 --- a/src/connman.h +++ b/src/connman.h @@ -204,9 +204,9 @@ int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, 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); +int __connman_resolvfile_append(int index, const char *domain, const char *server); +int __connman_resolvfile_remove(int index, const char *domain, const char *server); +int __connman_resolver_redo_servers(int index); void __connman_storage_migrate(void); GKeyFile *__connman_storage_open_global(void); @@ -790,10 +790,10 @@ int __connman_iptables_commit(const char *table_name); int __connman_dnsproxy_init(void); void __connman_dnsproxy_cleanup(void); -int __connman_dnsproxy_add_listener(const char *interface); -void __connman_dnsproxy_remove_listener(const char *interface); -int __connman_dnsproxy_append(const char *interface, const char *domain, const char *server); -int __connman_dnsproxy_remove(const char *interface, const char *domain, const char *server); +int __connman_dnsproxy_add_listener(int index); +void __connman_dnsproxy_remove_listener(int index); +int __connman_dnsproxy_append(int index, const char *domain, const char *server); +int __connman_dnsproxy_remove(int index, const char *domain, const char *server); void __connman_dnsproxy_flush(void); int __connman_6to4_probe(struct connman_service *service); diff --git a/src/dnsproxy.c b/src/dnsproxy.c index df1f6d26..5e06a97e 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -83,7 +83,7 @@ struct partial_reply { }; struct server_data { - char *interface; + int index; GList *domains; char *server; struct sockaddr *server_addr; @@ -122,7 +122,7 @@ struct request_data { }; struct listener_data { - char *ifname; + int index; GIOChannel *udp_listener_channel; guint udp_listener_watch; GIOChannel *tcp_listener_channel; @@ -243,27 +243,27 @@ static struct request_data *find_request(guint16 id) return NULL; } -static struct server_data *find_server(const char *interface, +static struct server_data *find_server(int index, const char *server, int protocol) { GSList *list; - DBG("interface %s server %s proto %d", interface, server, protocol); + DBG("index %d server %s proto %d", index, server, protocol); for (list = server_list; list; list = list->next) { struct server_data *data = list->data; - if (interface == NULL && data->interface == NULL && + if (index < 0 && data->index < 0 && g_str_equal(data->server, server) == TRUE && data->protocol == protocol) return data; - if (interface == NULL || - data->interface == NULL || data->server == NULL) + if (index < 0 || + data->index < 0 || data->server == NULL) continue; - if (g_str_equal(data->interface, interface) == TRUE && + if (data->index == index && g_str_equal(data->server, server) == TRUE && data->protocol == protocol) return data; @@ -1752,7 +1752,7 @@ static gboolean try_remove_cache(gpointer user_data) static void server_destroy_socket(struct server_data *data) { - DBG("interface %s server %s proto %d", data->interface, + DBG("index %d server %s proto %d", data->index, data->server, data->protocol); if (data->watch > 0) { @@ -1779,7 +1779,7 @@ static void destroy_server(struct server_data *server) { GList *list; - DBG("interface %s server %s sock %d", server->interface, server->server, + DBG("index %d server %s sock %d", server->index, server->server, server->channel != NULL ? g_io_channel_unix_get_fd(server->channel): -1); @@ -1796,7 +1796,6 @@ static void destroy_server(struct server_data *server) server->domains = g_list_remove(server->domains, domain); g_free(domain); } - g_free(server->interface); g_free(server->server_addr); /* @@ -1898,7 +1897,7 @@ hangup: int no_request_sent = TRUE; struct server_data *udp_server; - udp_server = find_server(server->interface, server->server, + udp_server = find_server(server->index, server->server, IPPROTO_UDP); if (udp_server != NULL) { for (domains = udp_server->domains; domains; @@ -2049,8 +2048,9 @@ static gboolean tcp_idle_timeout(gpointer user_data) static int server_create_socket(struct server_data *data) { int sk, err; + char *interface; - DBG("interface %s server %s proto %d", data->interface, + DBG("index %d server %s proto %d", data->index, data->server, data->protocol); sk = socket(data->server_addr->sa_family, @@ -2066,18 +2066,21 @@ static int server_create_socket(struct server_data *data) DBG("sk %d", sk); - if (data->interface != NULL) { + interface = connman_inet_ifname(data->index); + if (interface != NULL) { if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, - data->interface, - strlen(data->interface) + 1) < 0) { + interface, + strlen(interface) + 1) < 0) { err = errno; connman_error("Failed to bind server %s " "to interface %s", - data->server, data->interface); + data->server, interface); close(sk); server_destroy_socket(data); + g_free(interface); return -err; } + g_free(interface); } data->channel = g_io_channel_unix_new(sk); @@ -2125,7 +2128,7 @@ static int server_create_socket(struct server_data *data) return 0; } -static struct server_data *create_server(const char *interface, +static struct server_data *create_server(int index, const char *domain, const char *server, int protocol) { @@ -2133,7 +2136,7 @@ static struct server_data *create_server(const char *interface, struct addrinfo hints, *rp; int ret; - DBG("interface %s server %s", interface, server); + DBG("index %d server %s", index, server); data = g_try_new0(struct server_data, 1); if (data == NULL) { @@ -2141,7 +2144,7 @@ static struct server_data *create_server(const char *interface, return NULL; } - data->interface = g_strdup(interface); + data->index = index; if (domain) data->domains = g_list_append(data->domains, g_strdup(domain)); data->server = g_strdup(server); @@ -2248,11 +2251,11 @@ static gboolean resolv(struct request_data *req, return FALSE; } -static void append_domain(const char *interface, const char *domain) +static void append_domain(int index, const char *domain) { GSList *list; - DBG("interface %s domain %s", interface, domain); + DBG("index %d domain %s", index, domain); if (domain == NULL) return; @@ -2263,10 +2266,10 @@ static void append_domain(const char *interface, const char *domain) char *dom; gboolean dom_found = FALSE; - if (data->interface == NULL) + if (data->index < 0) continue; - if (g_str_equal(data->interface, interface) == FALSE) + if (data->index != index) continue; for (dom_list = data->domains; dom_list; @@ -2286,18 +2289,18 @@ static void append_domain(const char *interface, const char *domain) } } -int __connman_dnsproxy_append(const char *interface, const char *domain, +int __connman_dnsproxy_append(int index, const char *domain, const char *server) { struct server_data *data; - DBG("interface %s server %s", interface, server); + DBG("index %d server %s", index, server); if (server == NULL && domain == NULL) return -EINVAL; if (server == NULL) { - append_domain(interface, domain); + append_domain(index, domain); return 0; } @@ -2305,35 +2308,35 @@ int __connman_dnsproxy_append(const char *interface, const char *domain, if (g_str_equal(server, "127.0.0.1") == TRUE) return -ENODEV; - data = find_server(interface, server, IPPROTO_UDP); + data = find_server(index, server, IPPROTO_UDP); if (data != NULL) { - append_domain(interface, domain); + append_domain(index, domain); return 0; } - data = create_server(interface, domain, server, IPPROTO_UDP); + data = create_server(index, domain, server, IPPROTO_UDP); if (data == NULL) return -EIO; return 0; } -static void remove_server(const char *interface, const char *domain, +static void remove_server(int index, const char *domain, const char *server, int protocol) { struct server_data *data; - data = find_server(interface, server, protocol); + data = find_server(index, server, protocol); if (data == NULL) return; destroy_server(data); } -int __connman_dnsproxy_remove(const char *interface, const char *domain, +int __connman_dnsproxy_remove(int index, const char *domain, const char *server) { - DBG("interface %s server %s", interface, server); + DBG("index %d server %s", index, server); if (server == NULL) return -EINVAL; @@ -2341,8 +2344,8 @@ int __connman_dnsproxy_remove(const char *interface, const char *domain, if (g_str_equal(server, "127.0.0.1") == TRUE) return -ENODEV; - remove_server(interface, domain, server, IPPROTO_UDP); - remove_server(interface, domain, server, IPPROTO_TCP); + remove_server(index, domain, server, IPPROTO_UDP); + remove_server(index, domain, server, IPPROTO_TCP); return 0; } @@ -2399,7 +2402,7 @@ static void dnsproxy_offline_mode(connman_bool_t enabled) static void dnsproxy_default_changed(struct connman_service *service) { GSList *list; - char *interface; + int index; DBG("service %p", service); @@ -2412,14 +2415,14 @@ static void dnsproxy_default_changed(struct connman_service *service) return; } - interface = connman_service_get_interface(service); - if (interface == NULL) + index = __connman_service_get_index(service); + if (index < 0) return; for (list = server_list; list; list = list->next) { struct server_data *data = list->data; - if (g_strcmp0(data->interface, interface) == 0) { + if (data->index == index) { DBG("Enabling DNS server %s", data->server); data->enabled = TRUE; } else { @@ -2428,7 +2431,6 @@ static void dnsproxy_default_changed(struct connman_service *service) } } - g_free(interface); cache_refresh(); } @@ -2616,7 +2618,7 @@ static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition, if (data->protocol != IPPROTO_UDP || data->enabled == FALSE) continue; - if(create_server(data->interface, NULL, + if(create_server(data->index, NULL, data->server, IPPROTO_TCP) == NULL) continue; @@ -2739,9 +2741,9 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata) socklen_t slen; int sk, type, v6only = 0; int family = AF_INET6; + char *interface; - - DBG("interface %s", ifdata->ifname); + DBG("index %d", ifdata->index); switch (protocol) { case IPPROTO_UDP: @@ -2769,13 +2771,17 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata) return -EIO; } - if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, - ifdata->ifname, - strlen(ifdata->ifname) + 1) < 0) { + interface = connman_inet_ifname(ifdata->index); + if (interface == NULL || setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE, + interface, + strlen(interface) + 1) < 0) { connman_error("Failed to bind %s listener interface", proto); close(sk); + g_free(interface); return -EIO; } + g_free(interface); + /* Ensure it accepts Legacy IP connections too */ if (family == AF_INET6 && setsockopt(sk, SOL_IPV6, IPV6_V6ONLY, @@ -2836,7 +2842,7 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata) static void destroy_udp_listener(struct listener_data *ifdata) { - DBG("interface %s", ifdata->ifname); + DBG("index %d", ifdata->index); if (ifdata->udp_listener_watch > 0) g_source_remove(ifdata->udp_listener_watch); @@ -2846,7 +2852,7 @@ static void destroy_udp_listener(struct listener_data *ifdata) static void destroy_tcp_listener(struct listener_data *ifdata) { - DBG("interface %s", ifdata->ifname); + DBG("index %d", ifdata->index); if (ifdata->tcp_listener_watch > 0) g_source_remove(ifdata->tcp_listener_watch); @@ -2856,7 +2862,7 @@ static void destroy_tcp_listener(struct listener_data *ifdata) static int create_listener(struct listener_data *ifdata) { - int err; + int err, index; err = create_dns_listener(IPPROTO_UDP, ifdata); if (err < 0) @@ -2868,18 +2874,21 @@ static int create_listener(struct listener_data *ifdata) return err; } - if (g_strcmp0(ifdata->ifname, "lo") == 0) - __connman_resolvfile_append("lo", NULL, "127.0.0.1"); + index = connman_inet_ifindex("lo"); + if (ifdata->index == index) + __connman_resolvfile_append(index, NULL, "127.0.0.1"); return 0; } static void destroy_listener(struct listener_data *ifdata) { + int index; GSList *list; - if (g_strcmp0(ifdata->ifname, "lo") == 0) - __connman_resolvfile_remove("lo", NULL, "127.0.0.1"); + index = connman_inet_ifindex("lo"); + if (ifdata->index == index) + __connman_resolvfile_remove(index, NULL, "127.0.0.1"); for (list = request_list; list; list = list->next) { struct request_data *req = list->data; @@ -2897,21 +2906,24 @@ static void destroy_listener(struct listener_data *ifdata) destroy_udp_listener(ifdata); } -int __connman_dnsproxy_add_listener(const char *interface) +int __connman_dnsproxy_add_listener(int index) { struct listener_data *ifdata; int err; - DBG("interface %s", interface); + DBG("index %d", index); + + if (index < 0) + return -EINVAL; - if (g_hash_table_lookup(listener_table, interface) != NULL) + if (g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)) != NULL) return 0; ifdata = g_try_new0(struct listener_data, 1); if (ifdata == NULL) return -ENOMEM; - ifdata->ifname = g_strdup(interface); + ifdata->index = index; ifdata->udp_listener_channel = NULL; ifdata->udp_listener_watch = 0; ifdata->tcp_listener_channel = NULL; @@ -2919,52 +2931,54 @@ int __connman_dnsproxy_add_listener(const char *interface) err = create_listener(ifdata); if (err < 0) { - connman_error("Couldn't create listener for %s err %d", - interface, err); - g_free(ifdata->ifname); + connman_error("Couldn't create listener for index %d err %d", + index, err); g_free(ifdata); return err; } - g_hash_table_insert(listener_table, ifdata->ifname, ifdata); + g_hash_table_insert(listener_table, GINT_TO_POINTER(ifdata->index), + ifdata); return 0; } -void __connman_dnsproxy_remove_listener(const char *interface) +void __connman_dnsproxy_remove_listener(int index) { struct listener_data *ifdata; - DBG("interface %s", interface); + DBG("index %d", index); - ifdata = g_hash_table_lookup(listener_table, interface); + ifdata = g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)); if (ifdata == NULL) return; destroy_listener(ifdata); - g_hash_table_remove(listener_table, interface); + g_hash_table_remove(listener_table, GINT_TO_POINTER(index)); } static void remove_listener(gpointer key, gpointer value, gpointer user_data) { - const char *interface = key; + int index = GPOINTER_TO_INT(key); struct listener_data *ifdata = value; - DBG("interface %s", interface); + DBG("index %d", index); destroy_listener(ifdata); } int __connman_dnsproxy_init(void) { - int err; + int err, index; DBG(""); srandom(time(NULL)); - listener_table = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); - err = __connman_dnsproxy_add_listener("lo"); + listener_table = g_hash_table_new_full(g_direct_hash, g_str_equal, + NULL, g_free); + + index = connman_inet_ifindex("lo"); + err = __connman_dnsproxy_add_listener(index); if (err < 0) return err; @@ -2975,7 +2989,7 @@ int __connman_dnsproxy_init(void) return 0; destroy: - __connman_dnsproxy_remove_listener("lo"); + __connman_dnsproxy_remove_listener(index); g_hash_table_destroy(listener_table); return err; diff --git a/src/resolver.c b/src/resolver.c index 982b767d..b965778b 100644 --- a/src/resolver.c +++ b/src/resolver.c @@ -44,7 +44,7 @@ #define RESOLVER_LIFETIME_REFRESH_THRESHOLD 0.8 struct entry_data { - char *interface; + int index; char *domain; char *server; int family; @@ -57,7 +57,7 @@ static GSList *entry_list = NULL; static connman_bool_t dnsproxy_enabled = FALSE; struct resolvfile_entry { - char *interface; + int index; char *domain; char *server; }; @@ -75,7 +75,6 @@ static void resolvfile_remove_entries(GList *entries) g_free(entry->server); g_free(entry->domain); - g_free(entry->interface); g_free(entry); } @@ -158,21 +157,21 @@ done: return err; } -int __connman_resolvfile_append(const char *interface, const char *domain, +int __connman_resolvfile_append(int index, const char *domain, const char *server) { struct resolvfile_entry *entry; - DBG("interface %s server %s", interface, server); + DBG("index %d server %s", index, server); - if (interface == NULL) + if (index < 0) return -ENOENT; entry = g_try_new0(struct resolvfile_entry, 1); if (entry == NULL) return -ENOMEM; - entry->interface = g_strdup(interface); + entry->index = index; entry->domain = g_strdup(domain); entry->server = g_strdup(server); @@ -181,18 +180,17 @@ int __connman_resolvfile_append(const char *interface, const char *domain, return resolvfile_export(); } -int __connman_resolvfile_remove(const char *interface, const char *domain, +int __connman_resolvfile_remove(int index, const char *domain, const char *server) { GList *list, *matches = NULL; - DBG("interface %s server %s", interface, server); + DBG("index %d server %s", index, 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) + if (index >= 0 && entry->index != index) continue; if (domain != NULL && g_strcmp0(entry->domain, domain) != 0) @@ -219,10 +217,10 @@ static void remove_entries(GSList *entries) entry_list = g_slist_remove(entry_list, entry); if (dnsproxy_enabled == TRUE) { - __connman_dnsproxy_remove(entry->interface, entry->domain, + __connman_dnsproxy_remove(entry->index, entry->domain, entry->server); } else { - __connman_resolvfile_remove(entry->interface, entry->domain, + __connman_resolvfile_remove(entry->index, entry->domain, entry->server); } @@ -230,7 +228,6 @@ static void remove_entries(GSList *entries) g_source_remove(entry->timeout); g_free(entry->server); g_free(entry->domain); - g_free(entry->interface); g_free(entry); } @@ -241,17 +238,15 @@ static gboolean resolver_expire_cb(gpointer user_data) { struct entry_data *entry = user_data; GSList *list; - int index; - DBG("interface %s domain %s server %s", - entry->interface, entry->domain, entry->server); + DBG("index %d domain %s server %s", + entry->index, entry->domain, entry->server); list = g_slist_prepend(NULL, entry); - index = connman_inet_ifindex(entry->interface); - if (index >= 0) { + if (entry->index >= 0) { struct connman_service *service; - service = __connman_service_lookup_from_index(index); + service = __connman_service_lookup_from_index(entry->index); if (service != NULL) __connman_service_nameserver_remove(service, entry->server, TRUE); @@ -265,7 +260,6 @@ static gboolean resolver_expire_cb(gpointer user_data) static gboolean resolver_refresh_cb(gpointer user_data) { struct entry_data *entry = user_data; - int index; unsigned int interval; struct connman_service *service = NULL; @@ -273,17 +267,16 @@ static gboolean resolver_refresh_cb(gpointer user_data) interval = entry->lifetime * (1 - RESOLVER_LIFETIME_REFRESH_THRESHOLD) + 1.0; - DBG("RDNSS start interface %s domain %s " + DBG("RDNSS start index %d domain %s " "server %s remaining lifetime %d", - entry->interface, entry->domain, + entry->index, entry->domain, entry->server, interval); entry->timeout = g_timeout_add_seconds(interval, resolver_expire_cb, entry); - index = connman_inet_ifindex(entry->interface); - if (index >= 0) { - service = __connman_service_lookup_from_index(index); + if (entry->index >= 0) { + service = __connman_service_lookup_from_index(entry->index); if (service != NULL) { /* * Send Router Solicitation to refresh RDNSS entries @@ -291,21 +284,21 @@ static gboolean resolver_refresh_cb(gpointer user_data) */ __connman_refresh_rs_ipv6( __connman_service_get_network(service), - index); + entry->index); } } return FALSE; } -static int append_resolver(const char *interface, const char *domain, +static int append_resolver(int index, const char *domain, const char *server, unsigned int lifetime, unsigned int flags) { struct entry_data *entry; unsigned int interval; - DBG("interface %s domain %s server %s lifetime %d flags %d", - interface, domain, server, lifetime, flags); + DBG("index %d domain %s server %s lifetime %d flags %d", + index, domain, server, lifetime, flags); if (server == NULL && domain == NULL) return -EINVAL; @@ -314,7 +307,7 @@ static int append_resolver(const char *interface, const char *domain, if (entry == NULL) return -ENOMEM; - entry->interface = g_strdup(interface); + entry->index = index; entry->domain = g_strdup(domain); entry->server = g_strdup(server); entry->flags = flags; @@ -324,12 +317,11 @@ static int append_resolver(const char *interface, const char *domain, entry->family = connman_inet_check_ipaddress(server); if (lifetime) { - int index; interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD; - DBG("RDNSS start interface %s domain %s " + DBG("RDNSS start index %d domain %s " "server %s lifetime threshold %d", - interface, domain, server, interval); + index, domain, server, interval); entry->timeout = g_timeout_add_seconds(interval, resolver_refresh_cb, entry); @@ -338,10 +330,9 @@ static int append_resolver(const char *interface, const char *domain, * We update the service only for those nameservers * that are automagically added via netlink (lifetime > 0) */ - index = connman_inet_ifindex(interface); - if (server != NULL && index >= 0) { + if (server != NULL && entry->index >= 0) { struct connman_service *service; - service = __connman_service_lookup_from_index(index); + service = __connman_service_lookup_from_index(entry->index); if (service != NULL) __connman_service_nameserver_append(service, server, TRUE); @@ -350,27 +341,27 @@ static int append_resolver(const char *interface, const char *domain, entry_list = g_slist_append(entry_list, entry); if (dnsproxy_enabled == TRUE) - __connman_dnsproxy_append(interface, domain, server); + __connman_dnsproxy_append(entry->index, domain, server); else - __connman_resolvfile_append(interface, domain, server); + __connman_resolvfile_append(entry->index, domain, server); return 0; } /** * connman_resolver_append: - * @interface: network interface + * @index: network interface index * @domain: domain limitation * @server: server address * * Append resolver server address to current list */ -int connman_resolver_append(const char *interface, const char *domain, +int connman_resolver_append(int index, const char *domain, const char *server) { GSList *list; - DBG("interface %s domain %s server %s", interface, domain, server); + DBG("index %d domain %s server %s", index, domain, server); if (server == NULL && domain == NULL) return -EINVAL; @@ -381,32 +372,32 @@ int connman_resolver_append(const char *interface, const char *domain, if (entry->timeout > 0) continue; - if (g_strcmp0(entry->interface, interface) == 0 && + if (entry->index == index && g_strcmp0(entry->domain, domain) == 0 && g_strcmp0(entry->server, server) == 0) return -EEXIST; } - return append_resolver(interface, domain, server, 0, 0); + return append_resolver(index, domain, server, 0, 0); } /** * connman_resolver_append_lifetime: - * @interface: network interface + * @index: network interface index * @domain: domain limitation * @server: server address * @timeout: server lifetime in seconds * * Append resolver server address to current list */ -int connman_resolver_append_lifetime(const char *interface, const char *domain, +int connman_resolver_append_lifetime(int index, const char *domain, const char *server, unsigned int lifetime) { GSList *list; unsigned int interval; - DBG("interface %s domain %s server %s lifetime %d", - interface, domain, server, lifetime); + DBG("index %d domain %s server %s lifetime %d", + index, domain, server, lifetime); if (server == NULL && domain == NULL) return -EINVAL; @@ -415,7 +406,7 @@ int connman_resolver_append_lifetime(const char *interface, const char *domain, struct entry_data *entry = list->data; if (entry->timeout == 0 || - g_strcmp0(entry->interface, interface) != 0 || + entry->index != index || g_strcmp0(entry->domain, domain) != 0 || g_strcmp0(entry->server, server) != 0) continue; @@ -429,37 +420,36 @@ int connman_resolver_append_lifetime(const char *interface, const char *domain, interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD; - DBG("RDNSS start interface %s domain %s " + DBG("RDNSS start index %d domain %s " "server %s lifetime threshold %d", - interface, domain, server, interval); + index, domain, server, interval); entry->timeout = g_timeout_add_seconds(interval, resolver_refresh_cb, entry); return 0; } - return append_resolver(interface, domain, server, lifetime, 0); + return append_resolver(index, domain, server, lifetime, 0); } /** * connman_resolver_remove: - * @interface: network interface + * @index: network interface index * @domain: domain limitation * @server: server address * * Remover resolver server address from current list */ -int connman_resolver_remove(const char *interface, const char *domain, - const char *server) +int connman_resolver_remove(int index, const char *domain, const char *server) { GSList *list, *matches = NULL; - DBG("interface %s domain %s server %s", interface, domain, server); + DBG("index %d domain %s server %s", index, domain, server); for (list = entry_list; list; list = list->next) { struct entry_data *entry = list->data; - if (g_strcmp0(entry->interface, interface) != 0) + if (entry->index != index) continue; if (g_strcmp0(entry->domain, domain) != 0) @@ -482,23 +472,23 @@ int connman_resolver_remove(const char *interface, const char *domain, /** * connman_resolver_remove_all: - * @interface: network interface + * @index: network interface index * - * Remove all resolver server address for the specified interface + * Remove all resolver server address for the specified interface index */ -int connman_resolver_remove_all(const char *interface) +int connman_resolver_remove_all(int index) { GSList *list, *matches = NULL; - DBG("interface %s", interface); + DBG("index %d", index); - if (interface == NULL) + if (index < 0) return -EINVAL; for (list = entry_list; list; list = list->next) { struct entry_data *entry = list->data; - if (g_strcmp0(entry->interface, interface) != 0) + if (entry->index != index) continue; matches = g_slist_prepend(matches, entry); @@ -525,23 +515,22 @@ void connman_resolver_flush(void) return; } -int __connman_resolver_redo_servers(const char *interface) +int __connman_resolver_redo_servers(int index) { GSList *list; if (dnsproxy_enabled == FALSE) return 0; - DBG("interface %s", interface); + DBG("index %d", index); - if (interface == NULL) + if (index < 0) 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) + if (entry->timeout == 0 || entry->index != index) continue; /* @@ -555,7 +544,7 @@ int __connman_resolver_redo_servers(const char *interface) * 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, + __connman_dnsproxy_remove(entry->index, entry->domain, entry->server); /* * Remove also the resolver timer for the old server entry. @@ -566,7 +555,7 @@ int __connman_resolver_redo_servers(const char *interface) g_source_remove(entry->timeout); entry->timeout = 0; - __connman_dnsproxy_append(entry->interface, entry->domain, + __connman_dnsproxy_append(entry->index, entry->domain, entry->server); } @@ -576,7 +565,6 @@ int __connman_resolver_redo_servers(const char *interface) static void free_entry(gpointer data) { struct entry_data *entry = data; - g_free(entry->interface); g_free(entry->domain); g_free(entry->server); g_free(entry); @@ -585,7 +573,6 @@ static void free_entry(gpointer data) static void free_resolvfile(gpointer data) { struct resolvfile_entry *entry = data; - g_free(entry->interface); g_free(entry->domain); g_free(entry->server); g_free(entry); @@ -611,7 +598,7 @@ int __connman_resolver_init(connman_bool_t dnsproxy) ns = connman_setting_get_string_list("FallbackNameservers"); for (i = 0; ns != NULL && ns[i] != NULL; i += 1) { DBG("server %s", ns[i]); - append_resolver(NULL, NULL, ns[i], 0, RESOLVER_FLAG_PUBLIC); + append_resolver(-1, NULL, ns[i], 0, RESOLVER_FLAG_PUBLIC); } return 0; diff --git a/src/rtnl.c b/src/rtnl.c index 5f3fe155..915654bc 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -611,11 +611,7 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen, * have now properly configured interface with proper * autoconfigured address. */ - char *interface = connman_inet_ifname(index); - - __connman_resolver_redo_servers(interface); - - g_free(interface); + __connman_resolver_redo_servers(index); } } @@ -1195,7 +1191,7 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) struct in6_addr *servers = NULL; int i, nr_servers = 0; int msglen = msg->nduseropt_opts_len; - char *interface; + int index; DBG("family %d index %d len %d type %d code %d", msg->nduseropt_family, msg->nduseropt_ifindex, @@ -1207,8 +1203,8 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) msg->nduseropt_icmp_code != 0) return; - interface = connman_inet_ifname(msg->nduseropt_ifindex); - if (!interface) + index = msg->nduseropt_ifindex; + if (index < 0) return; for (opt = (void *)&msg[1]; @@ -1229,7 +1225,7 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) sizeof(buf))) continue; - connman_resolver_append_lifetime(interface, + connman_resolver_append_lifetime(index, NULL, buf, lifetime); } @@ -1238,13 +1234,12 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) domains = rtnl_nd_opt_dnssl(opt, &lifetime); for (i = 0; domains != NULL && domains[i] != NULL; i++) - connman_resolver_append_lifetime(interface, + connman_resolver_append_lifetime(index, domains[i], NULL, lifetime); } } g_free(domains); - g_free(interface); } static const char *type2string(uint16_t type) diff --git a/src/service.c b/src/service.c index 7381af35..ac0704f5 100644 --- a/src/service.c +++ b/src/service.c @@ -860,19 +860,14 @@ static connman_bool_t is_connected(struct connman_service *service) return is_connected_state(service, service->state); } -static const char *nameserver_get_ifname(struct connman_service *service) +static int nameserver_get_index(struct connman_service *service) { - const char *ifname; + int index; - if (service->ipconfig_ipv4) - ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv4); - else if (service->ipconfig_ipv6) - ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv6); - else - ifname = NULL; + index = __connman_service_get_index(service); - if (ifname == NULL) - return NULL; + if (index < 0) + return -1; switch (combine_state(service->state_ipv4, service->state_ipv6)) { case CONNMAN_SERVICE_STATE_UNKNOWN: @@ -881,65 +876,57 @@ static const char *nameserver_get_ifname(struct connman_service *service) case CONNMAN_SERVICE_STATE_CONFIGURATION: case CONNMAN_SERVICE_STATE_FAILURE: case CONNMAN_SERVICE_STATE_DISCONNECT: - return NULL; + return -1; case CONNMAN_SERVICE_STATE_READY: case CONNMAN_SERVICE_STATE_ONLINE: break; } - return ifname; + return index; } static void remove_nameservers(struct connman_service *service, - const char* interface, char **ns) + int index, char **ns) { - const char *ifname = interface; int i; if (ns == NULL) return; - if (interface == NULL) - ifname = nameserver_get_ifname(service); + if (index < 0) + index = nameserver_get_index(service); - if (ifname == NULL) + if (index < 0) return; for (i = 0; ns[i] != NULL; i++) - connman_resolver_remove(ifname, NULL, ns[i]); + connman_resolver_remove(index, NULL, ns[i]); } static void remove_searchdomains(struct connman_service *service, - const char *interface, char **sd) + int index, char **sd) { - const char *ifname = interface; int i; if (sd == NULL) return; - if (interface == NULL) - ifname = nameserver_get_ifname(service); + if (index < 0) + index = nameserver_get_index(service); - if (ifname == NULL) + if (index < 0) return; for (i = 0; sd[i] != NULL; i++) - connman_resolver_remove(ifname, sd[i], NULL); + connman_resolver_remove(index, sd[i], NULL); } static void update_nameservers(struct connman_service *service) { - const char *ifname; - - if (service->ipconfig_ipv4) - ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv4); - else if (service->ipconfig_ipv6) - ifname = __connman_ipconfig_get_ifname(service->ipconfig_ipv6); - else - ifname = NULL; + int index; - if (ifname == NULL) + index = __connman_service_get_index(service); + if (index < 0) return; switch (combine_state(service->state_ipv4, service->state_ipv6)) { @@ -950,7 +937,7 @@ static void update_nameservers(struct connman_service *service) return; case CONNMAN_SERVICE_STATE_FAILURE: case CONNMAN_SERVICE_STATE_DISCONNECT: - connman_resolver_remove_all(ifname); + connman_resolver_remove_all(index); return; case CONNMAN_SERVICE_STATE_READY: case CONNMAN_SERVICE_STATE_ONLINE: @@ -960,12 +947,12 @@ static void update_nameservers(struct connman_service *service) if (service->nameservers_config != NULL) { int i; - remove_nameservers(service, ifname, service->nameservers); + remove_nameservers(service, index, service->nameservers); i = g_strv_length(service->nameservers_config); while (i != 0) { i--; - connman_resolver_append(ifname, NULL, + connman_resolver_append(index, NULL, service->nameservers_config[i]); } } else if (service->nameservers != NULL) { @@ -974,7 +961,7 @@ static void update_nameservers(struct connman_service *service) i = g_strv_length(service->nameservers); while (i != 0) { i--; - connman_resolver_append(ifname, NULL, + connman_resolver_append(index, NULL, service->nameservers[i]); } } @@ -984,16 +971,16 @@ static void update_nameservers(struct connman_service *service) int i; searchdomains[0] = service->domainname; - remove_searchdomains(service, ifname, searchdomains); + remove_searchdomains(service, index, searchdomains); i = g_strv_length(service->domains); while (i != 0) { i--; - connman_resolver_append(ifname, service->domains[i], + connman_resolver_append(index, service->domains[i], NULL); } } else if (service->domainname != NULL) - connman_resolver_append(ifname, service->domainname, NULL); + connman_resolver_append(index, service->domainname, NULL); connman_resolver_flush(); } @@ -3100,7 +3087,7 @@ static DBusMessage *set_property(DBusConnection *conn, } } - remove_nameservers(service, NULL, service->nameservers_config); + remove_nameservers(service, -1, service->nameservers_config); g_strfreev(service->nameservers_config); if (str->len > 0) { @@ -3184,7 +3171,7 @@ static DBusMessage *set_property(DBusConnection *conn, g_string_append(str, val); } - remove_searchdomains(service, NULL, service->domains); + remove_searchdomains(service, -1, service->domains); g_strfreev(service->domains); if (str->len > 0) diff --git a/src/tethering.c b/src/tethering.c index f3d67dfa..b9df21b3 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -228,7 +228,7 @@ void __connman_tethering_set_enabled(void) } dns = gateway; - if (__connman_dnsproxy_add_listener(BRIDGE_NAME) < 0) { + if (__connman_dnsproxy_add_listener(index) < 0) { connman_error("Can't add listener %s to DNS proxy", BRIDGE_NAME); dns = BRIDGE_DNS; @@ -255,9 +255,12 @@ void __connman_tethering_set_enabled(void) void __connman_tethering_set_disabled(void) { + int index; + DBG("enabled %d", tethering_enabled - 1); - __connman_dnsproxy_remove_listener(BRIDGE_NAME); + index = connman_inet_ifindex(BRIDGE_NAME); + __connman_dnsproxy_remove_listener(index); if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1) return;