[IOMultiplexer] Added asynchronous DNS Lookups
[IOMultiplexer.git] / src / IODNSEngine_default.c
1 /* IODNSEngine_default.c - IOMultiplexer
2  * Copyright (C) 2012  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17 #include "IODNSEngine.h"
18
19 static int dnsengine_default_init() {
20     return 1;
21 }
22
23 static void dnsengine_default_add(struct IODNSQuery *iodns) {
24     /* unused */
25 }
26
27 static void dnsengine_default_remove(struct IODNSQuery *iodns) {
28     /* unused */
29 }
30
31 static void dnsengine_default_loop() {
32     enum IODNSEventType querystate;
33     struct addrinfo hints, *res, *next_res;
34     struct IODNSQuery *iodns, *next_iodns;
35     struct IODNSResult *dnsresult;
36     for(iodns = first_dnsquery; iodns; iodns = next_iodns) {
37         next_iodns = iodns->next;
38         querystate = IODNSEVENT_FAILED;
39         
40         if((iodns->type & IODNS_FORWARD)) {
41             memset (&hints, 0, sizeof (hints));
42             hints.ai_family = PF_UNSPEC;
43             hints.ai_socktype = SOCK_STREAM;
44             hints.ai_flags |= AI_CANONNAME;
45             if (!getaddrinfo(iodns->hostname, NULL, &hints, &res)) {
46                 while (res) {
47                     switch (res->ai_family) {
48                     case AF_INET:
49                         if((iodns->type & IODNS_RECORD_A)) {
50                             dnsresult = malloc(sizeof(*dnsresult));
51                             dnsresult->type = IODNS_RECORD_A;
52                             dnsresult->addresslen = res->ai_addrlen;
53                             dnsresult->address = malloc(dnsresult->addresslen);
54                             memcpy(dnsresult->address, res->ai_addr, dnsresult->addresslen);
55                             dnsresult->next = iodns->addr.results;
56                             iodns->addr.results = dnsresult;
57                             querystate = IODNSEVENT_SUCCESS;
58                         }
59                         break;
60                     case AF_INET6:
61                         if((iodns->type & IODNS_RECORD_AAAA)) {
62                             dnsresult = malloc(sizeof(*dnsresult));
63                             dnsresult->type = IODNS_RECORD_AAAA;
64                             dnsresult->addresslen = res->ai_addrlen;
65                             dnsresult->address = malloc(dnsresult->addresslen);
66                             memcpy(dnsresult->address, res->ai_addr, dnsresult->addresslen);
67                             dnsresult->next = iodns->addr.results;
68                             iodns->addr.results = dnsresult;
69                             querystate = IODNSEVENT_SUCCESS;
70                         }
71                         break;
72                     }
73                     next_res = res->ai_next;
74                     freeaddrinfo(res);
75                     res = next_res;
76                 }
77             }
78             iodns_event_callback(iodns, querystate);
79         }
80     }
81 }
82
83 struct IODNSEngine dnsengine_default = {
84     .name = "default",
85     .init = dnsengine_default_init,
86     .add = dnsengine_default_add,
87     .remove = dnsengine_default_remove,
88     .loop = dnsengine_default_loop,
89 };