Add support for WPAD setting proxy information
[platform/upstream/connman.git] / src / wpad.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27
28 #include <gresolv/gresolv.h>
29
30 #include "connman.h"
31
32 struct connman_wpad {
33         struct connman_service *service;
34         GResolv *resolv;
35         char *hostname;
36 };
37
38 static GHashTable *wpad_list = NULL;
39
40 static void resolv_debug(const char *str, void *data)
41 {
42         connman_info("%s: %s\n", (const char *) data, str);
43 }
44
45 static void free_wpad(gpointer data)
46 {
47         struct connman_wpad *wpad = data;
48
49         g_resolv_unref(wpad->resolv);
50
51         g_free(wpad->hostname);
52         g_free(wpad);
53 }
54
55 static void wpad_result(GResolvResultStatus status,
56                                         char **results, gpointer user_data)
57 {
58         struct connman_wpad *wpad = user_data;
59
60         DBG("status %d", status);
61
62         if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
63                 char *url;
64
65                 url = g_strdup_printf("http://%s/wpad.dat", wpad->hostname);
66                 __connman_service_set_proxy_autoconfig(wpad->service, url);
67                 g_free(url);
68         }
69 }
70
71 void __connman_wpad_start(struct connman_service *service)
72 {
73         struct connman_wpad *wpad;
74         const char *domainname, *nameserver;
75         int index;
76
77         DBG("service %p", service);
78
79         if (wpad_list == NULL)
80                 return;
81
82         index = __connman_service_get_index(service);
83         if (index < 0)
84                 return;
85
86         domainname = __connman_service_get_domainname(service);
87         if (domainname == NULL)
88                 return;
89
90         nameserver = __connman_service_get_nameserver(service);
91         if (nameserver == NULL)
92                 return;
93
94         wpad = g_try_new0(struct connman_wpad, 1);
95         if (wpad == NULL)
96                 return;
97
98         wpad->service = service;
99         wpad->resolv = g_resolv_new(index);
100         if (wpad->resolv == NULL) {
101                 g_free(wpad);
102                 return;
103         }
104
105         if (getenv("CONNMAN_RESOLV_DEBUG"))
106                 g_resolv_set_debug(wpad->resolv, resolv_debug, "RESOLV");
107
108         g_resolv_add_nameserver(wpad->resolv, nameserver, 53, 0);
109
110         wpad->hostname = g_strdup_printf("wpad.%s", domainname);
111
112         g_resolv_lookup_hostname(wpad->resolv, wpad->hostname,
113                                                         wpad_result, wpad);
114
115         g_hash_table_insert(wpad_list, GINT_TO_POINTER(index), wpad);
116 }
117
118 void __connman_wpad_stop(struct connman_service *service)
119 {
120         int index;
121
122         DBG("service %p", service);
123
124         if (wpad_list == NULL)
125                 return;
126
127         index = __connman_service_get_index(service);
128         if (index < 0)
129                 return;
130
131         g_hash_table_remove(wpad_list, GINT_TO_POINTER(index));
132 }
133
134 int __connman_wpad_init(void)
135 {
136         DBG("");
137
138         wpad_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
139                                                         NULL, free_wpad);
140
141         return 0;
142 }
143
144 void __connman_wpad_cleanup(void)
145 {
146         DBG("");
147
148         g_hash_table_destroy(wpad_list);
149         wpad_list = NULL;
150 }