X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=net%2Fadns.lua;h=d3da2065526e7218afdffce097d2319d5523cd87;hb=59224f73ca26a00292f127e081af3cf47f57ae1f;hp=5d5a2256414bf2ee9f90d9a9f12e2b1a40f144c2;hpb=b4cb1e8079c6d93fdb6997327f06b8461244175b;p=prosody.git diff --git a/net/adns.lua b/net/adns.lua index 5d5a2256..d3da2065 100644 --- a/net/adns.lua +++ b/net/adns.lua @@ -1,7 +1,7 @@ -- Prosody IM -- Copyright (C) 2008-2010 Matthew Wild -- Copyright (C) 2008-2010 Waqas Hussain --- +-- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- @@ -14,9 +14,11 @@ local log = require "util.logger".init("adns"); local t_insert, t_remove = table.insert, table.remove; local coroutine, tostring, pcall = coroutine, tostring, pcall; -module "adns" +local function dummy_send(sock, data, i, j) return (j-i)+1; end + +local _ENV = nil; -function lookup(handler, qname, qtype, qclass) +local function lookup(handler, qname, qtype, qclass) return coroutine.wrap(function (peek) if peek then log("debug", "Records for %s already cached, using those...", qname); @@ -24,54 +26,70 @@ function lookup(handler, qname, qtype, qclass) return; end log("debug", "Records for %s not in cache, sending query (%s)...", qname, tostring(coroutine.running())); - dns.query(qname, qtype, qclass); - coroutine.yield({ qclass or "IN", qtype or "A", qname, coroutine.running()}); -- Wait for reply - log("debug", "Reply for %s (%s)", qname, tostring(coroutine.running())); - local ok, err = pcall(handler, dns.peek(qname, qtype, qclass)); + local ok, err = dns.query(qname, qtype, qclass); + if ok then + coroutine.yield({ qclass or "IN", qtype or "A", qname, coroutine.running()}); -- Wait for reply + log("debug", "Reply for %s (%s)", qname, tostring(coroutine.running())); + end + if ok then + ok, err = pcall(handler, dns.peek(qname, qtype, qclass)); + else + log("error", "Error sending DNS query: %s", err); + ok, err = pcall(handler, nil, err); + end if not ok then log("error", "Error in DNS response handler: %s", tostring(err)); end end)(dns.peek(qname, qtype, qclass)); end -function cancel(handle, call_handler) +local function cancel(handle, call_handler, reason) log("warn", "Cancelling DNS lookup for %s", tostring(handle[3])); - dns.cancel(handle); - if call_handler then - coroutine.resume(handle[4]); - end + dns.cancel(handle[1], handle[2], handle[3], handle[4], call_handler); end -function new_async_socket(sock, resolver) - local newconn, peername = {}, ""; +local function new_async_socket(sock, resolver) + local peername = ""; local listener = {}; - function listener.incoming(conn, data) - dns.feed(sock, data); + local handler = {}; + local err; + function listener.onincoming(conn, data) + if data then + dns.feed(handler, data); + end end - function listener.disconnect(conn, err) - log("warn", "DNS socket for %s disconnected: %s", peername, err); - local servers = resolver.server; - if resolver.socketset[newconn.handler] == resolver.best_server and resolver.best_server == #servers then - log("error", "Exhausted all %d configured DNS servers, next lookup will try %s again", #servers, servers[1]); + function listener.ondisconnect(conn, err) + if err then + log("warn", "DNS socket for %s disconnected: %s", peername, err); + local servers = resolver.server; + if resolver.socketset[conn] == resolver.best_server and resolver.best_server == #servers then + log("error", "Exhausted all %d configured DNS servers, next lookup will try %s again", #servers, servers[1]); + end + + resolver:servfail(conn); -- Let the magic commence end - - resolver:servfail(conn); -- Let the magic commence end - newconn.handler, newconn._socket = server.wrapclient(sock, "dns", 53, listener); - if not newconn.handler then - log("warn", "handler is nil"); + handler, err = server.wrapclient(sock, "dns", 53, listener); + if not handler then + return nil, err; end - if not newconn._socket then - log("warn", "socket is nil"); + + handler.settimeout = function () end + handler.setsockname = function (_, ...) return sock:setsockname(...); end + handler.setpeername = function (_, ...) peername = (...); local ret, err = sock:setpeername(...); _:set_send(dummy_send); return ret, err; end + handler.connect = function (_, ...) return sock:connect(...) end + --handler.send = function (_, data) _:write(data); return _.sendbuffer and _.sendbuffer(); end + handler.send = function (_, data) + log("debug", "Sending DNS query to %s", peername); + return sock:send(data); end - newconn.handler.settimeout = function () end - newconn.handler.setsockname = function (_, ...) return sock:setsockname(...); end - newconn.handler.setpeername = function (_, ...) peername = (...); local ret = sock:setpeername(...); _.setsend(sock.send); return ret; end - newconn.handler.connect = function (_, ...) return sock:connect(...) end - newconn.handler.send = function (_, data) _.write(data); return _.sendbuffer(); end - return newconn.handler; + return handler; end -dns:socket_wrapper_set(new_async_socket); +dns.socket_wrapper_set(new_async_socket); -return _M; +return { + lookup = lookup; + cancel = cancel; + new_async_socket = new_async_socket; +};