Software /
code /
prosody
Comparison
net/dns.lua @ 1786:4016d8bc30b8
net.dns: Multiple internal changes and API extensions to allow for more reliable DNS lookups
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 18 Sep 2009 02:45:15 +0100 |
parent | 1523:841d61be198f |
child | 1788:45779d67c26c |
child | 1805:7e41ad68fe3c |
comparison
equal
deleted
inserted
replaced
1785:17c0fb598c97 | 1786:4016d8bc30b8 |
---|---|
15 | 15 |
16 | 16 |
17 require 'socket' | 17 require 'socket' |
18 local ztact = require 'util.ztact' | 18 local ztact = require 'util.ztact' |
19 local require = require | 19 local require = require |
20 local os = os; | |
20 | 21 |
21 local coroutine, io, math, socket, string, table = | 22 local coroutine, io, math, socket, string, table = |
22 coroutine, io, math, socket, string, table | 23 coroutine, io, math, socket, string, table |
23 | 24 |
24 local ipairs, next, pairs, print, setmetatable, tostring, assert, error, unpack = | 25 local ipairs, next, pairs, print, setmetatable, tostring, assert, error, unpack = |
485 | 486 |
486 | 487 |
487 -- socket layer -------------------------------------------------- socket layer | 488 -- socket layer -------------------------------------------------- socket layer |
488 | 489 |
489 | 490 |
490 resolver.delays = { 1, 3, 11, 45 } | 491 resolver.delays = { 1, 3 } |
491 | 492 |
492 | 493 |
493 function resolver:addnameserver (address) -- - - - - - - - - - addnameserver | 494 function resolver:addnameserver (address) -- - - - - - - - - - addnameserver |
494 self.server = self.server or {} | 495 self.server = self.server or {} |
495 append (self.server, address) | 496 append (self.server, address) |
507 if resolv_conf then | 508 if resolv_conf then |
508 for line in resolv_conf:lines() do | 509 for line in resolv_conf:lines() do |
509 local address = string.match (line, 'nameserver%s+(%d+%.%d+%.%d+%.%d+)') | 510 local address = string.match (line, 'nameserver%s+(%d+%.%d+%.%d+%.%d+)') |
510 if address then self:addnameserver (address) end | 511 if address then self:addnameserver (address) end |
511 end | 512 end |
512 else -- FIXME correct for windows, using opendns nameservers for now | 513 elseif os.getenv("WINDIR") then |
513 self:addnameserver ("208.67.222.222") | 514 self:addnameserver ("208.67.222.222") |
514 self:addnameserver ("208.67.220.220") | 515 self:addnameserver ("208.67.220.220") |
516 end | |
517 if not self.server or #self.server == 0 then | |
518 self:addnameserver("127.0.0.1"); | |
515 end | 519 end |
516 end | 520 end |
517 | 521 |
518 | 522 |
519 function resolver:getsocket (servernum) -- - - - - - - - - - - - - getsocket | 523 function resolver:getsocket (servernum) -- - - - - - - - - - - - - getsocket |
523 | 527 |
524 local sock = self.socket[servernum] | 528 local sock = self.socket[servernum] |
525 if sock then return sock end | 529 if sock then return sock end |
526 | 530 |
527 sock = socket.udp () | 531 sock = socket.udp () |
528 if self.socket_wrapper then sock = self.socket_wrapper (sock) end | 532 if self.socket_wrapper then sock = self.socket_wrapper (sock, self) end |
529 sock:settimeout (0) | 533 sock:settimeout (0) |
530 -- todo: attempt to use a random port, fallback to 0 | 534 -- todo: attempt to use a random port, fallback to 0 |
531 sock:setsockname ('*', 0) | 535 sock:setsockname ('*', 0) |
532 sock:setpeername (self.server[servernum], 53) | 536 sock:setpeername (self.server[servernum], 53) |
533 self.socket[servernum] = sock | 537 self.socket[servernum] = sock |
534 self.socketset[sock] = sock | 538 self.socketset[sock] = servernum |
535 return sock | 539 return sock |
536 end | 540 end |
537 | 541 |
542 function resolver:voidsocket (sock) | |
543 if self.socket[sock] then | |
544 self.socketset[self.socket[sock]] = nil | |
545 self.socket[sock] = nil | |
546 elseif self.socketset[sock] then | |
547 self.socket[self.socketset[sock]] = nil | |
548 self.socketset[sock] = nil | |
549 end | |
550 end | |
538 | 551 |
539 function resolver:socket_wrapper_set (func) -- - - - - - - socket_wrapper_set | 552 function resolver:socket_wrapper_set (func) -- - - - - - - socket_wrapper_set |
540 self.socket_wrapper = func | 553 self.socket_wrapper = func |
541 end | 554 end |
542 | 555 |
606 if peek then return peek end | 619 if peek then return peek end |
607 | 620 |
608 local header, id = encodeHeader () | 621 local header, id = encodeHeader () |
609 --print ('query id', id, qclass, qtype, qname) | 622 --print ('query id', id, qclass, qtype, qname) |
610 local o = { packet = header..question, | 623 local o = { packet = header..question, |
611 server = 1, | 624 server = self.best_server, |
612 delay = 1, | 625 delay = 1, |
613 retry = socket.gettime () + self.delays[1] } | 626 retry = socket.gettime () + self.delays[1] } |
614 self:getsocket (o.server):send (o.packet) | |
615 | 627 |
616 -- remember the query | 628 -- remember the query |
617 self.active[id] = self.active[id] or {} | 629 self.active[id] = self.active[id] or {} |
618 self.active[id][question] = o | 630 self.active[id][question] = o |
619 | 631 |
621 local co = coroutine.running () | 633 local co = coroutine.running () |
622 if co then | 634 if co then |
623 set (self.wanted, qclass, qtype, qname, co, true) | 635 set (self.wanted, qclass, qtype, qname, co, true) |
624 --set (self.yielded, co, qclass, qtype, qname, true) | 636 --set (self.yielded, co, qclass, qtype, qname, true) |
625 end | 637 end |
638 | |
639 self:getsocket (o.server):send (o.packet) | |
640 | |
626 end | 641 end |
627 | 642 |
628 | 643 function resolver:servfail(sock) |
644 -- Resend all queries for this server | |
645 | |
646 local num = self.socketset[sock] | |
647 | |
648 -- Socket is dead now | |
649 self:voidsocket(sock); | |
650 | |
651 -- Find all requests to the down server, and retry on the next server | |
652 self.time = socket.gettime () | |
653 for id,queries in pairs (self.active) do | |
654 for question,o in pairs (queries) do | |
655 if o.server == num then -- This request was to the broken server | |
656 o.server = o.server + 1 -- Use next server | |
657 if o.server > #self.server then | |
658 o.server = 1 | |
659 end | |
660 | |
661 o.retries = (o.retries or 0) + 1; | |
662 if o.retries >= #self.server then | |
663 --print ('timeout') | |
664 queries[question] = nil | |
665 else | |
666 local _a = self:getsocket(o.server); | |
667 if _a then _a:send (o.packet) end | |
668 end | |
669 end | |
670 end | |
671 end | |
672 | |
673 if num == self.best_server then | |
674 self.best_server = self.best_server + 1 | |
675 if self.best_server > #self.server then | |
676 -- Exhausted all servers, try first again | |
677 self.best_server = 1 | |
678 end | |
679 end | |
680 end | |
629 | 681 |
630 function resolver:receive (rset) -- - - - - - - - - - - - - - - - - receive | 682 function resolver:receive (rset) -- - - - - - - - - - - - - - - - - receive |
631 | 683 |
632 --print 'receive' print (self.socket) | 684 --print 'receive' print (self.socket) |
633 self.time = socket.gettime () | 685 self.time = socket.gettime () |
826 | 878 |
827 function dns.resolver () -- - - - - - - - - - - - - - - - - - - - - resolver | 879 function dns.resolver () -- - - - - - - - - - - - - - - - - - - - - resolver |
828 | 880 |
829 -- this function seems to be redundant with resolver.new () | 881 -- this function seems to be redundant with resolver.new () |
830 | 882 |
831 local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {} } | 883 local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {}, |
884 best_server = 1 } | |
832 setmetatable (r, resolver) | 885 setmetatable (r, resolver) |
833 setmetatable (r.cache, cache_metatable) | 886 setmetatable (r.cache, cache_metatable) |
834 setmetatable (r.unsorted, { __mode = 'kv' }) | 887 setmetatable (r.unsorted, { __mode = 'kv' }) |
835 return r | 888 return r |
836 end | 889 end |