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