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