5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
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.
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.
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
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
40 #if __BYTE_ORDER == __LITTLE_ENDIAN
55 } __attribute__ ((packed));
56 #elif __BYTE_ORDER == __BIG_ENDIAN
71 } __attribute__ ((packed));
73 #error "Unknown byte order"
76 struct partial_reply {
92 struct partial_reply *incoming_reply;
97 struct sockaddr_in6 __sin6; /* Only for the length */
115 struct listener_data *ifdata;
116 gboolean append_domain;
119 struct listener_data {
121 GIOChannel *udp_listener_channel;
122 guint udp_listener_watch;
123 GIOChannel *tcp_listener_channel;
124 guint tcp_listener_watch;
127 static GSList *server_list = NULL;
128 static GSList *request_list = NULL;
129 static GSList *request_pending_list = NULL;
130 static guint16 request_id = 0x0000;
131 static GHashTable *listener_table = NULL;
133 static int protocol_offset(int protocol)
148 static struct request_data *find_request(guint16 id)
152 for (list = request_list; list; list = list->next) {
153 struct request_data *req = list->data;
155 if (req->dstid == id || req->altid == id)
162 static struct server_data *find_server(const char *interface,
168 DBG("interface %s server %s", interface, server);
170 for (list = server_list; list; list = list->next) {
171 struct server_data *data = list->data;
173 if (interface == NULL && data->interface == NULL &&
174 g_str_equal(data->server, server) == TRUE &&
175 data->protocol == protocol)
178 if (interface == NULL ||
179 data->interface == NULL || data->server == NULL)
182 if (g_str_equal(data->interface, interface) == TRUE &&
183 g_str_equal(data->server, server) == TRUE &&
184 data->protocol == protocol)
192 static void send_response(int sk, unsigned char *buf, int len,
193 const struct sockaddr *to, socklen_t tolen,
196 struct domain_hdr *hdr;
197 int err, offset = protocol_offset(protocol);
207 hdr = (void *) (buf + offset);
209 DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
218 err = sendto(sk, buf, len, 0, to, tolen);
220 connman_error("Failed to send DNS response: %s",
226 static gboolean request_timeout(gpointer user_data)
228 struct request_data *req = user_data;
229 struct listener_data *ifdata;
231 DBG("id 0x%04x", req->srcid);
236 ifdata = req->ifdata;
238 request_list = g_slist_remove(request_list, req);
241 if (req->resplen > 0 && req->resp != NULL) {
244 sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
246 err = sendto(sk, req->resp, req->resplen, 0,
247 &req->sa, req->sa_len);
250 } else if (req->request && req->numserv == 0) {
251 struct domain_hdr *hdr;
253 if (req->protocol == IPPROTO_TCP) {
254 hdr = (void *) (req->request + 2);
255 hdr->id = req->srcid;
256 send_response(req->client_sk, req->request,
257 req->request_len, NULL, 0, IPPROTO_TCP);
259 } else if (req->protocol == IPPROTO_UDP) {
262 hdr = (void *) (req->request);
263 hdr->id = req->srcid;
264 sk = g_io_channel_unix_get_fd(
265 ifdata->udp_listener_channel);
266 send_response(sk, req->request, req->request_len,
267 &req->sa, req->sa_len, IPPROTO_UDP);
277 static int append_query(unsigned char *buf, unsigned int size,
278 const char *query, const char *domain)
280 unsigned char *ptr = buf;
283 DBG("query %s domain %s", query, domain);
285 offset = (char *) query;
286 while (offset != NULL) {
289 tmp = strchr(offset, '.');
291 if (strlen(offset) == 0)
293 *ptr = strlen(offset);
294 memcpy(ptr + 1, offset, strlen(offset));
295 ptr += strlen(offset) + 1;
300 memcpy(ptr + 1, offset, tmp - offset);
301 ptr += tmp - offset + 1;
306 offset = (char *) domain;
307 while (offset != NULL) {
310 tmp = strchr(offset, '.');
312 if (strlen(offset) == 0)
314 *ptr = strlen(offset);
315 memcpy(ptr + 1, offset, strlen(offset));
316 ptr += strlen(offset) + 1;
321 memcpy(ptr + 1, offset, tmp - offset);
322 ptr += tmp - offset + 1;
332 static int ns_resolv(struct server_data *server, struct request_data *req,
333 gpointer request, gpointer name)
337 char *dot, *lookup = (char *) name;
339 sk = g_io_channel_unix_get_fd(server->channel);
341 err = send(sk, request, req->request_len, 0);
345 /* If we have more than one dot, we don't add domains */
346 dot = strchr(lookup, '.');
347 if (dot != NULL && dot != lookup + strlen(lookup) - 1)
350 if (server->domains != NULL && server->domains->data != NULL)
351 req->append_domain = TRUE;
353 for (list = server->domains; list; list = list->next) {
355 unsigned char alt[1024];
356 struct domain_hdr *hdr = (void *) &alt;
357 int altlen, domlen, offset;
364 offset = protocol_offset(server->protocol);
368 domlen = strlen(domain) + 1;
372 alt[offset] = req->altid & 0xff;
373 alt[offset + 1] = req->altid >> 8;
375 memcpy(alt + offset + 2, request + offset + 2, 10);
376 hdr->qdcount = htons(1);
378 altlen = append_query(alt + offset + 12, sizeof(alt) - 12,
385 memcpy(alt + offset + altlen,
386 request + offset + altlen - domlen,
387 req->request_len - altlen + domlen);
389 if (server->protocol == IPPROTO_TCP) {
390 int req_len = req->request_len + domlen - 1;
392 alt[0] = (req_len >> 8) & 0xff;
393 alt[1] = req_len & 0xff;
396 err = send(sk, alt, req->request_len + domlen + 1, 0);
406 static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol)
408 struct domain_hdr *hdr;
409 struct request_data *req;
410 int dns_id, sk, err, offset = protocol_offset(protocol);
411 struct listener_data *ifdata;
416 hdr = (void *)(reply + offset);
417 dns_id = reply[offset] | reply[offset + 1] << 8;
419 DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
421 req = find_request(dns_id);
425 DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode);
427 ifdata = req->ifdata;
429 reply[offset] = req->srcid & 0xff;
430 reply[offset + 1] = req->srcid >> 8;
434 if (hdr->rcode == 0 || req->resp == NULL) {
437 * If the domain name was append
438 * remove it before forwarding the reply.
440 if (req->append_domain == TRUE) {
443 unsigned int domain_len;
446 * ptr points to the first char of the hostname.
447 * ->hostname.domain.net
449 ptr = reply + offset + sizeof(struct domain_hdr);
451 domain_len = strlen((const char *)ptr) - host_len - 1;
454 * remove the domain name and replaced it by the end
457 memmove(ptr + host_len + 1,
458 ptr + host_len + domain_len + 1,
459 reply_len - (ptr - reply + domain_len));
461 reply_len = reply_len - domain_len;
467 req->resp = g_try_malloc(reply_len);
468 if (req->resp == NULL)
471 memcpy(req->resp, reply, reply_len);
472 req->resplen = reply_len;
475 if (hdr->rcode > 0 && req->numresp < req->numserv)
478 if (req->timeout > 0)
479 g_source_remove(req->timeout);
481 request_list = g_slist_remove(request_list, req);
483 if (protocol == IPPROTO_UDP) {
484 sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
485 err = sendto(sk, req->resp, req->resplen, 0,
486 &req->sa, req->sa_len);
489 err = send(sk, req->resp, req->resplen, 0);
499 static void destroy_server(struct server_data *server)
503 DBG("interface %s server %s", server->interface, server->server);
505 server_list = g_slist_remove(server_list, server);
507 if (server->watch > 0)
508 g_source_remove(server->watch);
510 if (server->timeout > 0)
511 g_source_remove(server->timeout);
513 g_io_channel_unref(server->channel);
515 if (server->protocol == IPPROTO_UDP)
516 connman_info("Removing DNS server %s", server->server);
518 g_free(server->incoming_reply);
519 g_free(server->server);
520 for (list = server->domains; list; list = list->next) {
521 char *domain = list->data;
523 server->domains = g_list_remove(server->domains, domain);
526 g_free(server->interface);
530 static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition,
533 unsigned char buf[4096];
536 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
537 struct server_data *data = user_data;
539 connman_error("Error with UDP server %s", data->server);
544 sk = g_io_channel_unix_get_fd(channel);
546 len = recv(sk, buf, sizeof(buf), 0);
550 err = forward_dns_reply(buf, len, IPPROTO_UDP);
557 static gboolean tcp_server_event(GIOChannel *channel, GIOCondition condition,
561 struct server_data *server = user_data;
563 sk = g_io_channel_unix_get_fd(channel);
567 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
570 DBG("TCP server channel closed");
573 * Discard any partial response which is buffered; better
574 * to get a proper response from a working server.
576 g_free(server->incoming_reply);
577 server->incoming_reply = NULL;
579 for (list = request_list; list; list = list->next) {
580 struct request_data *req = list->data;
581 struct domain_hdr *hdr;
583 if (req->protocol == IPPROTO_UDP)
586 if (req->request == NULL)
590 * If we're not waiting for any further response
591 * from another name server, then we send an error
592 * response to the client.
594 if (req->numserv && --(req->numserv))
597 hdr = (void *) (req->request + 2);
598 hdr->id = req->srcid;
599 send_response(req->client_sk, req->request,
600 req->request_len, NULL, 0, IPPROTO_TCP);
602 request_list = g_slist_remove(request_list, req);
605 destroy_server(server);
610 if ((condition & G_IO_OUT) && !server->connected) {
613 struct server_data *udp_server;
615 udp_server = find_server(server->interface, server->server,
617 if (udp_server != NULL) {
618 for (domains = udp_server->domains; domains;
619 domains = domains->next) {
620 char *dom = domains->data;
622 DBG("Adding domain %s to %s",
623 dom, server->server);
625 server->domains = g_list_append(server->domains,
630 server->connected = TRUE;
631 server_list = g_slist_append(server_list, server);
633 if (server->timeout > 0) {
634 g_source_remove(server->timeout);
638 for (list = request_list; list; list = list->next) {
639 struct request_data *req = list->data;
641 if (req->protocol == IPPROTO_UDP)
644 DBG("Sending req %s over TCP", (char *)req->name);
646 if (req->timeout > 0)
647 g_source_remove(req->timeout);
649 req->timeout = g_timeout_add_seconds(30,
650 request_timeout, req);
651 ns_resolv(server, req, req->request, req->name);
654 } else if (condition & G_IO_IN) {
655 struct partial_reply *reply = server->incoming_reply;
659 unsigned char reply_len_buf[2];
662 bytes_recv = recv(sk, reply_len_buf, 2, MSG_PEEK);
665 } else if (bytes_recv < 0) {
666 if (errno == EAGAIN || errno == EWOULDBLOCK)
669 connman_error("DNS proxy error %s",
672 } else if (bytes_recv < 2)
675 reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
678 DBG("TCP reply %d bytes", reply_len);
680 reply = g_try_malloc(sizeof(*reply) + reply_len + 2);
684 reply->len = reply_len;
687 server->incoming_reply = reply;
690 while (reply->received < reply->len) {
691 bytes_recv = recv(sk, reply->buf + reply->received,
692 reply->len - reply->received, 0);
694 connman_error("DNS proxy TCP disconnect");
696 } else if (bytes_recv < 0) {
697 if (errno == EAGAIN || errno == EWOULDBLOCK)
700 connman_error("DNS proxy error %s",
704 reply->received += bytes_recv;
707 forward_dns_reply(reply->buf, reply->received, IPPROTO_TCP);
710 server->incoming_reply = NULL;
712 destroy_server(server);
720 static gboolean tcp_idle_timeout(gpointer user_data)
722 struct server_data *server = user_data;
729 destroy_server(server);
734 static struct server_data *create_server(const char *interface,
735 const char *domain, const char *server,
738 struct addrinfo hints, *rp;
739 struct server_data *data;
742 DBG("interface %s server %s", interface, server);
744 memset(&hints, 0, sizeof(hints));
748 hints.ai_socktype = SOCK_DGRAM;
752 hints.ai_socktype = SOCK_STREAM;
758 hints.ai_family = AF_UNSPEC;
759 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
761 ret = getaddrinfo(server, "53", &hints, &rp);
763 connman_error("Failed to parse server %s address: %s\n",
764 server, gai_strerror(ret));
767 /* Do not blindly copy this code elsewhere; it doesn't loop over the
768 results using ->ai_next as it should. That's OK in *this* case
769 because it was a numeric lookup; we *know* there's only one. */
771 sk = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
773 connman_error("Failed to create server %s socket", server);
778 if (interface != NULL) {
779 if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
780 interface, strlen(interface) + 1) < 0) {
781 connman_error("Failed to bind server %s "
790 data = g_try_new0(struct server_data, 1);
792 connman_error("Failed to allocate server %s data", server);
798 data->channel = g_io_channel_unix_new(sk);
799 if (data->channel == NULL) {
800 connman_error("Failed to create server %s channel", server);
807 g_io_channel_set_close_on_unref(data->channel, TRUE);
809 if (protocol == IPPROTO_TCP) {
810 g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, NULL);
811 data->watch = g_io_add_watch(data->channel,
812 G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
813 tcp_server_event, data);
814 data->timeout = g_timeout_add_seconds(30, tcp_idle_timeout,
817 data->watch = g_io_add_watch(data->channel,
818 G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
819 udp_server_event, data);
821 data->interface = g_strdup(interface);
823 data->domains = g_list_append(data->domains, g_strdup(domain));
824 data->server = g_strdup(server);
825 data->protocol = protocol;
827 ret = connect(sk, rp->ai_addr, rp->ai_addrlen);
830 if ((protocol == IPPROTO_TCP && errno != EINPROGRESS) ||
831 protocol == IPPROTO_UDP) {
834 connman_error("Failed to connect to server %s", server);
836 g_source_remove(data->watch);
837 if (data->timeout > 0)
838 g_source_remove(data->timeout);
840 g_io_channel_unref(data->channel);
843 g_free(data->server);
844 g_free(data->interface);
845 for (list = data->domains; list; list = list->next) {
846 char *domain = list->data;
848 data->domains = g_list_remove(data->domains,
857 if (protocol == IPPROTO_UDP) {
858 /* Enable new servers by default */
859 data->enabled = TRUE;
860 connman_info("Adding DNS server %s", data->server);
862 server_list = g_slist_append(server_list, data);
870 static gboolean resolv(struct request_data *req,
871 gpointer request, gpointer name)
875 for (list = server_list; list; list = list->next) {
876 struct server_data *data = list->data;
878 DBG("server %s enabled %d", data->server, data->enabled);
880 if (data->enabled == FALSE)
883 if (data->watch == 0 && data->protocol == IPPROTO_UDP)
884 data->watch = g_io_add_watch(data->channel,
885 G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
886 udp_server_event, data);
888 if (ns_resolv(data, req, request, name) < 0)
895 static void append_domain(const char *interface, const char *domain)
899 DBG("interface %s domain %s", interface, domain);
904 for (list = server_list; list; list = list->next) {
905 struct server_data *data = list->data;
908 gboolean dom_found = FALSE;
910 if (data->interface == NULL)
913 if (g_str_equal(data->interface, interface) == FALSE)
916 for (dom_list = data->domains; dom_list;
917 dom_list = dom_list->next) {
918 dom = dom_list->data;
920 if (g_str_equal(dom, domain)) {
926 if (dom_found == FALSE) {
928 g_list_append(data->domains, g_strdup(domain));
933 int __connman_dnsproxy_append(const char *interface, const char *domain,
936 struct server_data *data;
938 DBG("interface %s server %s", interface, server);
940 if (server == NULL && domain == NULL)
943 if (server == NULL) {
944 append_domain(interface, domain);
949 if (g_str_equal(server, "127.0.0.1") == TRUE)
952 data = find_server(interface, server, IPPROTO_UDP);
954 append_domain(interface, domain);
958 data = create_server(interface, domain, server, IPPROTO_UDP);
965 static void remove_server(const char *interface, const char *domain,
966 const char *server, int protocol)
968 struct server_data *data;
970 data = find_server(interface, server, protocol);
974 destroy_server(data);
977 int __connman_dnsproxy_remove(const char *interface, const char *domain,
980 DBG("interface %s server %s", interface, server);
985 if (g_str_equal(server, "127.0.0.1") == TRUE)
988 remove_server(interface, domain, server, IPPROTO_UDP);
989 remove_server(interface, domain, server, IPPROTO_TCP);
994 void __connman_dnsproxy_flush(void)
998 list = request_pending_list;
1000 struct request_data *req = list->data;
1004 request_pending_list =
1005 g_slist_remove(request_pending_list, req);
1006 resolv(req, req->request, req->name);
1007 g_free(req->request);
1012 static void dnsproxy_offline_mode(connman_bool_t enabled)
1016 DBG("enabled %d", enabled);
1018 for (list = server_list; list; list = list->next) {
1019 struct server_data *data = list->data;
1021 if (enabled == FALSE) {
1022 connman_info("Enabling DNS server %s", data->server);
1023 data->enabled = TRUE;
1025 connman_info("Disabling DNS server %s", data->server);
1026 data->enabled = FALSE;
1031 static void dnsproxy_default_changed(struct connman_service *service)
1036 DBG("service %p", service);
1038 if (service == NULL) {
1039 /* When no services are active, then disable DNS proxying */
1040 dnsproxy_offline_mode(TRUE);
1044 interface = connman_service_get_interface(service);
1045 if (interface == NULL)
1048 for (list = server_list; list; list = list->next) {
1049 struct server_data *data = list->data;
1051 if (g_strcmp0(data->interface, interface) == 0) {
1052 connman_info("Enabling DNS server %s", data->server);
1053 data->enabled = TRUE;
1055 connman_info("Disabling DNS server %s", data->server);
1056 data->enabled = FALSE;
1063 static struct connman_notifier dnsproxy_notifier = {
1065 .default_changed = dnsproxy_default_changed,
1066 .offline_mode = dnsproxy_offline_mode,
1069 static unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
1071 static int parse_request(unsigned char *buf, int len,
1072 char *name, unsigned int size)
1074 struct domain_hdr *hdr = (void *) buf;
1075 uint16_t qdcount = ntohs(hdr->qdcount);
1076 uint16_t arcount = ntohs(hdr->arcount);
1078 char *last_label = NULL;
1079 unsigned int remain, used = 0;
1084 DBG("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
1085 hdr->id, hdr->qr, hdr->opcode,
1088 if (hdr->qr != 0 || qdcount != 1)
1091 memset(name, 0, size);
1093 ptr = buf + sizeof(struct domain_hdr);
1094 remain = len - sizeof(struct domain_hdr);
1096 while (remain > 0) {
1100 last_label = (char *) (ptr + 1);
1104 if (used + len + 1 > size)
1107 strncat(name, (char *) (ptr + 1), len);
1116 if (last_label && arcount && remain >= 9 && last_label[4] == 0 &&
1117 !memcmp(last_label + 5, opt_edns0_type, 2)) {
1118 uint16_t edns0_bufsize;
1120 edns0_bufsize = last_label[7] << 8 | last_label[8];
1122 DBG("EDNS0 buffer size %u", edns0_bufsize);
1124 /* This is an evil hack until full TCP support has been
1127 * Somtimes the EDNS0 request gets send with a too-small
1128 * buffer size. Since glibc doesn't seem to crash when it
1129 * gets a response biffer then it requested, just bump
1130 * the buffer size up to 4KiB.
1132 if (edns0_bufsize < 0x1000) {
1133 last_label[7] = 0x10;
1134 last_label[8] = 0x00;
1138 DBG("query %s", name);
1143 static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
1146 unsigned char buf[768];
1148 struct request_data *req;
1149 struct server_data *server;
1150 int sk, client_sk, len, err;
1151 struct sockaddr_in6 client_addr;
1152 socklen_t client_addr_len = sizeof(client_addr);
1154 struct listener_data *ifdata = user_data;
1156 DBG("condition 0x%x", condition);
1158 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1159 if (ifdata->tcp_listener_watch > 0)
1160 g_source_remove(ifdata->tcp_listener_watch);
1161 ifdata->tcp_listener_watch = 0;
1163 connman_error("Error with TCP listener channel");
1168 sk = g_io_channel_unix_get_fd(channel);
1170 client_sk = accept(sk, (void *)&client_addr, &client_addr_len);
1171 if (client_sk < 0) {
1172 connman_error("Accept failure on TCP listener");
1173 ifdata->tcp_listener_watch = 0;
1177 len = recv(client_sk, buf, sizeof(buf), 0);
1181 DBG("Received %d bytes (id 0x%04x)", len, buf[2] | buf[3] << 8);
1183 err = parse_request(buf + 2, len - 2, query, sizeof(query));
1184 if (err < 0 || (g_slist_length(server_list) == 0)) {
1185 send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
1189 req = g_try_new0(struct request_data, 1);
1193 memcpy(&req->sa, &client_addr, client_addr_len);
1194 req->sa_len = client_addr_len;
1195 req->client_sk = client_sk;
1196 req->protocol = IPPROTO_TCP;
1199 if (request_id == 0x0000 || request_id == 0xffff)
1202 req->srcid = buf[2] | (buf[3] << 8);
1203 req->dstid = request_id;
1204 req->altid = request_id + 1;
1205 req->request_len = len;
1207 buf[2] = req->dstid & 0xff;
1208 buf[3] = req->dstid >> 8;
1211 req->ifdata = (struct listener_data *) ifdata;
1212 req->append_domain = FALSE;
1213 request_list = g_slist_append(request_list, req);
1215 for (list = server_list; list; list = list->next) {
1216 struct server_data *data = list->data;
1219 if (data->protocol != IPPROTO_UDP || data->enabled == FALSE)
1222 server = create_server(data->interface, NULL,
1223 data->server, IPPROTO_TCP);
1226 * If server is NULL, we're not connected yet.
1227 * Copy the relevant buffers and continue with
1228 * the next nameserver.
1229 * The request will actually be sent once we're
1230 * properly connected over TCP to this nameserver.
1232 if (server == NULL) {
1233 req->request = g_try_malloc0(req->request_len);
1234 if (req->request == NULL)
1237 memcpy(req->request, buf, req->request_len);
1239 req->name = g_try_malloc0(sizeof(query));
1240 if (req->name == NULL) {
1241 g_free(req->request);
1244 memcpy(req->name, query, sizeof(query));
1249 if (req->timeout > 0)
1250 g_source_remove(req->timeout);
1252 for (domains = data->domains; domains;
1253 domains = domains->next) {
1254 char *dom = domains->data;
1256 DBG("Adding domain %s to %s", dom, server->server);
1258 server->domains = g_list_append(server->domains,
1262 req->timeout = g_timeout_add_seconds(30, request_timeout, req);
1263 ns_resolv(server, req, buf, query);
1269 static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
1272 unsigned char buf[768];
1274 struct request_data *req;
1275 struct sockaddr_in6 client_addr;
1276 socklen_t client_addr_len = sizeof(client_addr);
1278 struct listener_data *ifdata = user_data;
1280 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1281 connman_error("Error with UDP listener channel");
1282 ifdata->udp_listener_watch = 0;
1286 sk = g_io_channel_unix_get_fd(channel);
1288 memset(&client_addr, 0, client_addr_len);
1289 len = recvfrom(sk, buf, sizeof(buf), 0, (void *)&client_addr,
1294 DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
1296 err = parse_request(buf, len, query, sizeof(query));
1297 if (err < 0 || (g_slist_length(server_list) == 0)) {
1298 send_response(sk, buf, len, (void *)&client_addr,
1299 client_addr_len, IPPROTO_UDP);
1303 req = g_try_new0(struct request_data, 1);
1307 memcpy(&req->sa, &client_addr, client_addr_len);
1308 req->sa_len = client_addr_len;
1310 req->protocol = IPPROTO_UDP;
1313 if (request_id == 0x0000 || request_id == 0xffff)
1316 req->srcid = buf[0] | (buf[1] << 8);
1317 req->dstid = request_id;
1318 req->altid = request_id + 1;
1319 req->request_len = len;
1321 buf[0] = req->dstid & 0xff;
1322 buf[1] = req->dstid >> 8;
1325 req->ifdata = (struct listener_data *) ifdata;
1326 req->timeout = g_timeout_add_seconds(5, request_timeout, req);
1327 req->append_domain = FALSE;
1328 request_list = g_slist_append(request_list, req);
1330 return resolv(req, buf, query);
1333 static int create_dns_listener(int protocol, struct listener_data *ifdata)
1335 GIOChannel *channel;
1339 struct sockaddr_in6 sin6;
1340 struct sockaddr_in sin;
1343 int sk, type, v6only = 0;
1344 int family = AF_INET6;
1347 DBG("interface %s", ifdata->ifname);
1352 type = SOCK_DGRAM | SOCK_CLOEXEC;
1357 type = SOCK_STREAM | SOCK_CLOEXEC;
1364 sk = socket(family, type, protocol);
1365 if (sk < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
1366 connman_error("No IPv6 support; DNS proxy listening only on Legacy IP");
1368 sk = socket(family, type, protocol);
1371 connman_error("Failed to create %s listener socket", proto);
1375 if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
1377 strlen(ifdata->ifname) + 1) < 0) {
1378 connman_error("Failed to bind %s listener interface", proto);
1382 /* Ensure it accepts Legacy IP connections too */
1383 if (family == AF_INET6 &&
1384 setsockopt(sk, SOL_IPV6, IPV6_V6ONLY,
1385 &v6only, sizeof(v6only)) < 0) {
1386 connman_error("Failed to clear V6ONLY on %s listener socket",
1392 if (family == AF_INET) {
1393 memset(&s.sin, 0, sizeof(s.sin));
1394 s.sin.sin_family = AF_INET;
1395 s.sin.sin_port = htons(53);
1396 s.sin.sin_addr.s_addr = htonl(INADDR_ANY);
1397 slen = sizeof(s.sin);
1399 memset(&s.sin6, 0, sizeof(s.sin6));
1400 s.sin6.sin6_family = AF_INET6;
1401 s.sin6.sin6_port = htons(53);
1402 s.sin6.sin6_addr = in6addr_any;
1403 slen = sizeof(s.sin6);
1406 if (bind(sk, &s.sa, slen) < 0) {
1407 connman_error("Failed to bind %s listener socket", proto);
1412 if (protocol == IPPROTO_TCP && listen(sk, 10) < 0) {
1413 connman_error("Failed to listen on TCP socket");
1418 channel = g_io_channel_unix_new(sk);
1419 if (channel == NULL) {
1420 connman_error("Failed to create %s listener channel", proto);
1425 g_io_channel_set_close_on_unref(channel, TRUE);
1427 if (protocol == IPPROTO_TCP) {
1428 ifdata->tcp_listener_channel = channel;
1429 ifdata->tcp_listener_watch = g_io_add_watch(channel,
1430 G_IO_IN, tcp_listener_event, (gpointer) ifdata);
1432 ifdata->udp_listener_channel = channel;
1433 ifdata->udp_listener_watch = g_io_add_watch(channel,
1434 G_IO_IN, udp_listener_event, (gpointer) ifdata);
1440 static void destroy_udp_listener(struct listener_data *ifdata)
1442 DBG("interface %s", ifdata->ifname);
1444 if (ifdata->udp_listener_watch > 0)
1445 g_source_remove(ifdata->udp_listener_watch);
1447 g_io_channel_unref(ifdata->udp_listener_channel);
1450 static void destroy_tcp_listener(struct listener_data *ifdata)
1452 DBG("interface %s", ifdata->ifname);
1454 if (ifdata->tcp_listener_watch > 0)
1455 g_source_remove(ifdata->tcp_listener_watch);
1457 g_io_channel_unref(ifdata->tcp_listener_channel);
1460 static int create_listener(struct listener_data *ifdata)
1464 err = create_dns_listener(IPPROTO_UDP, ifdata);
1468 err = create_dns_listener(IPPROTO_TCP, ifdata);
1470 destroy_udp_listener(ifdata);
1474 if (g_strcmp0(ifdata->ifname, "lo") == 0)
1475 __connman_resolvfile_append("lo", NULL, "127.0.0.1");
1480 static void destroy_listener(struct listener_data *ifdata)
1484 if (g_strcmp0(ifdata->ifname, "lo") == 0)
1485 __connman_resolvfile_remove("lo", NULL, "127.0.0.1");
1487 for (list = request_pending_list; list; list = list->next) {
1488 struct request_data *req = list->data;
1490 DBG("Dropping pending request (id 0x%04x -> 0x%04x)",
1491 req->srcid, req->dstid);
1494 g_free(req->request);
1500 g_slist_free(request_pending_list);
1501 request_pending_list = NULL;
1503 for (list = request_list; list; list = list->next) {
1504 struct request_data *req = list->data;
1506 DBG("Dropping request (id 0x%04x -> 0x%04x)",
1507 req->srcid, req->dstid);
1510 g_free(req->request);
1516 g_slist_free(request_list);
1517 request_list = NULL;
1519 destroy_tcp_listener(ifdata);
1520 destroy_udp_listener(ifdata);
1523 int __connman_dnsproxy_add_listener(const char *interface)
1525 struct listener_data *ifdata;
1528 DBG("interface %s", interface);
1530 if (g_hash_table_lookup(listener_table, interface) != NULL)
1533 ifdata = g_try_new0(struct listener_data, 1);
1537 ifdata->ifname = g_strdup(interface);
1538 ifdata->udp_listener_channel = NULL;
1539 ifdata->udp_listener_watch = 0;
1540 ifdata->tcp_listener_channel = NULL;
1541 ifdata->tcp_listener_watch = 0;
1543 err = create_listener(ifdata);
1545 connman_error("Couldn't create listener for %s err %d",
1547 g_free(ifdata->ifname);
1551 g_hash_table_insert(listener_table, ifdata->ifname, ifdata);
1555 void __connman_dnsproxy_remove_listener(const char *interface)
1557 struct listener_data *ifdata;
1559 DBG("interface %s", interface);
1561 ifdata = g_hash_table_lookup(listener_table, interface);
1565 destroy_listener(ifdata);
1567 g_hash_table_remove(listener_table, interface);
1570 static void remove_listener(gpointer key, gpointer value, gpointer user_data)
1572 __connman_dnsproxy_remove_listener(key);
1575 int __connman_dnsproxy_init(void)
1581 listener_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1583 err = __connman_dnsproxy_add_listener("lo");
1587 err = connman_notifier_register(&dnsproxy_notifier);
1594 __connman_dnsproxy_remove_listener("lo");
1595 g_hash_table_destroy(listener_table);
1600 void __connman_dnsproxy_cleanup(void)
1604 connman_notifier_unregister(&dnsproxy_notifier);
1606 g_hash_table_foreach(listener_table, remove_listener, NULL);
1608 g_hash_table_destroy(listener_table);