summaryrefslogtreecommitdiff
path: root/src/dnsproxy.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2013-04-04 14:44:51 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-04-05 14:43:15 +0300
commite0f7dc80fe172d8e3115ec3f08c281bc37ee8019 (patch)
tree4cae43fc1634555e10d2566136dc47bae5f08d5a /src/dnsproxy.c
parent88a2b9b5d76d347af42a639e9127b5ad2b3abe4e (diff)
downloadconnman-e0f7dc80fe172d8e3115ec3f08c281bc37ee8019.tar.gz
connman-e0f7dc80fe172d8e3115ec3f08c281bc37ee8019.tar.bz2
connman-e0f7dc80fe172d8e3115ec3f08c281bc37ee8019.zip
dnsproxy: Add or remove ::1 to/from resolv.conf when necessary
We add IPv6 loopback address to resolv.conf if we have created an IPv6 listening socket to port 53. Also remove ::1 from resolv.conf when deleting the proxy.
Diffstat (limited to 'src/dnsproxy.c')
-rw-r--r--src/dnsproxy.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 60b15129..f1f7e4c8 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -2924,8 +2924,19 @@ static GIOChannel *get_listener(int family, int protocol, int index)
return channel;
}
+#define UDP_IPv4_FAILED 0x01
+#define TCP_IPv4_FAILED 0x02
+#define UDP_IPv6_FAILED 0x04
+#define TCP_IPv6_FAILED 0x08
+#define UDP_FAILED (UDP_IPv4_FAILED | UDP_IPv6_FAILED)
+#define TCP_FAILED (TCP_IPv4_FAILED | TCP_IPv6_FAILED)
+#define IPv6_FAILED (UDP_IPv6_FAILED | TCP_IPv6_FAILED)
+#define IPv4_FAILED (UDP_IPv4_FAILED | TCP_IPv4_FAILED)
+
static int create_dns_listener(int protocol, struct listener_data *ifdata)
{
+ int ret = 0;
+
if (protocol == IPPROTO_TCP) {
ifdata->tcp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
@@ -2934,6 +2945,8 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
g_io_add_watch(ifdata->tcp4_listener_channel,
G_IO_IN, tcp4_listener_event,
(gpointer)ifdata);
+ else
+ ret |= TCP_IPv4_FAILED;
ifdata->tcp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
@@ -2942,6 +2955,8 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
g_io_add_watch(ifdata->tcp6_listener_channel,
G_IO_IN, tcp6_listener_event,
(gpointer)ifdata);
+ else
+ ret |= TCP_IPv6_FAILED;
} else {
ifdata->udp4_listener_channel = get_listener(AF_INET, protocol,
ifdata->index);
@@ -2950,6 +2965,8 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
g_io_add_watch(ifdata->udp4_listener_channel,
G_IO_IN, udp4_listener_event,
(gpointer)ifdata);
+ else
+ ret |= UDP_IPv4_FAILED;
ifdata->udp6_listener_channel = get_listener(AF_INET6, protocol,
ifdata->index);
@@ -2958,9 +2975,11 @@ static int create_dns_listener(int protocol, struct listener_data *ifdata)
g_io_add_watch(ifdata->udp6_listener_channel,
G_IO_IN, udp6_listener_event,
(gpointer)ifdata);
+ else
+ ret |= UDP_IPv6_FAILED;
}
- return 0;
+ return ret;
}
static void destroy_udp_listener(struct listener_data *ifdata)
@@ -2995,18 +3014,23 @@ static int create_listener(struct listener_data *ifdata)
int err, index;
err = create_dns_listener(IPPROTO_UDP, ifdata);
- if (err < 0)
- return err;
+ if ((err & UDP_FAILED) == UDP_FAILED)
+ return -EIO;
- err = create_dns_listener(IPPROTO_TCP, ifdata);
- if (err < 0) {
+ err |= create_dns_listener(IPPROTO_TCP, ifdata);
+ if ((err & TCP_FAILED) == TCP_FAILED) {
destroy_udp_listener(ifdata);
- return err;
+ return -EIO;
}
index = connman_inet_ifindex("lo");
- if (ifdata->index == index)
- __connman_resolvfile_append(index, NULL, "127.0.0.1");
+ if (ifdata->index == index) {
+ if ((err & IPv6_FAILED) != IPv6_FAILED)
+ __connman_resolvfile_append(index, NULL, "::1");
+
+ if ((err & IPv4_FAILED) != IPv4_FAILED)
+ __connman_resolvfile_append(index, NULL, "127.0.0.1");
+ }
return 0;
}
@@ -3017,8 +3041,10 @@ static void destroy_listener(struct listener_data *ifdata)
GSList *list;
index = connman_inet_ifindex("lo");
- if (ifdata->index == index)
+ if (ifdata->index == index) {
__connman_resolvfile_remove(index, NULL, "127.0.0.1");
+ __connman_resolvfile_remove(index, NULL, "::1");
+ }
for (list = request_list; list; list = list->next) {
struct request_data *req = list->data;