---
 src/connman.h |    3 +-
 src/service.c |    2 +-
 src/wpad.c    |  147 +++++++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 105 insertions(+), 47 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 90572b5..bbeb8ed 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -302,7 +302,8 @@ void __connman_connection_gateway_activate(struct 
connman_service *service,
 
 int __connman_wpad_init(void);
 void __connman_wpad_cleanup(void);
-int __connman_wpad_start(struct connman_service *service);
+int __connman_wpad_start(struct connman_service *service,
+                                       enum connman_ipconfig_type type);
 void __connman_wpad_stop(struct connman_service *service);
 
 #include <connman/technology.h>
diff --git a/src/service.c b/src/service.c
index b4e1fcb..38dfcad 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3569,7 +3569,7 @@ int __connman_service_indicate_state(struct 
connman_service *service,
                                (proxy_config ==
                                        CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
                                        service->pac == NULL))) {
-                       if (__connman_wpad_start(service) < 0) {
+                 if (__connman_wpad_start(service, type) < 0) {
                                service->proxy =
                                        CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
 
diff --git a/src/wpad.c b/src/wpad.c
index 6284eb7..42d71e0 100644
--- a/src/wpad.c
+++ b/src/wpad.c
@@ -26,18 +26,28 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
 
 #include <gweb/gresolv.h>
 
 #include "connman.h"
 
-struct connman_wpad {
+struct connman_wpad_context {
        struct connman_service *service;
+       enum connman_ipconfig_type type;
+
        GResolv *resolv;
        char *hostname;
        char **addrlist;
 };
 
+struct connman_wpad {
+       struct connman_wpad_context *ipv4_context;
+       struct connman_wpad_context *ipv6_context;
+};
+
 static GHashTable *wpad_list = NULL;
 
 static void resolv_debug(const char *str, void *data)
@@ -45,25 +55,37 @@ static void resolv_debug(const char *str, void *data)
        connman_info("%s: %s\n", (const char *) data, str);
 }
 
+static void free_wpad_context(struct connman_wpad_context *wpad_context)
+{
+       g_resolv_unref(wpad_context->resolv);
+
+       g_strfreev(wpad_context->addrlist);
+       g_free(wpad_context->hostname);
+       g_free(wpad_context);
+}
+
 static void free_wpad(gpointer data)
 {
-        struct connman_wpad *wpad = data;
+       struct connman_wpad *wpad = data;
 
-       g_resolv_unref(wpad->resolv);
+       if (wpad == NULL)
+               return;
+
+       free_wpad_context(wpad->ipv4_context);
+       free_wpad_context(wpad->ipv6_context);
 
-       g_strfreev(wpad->addrlist);
-       g_free(wpad->hostname);
-        g_free(wpad);
+       g_free(wpad);
 }
 
-static void download_pac(struct connman_wpad *wpad, const char *target)
+static void download_pac(struct connman_wpad_context *wpad_context,
+                                                       const char *target)
 {
 }
 
 static void wpad_result(GResolvResultStatus status,
                                        char **results, gpointer user_data)
 {
-       struct connman_wpad *wpad = user_data;
+       struct connman_wpad_context *wpad_context = user_data;
        const char *ptr;
        char *hostname;
 
@@ -75,23 +97,25 @@ static void wpad_result(GResolvResultStatus status,
                if (results == NULL || g_strv_length(results) == 0)
                        goto failed;
 
-               url = g_strdup_printf("http://%s/wpad.dat";, wpad->hostname);
+               url = g_strdup_printf("http://%s/wpad.dat";,
+                                               wpad_context->hostname);
 
-               __connman_service_set_proxy_autoconfig(wpad->service, url);
+               __connman_service_set_proxy_autoconfig(wpad_context->service,
+                                                                       url);
 
-               wpad->addrlist = g_strdupv(results);
-               if (wpad->addrlist != NULL)
-                       download_pac(wpad, "wpad.dat");
+               wpad_context->addrlist = g_strdupv(results);
+               if (wpad_context->addrlist != NULL)
+                       download_pac(wpad_context, "wpad.dat");
 
                g_free(url);
 
-               __connman_wispr_portal_start(wpad->service,
-                                       CONNMAN_IPCONFIG_TYPE_IPV4);
+               __connman_wispr_portal_start(wpad_context->service,
+                                                       wpad_context->type);
 
                return;
        }
 
-       hostname = wpad->hostname;
+       hostname = wpad_context->hostname;
 
        if (strlen(hostname) < 6)
                goto failed;
@@ -103,26 +127,28 @@ static void wpad_result(GResolvResultStatus status,
        if (strchr(ptr + 1, '.') == NULL)
                goto failed;
 
-       wpad->hostname = g_strdup_printf("wpad.%s", ptr + 1);
+       wpad_context->hostname = g_strdup_printf("wpad.%s", ptr + 1);
        g_free(hostname);
 
-       DBG("hostname %s", wpad->hostname);
+       DBG("hostname %s", wpad_context->hostname);
 
-       g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
-                                                       wpad_result, wpad);
+       g_resolv_lookup_hostname(wpad_context->resolv,
+               wpad_context->hostname, wpad_result, wpad_context);
 
        return;
 
 failed:
-       connman_service_set_proxy_method(wpad->service,
+       connman_service_set_proxy_method(wpad_context->service,
                                CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
 
-       __connman_wispr_portal_start(wpad->service,
-                                       CONNMAN_IPCONFIG_TYPE_IPV4);
+       __connman_wispr_portal_start(wpad_context->service,
+                                               wpad_context->type);
 }
 
-int __connman_wpad_start(struct connman_service *service)
+int __connman_wpad_start(struct connman_service *service,
+                                       enum connman_ipconfig_type type)
 {
+       struct connman_wpad_context *wpad_context;
        struct connman_wpad *wpad;
        const char *domainname;
        char **nameservers;
@@ -146,31 +172,62 @@ int __connman_wpad_start(struct connman_service *service)
        if (nameservers == NULL)
                return -EINVAL;
 
-       wpad = g_try_new0(struct connman_wpad, 1);
-       if (wpad == NULL)
-               return -ENOMEM;
+       wpad =  g_hash_table_lookup(wpad_list, GINT_TO_POINTER(index));
+       if (wpad == NULL) {
+               wpad = g_try_new0(struct connman_wpad, 1);
+               if (wpad == NULL)
+                       return -ENOMEM;
 
-       wpad->service = service;
-       wpad->resolv = g_resolv_new(index);
-       if (wpad->resolv == NULL) {
-               g_free(wpad);
-               return -ENOMEM;
+               g_hash_table_replace(wpad_list, GINT_TO_POINTER(index), wpad);
        }
 
-       if (getenv("CONNMAN_RESOLV_DEBUG"))
-               g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV");
-
-       for (i = 0; nameservers[i] != NULL; i++)
-               g_resolv_add_nameserver(wpad->resolv, nameservers[i], 53, 0);
-
-       wpad->hostname = g_strdup_printf("wpad.%s", domainname);
-
-       DBG("hostname %s", wpad->hostname);
-
-       g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
-                                                       wpad_result, wpad);
+       if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
+               wpad_context = wpad->ipv4_context;
+       else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
+               wpad_context = wpad->ipv6_context;
+       else
+               return -EINVAL;
 
-       g_hash_table_replace(wpad_list, GINT_TO_POINTER(index), wpad);
+       if (wpad_context == NULL) {
+               wpad_context = g_try_new0(struct connman_wpad_context, 1);
+               if (wpad_context == NULL)
+                       return -ENOMEM;
+
+               wpad_context->service = service;
+               wpad_context->type = type;
+
+               wpad_context->resolv = g_resolv_new(index);
+               if (wpad_context->resolv == NULL) {
+                       g_free(wpad_context);
+                       return -ENOMEM;
+               }
+
+               if (getenv("CONNMAN_RESOLV_DEBUG"))
+                       g_resolv_set_debug(wpad_context->resolv,
+                                               resolv_debug, "RESOLV");
+
+               for (i = 0; nameservers[i] != NULL; i++)
+                       g_resolv_add_nameserver(wpad_context->resolv,
+                                                       nameservers[i], 53, 0);
+
+               wpad_context->hostname = g_strdup_printf("wpad.%s", domainname);
+
+               DBG("hostname %s", wpad_context->hostname);
+
+               if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
+                       wpad->ipv6_context = wpad_context;
+                       g_resolv_set_result_address_family(wpad_context->resolv,
+                                                               AF_INET6);
+               } else {
+                       wpad->ipv4_context = wpad_context;
+                       g_resolv_set_result_address_family(wpad_context->resolv,
+                                                               AF_INET);
+               }
+
+               g_resolv_lookup_hostname(wpad_context->resolv,
+                                       wpad_context->hostname,
+                                       wpad_result, wpad_context);
+       }
 
        return 0;
 }
-- 
1.7.3.4

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to