dnsproxy: Send the correct TTL to our clients
[platform/upstream/connman.git] / src / 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 #include <resolv.h>
36
37 #include <glib.h>
38
39 #include "connman.h"
40
41 #if __BYTE_ORDER == __LITTLE_ENDIAN
42 struct domain_hdr {
43         uint16_t id;
44         uint8_t rd:1;
45         uint8_t tc:1;
46         uint8_t aa:1;
47         uint8_t opcode:4;
48         uint8_t qr:1;
49         uint8_t rcode:4;
50         uint8_t z:3;
51         uint8_t ra:1;
52         uint16_t qdcount;
53         uint16_t ancount;
54         uint16_t nscount;
55         uint16_t arcount;
56 } __attribute__ ((packed));
57 #elif __BYTE_ORDER == __BIG_ENDIAN
58 struct domain_hdr {
59         uint16_t id;
60         uint8_t qr:1;
61         uint8_t opcode:4;
62         uint8_t aa:1;
63         uint8_t tc:1;
64         uint8_t rd:1;
65         uint8_t ra:1;
66         uint8_t z:3;
67         uint8_t rcode:4;
68         uint16_t qdcount;
69         uint16_t ancount;
70         uint16_t nscount;
71         uint16_t arcount;
72 } __attribute__ ((packed));
73 #else
74 #error "Unknown byte order"
75 #endif
76
77 struct partial_reply {
78         uint16_t len;
79         uint16_t received;
80         unsigned char buf[];
81 };
82
83 struct server_data {
84         char *interface;
85         GList *domains;
86         char *server;
87         int protocol;
88         GIOChannel *channel;
89         guint watch;
90         guint timeout;
91         gboolean enabled;
92         gboolean connected;
93         struct partial_reply *incoming_reply;
94 };
95
96 struct request_data {
97         union {
98                 struct sockaddr_in6 __sin6; /* Only for the length */
99                 struct sockaddr sa;
100         };
101         socklen_t sa_len;
102         int client_sk;
103         int protocol;
104         guint16 srcid;
105         guint16 dstid;
106         guint16 altid;
107         guint timeout;
108         guint watch;
109         guint numserv;
110         guint numresp;
111         gpointer request;
112         gsize request_len;
113         gpointer name;
114         gpointer resp;
115         gsize resplen;
116         struct listener_data *ifdata;
117         gboolean append_domain;
118 };
119
120 struct listener_data {
121         char *ifname;
122         GIOChannel *udp_listener_channel;
123         guint udp_listener_watch;
124         GIOChannel *tcp_listener_channel;
125         guint tcp_listener_watch;
126 };
127
128 struct cache_data {
129         time_t inserted;
130         time_t valid_until;
131         time_t cache_until;
132         int timeout;
133         uint16_t type;
134         uint16_t answers;
135         unsigned int data_len;
136         unsigned char *data; /* contains DNS header + body */
137 };
138
139 struct cache_entry {
140         char *key;
141         struct cache_data *ipv4;
142         struct cache_data *ipv6;
143 };
144
145 struct domain_question {
146         uint16_t type;
147         uint16_t class;
148 } __attribute__ ((packed));
149
150 struct domain_rr {
151         uint16_t type;
152         uint16_t class;
153         uint32_t ttl;
154         uint16_t rdlen;
155 } __attribute__ ((packed));
156
157 /*
158  * We limit how long the cached DNS entry stays in the cache.
159  * By default the TTL (time-to-live) of the DNS response is used
160  * when setting the cache entry life time. The value is in seconds.
161  */
162 #define MAX_CACHE_TTL (60 * 30)
163
164 /*
165  * We limit the cache size to some sane value so that cached data does
166  * not occupy too much memory. Each cached entry occupies on average
167  * about 100 bytes memory (depending on DNS name length).
168  * Example: caching www.connman.net uses 97 bytes memory.
169  * The value is the max amount of cached DNS responses (count).
170  */
171 #define MAX_CACHE_SIZE 256
172
173 static int cache_size;
174 static GHashTable *cache;
175 static int cache_refcount;
176 static GSList *server_list = NULL;
177 static GSList *request_list = NULL;
178 static GSList *request_pending_list = NULL;
179 static guint16 request_id = 0x0000;
180 static GHashTable *listener_table = NULL;
181
182 static int protocol_offset(int protocol)
183 {
184         switch (protocol) {
185         case IPPROTO_UDP:
186                 return 0;
187
188         case IPPROTO_TCP:
189                 return 2;
190
191         default:
192                 return -EINVAL;
193         }
194
195 }
196
197 /*
198  * There is a power and efficiency benefit to have entries
199  * in our cache expire at the same time. To this extend,
200  * we round down the cache valid time to common boundaries.
201  */
202 static time_t round_down_ttl(time_t end_time, int ttl)
203 {
204         if (ttl < 15)
205                 return end_time;
206
207         /* Less than 5 minutes, round to 10 second boundary */
208         if (ttl < 300) {
209                 end_time = end_time / 10;
210                 end_time = end_time * 10;
211         } else { /* 5 or more minutes, round to 30 seconds */
212                 end_time = end_time / 30;
213                 end_time = end_time * 30;
214         }
215         return end_time;
216 }
217
218 static struct request_data *find_request(guint16 id)
219 {
220         GSList *list;
221
222         for (list = request_list; list; list = list->next) {
223                 struct request_data *req = list->data;
224
225                 if (req->dstid == id || req->altid == id)
226                         return req;
227         }
228
229         return NULL;
230 }
231
232 static struct server_data *find_server(const char *interface,
233                                         const char *server,
234                                                 int protocol)
235 {
236         GSList *list;
237
238         DBG("interface %s server %s", interface, server);
239
240         for (list = server_list; list; list = list->next) {
241                 struct server_data *data = list->data;
242
243                 if (interface == NULL && data->interface == NULL &&
244                                 g_str_equal(data->server, server) == TRUE &&
245                                 data->protocol == protocol)
246                         return data;
247
248                 if (interface == NULL ||
249                                 data->interface == NULL || data->server == NULL)
250                         continue;
251
252                 if (g_str_equal(data->interface, interface) == TRUE &&
253                                 g_str_equal(data->server, server) == TRUE &&
254                                 data->protocol == protocol)
255                         return data;
256         }
257
258         return NULL;
259 }
260
261 static int dns_name_length(unsigned char *buf)
262 {
263         if ((buf[0] & NS_CMPRSFLGS) == NS_CMPRSFLGS) /* compressed name */
264                 return 2;
265         return strlen((char *)buf);
266 }
267
268 static void update_cached_ttl(unsigned char *buf, int len, int new_ttl)
269 {
270         unsigned char *c;
271         uint32_t *i;
272         uint16_t *w;
273         int l;
274
275         /* skip the header */
276         c = buf + 12;
277         len -= 12;
278
279         /* skip the query, which is a name and 2 16 bit words */
280         l = dns_name_length(c);
281         c += l;
282         len -= l;
283         c += 4;
284         len -= 4;
285
286         /* now we get the answer records */
287
288         while (len > 0) {
289                 /* first a name */
290                 l = dns_name_length(c);
291                 c += l;
292                 len -= l;
293                 if (len < 0)
294                         break;
295                 /* then type + class, 2 bytes each */
296                 c += 4;
297                 len -= 4;
298                 if (len < 0)
299                         break;
300
301                 /* now the 4 byte TTL field */
302                 i = (uint32_t *)c;
303                 *i = htonl(new_ttl);
304                 c += 4;
305                 len -= 4;
306                 if (len < 0)
307                         break;
308
309                 /* now the 2 byte rdlen field */
310                 w = (uint16_t *)c;
311                 c += ntohs(*w) + 2;
312                 len -= ntohs(*w) + 2;
313         }
314 }
315
316
317
318 static void send_cached_response(int sk, unsigned char *buf, int len,
319                                 const struct sockaddr *to, socklen_t tolen,
320                                 int protocol, int id, uint16_t answers, int ttl)
321 {
322         struct domain_hdr *hdr;
323         int err, offset = protocol_offset(protocol);
324
325         if (offset < 0)
326                 return;
327
328         if (len < 12)
329                 return;
330
331         hdr = (void *) (buf + offset);
332
333         hdr->id = id;
334         hdr->qr = 1;
335         hdr->rcode = 0;
336         hdr->ancount = htons(answers);
337         hdr->nscount = 0;
338         hdr->arcount = 0;
339
340         update_cached_ttl(buf, len, ttl);
341
342         DBG("id 0x%04x answers %d", hdr->id, answers);
343
344         err = sendto(sk, buf, len, 0, to, tolen);
345         if (err < 0) {
346                 connman_error("Cannot send cached DNS response: %s",
347                                 strerror(errno));
348                 return;
349         }
350 }
351
352 static void send_response(int sk, unsigned char *buf, int len,
353                                 const struct sockaddr *to, socklen_t tolen,
354                                 int protocol)
355 {
356         struct domain_hdr *hdr;
357         int err, offset = protocol_offset(protocol);
358
359         DBG("");
360
361         if (offset < 0)
362                 return;
363
364         if (len < 12)
365                 return;
366
367         hdr = (void *) (buf + offset);
368
369         DBG("id 0x%04x qr %d opcode %d", hdr->id, hdr->qr, hdr->opcode);
370
371         hdr->qr = 1;
372         hdr->rcode = 2;
373
374         hdr->ancount = 0;
375         hdr->nscount = 0;
376         hdr->arcount = 0;
377
378         err = sendto(sk, buf, len, 0, to, tolen);
379         if (err < 0) {
380                 connman_error("Failed to send DNS response: %s",
381                                 strerror(errno));
382                 return;
383         }
384 }
385
386 static gboolean request_timeout(gpointer user_data)
387 {
388         struct request_data *req = user_data;
389         struct listener_data *ifdata;
390
391         DBG("id 0x%04x", req->srcid);
392
393         if (req == NULL)
394                 return FALSE;
395
396         ifdata = req->ifdata;
397
398         request_list = g_slist_remove(request_list, req);
399         req->numserv--;
400
401         if (req->resplen > 0 && req->resp != NULL) {
402                 int sk, err;
403
404                 sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
405
406                 err = sendto(sk, req->resp, req->resplen, 0,
407                                                 &req->sa, req->sa_len);
408                 if (err < 0)
409                         return FALSE;
410         } else if (req->request && req->numserv == 0) {
411                 struct domain_hdr *hdr;
412
413                 if (req->protocol == IPPROTO_TCP) {
414                         hdr = (void *) (req->request + 2);
415                         hdr->id = req->srcid;
416                         send_response(req->client_sk, req->request,
417                                 req->request_len, NULL, 0, IPPROTO_TCP);
418
419                 } else if (req->protocol == IPPROTO_UDP) {
420                         int sk;
421
422                         hdr = (void *) (req->request);
423                         hdr->id = req->srcid;
424                         sk = g_io_channel_unix_get_fd(
425                                                 ifdata->udp_listener_channel);
426                         send_response(sk, req->request, req->request_len,
427                                         &req->sa, req->sa_len, IPPROTO_UDP);
428                 }
429         }
430
431         g_free(req->resp);
432         g_free(req);
433
434         return FALSE;
435 }
436
437 static int append_query(unsigned char *buf, unsigned int size,
438                                 const char *query, const char *domain)
439 {
440         unsigned char *ptr = buf;
441         char *offset;
442         int len;
443
444         DBG("query %s domain %s", query, domain);
445
446         offset = (char *) query;
447         while (offset != NULL) {
448                 char *tmp;
449
450                 tmp = strchr(offset, '.');
451                 if (tmp == NULL) {
452                         len = strlen(offset);
453                         if (len == 0)
454                                 break;
455                         *ptr = len;
456                         memcpy(ptr + 1, offset, len);
457                         ptr += len + 1;
458                         break;
459                 }
460
461                 *ptr = tmp - offset;
462                 memcpy(ptr + 1, offset, tmp - offset);
463                 ptr += tmp - offset + 1;
464
465                 offset = tmp + 1;
466         }
467
468         offset = (char *) domain;
469         while (offset != NULL) {
470                 char *tmp;
471
472                 tmp = strchr(offset, '.');
473                 if (tmp == NULL) {
474                         len = strlen(offset);
475                         if (len == 0)
476                                 break;
477                         *ptr = len;
478                         memcpy(ptr + 1, offset, len);
479                         ptr += len + 1;
480                         break;
481                 }
482
483                 *ptr = tmp - offset;
484                 memcpy(ptr + 1, offset, tmp - offset);
485                 ptr += tmp - offset + 1;
486
487                 offset = tmp + 1;
488         }
489
490         *ptr++ = 0x00;
491
492         return ptr - buf;
493 }
494
495 static gboolean cache_check_is_valid(struct cache_data *data,
496                                 time_t current_time)
497 {
498         if (data == NULL)
499                 return FALSE;
500
501         if (data->cache_until < current_time)
502                 return FALSE;
503
504         return TRUE;
505 }
506
507 /*
508  * remove stale cached entries so that they can be refreshed
509  */
510 static void cache_enforce_validity(struct cache_entry *entry)
511 {
512         time_t current_time = time(0);
513
514         if (cache_check_is_valid(entry->ipv4, current_time) == FALSE
515                                                         && entry->ipv4) {
516                 DBG("cache timeout \"%s\" type A", entry->key);
517                 g_free(entry->ipv4->data);
518                 g_free(entry->ipv4);
519                 entry->ipv4 = NULL;
520
521         }
522
523         if (cache_check_is_valid(entry->ipv6, current_time) == FALSE
524                                                         && entry->ipv6) {
525                 DBG("cache timeout \"%s\" type AAAA", entry->key);
526                 g_free(entry->ipv6->data);
527                 g_free(entry->ipv6);
528                 entry->ipv6 = NULL;
529         }
530 }
531
532
533 static uint16_t cache_check_validity(char *question, uint16_t type,
534                                 struct cache_entry *entry)
535 {
536         time_t current_time = time(0);
537
538         cache_enforce_validity(entry);
539
540         switch (type) {
541         case 1:         /* IPv4 */
542                 if (cache_check_is_valid(entry->ipv4, current_time) == FALSE) {
543                         DBG("cache %s \"%s\" type A", entry->ipv4 ?
544                                         "timeout" : "entry missing", question);
545
546                         /*
547                          * We do not remove cache entry if there is still
548                          * valid IPv6 entry found in the cache.
549                          */
550                         if (cache_check_is_valid(entry->ipv6, current_time) == FALSE)
551                                 g_hash_table_remove(cache, question);
552
553                         type = 0;
554                 }
555                 break;
556
557         case 28:        /* IPv6 */
558                 if (cache_check_is_valid(entry->ipv6, current_time) == FALSE) {
559                         DBG("cache %s \"%s\" type AAAA", entry->ipv6 ?
560                                         "timeout" : "entry missing", question);
561
562                         if (cache_check_is_valid(entry->ipv4, current_time) == FALSE)
563                                 g_hash_table_remove(cache, question);
564
565                         type = 0;
566                 }
567                 break;
568         }
569
570         return type;
571 }
572
573 static struct cache_entry *cache_check(gpointer request, int *qtype)
574 {
575         char *question = request + 12;
576         struct cache_entry *entry;
577         struct domain_question *q;
578         uint16_t type;
579         int offset;
580
581         offset = strlen(question) + 1;
582         q = (void *) (question + offset);
583         type = ntohs(q->type);
584
585         /* We only cache either A (1) or AAAA (28) requests */
586         if (type != 1 && type != 28)
587                 return NULL;
588
589         entry = g_hash_table_lookup(cache, question);
590         if (entry == NULL)
591                 return NULL;
592
593         type = cache_check_validity(question, type, entry);
594         if (type == 0)
595                 return NULL;
596
597         *qtype = type;
598         return entry;
599 }
600
601 /*
602  * Get a label/name from DNS resource record. The function decompresses the
603  * label if necessary. The function does not convert the name to presentation
604  * form. This means that the result string will contain label lengths instead
605  * of dots between labels. We intentionally do not want to convert to dotted
606  * format so that we can cache the wire format string directly.
607  */
608 static int get_name(int counter,
609                 unsigned char *pkt, unsigned char *start, unsigned char *max,
610                 unsigned char *output, int output_max, int *output_len,
611                 unsigned char **end, char *name, int *name_len)
612 {
613         unsigned char *p;
614
615         /* Limit recursion to 10 (this means up to 10 labels in domain name) */
616         if (counter > 10)
617                 return -EINVAL;
618
619         p = start;
620         while (*p) {
621                 if ((*p & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
622                         uint16_t offset = (*p & 0x3F) * 256 + *(p + 1);
623
624                         if (offset >= max - pkt)
625                                 return -ENOBUFS;
626
627                         if (*end == NULL)
628                                 *end = p + 2;
629
630                         return get_name(counter + 1, pkt, pkt + offset, max,
631                                         output, output_max, output_len, end,
632                                         name, name_len);
633                 } else {
634                         unsigned label_len = *p;
635
636                         if (pkt + label_len > max)
637                                 return -ENOBUFS;
638
639                         if (*output_len > output_max)
640                                 return -ENOBUFS;
641
642                         /*
643                          * We need the original name in order to check
644                          * if this answer is the correct one.
645                          */
646                         name[(*name_len)++] = label_len;
647                         memcpy(name + *name_len, p + 1, label_len + 1);
648                         *name_len += label_len;
649
650                         /* We compress the result */
651                         output[0] = NS_CMPRSFLGS;
652                         output[1] = 0x0C;
653                         *output_len = 2;
654
655                         p += label_len + 1;
656
657                         if (*end == NULL)
658                                 *end = p;
659
660                         if (p >= max)
661                                 return -ENOBUFS;
662                 }
663         }
664
665         return 0;
666 }
667
668 static int parse_rr(unsigned char *buf, unsigned char *start,
669                         unsigned char *max,
670                         unsigned char *response, unsigned int *response_size,
671                         uint16_t *type, uint16_t *class, int *ttl, int *rdlen,
672                         unsigned char **end,
673                         char *name)
674 {
675         struct domain_rr *rr;
676         int err, offset;
677         int name_len = 0, output_len = 0, max_rsp = *response_size;
678
679         err = get_name(0, buf, start, max, response, max_rsp,
680                 &output_len, end, name, &name_len);
681         if (err < 0)
682                 return err;
683
684         offset = output_len;
685
686         if ((unsigned int) offset > *response_size)
687                 return -ENOBUFS;
688
689         rr = (void *) (*end);
690
691         if (rr == NULL)
692                 return -EINVAL;
693
694         *type = ntohs(rr->type);
695         *class = ntohs(rr->class);
696         *ttl = ntohl(rr->ttl);
697         *rdlen = ntohs(rr->rdlen);
698
699         if (*ttl < 0)
700                 return -EINVAL;
701
702         memcpy(response + offset, *end, sizeof(struct domain_rr));
703
704         offset += sizeof(struct domain_rr);
705         *end += sizeof(struct domain_rr);
706
707         if ((unsigned int) (offset + *rdlen) > *response_size)
708                 return -ENOBUFS;
709
710         memcpy(response + offset, *end, *rdlen);
711
712         *end += *rdlen;
713
714         *response_size = offset + *rdlen;
715
716         return 0;
717 }
718
719 static gboolean check_alias(GSList *aliases, char *name)
720 {
721         GSList *list;
722
723         if (aliases != NULL) {
724                 for (list = aliases; list; list = list->next) {
725                         int len = strlen((char *)list->data);
726                         if (strncmp((char *)list->data, name, len) == 0)
727                                 return TRUE;
728                 }
729         }
730
731         return FALSE;
732 }
733
734 static int parse_response(unsigned char *buf, int buflen,
735                         char *question, int qlen,
736                         uint16_t *type, uint16_t *class, int *ttl,
737                         unsigned char *response, unsigned int *response_len,
738                         uint16_t *answers)
739 {
740         struct domain_hdr *hdr = (void *) buf;
741         struct domain_question *q;
742         unsigned char *ptr;
743         uint16_t qdcount = ntohs(hdr->qdcount);
744         uint16_t ancount = ntohs(hdr->ancount);
745         int err, i;
746         uint16_t qtype, qclass;
747         unsigned char *next = NULL;
748         unsigned int maxlen = *response_len;
749         GSList *aliases = NULL, *list;
750         char name[NS_MAXDNAME + 1];
751
752         if (buflen < 12)
753                 return -EINVAL;
754
755         DBG("qr %d qdcount %d", hdr->qr, qdcount);
756
757         /* We currently only cache responses where question count is 1 */
758         if (hdr->qr != 1 || qdcount != 1)
759                 return -EINVAL;
760
761         ptr = buf + sizeof(struct domain_hdr);
762
763         strncpy(question, (char *) ptr, qlen);
764         qlen = strlen(question);
765         ptr += qlen + 1; /* skip \0 */
766
767         q = (void *) ptr;
768         qtype = ntohs(q->type);
769
770         /* We cache only A and AAAA records */
771         if (qtype != 1 && qtype != 28)
772                 return -ENOMSG;
773
774         qclass = ntohs(q->class);
775
776         ptr += 2 + 2; /* ptr points now to answers */
777
778         err = -ENOMSG;
779         *response_len = 0;
780         *answers = 0;
781
782         /*
783          * We have a bunch of answers (like A, AAAA, CNAME etc) to
784          * A or AAAA question. We traverse the answers and parse the
785          * resource records. Only A and AAAA records are cached, all
786          * the other records in answers are skipped.
787          */
788         for (i = 0; i < ancount; i++) {
789                 /*
790                  * Get one address at a time to this buffer.
791                  * The max size of the answer is
792                  *   2 (pointer) + 2 (type) + 2 (class) +
793                  *   4 (ttl) + 2 (rdlen) + addr (16 or 4) = 28
794                  * for A or AAAA record.
795                  * For CNAME the size can be bigger.
796                  */
797                 unsigned char rsp[NS_MAXCDNAME];
798                 unsigned int rsp_len = sizeof(rsp) - 1;
799                 int ret, rdlen;
800
801                 memset(rsp, 0, sizeof(rsp));
802
803                 ret = parse_rr(buf, ptr, buf + buflen, rsp, &rsp_len,
804                         type, class, ttl, &rdlen, &next, name);
805                 if (ret != 0) {
806                         err = ret;
807                         goto out;
808                 }
809
810                 /*
811                  * Now rsp contains compressed or uncompressed resource
812                  * record. Next we check if this record answers the question.
813                  * The name var contains the uncompressed label.
814                  * One tricky bit is the CNAME records as they alias
815                  * the name we might be interested in.
816                  */
817
818                 /*
819                  * Go to next answer if the class is not the one we are
820                  * looking for.
821                  */
822                 if (*class != qclass) {
823                         ptr = next;
824                         next = NULL;
825                         continue;
826                 }
827
828                 /*
829                  * Try to resolve aliases also, type is CNAME(5).
830                  * This is important as otherwise the aliased names would not
831                  * be cached at all as the cache would not contain the aliased
832                  * question.
833                  *
834                  * If any CNAME is found in DNS packet, then we cache the alias
835                  * IP address instead of the question (as the server
836                  * said that question has only an alias).
837                  * This means in practice that if e.g., ipv6.google.com is
838                  * queried, DNS server returns CNAME of that name which is
839                  * ipv6.l.google.com. We then cache the address of the CNAME
840                  * but return the question name to client. So the alias
841                  * status of the name is not saved in cache and thus not
842                  * returned to the client. We do not return DNS packets from
843                  * cache to client saying that ipv6.google.com is an alias to
844                  * ipv6.l.google.com but we return instead a DNS packet that
845                  * says ipv6.google.com has address xxx which is in fact the
846                  * address of ipv6.l.google.com. For caching purposes this
847                  * should not cause any issues.
848                  */
849                 if (*type == 5 && strncmp(question, name, qlen) == 0) {
850                         /*
851                          * So now the alias answered the question. This is
852                          * not very useful from caching point of view as
853                          * the following A or AAAA records will not match the
854                          * question. We need to find the real A/AAAA record
855                          * of the alias and cache that.
856                          */
857                         unsigned char *end = NULL;
858                         int name_len = 0, output_len;
859
860                         memset(rsp, 0, sizeof(rsp));
861                         rsp_len = sizeof(rsp) - 1;
862
863                         /*
864                          * Alias is in rdata part of the message,
865                          * and next-rdlen points to it. So we need to get
866                          * the real name of the alias.
867                          */
868                         ret = get_name(0, buf, next - rdlen, buf + buflen,
869                                         rsp, rsp_len, &output_len, &end,
870                                         name, &name_len);
871                         if (ret != 0) {
872                                 /* just ignore the error at this point */
873                                 ptr = next;
874                                 next = NULL;
875                                 continue;
876                         }
877
878                         /*
879                          * We should now have the alias of the entry we might
880                          * want to cache. Just remember it for a while.
881                          * We check the alias list when we have parsed the
882                          * A or AAAA record.
883                          */
884                         aliases = g_slist_prepend(aliases, g_strdup(name));
885
886                         ptr = next;
887                         next = NULL;
888                         continue;
889                 }
890
891                 if (*type == qtype) {
892                         /*
893                          * We found correct type (A or AAAA)
894                          */
895                         if (check_alias(aliases, name) == TRUE ||
896                                 (aliases == NULL && strncmp(question, name,
897                                                         qlen) == 0)) {
898                                 /*
899                                  * We found an alias or the name of the rr
900                                  * matches the question. If so, we append
901                                  * the compressed label to the cache.
902                                  * The end result is a response buffer that
903                                  * will contain one or more cached and
904                                  * compressed resource records.
905                                  */
906                                 if (*response_len + rsp_len > maxlen) {
907                                         err = -ENOBUFS;
908                                         goto out;
909                                 }
910                                 memcpy(response + *response_len, rsp, rsp_len);
911                                 *response_len += rsp_len;
912                                 (*answers)++;
913                                 err = 0;
914                         }
915                 }
916
917                 ptr = next;
918                 next = NULL;
919         }
920
921 out:
922         for (list = aliases; list; list = list->next)
923                 g_free(list->data);
924         g_slist_free(aliases);
925
926         return err;
927 }
928
929 struct cache_timeout {
930         time_t current_time;
931         int max_timeout;
932 };
933
934 static gboolean cache_check_entry(gpointer key, gpointer value,
935                                         gpointer user_data)
936 {
937         struct cache_timeout *data = user_data;
938         struct cache_entry *entry = value;
939         int max_timeout;
940
941         /*
942          * If either IPv4 or IPv6 cached entry has expired, we
943          * remove both from the cache.
944          */
945
946         if (entry->ipv4 != NULL && entry->ipv4->timeout > 0) {
947                 max_timeout = entry->ipv4->cache_until;
948                 if (max_timeout > data->max_timeout)
949                         data->max_timeout = max_timeout;
950
951                 if (entry->ipv4->cache_until < data->current_time)
952                         return TRUE;
953         }
954
955         if (entry->ipv6 != NULL && entry->ipv6->timeout > 0) {
956                 max_timeout = entry->ipv6->cache_until;
957                 if (max_timeout > data->max_timeout)
958                         data->max_timeout = max_timeout;
959
960                 if (entry->ipv6->cache_until < data->current_time)
961                         return TRUE;
962         }
963
964         return FALSE;
965 }
966
967 static void cache_cleanup(void)
968 {
969         static int max_timeout;
970         struct cache_timeout data;
971         int count;
972
973         data.current_time = time(0);
974         data.max_timeout = 0;
975
976         if (max_timeout > data.current_time) {
977                 DBG("waiting %ld secs before cleaning cache",
978                         max_timeout - data.current_time);
979                 return;
980         }
981
982         count = g_hash_table_foreach_remove(cache, cache_check_entry,
983                                                 &data);
984         DBG("removed %d", count);
985
986         if (count == 0)
987                 /*
988                  * If we could not remove anything, then remember
989                  * what is the max timeout and do nothing if we
990                  * have not yet reached it. This will prevent
991                  * constant traversal of the cache if it is full.
992                  */
993                 max_timeout = data.max_timeout;
994         else
995                 max_timeout = 0;
996 }
997
998 static int cache_update(struct server_data *srv, unsigned char *msg,
999                         unsigned int msg_len)
1000 {
1001         int offset = protocol_offset(srv->protocol);
1002         int err, qlen, ttl = 0;
1003         uint16_t answers, type = 0, class = 0;
1004         struct domain_question *q;
1005         struct cache_entry *entry;
1006         struct cache_data *data;
1007         char question[NS_MAXDNAME + 1];
1008         unsigned char response[NS_MAXDNAME + 1];
1009         unsigned char *ptr;
1010         unsigned int rsplen;
1011         gboolean new_entry = TRUE;
1012         time_t current_time;
1013
1014         if (cache_size >= MAX_CACHE_SIZE) {
1015                 cache_cleanup();
1016                 if (cache_size >= MAX_CACHE_SIZE)
1017                         return 0;
1018         }
1019
1020         /* Continue only if response code is 0 (=ok) */
1021         if (msg[3] & 0x0f)
1022                 return 0;
1023
1024         if (offset < 0)
1025                 return 0;
1026
1027         rsplen = sizeof(response) - 1;
1028         question[sizeof(question) - 1] = '\0';
1029
1030         err = parse_response(msg + offset, msg_len - offset,
1031                                 question, sizeof(question) - 1,
1032                                 &type, &class, &ttl,
1033                                 response, &rsplen, &answers);
1034         if (err < 0 || ttl == 0)
1035                 return 0;
1036
1037         qlen = strlen(question);
1038         current_time = time(0);
1039
1040         /*
1041          * If the cache contains already data, check if the
1042          * type of the cached data is the same and do not add
1043          * to cache if data is already there.
1044          * This is needed so that we can cache both A and AAAA
1045          * records for the same name.
1046          */
1047         entry = g_hash_table_lookup(cache, question);
1048         if (entry == NULL) {
1049                 entry = g_try_new(struct cache_entry, 1);
1050                 if (entry == NULL)
1051                         return -ENOMEM;
1052
1053                 data = g_try_new(struct cache_data, 1);
1054                 if (data == NULL) {
1055                         g_free(entry);
1056                         return -ENOMEM;
1057                 }
1058
1059                 entry->key = g_strdup(question);
1060                 entry->ipv4 = entry->ipv6 = NULL;
1061
1062                 if (type == 1)
1063                         entry->ipv4 = data;
1064                 else
1065                         entry->ipv6 = data;
1066         } else {
1067                 if (type == 1 && entry->ipv4 != NULL)
1068                         return 0;
1069
1070                 if (type == 28 && entry->ipv6 != NULL)
1071                         return 0;
1072
1073                 data = g_try_new(struct cache_data, 1);
1074                 if (data == NULL)
1075                         return -ENOMEM;
1076
1077                 if (type == 1)
1078                         entry->ipv4 = data;
1079                 else
1080                         entry->ipv6 = data;
1081
1082                 new_entry = FALSE;
1083         }
1084
1085         data->inserted = current_time;
1086         data->type = type;
1087         data->answers = answers;
1088         data->timeout = ttl;
1089         data->data_len = 12 + qlen + 1 + 2 + 2 + rsplen;
1090         data->data = ptr = g_malloc(data->data_len);
1091         data->valid_until = current_time + ttl;
1092
1093         /*
1094          * Restrict the cached DNS record TTL to some sane value
1095          * in order to prevent data staying in the cache too long.
1096          */
1097         if (ttl > MAX_CACHE_TTL)
1098                 ttl = MAX_CACHE_TTL;
1099
1100         data->cache_until = round_down_ttl(current_time + ttl, ttl);
1101
1102         if (data->data == NULL) {
1103                 g_free(entry->key);
1104                 g_free(data);
1105                 g_free(entry);
1106                 return -ENOMEM;
1107         }
1108
1109         memcpy(ptr, msg, 12);
1110         memcpy(ptr + 12, question, qlen + 1); /* copy also the \0 */
1111
1112         q = (void *) (ptr + 12 + qlen + 1);
1113         q->type = htons(type);
1114         q->class = htons(class);
1115         memcpy(ptr + 12 + qlen + 1 + sizeof(struct domain_question),
1116                 response, rsplen);
1117
1118         if (new_entry == TRUE) {
1119                 g_hash_table_replace(cache, entry->key, entry);
1120                 cache_size++;
1121         }
1122
1123         DBG("cache %d %squestion \"%s\" type %d ttl %d size %zd",
1124                 cache_size, new_entry ? "new " : "old ",
1125                 question, type, ttl,
1126                 sizeof(*entry) + sizeof(*data) + data->data_len + qlen);
1127
1128         return 0;
1129 }
1130
1131 static int ns_resolv(struct server_data *server, struct request_data *req,
1132                                 gpointer request, gpointer name)
1133 {
1134         GList *list;
1135         int sk, err, type = 0;
1136         char *dot, *lookup = (char *) name;
1137         struct cache_entry *entry;
1138
1139         entry = cache_check(request, &type);
1140         if (entry != NULL) {
1141                 int ttl_left = 0;
1142                 struct cache_data *data;
1143
1144                 DBG("cache hit %s type %s", lookup, type == 1 ? "A" : "AAAA");
1145                 if (type == 1)
1146                         data = entry->ipv4;
1147                 else
1148                         data = entry->ipv6;
1149
1150                 if (data)
1151                         ttl_left = data->valid_until - time(0);
1152
1153                 if (data != NULL && req->protocol == IPPROTO_TCP) {
1154                         send_cached_response(req->client_sk, data->data,
1155                                         data->data_len, NULL, 0, IPPROTO_TCP,
1156                                         req->srcid, data->answers, ttl_left);
1157                         return 1;
1158                 }
1159
1160                 if (data != NULL && req->protocol == IPPROTO_UDP) {
1161                         int sk;
1162                         sk = g_io_channel_unix_get_fd(
1163                                         req->ifdata->udp_listener_channel);
1164
1165                         send_cached_response(sk, data->data,
1166                                 data->data_len, &req->sa, req->sa_len,
1167                                 IPPROTO_UDP, req->srcid, data->answers,
1168                                 ttl_left);
1169                         return 1;
1170                 }
1171         }
1172
1173         sk = g_io_channel_unix_get_fd(server->channel);
1174
1175         err = send(sk, request, req->request_len, 0);
1176
1177         req->numserv++;
1178
1179         /* If we have more than one dot, we don't add domains */
1180         dot = strchr(lookup, '.');
1181         if (dot != NULL && dot != lookup + strlen(lookup) - 1)
1182                 return 0;
1183
1184         if (server->domains != NULL && server->domains->data != NULL)
1185                 req->append_domain = TRUE;
1186
1187         for (list = server->domains; list; list = list->next) {
1188                 char *domain;
1189                 unsigned char alt[1024];
1190                 struct domain_hdr *hdr = (void *) &alt;
1191                 int altlen, domlen, offset;
1192
1193                 domain = list->data;
1194
1195                 if (domain == NULL)
1196                         continue;
1197
1198                 offset = protocol_offset(server->protocol);
1199                 if (offset < 0)
1200                         return offset;
1201
1202                 domlen = strlen(domain) + 1;
1203                 if (domlen < 5)
1204                         return -EINVAL;
1205
1206                 alt[offset] = req->altid & 0xff;
1207                 alt[offset + 1] = req->altid >> 8;
1208
1209                 memcpy(alt + offset + 2, request + offset + 2, 10);
1210                 hdr->qdcount = htons(1);
1211
1212                 altlen = append_query(alt + offset + 12, sizeof(alt) - 12,
1213                                         name, domain);
1214                 if (altlen < 0)
1215                         return -EINVAL;
1216
1217                 altlen += 12;
1218
1219                 memcpy(alt + offset + altlen,
1220                         request + offset + altlen - domlen,
1221                                 req->request_len - altlen - offset + domlen);
1222
1223                 if (server->protocol == IPPROTO_TCP) {
1224                         int req_len = req->request_len + domlen - 2;
1225
1226                         alt[0] = (req_len >> 8) & 0xff;
1227                         alt[1] = req_len & 0xff;
1228                 }
1229
1230                 err = send(sk, alt, req->request_len + domlen, 0);
1231                 if (err < 0)
1232                         return -EIO;
1233
1234                 req->numserv++;
1235         }
1236
1237         return 0;
1238 }
1239
1240 static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
1241                                 struct server_data *data)
1242 {
1243         struct domain_hdr *hdr;
1244         struct request_data *req;
1245         int dns_id, sk, err, offset = protocol_offset(protocol);
1246         struct listener_data *ifdata;
1247
1248         if (offset < 0)
1249                 return offset;
1250
1251         hdr = (void *)(reply + offset);
1252         dns_id = reply[offset] | reply[offset + 1] << 8;
1253
1254         DBG("Received %d bytes (id 0x%04x)", reply_len, dns_id);
1255
1256         req = find_request(dns_id);
1257         if (req == NULL)
1258                 return -EINVAL;
1259
1260         DBG("id 0x%04x rcode %d", hdr->id, hdr->rcode);
1261
1262         ifdata = req->ifdata;
1263
1264         reply[offset] = req->srcid & 0xff;
1265         reply[offset + 1] = req->srcid >> 8;
1266
1267         req->numresp++;
1268
1269         if (hdr->rcode == 0 || req->resp == NULL) {
1270
1271                 /*
1272                  * If the domain name was append
1273                  * remove it before forwarding the reply.
1274                  */
1275                 if (req->append_domain == TRUE) {
1276                         unsigned char *ptr;
1277                         uint8_t host_len;
1278                         unsigned int domain_len;
1279
1280                         /*
1281                          * ptr points to the first char of the hostname.
1282                          * ->hostname.domain.net
1283                          */
1284                         ptr = reply + offset + sizeof(struct domain_hdr);
1285                         host_len = *ptr;
1286                         domain_len = strlen((const char *)ptr) - host_len - 1;
1287
1288                         /*
1289                          * remove the domain name and replaced it by the end
1290                          * of reply.
1291                          */
1292                         memmove(ptr + host_len + 1,
1293                                 ptr + host_len + domain_len + 1,
1294                                 reply_len - (ptr - reply + domain_len));
1295
1296                         reply_len = reply_len - domain_len;
1297                 }
1298
1299                 g_free(req->resp);
1300                 req->resplen = 0;
1301
1302                 req->resp = g_try_malloc(reply_len);
1303                 if (req->resp == NULL)
1304                         return -ENOMEM;
1305
1306                 memcpy(req->resp, reply, reply_len);
1307                 req->resplen = reply_len;
1308
1309                 cache_update(data, reply, reply_len);
1310         }
1311
1312         if (hdr->rcode > 0 && req->numresp < req->numserv)
1313                 return -EINVAL;
1314
1315         if (req->timeout > 0)
1316                 g_source_remove(req->timeout);
1317
1318         request_list = g_slist_remove(request_list, req);
1319
1320         if (protocol == IPPROTO_UDP) {
1321                 sk = g_io_channel_unix_get_fd(ifdata->udp_listener_channel);
1322                 err = sendto(sk, req->resp, req->resplen, 0,
1323                              &req->sa, req->sa_len);
1324         } else {
1325                 sk = req->client_sk;
1326                 err = send(sk, req->resp, req->resplen, 0);
1327                 close(sk);
1328         }
1329
1330         g_free(req->resp);
1331         g_free(req);
1332
1333         return err;
1334 }
1335
1336 static void cache_element_destroy(gpointer value)
1337 {
1338         struct cache_entry *entry = value;
1339
1340         if (entry == NULL)
1341                 return;
1342
1343         if (entry->ipv4 != NULL) {
1344                 g_free(entry->ipv4->data);
1345                 g_free(entry->ipv4);
1346         }
1347
1348         if (entry->ipv6 != NULL) {
1349                 g_free(entry->ipv6->data);
1350                 g_free(entry->ipv6);
1351         }
1352
1353         g_free(entry->key);
1354         g_free(entry);
1355
1356         if (--cache_size < 0)
1357                 cache_size = 0;
1358 }
1359
1360 static void destroy_server(struct server_data *server)
1361 {
1362         GList *list;
1363
1364         DBG("interface %s server %s", server->interface, server->server);
1365
1366         server_list = g_slist_remove(server_list, server);
1367
1368         if (server->watch > 0)
1369                 g_source_remove(server->watch);
1370
1371         if (server->timeout > 0)
1372                 g_source_remove(server->timeout);
1373
1374         g_io_channel_unref(server->channel);
1375
1376         if (server->protocol == IPPROTO_UDP)
1377                 connman_info("Removing DNS server %s", server->server);
1378
1379         g_free(server->incoming_reply);
1380         g_free(server->server);
1381         for (list = server->domains; list; list = list->next) {
1382                 char *domain = list->data;
1383
1384                 server->domains = g_list_remove(server->domains, domain);
1385                 g_free(domain);
1386         }
1387         g_free(server->interface);
1388
1389         if (__sync_fetch_and_sub(&cache_refcount, 1) == 1)
1390                 g_hash_table_destroy(cache);
1391
1392         g_free(server);
1393 }
1394
1395 static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition,
1396                                                         gpointer user_data)
1397 {
1398         unsigned char buf[4096];
1399         int sk, err, len;
1400         struct server_data *data = user_data;
1401
1402         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1403                 connman_error("Error with UDP server %s", data->server);
1404                 data->watch = 0;
1405                 return FALSE;
1406         }
1407
1408         sk = g_io_channel_unix_get_fd(channel);
1409
1410         len = recv(sk, buf, sizeof(buf), 0);
1411         if (len < 12)
1412                 return TRUE;
1413
1414         err = forward_dns_reply(buf, len, IPPROTO_UDP, data);
1415         if (err < 0)
1416                 return TRUE;
1417
1418         return TRUE;
1419 }
1420
1421 static gboolean tcp_server_event(GIOChannel *channel, GIOCondition condition,
1422                                                         gpointer user_data)
1423 {
1424         int sk;
1425         struct server_data *server = user_data;
1426
1427         sk = g_io_channel_unix_get_fd(channel);
1428         if (sk == 0)
1429                 return FALSE;
1430
1431         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
1432                 GSList *list;
1433 hangup:
1434                 DBG("TCP server channel closed");
1435
1436                 /*
1437                  * Discard any partial response which is buffered; better
1438                  * to get a proper response from a working server.
1439                  */
1440                 g_free(server->incoming_reply);
1441                 server->incoming_reply = NULL;
1442
1443                 for (list = request_list; list; list = list->next) {
1444                         struct request_data *req = list->data;
1445                         struct domain_hdr *hdr;
1446
1447                         if (req->protocol == IPPROTO_UDP)
1448                                 continue;
1449
1450                         if (req->request == NULL)
1451                                 continue;
1452
1453                         /*
1454                          * If we're not waiting for any further response
1455                          * from another name server, then we send an error
1456                          * response to the client.
1457                          */
1458                         if (req->numserv && --(req->numserv))
1459                                 continue;
1460
1461                         hdr = (void *) (req->request + 2);
1462                         hdr->id = req->srcid;
1463                         send_response(req->client_sk, req->request,
1464                                 req->request_len, NULL, 0, IPPROTO_TCP);
1465
1466                         request_list = g_slist_remove(request_list, req);
1467                 }
1468
1469                 destroy_server(server);
1470
1471                 return FALSE;
1472         }
1473
1474         if ((condition & G_IO_OUT) && !server->connected) {
1475                 GSList *list;
1476                 GList *domains;
1477                 struct server_data *udp_server;
1478
1479                 udp_server = find_server(server->interface, server->server,
1480                                                                 IPPROTO_UDP);
1481                 if (udp_server != NULL) {
1482                         for (domains = udp_server->domains; domains;
1483                                                 domains = domains->next) {
1484                                 char *dom = domains->data;
1485
1486                                 DBG("Adding domain %s to %s",
1487                                                 dom, server->server);
1488
1489                                 server->domains = g_list_append(server->domains,
1490                                                                 g_strdup(dom));
1491                         }
1492                 }
1493
1494                 server->connected = TRUE;
1495                 server_list = g_slist_append(server_list, server);
1496
1497                 if (server->timeout > 0) {
1498                         g_source_remove(server->timeout);
1499                         server->timeout = 0;
1500                 }
1501
1502                 for (list = request_list; list; list = list->next) {
1503                         struct request_data *req = list->data;
1504
1505                         if (req->protocol == IPPROTO_UDP)
1506                                 continue;
1507
1508                         DBG("Sending req %s over TCP", (char *)req->name);
1509
1510                         if (req->timeout > 0)
1511                                 g_source_remove(req->timeout);
1512
1513                         req->timeout = g_timeout_add_seconds(30,
1514                                                 request_timeout, req);
1515                         if (ns_resolv(server, req, req->request,
1516                                         req->name) > 0) {
1517                                 /* We sent cached result so no need for timeout
1518                                  * handler.
1519                                  */
1520                                 if (req->timeout > 0) {
1521                                         g_source_remove(req->timeout);
1522                                         req->timeout = 0;
1523                                 }
1524                         }
1525                 }
1526
1527         } else if (condition & G_IO_IN) {
1528                 struct partial_reply *reply = server->incoming_reply;
1529                 int bytes_recv;
1530
1531                 if (!reply) {
1532                         unsigned char reply_len_buf[2];
1533                         uint16_t reply_len;
1534
1535                         bytes_recv = recv(sk, reply_len_buf, 2, MSG_PEEK);
1536                         if (!bytes_recv) {
1537                                 goto hangup;
1538                         } else if (bytes_recv < 0) {
1539                                 if (errno == EAGAIN || errno == EWOULDBLOCK)
1540                                         return TRUE;
1541
1542                                 connman_error("DNS proxy error %s",
1543                                                 strerror(errno));
1544                                 goto hangup;
1545                         } else if (bytes_recv < 2)
1546                                 return TRUE;
1547
1548                         reply_len = reply_len_buf[1] | reply_len_buf[0] << 8;
1549                         reply_len += 2;
1550
1551                         DBG("TCP reply %d bytes", reply_len);
1552
1553                         reply = g_try_malloc(sizeof(*reply) + reply_len + 2);
1554                         if (!reply)
1555                                 return TRUE;
1556
1557                         reply->len = reply_len;
1558                         reply->received = 0;
1559
1560                         server->incoming_reply = reply;
1561                 }
1562
1563                 while (reply->received < reply->len) {
1564                         bytes_recv = recv(sk, reply->buf + reply->received,
1565                                         reply->len - reply->received, 0);
1566                         if (!bytes_recv) {
1567                                 connman_error("DNS proxy TCP disconnect");
1568                                 break;
1569                         } else if (bytes_recv < 0) {
1570                                 if (errno == EAGAIN || errno == EWOULDBLOCK)
1571                                         return TRUE;
1572
1573                                 connman_error("DNS proxy error %s",
1574                                                 strerror(errno));
1575                                 break;
1576                         }
1577                         reply->received += bytes_recv;
1578                 }
1579
1580                 forward_dns_reply(reply->buf, reply->received, IPPROTO_TCP,
1581                                         server);
1582
1583                 g_free(reply);
1584                 server->incoming_reply = NULL;
1585
1586                 destroy_server(server);
1587
1588                 return FALSE;
1589         }
1590
1591         return TRUE;
1592 }
1593
1594 static gboolean tcp_idle_timeout(gpointer user_data)
1595 {
1596         struct server_data *server = user_data;
1597
1598         DBG("");
1599
1600         if (server == NULL)
1601                 return FALSE;
1602
1603         destroy_server(server);
1604
1605         return FALSE;
1606 }
1607
1608 static struct server_data *create_server(const char *interface,
1609                                         const char *domain, const char *server,
1610                                         int protocol)
1611 {
1612         struct addrinfo hints, *rp;
1613         struct server_data *data;
1614         int sk, ret;
1615
1616         DBG("interface %s server %s", interface, server);
1617
1618         memset(&hints, 0, sizeof(hints));
1619
1620         switch (protocol) {
1621         case IPPROTO_UDP:
1622                 hints.ai_socktype = SOCK_DGRAM;
1623                 break;
1624
1625         case IPPROTO_TCP:
1626                 hints.ai_socktype = SOCK_STREAM;
1627                 break;
1628
1629         default:
1630                 return NULL;
1631         }
1632         hints.ai_family = AF_UNSPEC;
1633         hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
1634
1635         ret = getaddrinfo(server, "53", &hints, &rp);
1636         if (ret) {
1637                 connman_error("Failed to parse server %s address: %s\n",
1638                               server, gai_strerror(ret));
1639                 return NULL;
1640         }
1641         /* Do not blindly copy this code elsewhere; it doesn't loop over the
1642            results using ->ai_next as it should. That's OK in *this* case
1643            because it was a numeric lookup; we *know* there's only one. */
1644
1645         sk = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
1646         if (sk < 0) {
1647                 connman_error("Failed to create server %s socket", server);
1648                 freeaddrinfo(rp);
1649                 return NULL;
1650         }
1651
1652         if (interface != NULL) {
1653                 if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
1654                                 interface, strlen(interface) + 1) < 0) {
1655                         connman_error("Failed to bind server %s "
1656                                                 "to interface %s",
1657                                                         server, interface);
1658                         freeaddrinfo(rp);
1659                         close(sk);
1660                         return NULL;
1661                 }
1662         }
1663
1664         data = g_try_new0(struct server_data, 1);
1665         if (data == NULL) {
1666                 connman_error("Failed to allocate server %s data", server);
1667                 freeaddrinfo(rp);
1668                 close(sk);
1669                 return NULL;
1670         }
1671
1672         data->channel = g_io_channel_unix_new(sk);
1673         if (data->channel == NULL) {
1674                 connman_error("Failed to create server %s channel", server);
1675                 freeaddrinfo(rp);
1676                 close(sk);
1677                 g_free(data);
1678                 return NULL;
1679         }
1680
1681         g_io_channel_set_close_on_unref(data->channel, TRUE);
1682
1683         if (protocol == IPPROTO_TCP) {
1684                 g_io_channel_set_flags(data->channel, G_IO_FLAG_NONBLOCK, NULL);
1685                 data->watch = g_io_add_watch(data->channel,
1686                         G_IO_OUT | G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
1687                                                 tcp_server_event, data);
1688                 data->timeout = g_timeout_add_seconds(30, tcp_idle_timeout,
1689                                                                 data);
1690         } else
1691                 data->watch = g_io_add_watch(data->channel,
1692                         G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
1693                                                 udp_server_event, data);
1694
1695         data->interface = g_strdup(interface);
1696         if (domain)
1697                 data->domains = g_list_append(data->domains, g_strdup(domain));
1698         data->server = g_strdup(server);
1699         data->protocol = protocol;
1700
1701         ret = connect(sk, rp->ai_addr, rp->ai_addrlen);
1702         freeaddrinfo(rp);
1703         if (ret < 0) {
1704                 if ((protocol == IPPROTO_TCP && errno != EINPROGRESS) ||
1705                                 protocol == IPPROTO_UDP) {
1706                         GList *list;
1707
1708                         connman_error("Failed to connect to server %s", server);
1709                         if (data->watch > 0)
1710                                 g_source_remove(data->watch);
1711                         if (data->timeout > 0)
1712                                 g_source_remove(data->timeout);
1713
1714                         g_io_channel_unref(data->channel);
1715                         close(sk);
1716
1717                         g_free(data->server);
1718                         g_free(data->interface);
1719                         for (list = data->domains; list; list = list->next) {
1720                                 char *domain = list->data;
1721
1722                                 data->domains = g_list_remove(data->domains,
1723                                                                         domain);
1724                                 g_free(domain);
1725                         }
1726                         g_free(data);
1727                         return NULL;
1728                 }
1729         }
1730
1731         if (__sync_fetch_and_add(&cache_refcount, 1) == 0)
1732                 cache = g_hash_table_new_full(g_str_hash,
1733                                         g_str_equal,
1734                                         NULL,
1735                                         cache_element_destroy);
1736
1737         if (protocol == IPPROTO_UDP) {
1738                 /* Enable new servers by default */
1739                 data->enabled = TRUE;
1740                 connman_info("Adding DNS server %s", data->server);
1741
1742                 server_list = g_slist_append(server_list, data);
1743
1744                 return data;
1745         }
1746
1747         return NULL;
1748 }
1749
1750 static gboolean resolv(struct request_data *req,
1751                                 gpointer request, gpointer name)
1752 {
1753         GSList *list;
1754         int status;
1755
1756         for (list = server_list; list; list = list->next) {
1757                 struct server_data *data = list->data;
1758
1759                 DBG("server %s enabled %d", data->server, data->enabled);
1760
1761                 if (data->enabled == FALSE)
1762                         continue;
1763
1764                 if (data->watch == 0 && data->protocol == IPPROTO_UDP)
1765                         data->watch = g_io_add_watch(data->channel,
1766                                 G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
1767                                                 udp_server_event, data);
1768
1769                 status = ns_resolv(data, req, request, name);
1770                 if (status < 0)
1771                         continue;
1772
1773                 if (status > 0) {
1774                         if (req->timeout > 0) {
1775                                 g_source_remove(req->timeout);
1776                                 req->timeout = 0;
1777                         }
1778                 }
1779         }
1780
1781         return TRUE;
1782 }
1783
1784 static void append_domain(const char *interface, const char *domain)
1785 {
1786         GSList *list;
1787
1788         DBG("interface %s domain %s", interface, domain);
1789
1790         if (domain == NULL)
1791                 return;
1792
1793         for (list = server_list; list; list = list->next) {
1794                 struct server_data *data = list->data;
1795                 GList *dom_list;
1796                 char *dom;
1797                 gboolean dom_found = FALSE;
1798
1799                 if (data->interface == NULL)
1800                         continue;
1801
1802                 if (g_str_equal(data->interface, interface) == FALSE)
1803                         continue;
1804
1805                 for (dom_list = data->domains; dom_list;
1806                                 dom_list = dom_list->next) {
1807                         dom = dom_list->data;
1808
1809                         if (g_str_equal(dom, domain)) {
1810                                 dom_found = TRUE;
1811                                 break;
1812                         }
1813                 }
1814
1815                 if (dom_found == FALSE) {
1816                         data->domains =
1817                                 g_list_append(data->domains, g_strdup(domain));
1818                 }
1819         }
1820 }
1821
1822 int __connman_dnsproxy_append(const char *interface, const char *domain,
1823                                                         const char *server)
1824 {
1825         struct server_data *data;
1826
1827         DBG("interface %s server %s", interface, server);
1828
1829         if (server == NULL && domain == NULL)
1830                 return -EINVAL;
1831
1832         if (server == NULL) {
1833                 append_domain(interface, domain);
1834
1835                 return 0;
1836         }
1837
1838         if (g_str_equal(server, "127.0.0.1") == TRUE)
1839                 return -ENODEV;
1840
1841         data = find_server(interface, server, IPPROTO_UDP);
1842         if (data != NULL) {
1843                 append_domain(interface, domain);
1844                 return 0;
1845         }
1846
1847         data = create_server(interface, domain, server, IPPROTO_UDP);
1848         if (data == NULL)
1849                 return -EIO;
1850
1851         return 0;
1852 }
1853
1854 static void remove_server(const char *interface, const char *domain,
1855                         const char *server, int protocol)
1856 {
1857         struct server_data *data;
1858
1859         data = find_server(interface, server, protocol);
1860         if (data == NULL)
1861                 return;
1862
1863         destroy_server(data);
1864 }
1865
1866 int __connman_dnsproxy_remove(const char *interface, const char *domain,
1867                                                         const char *server)
1868 {
1869         DBG("interface %s server %s", interface, server);
1870
1871         if (server == NULL)
1872                 return -EINVAL;
1873
1874         if (g_str_equal(server, "127.0.0.1") == TRUE)
1875                 return -ENODEV;
1876
1877         remove_server(interface, domain, server, IPPROTO_UDP);
1878         remove_server(interface, domain, server, IPPROTO_TCP);
1879
1880         return 0;
1881 }
1882
1883 void __connman_dnsproxy_flush(void)
1884 {
1885         GSList *list;
1886
1887         list = request_pending_list;
1888         while (list) {
1889                 struct request_data *req = list->data;
1890
1891                 list = list->next;
1892
1893                 request_pending_list =
1894                                 g_slist_remove(request_pending_list, req);
1895                 resolv(req, req->request, req->name);
1896                 g_free(req->request);
1897                 g_free(req->name);
1898         }
1899 }
1900
1901 static void dnsproxy_offline_mode(connman_bool_t enabled)
1902 {
1903         GSList *list;
1904
1905         DBG("enabled %d", enabled);
1906
1907         for (list = server_list; list; list = list->next) {
1908                 struct server_data *data = list->data;
1909
1910                 if (enabled == FALSE) {
1911                         connman_info("Enabling DNS server %s", data->server);
1912                         data->enabled = TRUE;
1913                 } else {
1914                         connman_info("Disabling DNS server %s", data->server);
1915                         data->enabled = FALSE;
1916                 }
1917         }
1918 }
1919
1920 static void dnsproxy_default_changed(struct connman_service *service)
1921 {
1922         GSList *list;
1923         char *interface;
1924
1925         DBG("service %p", service);
1926
1927         if (service == NULL) {
1928                 /* When no services are active, then disable DNS proxying */
1929                 dnsproxy_offline_mode(TRUE);
1930                 return;
1931         }
1932
1933         interface = connman_service_get_interface(service);
1934         if (interface == NULL)
1935                 return;
1936
1937         for (list = server_list; list; list = list->next) {
1938                 struct server_data *data = list->data;
1939
1940                 if (g_strcmp0(data->interface, interface) == 0) {
1941                         connman_info("Enabling DNS server %s", data->server);
1942                         data->enabled = TRUE;
1943                 } else {
1944                         connman_info("Disabling DNS server %s", data->server);
1945                         data->enabled = FALSE;
1946                 }
1947         }
1948
1949         g_free(interface);
1950 }
1951
1952 static struct connman_notifier dnsproxy_notifier = {
1953         .name                   = "dnsproxy",
1954         .default_changed        = dnsproxy_default_changed,
1955         .offline_mode           = dnsproxy_offline_mode,
1956 };
1957
1958 static unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
1959
1960 static int parse_request(unsigned char *buf, int len,
1961                                         char *name, unsigned int size)
1962 {
1963         struct domain_hdr *hdr = (void *) buf;
1964         uint16_t qdcount = ntohs(hdr->qdcount);
1965         uint16_t arcount = ntohs(hdr->arcount);
1966         unsigned char *ptr;
1967         char *last_label = NULL;
1968         unsigned int remain, used = 0;
1969
1970         if (len < 12)
1971                 return -EINVAL;
1972
1973         DBG("id 0x%04x qr %d opcode %d qdcount %d arcount %d",
1974                                         hdr->id, hdr->qr, hdr->opcode,
1975                                                         qdcount, arcount);
1976
1977         if (hdr->qr != 0 || qdcount != 1)
1978                 return -EINVAL;
1979
1980         memset(name, 0, size);
1981
1982         ptr = buf + sizeof(struct domain_hdr);
1983         remain = len - sizeof(struct domain_hdr);
1984
1985         while (remain > 0) {
1986                 uint8_t len = *ptr;
1987
1988                 if (len == 0x00) {
1989                         last_label = (char *) (ptr + 1);
1990                         break;
1991                 }
1992
1993                 if (used + len + 1 > size)
1994                         return -ENOBUFS;
1995
1996                 strncat(name, (char *) (ptr + 1), len);
1997                 strcat(name, ".");
1998
1999                 used += len + 1;
2000
2001                 ptr += len + 1;
2002                 remain -= len + 1;
2003         }
2004
2005         if (last_label && arcount && remain >= 9 && last_label[4] == 0 &&
2006                                 !memcmp(last_label + 5, opt_edns0_type, 2)) {
2007                 uint16_t edns0_bufsize;
2008
2009                 edns0_bufsize = last_label[7] << 8 | last_label[8];
2010
2011                 DBG("EDNS0 buffer size %u", edns0_bufsize);
2012
2013                 /* This is an evil hack until full TCP support has been
2014                  * implemented.
2015                  *
2016                  * Somtimes the EDNS0 request gets send with a too-small
2017                  * buffer size. Since glibc doesn't seem to crash when it
2018                  * gets a response biffer then it requested, just bump
2019                  * the buffer size up to 4KiB.
2020                  */
2021                 if (edns0_bufsize < 0x1000) {
2022                         last_label[7] = 0x10;
2023                         last_label[8] = 0x00;
2024                 }
2025         }
2026
2027         DBG("query %s", name);
2028
2029         return 0;
2030 }
2031
2032 static gboolean tcp_listener_event(GIOChannel *channel, GIOCondition condition,
2033                                                         gpointer user_data)
2034 {
2035         unsigned char buf[768];
2036         char query[512];
2037         struct request_data *req;
2038         struct server_data *server;
2039         int sk, client_sk, len, err;
2040         struct sockaddr_in6 client_addr;
2041         socklen_t client_addr_len = sizeof(client_addr);
2042         GSList *list;
2043         struct listener_data *ifdata = user_data;
2044
2045         DBG("condition 0x%x", condition);
2046
2047         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
2048                 if (ifdata->tcp_listener_watch > 0)
2049                         g_source_remove(ifdata->tcp_listener_watch);
2050                 ifdata->tcp_listener_watch = 0;
2051
2052                 connman_error("Error with TCP listener channel");
2053
2054                 return FALSE;
2055         }
2056
2057         sk = g_io_channel_unix_get_fd(channel);
2058
2059         client_sk = accept(sk, (void *)&client_addr, &client_addr_len);
2060         if (client_sk < 0) {
2061                 connman_error("Accept failure on TCP listener");
2062                 ifdata->tcp_listener_watch = 0;
2063                 return FALSE;
2064         }
2065
2066         len = recv(client_sk, buf, sizeof(buf), 0);
2067         if (len < 2)
2068                 return TRUE;
2069
2070         DBG("Received %d bytes (id 0x%04x)", len, buf[2] | buf[3] << 8);
2071
2072         err = parse_request(buf + 2, len - 2, query, sizeof(query));
2073         if (err < 0 || (g_slist_length(server_list) == 0)) {
2074                 send_response(client_sk, buf, len, NULL, 0, IPPROTO_TCP);
2075                 return TRUE;
2076         }
2077
2078         req = g_try_new0(struct request_data, 1);
2079         if (req == NULL)
2080                 return TRUE;
2081
2082         memcpy(&req->sa, &client_addr, client_addr_len);
2083         req->sa_len = client_addr_len;
2084         req->client_sk = client_sk;
2085         req->protocol = IPPROTO_TCP;
2086
2087         request_id += 2;
2088         if (request_id == 0x0000 || request_id == 0xffff)
2089                 request_id += 2;
2090
2091         req->srcid = buf[2] | (buf[3] << 8);
2092         req->dstid = request_id;
2093         req->altid = request_id + 1;
2094         req->request_len = len;
2095
2096         buf[2] = req->dstid & 0xff;
2097         buf[3] = req->dstid >> 8;
2098
2099         req->numserv = 0;
2100         req->ifdata = (struct listener_data *) ifdata;
2101         req->append_domain = FALSE;
2102         request_list = g_slist_append(request_list, req);
2103
2104         for (list = server_list; list; list = list->next) {
2105                 struct server_data *data = list->data;
2106                 GList *domains;
2107
2108                 if (data->protocol != IPPROTO_UDP || data->enabled == FALSE)
2109                         continue;
2110
2111                 server = create_server(data->interface, NULL,
2112                                         data->server, IPPROTO_TCP);
2113
2114                 /*
2115                  * If server is NULL, we're not connected yet.
2116                  * Copy the relevant buffers and continue with
2117                  * the next nameserver.
2118                  * The request will actually be sent once we're
2119                  * properly connected over TCP to this nameserver.
2120                  */
2121                 if (server == NULL) {
2122                         req->request = g_try_malloc0(req->request_len);
2123                         if (req->request == NULL)
2124                                 return TRUE;
2125
2126                         memcpy(req->request, buf, req->request_len);
2127
2128                         req->name = g_try_malloc0(sizeof(query));
2129                         if (req->name == NULL) {
2130                                 g_free(req->request);
2131                                 return TRUE;
2132                         }
2133                         memcpy(req->name, query, sizeof(query));
2134
2135                         continue;
2136                 }
2137
2138                 if (req->timeout > 0)
2139                         g_source_remove(req->timeout);
2140
2141                 for (domains = data->domains; domains;
2142                                 domains = domains->next) {
2143                         char *dom = domains->data;
2144
2145                         DBG("Adding domain %s to %s", dom, server->server);
2146
2147                         server->domains = g_list_append(server->domains,
2148                                                 g_strdup(dom));
2149                 }
2150
2151                 req->timeout = g_timeout_add_seconds(30, request_timeout, req);
2152                 if (ns_resolv(server, req, buf, query) > 0) {
2153                         if (req->timeout > 0) {
2154                                 g_source_remove(req->timeout);
2155                                 req->timeout = 0;
2156                         }
2157                 }
2158         }
2159
2160         return TRUE;
2161 }
2162
2163 static gboolean udp_listener_event(GIOChannel *channel, GIOCondition condition,
2164                                                         gpointer user_data)
2165 {
2166         unsigned char buf[768];
2167         char query[512];
2168         struct request_data *req;
2169         struct sockaddr_in6 client_addr;
2170         socklen_t client_addr_len = sizeof(client_addr);
2171         int sk, err, len;
2172         struct listener_data *ifdata = user_data;
2173
2174         if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
2175                 connman_error("Error with UDP listener channel");
2176                 ifdata->udp_listener_watch = 0;
2177                 return FALSE;
2178         }
2179
2180         sk = g_io_channel_unix_get_fd(channel);
2181
2182         memset(&client_addr, 0, client_addr_len);
2183         len = recvfrom(sk, buf, sizeof(buf), 0, (void *)&client_addr,
2184                        &client_addr_len);
2185         if (len < 2)
2186                 return TRUE;
2187
2188         DBG("Received %d bytes (id 0x%04x)", len, buf[0] | buf[1] << 8);
2189
2190         err = parse_request(buf, len, query, sizeof(query));
2191         if (err < 0 || (g_slist_length(server_list) == 0)) {
2192                 send_response(sk, buf, len, (void *)&client_addr,
2193                                 client_addr_len, IPPROTO_UDP);
2194                 return TRUE;
2195         }
2196
2197         req = g_try_new0(struct request_data, 1);
2198         if (req == NULL)
2199                 return TRUE;
2200
2201         memcpy(&req->sa, &client_addr, client_addr_len);
2202         req->sa_len = client_addr_len;
2203         req->client_sk = 0;
2204         req->protocol = IPPROTO_UDP;
2205
2206         request_id += 2;
2207         if (request_id == 0x0000 || request_id == 0xffff)
2208                 request_id += 2;
2209
2210         req->srcid = buf[0] | (buf[1] << 8);
2211         req->dstid = request_id;
2212         req->altid = request_id + 1;
2213         req->request_len = len;
2214
2215         buf[0] = req->dstid & 0xff;
2216         buf[1] = req->dstid >> 8;
2217
2218         req->numserv = 0;
2219         req->ifdata = (struct listener_data *) ifdata;
2220         req->timeout = g_timeout_add_seconds(5, request_timeout, req);
2221         req->append_domain = FALSE;
2222         request_list = g_slist_append(request_list, req);
2223
2224         return resolv(req, buf, query);
2225 }
2226
2227 static int create_dns_listener(int protocol, struct listener_data *ifdata)
2228 {
2229         GIOChannel *channel;
2230         const char *proto;
2231         union {
2232                 struct sockaddr sa;
2233                 struct sockaddr_in6 sin6;
2234                 struct sockaddr_in sin;
2235         } s;
2236         socklen_t slen;
2237         int sk, type, v6only = 0;
2238         int family = AF_INET6;
2239
2240
2241         DBG("interface %s", ifdata->ifname);
2242
2243         switch (protocol) {
2244         case IPPROTO_UDP:
2245                 proto = "UDP";
2246                 type = SOCK_DGRAM | SOCK_CLOEXEC;
2247                 break;
2248
2249         case IPPROTO_TCP:
2250                 proto = "TCP";
2251                 type = SOCK_STREAM | SOCK_CLOEXEC;
2252                 break;
2253
2254         default:
2255                 return -EINVAL;
2256         }
2257
2258         sk = socket(family, type, protocol);
2259         if (sk < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
2260                 connman_error("No IPv6 support; DNS proxy listening only on Legacy IP");
2261                 family = AF_INET;
2262                 sk = socket(family, type, protocol);
2263         }
2264         if (sk < 0) {
2265                 connman_error("Failed to create %s listener socket", proto);
2266                 return -EIO;
2267         }
2268
2269         if (setsockopt(sk, SOL_SOCKET, SO_BINDTODEVICE,
2270                                         ifdata->ifname,
2271                                         strlen(ifdata->ifname) + 1) < 0) {
2272                 connman_error("Failed to bind %s listener interface", proto);
2273                 close(sk);
2274                 return -EIO;
2275         }
2276         /* Ensure it accepts Legacy IP connections too */
2277         if (family == AF_INET6 &&
2278                         setsockopt(sk, SOL_IPV6, IPV6_V6ONLY,
2279                                         &v6only, sizeof(v6only)) < 0) {
2280                 connman_error("Failed to clear V6ONLY on %s listener socket",
2281                               proto);
2282                 close(sk);
2283                 return -EIO;
2284         }
2285
2286         if (family == AF_INET) {
2287                 memset(&s.sin, 0, sizeof(s.sin));
2288                 s.sin.sin_family = AF_INET;
2289                 s.sin.sin_port = htons(53);
2290                 s.sin.sin_addr.s_addr = htonl(INADDR_ANY);
2291                 slen = sizeof(s.sin);
2292         } else {
2293                 memset(&s.sin6, 0, sizeof(s.sin6));
2294                 s.sin6.sin6_family = AF_INET6;
2295                 s.sin6.sin6_port = htons(53);
2296                 s.sin6.sin6_addr = in6addr_any;
2297                 slen = sizeof(s.sin6);
2298         }
2299
2300         if (bind(sk, &s.sa, slen) < 0) {
2301                 connman_error("Failed to bind %s listener socket", proto);
2302                 close(sk);
2303                 return -EIO;
2304         }
2305
2306         if (protocol == IPPROTO_TCP && listen(sk, 10) < 0) {
2307                 connman_error("Failed to listen on TCP socket");
2308                 close(sk);
2309                 return -EIO;
2310         }
2311
2312         channel = g_io_channel_unix_new(sk);
2313         if (channel == NULL) {
2314                 connman_error("Failed to create %s listener channel", proto);
2315                 close(sk);
2316                 return -EIO;
2317         }
2318
2319         g_io_channel_set_close_on_unref(channel, TRUE);
2320
2321         if (protocol == IPPROTO_TCP) {
2322                 ifdata->tcp_listener_channel = channel;
2323                 ifdata->tcp_listener_watch = g_io_add_watch(channel,
2324                                 G_IO_IN, tcp_listener_event, (gpointer) ifdata);
2325         } else {
2326                 ifdata->udp_listener_channel = channel;
2327                 ifdata->udp_listener_watch = g_io_add_watch(channel,
2328                                 G_IO_IN, udp_listener_event, (gpointer) ifdata);
2329         }
2330
2331         return 0;
2332 }
2333
2334 static void destroy_udp_listener(struct listener_data *ifdata)
2335 {
2336         DBG("interface %s", ifdata->ifname);
2337
2338         if (ifdata->udp_listener_watch > 0)
2339                 g_source_remove(ifdata->udp_listener_watch);
2340
2341         g_io_channel_unref(ifdata->udp_listener_channel);
2342 }
2343
2344 static void destroy_tcp_listener(struct listener_data *ifdata)
2345 {
2346         DBG("interface %s", ifdata->ifname);
2347
2348         if (ifdata->tcp_listener_watch > 0)
2349                 g_source_remove(ifdata->tcp_listener_watch);
2350
2351         g_io_channel_unref(ifdata->tcp_listener_channel);
2352 }
2353
2354 static int create_listener(struct listener_data *ifdata)
2355 {
2356         int err;
2357
2358         err = create_dns_listener(IPPROTO_UDP, ifdata);
2359         if (err < 0)
2360                 return err;
2361
2362         err = create_dns_listener(IPPROTO_TCP, ifdata);
2363         if (err < 0) {
2364                 destroy_udp_listener(ifdata);
2365                 return err;
2366         }
2367
2368         if (g_strcmp0(ifdata->ifname, "lo") == 0)
2369                 __connman_resolvfile_append("lo", NULL, "127.0.0.1");
2370
2371         return 0;
2372 }
2373
2374 static void destroy_listener(struct listener_data *ifdata)
2375 {
2376         GSList *list;
2377
2378         if (g_strcmp0(ifdata->ifname, "lo") == 0)
2379                 __connman_resolvfile_remove("lo", NULL, "127.0.0.1");
2380
2381         for (list = request_pending_list; list; list = list->next) {
2382                 struct request_data *req = list->data;
2383
2384                 DBG("Dropping pending request (id 0x%04x -> 0x%04x)",
2385                                                 req->srcid, req->dstid);
2386
2387                 g_free(req->resp);
2388                 g_free(req->request);
2389                 g_free(req->name);
2390                 g_free(req);
2391                 list->data = NULL;
2392         }
2393
2394         g_slist_free(request_pending_list);
2395         request_pending_list = NULL;
2396
2397         for (list = request_list; list; list = list->next) {
2398                 struct request_data *req = list->data;
2399
2400                 DBG("Dropping request (id 0x%04x -> 0x%04x)",
2401                                                 req->srcid, req->dstid);
2402
2403                 g_free(req->resp);
2404                 g_free(req->request);
2405                 g_free(req->name);
2406                 g_free(req);
2407                 list->data = NULL;
2408         }
2409
2410         g_slist_free(request_list);
2411         request_list = NULL;
2412
2413         destroy_tcp_listener(ifdata);
2414         destroy_udp_listener(ifdata);
2415 }
2416
2417 int __connman_dnsproxy_add_listener(const char *interface)
2418 {
2419         struct listener_data *ifdata;
2420         int err;
2421
2422         DBG("interface %s", interface);
2423
2424         if (g_hash_table_lookup(listener_table, interface) != NULL)
2425                 return 0;
2426
2427         ifdata = g_try_new0(struct listener_data, 1);
2428         if (ifdata == NULL)
2429                 return -ENOMEM;
2430
2431         ifdata->ifname = g_strdup(interface);
2432         ifdata->udp_listener_channel = NULL;
2433         ifdata->udp_listener_watch = 0;
2434         ifdata->tcp_listener_channel = NULL;
2435         ifdata->tcp_listener_watch = 0;
2436
2437         err = create_listener(ifdata);
2438         if (err < 0) {
2439                 connman_error("Couldn't create listener for %s err %d",
2440                                 interface, err);
2441                 g_free(ifdata->ifname);
2442                 g_free(ifdata);
2443                 return err;
2444         }
2445         g_hash_table_insert(listener_table, ifdata->ifname, ifdata);
2446         return 0;
2447 }
2448
2449 void __connman_dnsproxy_remove_listener(const char *interface)
2450 {
2451         struct listener_data *ifdata;
2452
2453         DBG("interface %s", interface);
2454
2455         ifdata = g_hash_table_lookup(listener_table, interface);
2456         if (ifdata == NULL)
2457                 return;
2458
2459         destroy_listener(ifdata);
2460
2461         g_hash_table_remove(listener_table, interface);
2462 }
2463
2464 static void remove_listener(gpointer key, gpointer value, gpointer user_data)
2465 {
2466         __connman_dnsproxy_remove_listener(key);
2467 }
2468
2469 int __connman_dnsproxy_init(void)
2470 {
2471         int err;
2472
2473         DBG("");
2474
2475         listener_table = g_hash_table_new_full(g_str_hash, g_str_equal,
2476                                                         g_free, g_free);
2477         err = __connman_dnsproxy_add_listener("lo");
2478         if (err < 0)
2479                 return err;
2480
2481         err = connman_notifier_register(&dnsproxy_notifier);
2482         if (err < 0)
2483                 goto destroy;
2484
2485         return 0;
2486
2487 destroy:
2488         __connman_dnsproxy_remove_listener("lo");
2489         g_hash_table_destroy(listener_table);
2490
2491         return err;
2492 }
2493
2494 void __connman_dnsproxy_cleanup(void)
2495 {
2496         DBG("");
2497
2498         connman_notifier_unregister(&dnsproxy_notifier);
2499
2500         g_hash_table_foreach(listener_table, remove_listener, NULL);
2501
2502         g_hash_table_destroy(listener_table);
2503 }