6062da73990d2da998c5e1f400e2f43e9f0869f1
[prosody.git] / net / adns.lua
1 local server = require "net.server";
2 local dns = require "net.dns";
3
4 local log = require "util.logger".init("adns");
5
6 local coroutine, tostring, pcall = coroutine, tostring, pcall;
7
8 module "adns"
9
10 function lookup(handler, qname, qtype, qclass)
11         return coroutine.wrap(function (peek)
12                                 if peek then
13                                         log("debug", "Records for %s already cached, using those...", qname);
14                                         handler(peek);
15                                         return;
16                                 end
17                                 log("debug", "Records for %s not in cache, sending query (%s)...", qname, tostring(coroutine.running()));
18                                 dns.query(qname, qtype, qclass);
19                                 coroutine.yield({ qclass or "IN", qtype or "A", qname, coroutine.running()}); -- Wait for reply
20                                 log("debug", "Reply for %s (%s)", qname, tostring(coroutine.running()));
21                                 local ok, err = pcall(handler, dns.peek(qname, qtype, qclass));
22                                 if not ok then
23                                         log("debug", "Error in DNS response handler: %s", tostring(err));
24                                 end
25                         end)(dns.peek(qname, qtype, qclass));
26 end
27
28 function cancel(handle, call_handler)
29         dns.cancel(handle);
30         if call_handler then
31                 handle[4]()
32         end
33 end
34
35 function new_async_socket(sock)
36         local newconn = {};
37         local listener = {};
38         function listener.incoming(conn, data)
39                 dns.feed(sock, data);
40         end
41         function listener.disconnect()
42         end
43         newconn.handler, newconn._socket = server.wrapclient(sock, "dns", 53, listener);
44         newconn.handler.settimeout = function () end
45         newconn.handler.setsockname = function (_, ...) return sock:setsockname(...); end
46         newconn.handler.setpeername = function (_, ...) local ret = sock:setpeername(...); _.setsend(sock.send); return ret; end
47         newconn.handler.connect = function (_, ...) return sock:connect(...) end        
48         newconn.handler.send = function (_, data) _.write(data); return _.sendbuffer(); end     
49         return newconn.handler;
50 end
51
52 dns:socket_wrapper_set(new_async_socket);
53
54 return _M;