[IOMultiplexer] Added asynchronous DNS Lookups
[IOMultiplexer.git] / src / IODNSEngine_default.c
diff --git a/src/IODNSEngine_default.c b/src/IODNSEngine_default.c
new file mode 100644 (file)
index 0000000..89427ec
--- /dev/null
@@ -0,0 +1,89 @@
+/* IODNSEngine_default.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 <http://www.gnu.org/licenses/>. 
+ */
+#include "IODNSEngine.h"
+
+static int dnsengine_default_init() {
+    return 1;
+}
+
+static void dnsengine_default_add(struct IODNSQuery *iodns) {
+    /* unused */
+}
+
+static void dnsengine_default_remove(struct IODNSQuery *iodns) {
+    /* unused */
+}
+
+static void dnsengine_default_loop() {
+    enum IODNSEventType querystate;
+    struct addrinfo hints, *res, *next_res;
+    struct IODNSQuery *iodns, *next_iodns;
+    struct IODNSResult *dnsresult;
+    for(iodns = first_dnsquery; iodns; iodns = next_iodns) {
+        next_iodns = iodns->next;
+        querystate = IODNSEVENT_FAILED;
+        
+        if((iodns->type & IODNS_FORWARD)) {
+            memset (&hints, 0, sizeof (hints));
+            hints.ai_family = PF_UNSPEC;
+            hints.ai_socktype = SOCK_STREAM;
+            hints.ai_flags |= AI_CANONNAME;
+            if (!getaddrinfo(iodns->hostname, NULL, &hints, &res)) {
+                while (res) {
+                    switch (res->ai_family) {
+                    case AF_INET:
+                        if((iodns->type & IODNS_RECORD_A)) {
+                            dnsresult = malloc(sizeof(*dnsresult));
+                            dnsresult->type = IODNS_RECORD_A;
+                            dnsresult->addresslen = res->ai_addrlen;
+                            dnsresult->address = malloc(dnsresult->addresslen);
+                            memcpy(dnsresult->address, res->ai_addr, dnsresult->addresslen);
+                            dnsresult->next = iodns->addr.results;
+                            iodns->addr.results = dnsresult;
+                            querystate = IODNSEVENT_SUCCESS;
+                        }
+                        break;
+                    case AF_INET6:
+                        if((iodns->type & IODNS_RECORD_AAAA)) {
+                            dnsresult = malloc(sizeof(*dnsresult));
+                            dnsresult->type = IODNS_RECORD_AAAA;
+                            dnsresult->addresslen = res->ai_addrlen;
+                            dnsresult->address = malloc(dnsresult->addresslen);
+                            memcpy(dnsresult->address, res->ai_addr, dnsresult->addresslen);
+                            dnsresult->next = iodns->addr.results;
+                            iodns->addr.results = dnsresult;
+                            querystate = IODNSEVENT_SUCCESS;
+                        }
+                        break;
+                    }
+                    next_res = res->ai_next;
+                    freeaddrinfo(res);
+                    res = next_res;
+                }
+            }
+            iodns_event_callback(iodns, querystate);
+        }
+    }
+}
+
+struct IODNSEngine dnsengine_default = {
+    .name = "default",
+    .init = dnsengine_default_init,
+    .add = dnsengine_default_add,
+    .remove = dnsengine_default_remove,
+    .loop = dnsengine_default_loop,
+};