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