Define protocol_offset() for DNS transport layer offset
[platform/upstream/connman.git] / plugins / dnsproxy.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 <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdint.h>
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
32
33 #define CONNMAN_API_SUBJECT_TO_CHANGE
34 #include <connman/plugin.h>
35 #include <connman/resolver.h>
36 #include <connman/notifier.h>
37 #include <connman/ondemand.h>
38 #include <connman/log.h>
39
40 #include <glib.h>
41
42 #if __BYTE_ORDER == __LITTLE_ENDIAN
43 struct domain_hdr {
44         uint16_t id;
45         uint8_t rd:1;
46         uint8_t tc:1;
47         uint8_t aa:1;
48         uint8_t opcode:4;
49         uint8_t qr:1;
50         uint8_t rcode:4;
51         uint8_t z:3;
52         uint8_t ra:1;
53         uint16_t qdcount;
54         uint16_t ancount;
55         uint16_t nscount;
56         uint16_t arcount;
57 } __attribute__ ((packed));
58 #elif __BYTE_ORDER == __BIG_ENDIAN
59 struct domain_hdr {
60         uint16_t id;
61         uint8_t qr:1;
62         uint8_t opcode:4;
63         uint8_t aa:1;
64         uint8_t tc:1;
65         uint8_t rd:1;
66         uint8_t ra:1;
67         uint8_t z:3;
68         uint8_t rcode:4;
69         uint16_t qdcount;
70         uint16_t ancount;
71         uint16_t nscount;
72         uint16_t arcount;
73 } __attribute__ ((packed));
74 #else
75 #error "Unknown byte order"
76 #endif
77
78 struct server_data {
79         char *interface;
80         char *domain;
81         char *server;
82         int protocol;
83         GIOChannel *channel;
84         guint watch;
85         guint timeout;
86         gboolean enabled;
87         gboolean connected;
88 };
89
90 struct request_data {
91         struct sockaddr_in sin;
92         int client_sk;
93         int protocol;
94         socklen_t len;
95         guint16 srcid;
96         guint16 dstid;
97         guint16 altid;
98         guint timeout;
99         guint watch;
100         guint numserv;
101         guint numresp;
102         gpointer request;
103         gsize request_len;
104         gpointer name;
105         gpointer resp;
106         gsize resplen;
107 };
108
109 static GSList *server_list = NULL;
110 static GSList *request_list = NULL;
111 static GSList *request_pending_list = NULL;
112 static guint16 request_id = 0x0000;
113
114 static GIOChannel *udp_listener_channel = NULL;
115 static guint udp_listener_watch = 0;
116 static GIOChannel *tcp_listener_channel = NULL;
117 static guint tcp_listener_watch = 0;
118
119 static int protocol_offset(int protocol)
120 {
121         switch (protocol) {
122         case IPPROTO_UDP:
123                 return 0;
124
125         case IPPROTO_TCP:
126                 return 2;
127
128         default:
129                 return -EINVAL;
130         }
131
132 }
133
134 static struct request_data *find_request(guint16 id)
135 {
136         GSList *list;
137
138         for (list = request_list; list; list = list->next) {
139                 struct request_data *req = list->data;
140
141                 if (req->dstid == id || req->altid == id)
142                         return req;
143         }
144
145         return NULL;
146 }
147
148 static struct server_data *find_server(const char *interface,
149                                         const char *domain, const char *server,
150                                                 int protocol)
151 {
152         GSList *list;
153
154         DBG("interface %s server %s", interface, server);
155
156         for (list = server_list; list; list = list->next) {
157                 struct server_data *data = list->data;
158
159                 if (data->interface == NULL || data->server == NULL)
160                         continue;
161
162                 if (g_str_equal(data->interface, interface) == TRUE &&
163                                 g_str_equal(data->server, server) == TRUE &&
164                                 data->protocol == protocol) {
165                         if (domain == NULL) {
166                                 if (data->domain == NULL)
167                                         return data;
168                                 continue;
169                         }
170
171                         if (g_str_equal(data->domain, domain) == TRUE)
172                                 return data;
173                 }
174         }
175
176         return NULL;
177 }
178
179
180 static void send_response(int sk, unsigned char *buf, int len,
181                                 const struct sockaddr *to, socklen_t tolen,
182                                 int protocol)
183 {
184         struct domain_hdr *hdr;
185         int err, offset = protocol_offset(protocol);
186
187         DBG("");
188
189         if (offset < 0)
190                 return;
191
192         if (len < 12)
193                 return;
194
195         hdr = (void*) (buf + offset);
196
197         DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
198
199         hdr->qr = 1;
200         hdr->rcode = 2;
201
202         hdr->ancount = 0;
203         hdr->nscount = 0;
204         hdr->arcount = 0;
205
206         err = sendto(sk, buf, len, 0, to, tolen);
207 }
208
209 static gboolean request_timeout(gpointer user_data)
210 {
211         struct request_data *req = user_data;
212
213         DBG("id 0x%04x", req->srcid);
214
215         if (req == NULL)
216                 return FALSE;
217
218         request_list = g_slist_remove(request_list, req);
219         req->numserv--;
220
221         if (req->resplen > 0 && req->resp != NULL) {
222                 int sk, err;
223
224                 sk = g_io_channel_unix_get_fd(udp_listener_channel);
225
226                 err = sendto(sk, req->resp, req->resplen, 0,
227                                 (struct sockaddr *) &req->sin, req->len);
228         } else if (req->request && req->numserv == 0) {
229                 struct domain_hdr *hdr;
230
231                 if (req->protocol == IPPROTO_TCP) {
232                         hdr = (void *) (req->request + 2);
233                         hdr->id = req->srcid;
234                         send_response(req->client_sk, req->request,
235                                         req->request_len, NULL, 0, IPPROTO_TCP);
236
237                 } else if (req->protocol == IPPROTO_UDP) {
238                         int sk;
239
240                         hdr = (void *) (req->request);
241                         hdr->id = req->srcid;
242                         sk = g_io_channel_unix_get_fd(udp_listener_channel);
243                         send_response(sk, req->request, req->request_len,
244                                         (struct sockaddr *)&req->sin,
245                                                 sizeof(req->sin), IPPROTO_UDP);
246                 }
247         }
248
249         g_free(req->resp);
250         g_free(req);
251
252         return FALSE;
253 }
254
255 static int append_query(unsigned char *buf, unsigned int size,
256                                 const char *query, const char *domain)
257 {
258         unsigned char *ptr = buf;
259         char *offset;
260
261         DBG("query %s domain %s", query, domain);
262
263         offset = (char *) query;
264         while (offset != NULL) {
265                 char *tmp;
266
267                 tmp = strchr(offset, '.');
268                 if (tmp == NULL) {
269                         if (strlen(offset) == 0)
270                                 break;
271                         *ptr = strlen(offset);
272                         memcpy(ptr + 1, offset, strlen(offset));
273                         ptr += strlen(offset) + 1;
274                         break;
275                 }
276
277                 *ptr = tmp - offset;
278                 memcpy(ptr + 1, offset, tmp - offset);
279                 ptr += tmp - offset + 1;
280
281                 offset = tmp + 1;
282         }
283
284         offset = (char *) domain;
285         while (offset != NULL) {
286                 char *tmp;
287
288                 tmp = strchr(offset, '.');
289                 if (tmp == NULL) {
290                         if (strlen(offset) == 0)
291                                 break;
292                         *ptr = strlen(offset);
293                         memcpy(ptr + 1, offset, strlen(offset));
294                         ptr += strlen(offset) + 1;
295                         break;
296                 }
297
298                 *ptr = tmp - offset;
299                 memcpy(ptr + 1, offset, tmp - offset);
300                 ptr += tmp - offset + 1;
301
302                 offset = tmp + 1;
303         }
304
305         *ptr++ = 0x00;
306
307         return ptr - buf;
308 }
309
310 static int ns_resolv(struct server_data *server, struct request_data *req,
311                                 gpointer request, gpointer name)
312 {
313         int sk, err;
314
315         sk = g_io_channel_unix_get_fd(server->channel);
316
317         err = send(sk, request, req->request_len, 0);
318
319         req->numserv++;
320
321         if (server->domain != NULL && server->protocol == IPPROTO_UDP) {
322                 unsigned char alt[1024];
323                 struct domain_hdr *hdr = (void *) &alt;
324                 int altlen, domlen;
325
326                 domlen = strlen(server->domain) + 1;
327                 if (domlen < 5)
328                         return -EINVAL;
329
330                 alt[0] = req->altid & 0xff;
331                 alt[1] = req->altid >> 8;
332
333                 memcpy(alt + 2, request + 2, 10);
334                 hdr->qdcount = htons(1);
335
336                 altlen = append_query(alt + 12, sizeof(alt) - 12,
337                                         name, server->domain);
338                 if (altlen < 0)
339                         return -EINVAL;
340
341                 altlen += 12;
342
343                 memcpy(alt + altlen, request + altlen - domlen,
344                                 req->request_len - altlen + domlen);
345
346                 err = send(sk, alt, req->request_len + domlen + 1, 0);
347
348                 req->numserv++;
349         }
350
351         return 0;
352 }
353
354 static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol)
355 {
356         struct domain_hdr *hdr;
357         struct request_data *req;
358         int dns_id, sk, err, offset = protocol_offset(protocol);
359
360         if (offset < 0)
361                 return offset;
362
363         hdr = (void *)(reply + offset);
364         dns_id = reply[offset] | reply[offset + 1] << 8;
365
366         DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
367
368         req = find_request(dns_id);
369         if (req == NULL)
370                 return -EINVAL;
371
372         DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode);
373
374         reply[offset] = req->srcid & 0xff;
375         reply[offset + 1] = req->srcid >> 8;
376
377         req->numresp++;
378
379         if (hdr->rcode == 0 || req->resp == NULL) {
380                 g_free(req->resp);
381                 req->resplen = 0;
382
383                 req->resp = g_try_malloc(reply_len);
384                 if (req->resp == NULL)
385                         return -ENOMEM;
386
387                 memcpy(req->resp, reply, reply_len);
388                 req->resplen = reply_len;
389         }
390
391         if (hdr->rcode > 0 && req->numresp < req->numserv)
392                 return -EINVAL;
393
394         if (req->timeout > 0)
395                 g_source_remove(req->timeout);
396
397         request_list = g_slist_remove(request_list, req);
398
399         if (protocol == IPPROTO_UDP) {
400                 sk = g_io_channel_unix_get_fd(udp_listener_channel);
401                 err = sendto(sk, req->resp, req->resplen, 0,
402                                 (struct sockaddr *) &req->sin, req->len);
403         } else {
404                 sk = req->client_sk;
405                 err = send(sk, req->resp, req->resplen, 0);
406                 close(sk);
407         }
408
409         g_free(req->resp);
410         g_free(req);
411
412         return err;
413 }
414
415 static void destroy_server(struct server_data *server)
416 {
417         DBG("interface %s server %s", server->interface, server->server);
418
419         server_list = g_slist_remove(server_list, server);
420
421         if (server->watch > 0)
422                 g_source_remove(server->watch);
423
424         if (server->timeout > 0)
425                 g_source_remove(server->timeout);
426
427         g_io_channel_unref(server->channel);
428
429         if (server->protocol == IPPROTO_UDP)
430                 connman_info("Removing DNS server %s", server->server);
431
432         g_free(server->server);
433         g_free(server->domain);
434         g_free(server->interface);
435         g_free(server);
436 }
437
438 static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition,
439                                                         gpointer user_data)
440 {
441         struct server_data *data = user_data;
442         unsigned char buf[4096];
443         int sk, err, len;
444
445         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
446                 connman_error("Error with server channel");
447                 data->watch = 0;
448                 return FALSE;
449         }
450
451         sk = g_io_channel_unix_get_fd(channel);
452
453         len = recv(sk, buf, sizeof(buf), 0);
454         if (len < 12)
455                 return TRUE;
456
457         err = forward_dns_reply(buf, len, IPPROTO_UDP);
458
459         return TRUE;
460 }
461
462 static gboolean tcp_server_event(GIOChannel *channel, GIOCondition condition,
463                                                         gpointer user_data)
464 {
465         int sk;
466         struct server_data *server = user_data;
467
468         sk = g_io_channel_unix_get_fd(channel);
469         if (sk == 0)
470                 return FALSE;
471
472         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
473                 GSList *list;
474
475                 DBG("TCP server channel closed");
476
477                 for (list = request_list; list; list = list->next) {
478                         struct request_data *req = list->data;
479                         struct domain_hdr *hdr;
480
481                         if (req->protocol == IPPROTO_UDP)
482                                 continue;
483
484                         if (req->request == NULL)
485                                 continue;
486
487                         /*
488                          * If we're not waiting for any further response
489                          * from another name server, then we send an error
490                          * response to the client.
491                          */
492                         if (req->numserv && --(req->numserv))
493                                 continue;
494
495                         hdr = (void *) (req->request + 2);
496                         hdr->id = req->srcid;
497                         send_response(req->client_sk, req->request,
498                                         req->request_len, NULL, 0, IPPROTO_TCP);
499
500                         request_list = g_slist_remove(request_list, req);
501                 }
502
503                 destroy_server(server);
504
505                 return FALSE;
506         }
507
508         if ((condition & G_IO_OUT) && !server->connected) {
509                 GSList *list;
510
511                 server->connected = TRUE;
512                 server_list = g_slist_append(server_list, server);
513
514                 if (server->timeout > 0) {
515                         g_source_remove(server->timeout);
516                         server->timeout = 0;
517                 }
518
519                 for (list = request_list; list; list = list->next) {
520                         struct request_data *req = list->data;
521
522                         if (req->protocol == IPPROTO_UDP)
523                                 continue;
524
525                         DBG("Sending req %s over TCP", (char *)req->name);
526
527                         if (req->timeout > 0)
528                                 g_source_remove(req->timeout);
529
530                         req->timeout = g_timeout_add_seconds(30,
531                                                 request_timeout, req);
532                         ns_resolv(server, req, req->request, req->name);
533                 }
534
535         } else if (condition & G_IO_IN) {
536                 int len, bytes_recv, total_bytes_recv;
537                 unsigned char reply_len_buf[2];
538                 uint16_t reply_len;
539                 unsigned char *reply;
540
541                 len = recv(sk, reply_len_buf, 2, 0);
542                 if (len < 2)
543                         return TRUE;
544
545                 reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
546
547                 DBG("TCP reply %d bytes", reply_len);
548
549                 reply = g_try_malloc(reply_len + 2);
550                 if (reply == NULL)
551                         return TRUE;
552
553                 reply[0] = reply_len_buf[0];
554                 reply[1] = reply_len_buf[1];
555
556                 total_bytes_recv = bytes_recv = 0;
557                 while (total_bytes_recv < reply_len) {
558                         bytes_recv = recv(sk, reply + 2, reply_len, 0);
559                         if (bytes_recv < 0)
560                                 break;
561
562                         total_bytes_recv += bytes_recv;
563                 }
564
565                 forward_dns_reply(reply, reply_len + 2, IPPROTO_TCP);
566
567                 g_free(reply);
568
569                 destroy_server(server);
570
571                 return FALSE;
572         }
573
574         return TRUE;
575 }
576
577 static gboolean tcp_idle_timeout(gpointer user_data)
578 {
579         struct server_data *server = user_data;
580
581         DBG("");
582
583         if (server == NULL)
584                 return FALSE;
585
586         destroy_server(server);
587
588         return FALSE;
589 }
590
591 static struct server_data *create_server(const char *interface,
592                                         const char *domain, const char *server,
593                                         int protocol)
594 {
595         struct server_data *data;
596         struct sockaddr_in sin;
597         int sk, type, ret;
598
599         DBG("interface %s server %s", interface, server);
600
601         switch (protocol) {
602         case IPPROTO_UDP:
603                 type = SOCK_DGRAM;
604                 break;
605
606         case IPPROTO_TCP:
607                 type = SOCK_STREAM;
608                 break;
609
610         default:
611                 return NULL;
612         }
613
614         data = find_server(interface, domain, server, protocol);
615         if (data) {
616                 if (data->watch > 0)
617                         g_source_remove(data->watch);
618                 data->watch = g_io_add_watch(data->channel,
619                         G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
620                                                 tcp_server_event, data);
621                 return data;
622         }
623
624         sk = socket(AF_INET, type, protocol);
625         if (sk < 0) {
626                 connman_error("Failed to create server %s socket", server);
627                 return NULL;
628         }
629
630         if (interface != NULL) {
631                 if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
632                                 interface, strlen(interface) + 1) < 0) {
633                         connman_error("Failed to bind server %s "
634                                                 "to interface %s",
635                                                         server, interface);
636                         close(sk);
637                         return NULL;
638                 }
639         }
640
641         data = g_try_new0(struct server_data, 1);
642         if (data == NULL) {
643                 connman_error("Failed to allocate server %s data", server);
644                 close(sk);
645                 return NULL;
646         }
647
648         data->channel = g_io_channel_unix_new(sk);
649         if (data->channel == NULL) {
650                 connman_error("Failed to create server %s channel", server);
651                 close(sk);
652                 g_free(data);
653                 return NULL;
654         }
655
656         g_io_channel_set_close_on_unref(data->channel, TRUE);
657
658         if (protocol == IPPROTO_TCP) {
659                 g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, NULL);
660                 data->watch = g_io_add_watch(data->channel,
661                         G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
662                                                 tcp_server_event, data);
663                 data->timeout = g_timeout_add_seconds(30, tcp_idle_timeout,
664                                                                 data);
665         } else
666                 data->watch = g_io_add_watch(data->channel, G_IO_IN,
667                                                 udp_server_event, data);
668
669         data->interface = g_strdup(interface);
670         data->domain = g_strdup(domain);
671         data->server = g_strdup(server);
672         data->protocol = protocol;
673
674         memset(&sin, 0, sizeof(sin));
675         sin.sin_family = AF_INET;
676         sin.sin_port = htons(53);
677         sin.sin_addr.s_addr = inet_addr(server);
678
679         ret = connect(sk, (struct sockaddr *) &sin, sizeof(sin));
680         if (ret < 0) {
681                 if ((protocol == IPPROTO_TCP && errno != EINPROGRESS) ||
682                                 protocol == IPPROTO_UDP) {
683                         connman_error("Failed to connect to server %s", server);
684                         close(sk);
685                         g_free(data);
686                         return NULL;
687                 }
688         }
689
690         if (protocol == IPPROTO_UDP) {
691                 /* Enable new servers by default */
692                 data->enabled = TRUE;
693                 connman_info("Adding DNS server %s", data->server);
694
695                 server_list = g_slist_append(server_list, data);
696
697                 return data;
698         }
699
700         return NULL;
701 }
702
703 static gboolean resolv(struct request_data *req,
704                                 gpointer request, gpointer name)
705 {
706         GSList *list;
707
708         for (list = server_list; list; list = list->next) {
709                 struct server_data *data = list->data;
710
711                 DBG("server %s domain %s enabled %d",
712                                 data->server, data->domain, data->enabled);
713
714                 if (data->enabled == FALSE)
715                         continue;
716
717                 if (ns_resolv(data, req, request, name) < 0)
718                         continue;
719         }
720
721         return TRUE;
722 }
723
724 static int dnsproxy_append(const char *interface, const char *domain,
725                                                         const char *server)
726 {
727         struct server_data *data;
728
729         DBG("interface %s server %s", interface, server);
730
731         if (g_str_equal(server, "127.0.0.1") == TRUE)
732                 return -ENODEV;
733
734         data = create_server(interface, domain, server, IPPROTO_UDP);
735         if (data == NULL)
736                 return -EIO;
737
738         return 0;
739 }
740
741 static void remove_server(const char *interface, const char *domain,
742                         const char *server, int protocol)
743 {
744         struct server_data *data;
745
746         data = find_server(interface, domain, server, protocol);
747         if (data == NULL)
748                 return;
749
750         destroy_server(data);
751 }
752
753 static int dnsproxy_remove(const char *interface, const char *domain,
754                                                         const char *server)
755 {
756         DBG("interface %s server %s", interface, server);
757
758         if (g_str_equal(server, "127.0.0.1") == TRUE)
759                 return -ENODEV;
760
761         remove_server(interface, domain, server, IPPROTO_UDP);
762         remove_server(interface, domain, server, IPPROTO_TCP);
763
764         return 0;
765 }
766
767 static void dnsproxy_flush(void)
768 {
769         GSList *list;
770
771         list = request_pending_list;
772         while (list) {
773                 struct request_data *req = list->data;
774
775                 list = list->next;
776
777                 request_pending_list =
778                                 g_slist_remove(request_pending_list, req);
779                 resolv(req, req->request, req->name);
780                 g_free(req->request);
781                 g_free(req->name);
782         }
783 }
784
785 static struct connman_resolver dnsproxy_resolver = {
786         .name           = "dnsproxy",
787         .priority       = CONNMAN_RESOLVER_PRIORITY_HIGH,
788         .append         = dnsproxy_append,
789         .remove         = dnsproxy_remove,
790         .flush          = dnsproxy_flush,
791 };
792
793 static void dnsproxy_offline_mode(connman_bool_t enabled)
794 {
795         GSList *list;
796
797         DBG("enabled %d", enabled);
798
799         for (list = server_list; list; list = list->next) {
800                 struct server_data *data = list->data;
801
802                 if (enabled == FALSE) {
803                         connman_info("Enabling DNS server %s", data->server);
804                         data->enabled = TRUE;
805                 } else {
806                         connman_info("Disabling DNS server %s", data->server);
807                         data->enabled = FALSE;
808                 }
809         }
810 }
811
812 static void dnsproxy_default_changed(struct connman_service *service)
813 {
814         GSList *list;
815         char *interface;
816
817         DBG("service %p", service);
818
819         if (service == NULL) {
820                 /* When no services are active, then disable DNS proxying */
821                 dnsproxy_offline_mode(TRUE);
822                 return;
823         }
824
825         interface = connman_service_get_interface(service);
826         if (interface == NULL)
827                 return;
828
829         for (list = server_list; list; list = list->next) {
830                 struct server_data *data = list->data;
831
832                 if (g_strcmp0(data->interface, interface) == 0) {
833                         connman_info("Enabling DNS server %s", data->server);
834                         data->enabled = TRUE;
835                 } else {
836                         connman_info("Disabling DNS server %s", data->server);
837                         data->enabled = FALSE;
838                 }
839         }
840
841         g_free(interface);
842 }
843
844 static struct connman_notifier dnsproxy_notifier = {
845         .name                   = "dnsproxy",
846         .default_changed        = dnsproxy_default_changed,
847         .offline_mode           = dnsproxy_offline_mode,
848 };
849
850 static unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
851
852 static int parse_request(unsigned char *buf, int len,
853                                         char *name, unsigned int size)
854 {
855         struct domain_hdr *hdr = (void *) buf;
856         uint16_t qdcount = ntohs(hdr->qdcount);
857         uint16_t arcount = ntohs(hdr->arcount);
858         unsigned char *ptr;
859         char *last_label = NULL;
860         unsigned int remain, used = 0;
861
862         if (len < 12)
863                 return -EINVAL;
864
865         DBG("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
866                                         hdr->id, hdr->qr, hdr->opcode,
867                                                         qdcount, arcount);
868
869         if (hdr->qr != 0 || qdcount != 1)
870                 return -EINVAL;
871
872         memset(name, 0, size);
873
874         ptr = buf + sizeof(struct domain_hdr);
875         remain = len - sizeof(struct domain_hdr);
876
877         while (remain > 0) {
878                 uint8_t len = *ptr;
879
880                 if (len == 0x00) {
881                         last_label = (char *) (ptr + 1);
882                         break;
883                 }
884
885                 if (used + len + 1 > size)
886                         return -ENOBUFS;
887
888                 strncat(name, (char *) (ptr + 1), len);
889                 strcat(name, ".");
890
891                 used += len + 1;
892
893                 ptr += len + 1;
894                 remain -= len + 1;
895         }
896
897         if (last_label && arcount && remain >= 9 && last_label[4] == 0 &&
898                                 !memcmp(last_label + 5, opt_edns0_type, 2)) {
899                 uint16_t edns0_bufsize;
900
901                 edns0_bufsize = last_label[7] << 8 | last_label[8];
902
903                 DBG("EDNS0 buffer size %u", edns0_bufsize);
904
905                 /* This is an evil hack until full TCP support has been
906                  * implemented.
907                  *
908                  * Somtimes the EDNS0 request gets send with a too-small
909                  * buffer size. Since glibc doesn't seem to crash when it
910                  * gets a response biffer then it requested, just bump
911                  * the buffer size up to 4KiB.
912                  */
913                 if (edns0_bufsize < 0x1000) {
914                         last_label[7] = 0x10;
915                         last_label[8] = 0x00;
916                 }
917         }
918
919         DBG("query %s", name);
920
921         return 0;
922 }
923
924 static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
925                                                         gpointer user_data)
926 {
927         unsigned char buf[768];
928         char query[512];
929         struct request_data *req;
930         struct server_data *server;
931         int sk, client_sk, len, err;
932         struct sockaddr client_addr;
933         socklen_t client_addr_len;
934         GSList *list;
935
936         DBG("condition 0x%x", condition);
937
938         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
939                 if (tcp_listener_watch > 0)
940                         g_source_remove(tcp_listener_watch);
941                 tcp_listener_watch = 0;
942
943                 connman_error("Error with TCP listener channel");
944
945                 return FALSE;
946         }
947
948         sk = g_io_channel_unix_get_fd(channel);
949
950         client_addr_len = sizeof(struct sockaddr);
951         client_sk = accept(sk, &client_addr, &client_addr_len);
952         if (client_sk < 0) {
953                 connman_error("Accept failure on TCP listener");
954                 tcp_listener_watch = 0;
955                 return FALSE;
956         }
957
958         len = recv(client_sk, buf, sizeof(buf), 0);
959         if (len < 2)
960                 return TRUE;
961
962         DBG("Received %d bytes (id 0x%04x)", len, buf[2] | buf[3] << 8);
963
964         err = parse_request(buf + 2, len - 2, query, sizeof(query));
965         if (err < 0 || (g_slist_length(server_list) == 0 &&
966                                 connman_ondemand_connected())) {
967                 send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
968                 return TRUE;
969         }
970
971         req = g_try_new0(struct request_data, 1);
972         if (req == NULL)
973                 return TRUE;
974
975         memcpy(&req->sin, (struct sockaddr_in *)&client_addr, sizeof(req->sin));
976         req->client_sk = client_sk;
977         req->protocol = IPPROTO_TCP;
978         req->len = client_addr_len;
979
980         request_id += 2;
981         if (request_id == 0x0000 || request_id == 0xffff)
982                 request_id += 2;
983
984         req->srcid = buf[2] | (buf[3] << 8);
985         req->dstid = request_id;
986         req->altid = request_id + 1;
987         req->request_len = len;
988
989         buf[2] = req->dstid & 0xff;
990         buf[3] = req->dstid >> 8;
991
992         req->numserv = 0;
993         request_list = g_slist_append(request_list, req);
994
995         for (list = server_list; list; list = list->next) {
996                 struct server_data *data = list->data;
997
998                 if (data->protocol != IPPROTO_UDP || data->enabled == FALSE)
999                         continue;
1000
1001                 server = create_server(data->interface, data->domain,
1002                                         data->server, IPPROTO_TCP);
1003
1004                 /*
1005                  * If server is NULL, we're not connected yet.
1006                  * Copy the relevant buffers and continue with
1007                  * the next nameserver.
1008                  * The request will actually be sent once we're
1009                  * properly connected over TCP to this nameserver.
1010                  */
1011                 if (server == NULL) {
1012                         req->request = g_try_malloc0(req->request_len);
1013                         if (req->request == NULL)
1014                                 return TRUE;
1015
1016                         memcpy(req->request, buf, req->request_len);
1017
1018                         req->name = g_try_malloc0(sizeof(query));
1019                         if (req->name == NULL) {
1020                                 g_free(req->request);
1021                                 return TRUE;
1022                         }
1023                         memcpy(req->name, query, sizeof(query));
1024
1025                         continue;
1026                 }
1027
1028                 if (req->timeout > 0)
1029                         g_source_remove(req->timeout);
1030
1031                 req->timeout = g_timeout_add_seconds(30, request_timeout, req);
1032                 ns_resolv(server, req, buf, query);
1033         }
1034
1035         return TRUE;
1036 }
1037
1038 static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
1039                                                         gpointer user_data)
1040 {
1041         unsigned char buf[768];
1042         char query[512];
1043         struct request_data *req;
1044         struct sockaddr_in sin;
1045         socklen_t size = sizeof(sin);
1046         int sk, err, len;
1047
1048         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1049                 connman_error("Error with UDP listener channel");
1050                 udp_listener_watch = 0;
1051                 return FALSE;
1052         }
1053
1054         sk = g_io_channel_unix_get_fd(channel);
1055
1056         memset(&sin, 0, sizeof(sin));
1057         len = recvfrom(sk, buf, sizeof(buf), 0,
1058                                         (struct sockaddr *) &sin, &size);
1059         if (len < 2)
1060                 return TRUE;
1061
1062         DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
1063
1064         err = parse_request(buf, len, query, sizeof(query));
1065         if (err < 0 || (g_slist_length(server_list) == 0 &&
1066                                 connman_ondemand_connected())) {
1067                 send_response(sk, buf, len, (struct sockaddr *) &sin, size,
1068                                 IPPROTO_UDP);
1069                 return TRUE;
1070         }
1071
1072         req = g_try_new0(struct request_data, 1);
1073         if (req == NULL)
1074                 return TRUE;
1075
1076         memcpy(&req->sin, &sin, sizeof(sin));
1077         req->client_sk = 0;
1078         req->protocol = IPPROTO_UDP;
1079         req->len = size;
1080
1081         request_id += 2;
1082         if (request_id == 0x0000 || request_id == 0xffff)
1083                 request_id += 2;
1084
1085         req->srcid = buf[0] | (buf[1] << 8);
1086         req->dstid = request_id;
1087         req->altid = request_id + 1;
1088         req->request_len = len;
1089
1090         buf[0] = req->dstid & 0xff;
1091         buf[1] = req->dstid >> 8;
1092
1093         if (!connman_ondemand_connected()) {
1094                 DBG("Starting on demand connection");
1095                 /*
1096                  * We're not connected, let's queue the request and start
1097                  * an on-demand connection.
1098                  */
1099                 req->request = g_try_malloc0(req->request_len);
1100                 if (req->request == NULL)
1101                         return TRUE;
1102
1103                 memcpy(req->request, buf, req->request_len);
1104
1105                 req->name = g_try_malloc0(sizeof(query));
1106                 if (req->name == NULL) {
1107                         g_free(req->request);
1108                         return TRUE;
1109                 }
1110                 memcpy(req->name, query, sizeof(query));
1111
1112                 request_pending_list = g_slist_append(request_pending_list,
1113                                                                         req);
1114
1115                 connman_ondemand_start("", 300);
1116
1117                 return TRUE;
1118         }
1119
1120
1121         req->numserv = 0;
1122         req->timeout = g_timeout_add_seconds(5, request_timeout, req);
1123         request_list = g_slist_append(request_list, req);
1124
1125         return resolv(req, buf, query);
1126 }
1127
1128 static int create_dns_listener(int protocol)
1129 {
1130         GIOChannel *channel;
1131         const char *ifname = "lo", *proto;
1132         struct sockaddr_in sin;
1133         int sk, type;
1134
1135         DBG("");
1136
1137         switch (protocol) {
1138         case IPPROTO_UDP:
1139                 proto = "UDP";
1140                 type = SOCK_DGRAM;
1141                 break;
1142
1143         case IPPROTO_TCP:
1144                 proto = "TCP";
1145                 type = SOCK_STREAM;
1146                 break;
1147
1148         default:
1149                 return -EINVAL;
1150         }
1151
1152         sk = socket(AF_INET, type, protocol);
1153         if (sk < 0) {
1154                 connman_error("Failed to create %s listener socket", proto);
1155                 return -EIO;
1156         }
1157
1158         if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
1159                                         ifname, strlen(ifname) + 1) < 0) {
1160                 connman_error("Failed to bind %s listener interface", proto);
1161                 close(sk);
1162                 return -EIO;
1163         }
1164
1165         memset(&sin, 0, sizeof(sin));
1166         sin.sin_family = AF_INET;
1167         sin.sin_port = htons(53);
1168         sin.sin_addr.s_addr = inet_addr("127.0.0.1");
1169         sin.sin_addr.s_addr = htonl(INADDR_ANY);
1170
1171         if (bind(sk, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
1172                 connman_error("Failed to bind %s listener socket", proto);
1173                 close(sk);
1174                 return -EIO;
1175         }
1176
1177         if (protocol == IPPROTO_TCP && listen(sk, 10) < 0) {
1178                 connman_error("Failed to listen on TCP socket");
1179                 close(sk);
1180                 return -EIO;
1181         }
1182
1183         channel = g_io_channel_unix_new(sk);
1184         if (channel == NULL) {
1185                 connman_error("Failed to create %s listener channel", proto);
1186                 close(sk);
1187                 return -EIO;
1188         }
1189
1190         g_io_channel_set_close_on_unref(channel, TRUE);
1191
1192         if (protocol == IPPROTO_TCP) {
1193                 tcp_listener_channel = channel;
1194                 tcp_listener_watch = g_io_add_watch(channel,
1195                                         G_IO_IN, tcp_listener_event, NULL);
1196         } else {
1197                 udp_listener_channel = channel;
1198                 udp_listener_watch = g_io_add_watch(channel,
1199                                         G_IO_IN, udp_listener_event, NULL);
1200         }
1201
1202         return 0;
1203 }
1204
1205 static void destroy_udp_listener(void)
1206 {
1207         DBG("");
1208
1209         if (udp_listener_watch > 0)
1210                 g_source_remove(udp_listener_watch);
1211
1212         g_io_channel_unref(udp_listener_channel);
1213 }
1214
1215 static void destroy_tcp_listener(void)
1216 {
1217         DBG("");
1218
1219         if (tcp_listener_watch > 0)
1220                 g_source_remove(tcp_listener_watch);
1221
1222         g_io_channel_unref(tcp_listener_channel);
1223 }
1224
1225 static int create_listener(void)
1226 {
1227         int err;
1228
1229         err = create_dns_listener(IPPROTO_UDP);
1230         if (err < 0)
1231                 return err;
1232
1233         err = create_dns_listener(IPPROTO_TCP);
1234         if (err < 0) {
1235                 destroy_udp_listener();
1236                 return err;
1237         }
1238
1239         connman_resolver_append("lo", NULL, "127.0.0.1");
1240
1241         return 0;
1242 }
1243
1244 static void destroy_listener(void)
1245 {
1246         GSList *list;
1247
1248         connman_resolver_remove_all("lo");
1249
1250         for (list = request_pending_list; list; list = list->next) {
1251                 struct request_data *req = list->data;
1252
1253                 DBG("Dropping pending request (id 0x%04x -> 0x%04x)",
1254                                                 req->srcid, req->dstid);
1255
1256                 g_free(req->resp);
1257                 g_free(req->request);
1258                 g_free(req->name);
1259                 g_free(req);
1260                 list->data = NULL;
1261         }
1262
1263         g_slist_free(request_pending_list);
1264         request_pending_list = NULL;
1265
1266         for (list = request_list; list; list = list->next) {
1267                 struct request_data *req = list->data;
1268
1269                 DBG("Dropping request (id 0x%04x -> 0x%04x)",
1270                                                 req->srcid, req->dstid);
1271
1272                 g_free(req->resp);
1273                 g_free(req->request);
1274                 g_free(req->name);
1275                 g_free(req);
1276                 list->data = NULL;
1277         }
1278
1279         g_slist_free(request_list);
1280         request_list = NULL;
1281
1282         destroy_tcp_listener();
1283         destroy_udp_listener();
1284 }
1285
1286 static int dnsproxy_init(void)
1287 {
1288         int err;
1289
1290         err = create_listener();
1291         if (err < 0)
1292                 return err;
1293
1294         err = connman_resolver_register(&dnsproxy_resolver);
1295         if (err < 0)
1296                 goto destroy;
1297
1298         err = connman_notifier_register(&dnsproxy_notifier);
1299         if (err < 0)
1300                 goto unregister;
1301
1302         return 0;
1303
1304 unregister:
1305         connman_resolver_unregister(&dnsproxy_resolver);
1306
1307 destroy:
1308         destroy_listener();
1309
1310         return err;
1311 }
1312
1313 static void dnsproxy_exit(void)
1314 {
1315         connman_notifier_unregister(&dnsproxy_notifier);
1316
1317         connman_resolver_unregister(&dnsproxy_resolver);
1318
1319         destroy_listener();
1320 }
1321
1322 CONNMAN_PLUGIN_DEFINE(dnsproxy, "DNS proxy resolver plugin", VERSION,
1323                  CONNMAN_PLUGIN_PRIORITY_DEFAULT, dnsproxy_init, dnsproxy_exit)