X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FIODNSHandler.c;fp=src%2FIODNSHandler.c;h=1caebddd50d3841ad4494d4250ee5f62ed67e6da;hb=e18ef9b450a0704ff5c55545f70e3f1ec215a5e6;hp=0000000000000000000000000000000000000000;hpb=5ad65e65d2234b02151ea7ca17e3fa9893a9b165;p=IOMultiplexer.git diff --git a/src/IODNSHandler.c b/src/IODNSHandler.c new file mode 100644 index 0000000..1caebdd --- /dev/null +++ b/src/IODNSHandler.c @@ -0,0 +1,138 @@ +/* IODNSHandler.c - IOMultiplexer + * Copyright (C) 2012 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "IODNSHandler.h" +#include "IODNSEngine.h" + +struct IODNSQuery *first_dnsquery = NULL; +struct IODNSQuery *last_dnsquery = NULL; +int dnsquery_count = 0; + +extern struct IODNSEngine dnsengine_cares; +extern struct IODNSEngine dnsengine_default; + +struct IODNSEngine *dnsengine = NULL; + +static void iodns_init_engine() { + if(dnsengine) + return; + //try DNS engines + if(dnsengine_cares.init && dnsengine_cares.init()) + dnsengine = &dnsengine_cares; + else if(dnsengine_default.init && dnsengine_default.init()) + dnsengine = &dnsengine_default; + else { + iohandler_log(IOLOG_FATAL, "found no useable IO DNS engine"); + return; + } +} + +static void iodns_append(struct IODNSQuery *query) { + IOSYNCHRONIZE(io_thread_sync); + query->next = NULL; + query->prev = last_dnsquery; + last_dnsquery = query; + if(!first_dnsquery) + first_dnsquery = query; + dnsquery_count++; + IODESYNCHRONIZE(io_thread_sync); +} + +static void iodns_remove(struct IODNSQuery *query) { + IOSYNCHRONIZE(io_thread_sync); + if(query->next) + query->next->prev = query->prev; + else + last_dnsquery = query->prev; + if(query->prev) + query->prev->next = query->next; + else + first_dnsquery = query->next; + dnsquery_count--; + IODESYNCHRONIZE(io_thread_sync); +} + +static void iodns_free(struct IODNSQuery *query) { + if(query->hostname) + free(query->hostname); + if((query->type & IODNS_REVERSE) && query->address.addr) + free(query->addr.address); + free(query); +} + +struct IODNSQuery *iodns_getaddrinfo(char *hostname, int records, iodns_callback *callback) { + if(!dnsengine) + iodns_init_engine(); + if(!(records & IODNS_FORWARD) || !hostname || !callback) + return NULL; + struct IODNSQuery *query = calloc(1, sizeof(*query)); + query->hostname = strdup(hostname); + query->type = (records & IODNS_FORWARD); + query->callback = callback; + iodns_append(query); + dnsengine->add(query); + return query; +} + +struct IODNSQuery *iodns_getnameinfo(const struct sockaddr *addr, socklen_t addrlen, iodns_callback *callback) { + if(!dnsengine) + iodns_init_engine(); + if(!addr || !callback) + return NULL; + struct IODNSQuery *query = calloc(1, sizeof(*query)); + query->address = malloc(addrlen); + memcpy(query->addr.address, addr, addrlen); + query->addresslen = addrlen; + query->type = IODNS_RECORD_PTR; + query->callback = callback; + iodns_append(query); + dnsengine->add(query); + return query; +} + +void iodns_abort(struct IODNSQuery *query) { + if(!dnsengine || !query) + return; + dnsengine->remove(query); + iodns_remove(query); + iodns_free(query); +} + +void iodns_event_callback(struct IODNSQuery *iodns, enum IODNSEventType state) { + struct IODNSEvent event; + event.type = state; + event.query = iodns; + dnsengine->remove(iodns); + iodns_remove(iodns); + if(iodns->callback) + iodns->callback(event); + iodns_free(iodns); +} + +void iodns_poll() { + if(dnsengine) + dnsengine.loop(); +} + +void iodns_free_result(struct IODNSResult *result) { + struct IODNSResult *next; + for(;result;result = next) { + next = result->next; + free(result->address); + free(result); + } +} +