1 /* IODNSHandler.c - IOMultiplexer
2 * Copyright (C) 2012 Philipp Kreil (pk910)
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.
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.
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/>.
17 #include "IODNSHandler.h"
18 #include "IODNSEngine.h"
20 struct IODNSQuery *first_dnsquery = NULL;
21 struct IODNSQuery *last_dnsquery = NULL;
22 int dnsquery_count = 0;
24 extern struct IODNSEngine dnsengine_cares;
25 extern struct IODNSEngine dnsengine_default;
27 struct IODNSEngine *dnsengine = NULL;
29 static void iodns_init_engine() {
33 if(dnsengine_cares.init && dnsengine_cares.init())
34 dnsengine = &dnsengine_cares;
35 else if(dnsengine_default.init && dnsengine_default.init())
36 dnsengine = &dnsengine_default;
38 iohandler_log(IOLOG_FATAL, "found no useable IO DNS engine");
43 static void iodns_append(struct IODNSQuery *query) {
44 IOSYNCHRONIZE(io_thread_sync);
46 query->prev = last_dnsquery;
47 last_dnsquery = query;
49 first_dnsquery = query;
51 IODESYNCHRONIZE(io_thread_sync);
54 static void iodns_remove(struct IODNSQuery *query) {
55 IOSYNCHRONIZE(io_thread_sync);
57 query->next->prev = query->prev;
59 last_dnsquery = query->prev;
61 query->prev->next = query->next;
63 first_dnsquery = query->next;
65 IODESYNCHRONIZE(io_thread_sync);
68 static void iodns_free(struct IODNSQuery *query) {
70 free(query->hostname);
71 if((query->type & IODNS_REVERSE) && query->address.addr)
72 free(query->addr.address);
76 struct IODNSQuery *iodns_getaddrinfo(char *hostname, int records, iodns_callback *callback) {
79 if(!(records & IODNS_FORWARD) || !hostname || !callback)
81 struct IODNSQuery *query = calloc(1, sizeof(*query));
82 query->hostname = strdup(hostname);
83 query->type = (records & IODNS_FORWARD);
84 query->callback = callback;
86 dnsengine->add(query);
90 struct IODNSQuery *iodns_getnameinfo(const struct sockaddr *addr, socklen_t addrlen, iodns_callback *callback) {
93 if(!addr || !callback)
95 struct IODNSQuery *query = calloc(1, sizeof(*query));
96 query->address = malloc(addrlen);
97 memcpy(query->addr.address, addr, addrlen);
98 query->addresslen = addrlen;
99 query->type = IODNS_RECORD_PTR;
100 query->callback = callback;
102 dnsengine->add(query);
106 void iodns_abort(struct IODNSQuery *query) {
107 if(!dnsengine || !query)
109 dnsengine->remove(query);
114 void iodns_event_callback(struct IODNSQuery *iodns, enum IODNSEventType state) {
115 struct IODNSEvent event;
118 dnsengine->remove(iodns);
121 iodns->callback(event);
130 void iodns_free_result(struct IODNSResult *result) {
131 struct IODNSResult *next;
132 for(;result;result = next) {
134 free(result->address);