Mercurial > prosody-hg
comparison net/dns.lua @ 11200:bf8f2da84007
Merge 0.11->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 05 Nov 2020 22:31:25 +0100 |
| parents | 540f1bc5f082 |
| children | 05c250fa335a |
comparison
equal
deleted
inserted
replaced
| 11199:6c7c50a4de32 | 11200:bf8f2da84007 |
|---|---|
| 11 -- reference: http://tools.ietf.org/html/rfc1035 | 11 -- reference: http://tools.ietf.org/html/rfc1035 |
| 12 -- reference: http://tools.ietf.org/html/rfc1876 (LOC) | 12 -- reference: http://tools.ietf.org/html/rfc1876 (LOC) |
| 13 | 13 |
| 14 | 14 |
| 15 local socket = require "socket"; | 15 local socket = require "socket"; |
| 16 local timer = require "util.timer"; | 16 local have_timer, timer = pcall(require, "util.timer"); |
| 17 local new_ip = require "util.ip".new_ip; | 17 local new_ip = require "util.ip".new_ip; |
| 18 local have_util_net, util_net = pcall(require, "util.net"); | 18 local have_util_net, util_net = pcall(require, "util.net"); |
| 19 | |
| 20 local log = require "util.logger".init("dns"); | |
| 19 | 21 |
| 20 local _, windows = pcall(require, "util.windows"); | 22 local _, windows = pcall(require, "util.windows"); |
| 21 local is_windows = (_ and windows) or os.getenv("WINDIR"); | 23 local is_windows = (_ and windows) or os.getenv("WINDIR"); |
| 22 | 24 |
| 23 local coroutine, io, math, string, table = | 25 local coroutine, io, math, string, table = |
| 67 end | 69 end |
| 68 end; | 70 end; |
| 69 }; | 71 }; |
| 70 local get, set = ztact.get, ztact.set; | 72 local get, set = ztact.get, ztact.set; |
| 71 | 73 |
| 72 local default_timeout = 15; | 74 local default_timeout = 5; |
| 75 local default_jitter = 1; | |
| 76 local default_retry_jitter = 2; | |
| 73 | 77 |
| 74 -------------------------------------------------- module dns | 78 -------------------------------------------------- module dns |
| 75 local _ENV = nil; | 79 local _ENV = nil; |
| 76 -- luacheck: std none | 80 -- luacheck: std none |
| 77 local dns = {}; | 81 local dns = {}; |
| 662 | 666 |
| 663 | 667 |
| 664 -- socket layer -------------------------------------------------- socket layer | 668 -- socket layer -------------------------------------------------- socket layer |
| 665 | 669 |
| 666 | 670 |
| 667 resolver.delays = { 1, 3 }; | 671 resolver.delays = { 1, 2, 3, 5 }; |
| 668 | 672 |
| 673 resolver.jitter = have_timer and default_jitter or nil; | |
| 674 resolver.retry_jitter = have_timer and default_retry_jitter or nil; | |
| 669 | 675 |
| 670 function resolver:addnameserver(address) -- - - - - - - - - - addnameserver | 676 function resolver:addnameserver(address) -- - - - - - - - - - addnameserver |
| 671 self.server = self.server or {}; | 677 self.server = self.server or {}; |
| 672 append(self.server, address); | 678 append(self.server, address); |
| 673 end | 679 end |
| 851 --print ('query id', id, qclass, qtype, qname) | 857 --print ('query id', id, qclass, qtype, qname) |
| 852 local o = { | 858 local o = { |
| 853 packet = header..question, | 859 packet = header..question, |
| 854 server = self.best_server, | 860 server = self.best_server, |
| 855 delay = 1, | 861 delay = 1, |
| 856 retry = socket.gettime() + self.delays[1] | 862 retry = socket.gettime() + self.delays[1]; |
| 863 qclass = qclass; | |
| 864 qtype = qtype; | |
| 865 qname = qname; | |
| 857 }; | 866 }; |
| 858 | 867 |
| 859 -- remember the query | 868 -- remember the query |
| 860 self.active[id] = self.active[id] or {}; | 869 self.active[id] = self.active[id] or {}; |
| 861 self.active[id][question] = o; | 870 self.active[id][question] = o; |
| 862 | 871 |
| 863 local conn, err = self:getsocket(o.server) | 872 local conn, err = self:getsocket(o.server) |
| 864 if not conn then | 873 if not conn then |
| 865 return nil, err; | 874 return nil, err; |
| 866 end | 875 end |
| 867 conn:send (o.packet) | 876 if self.jitter then |
| 877 timer.add_task(math.random()*self.jitter, function () | |
| 878 conn:send(o.packet); | |
| 879 end); | |
| 880 else | |
| 881 conn:send(o.packet); | |
| 882 end | |
| 868 | 883 |
| 869 -- remember which coroutine wants the answer | 884 -- remember which coroutine wants the answer |
| 870 if co then | 885 if co then |
| 871 set(self.wanted, qclass, qtype, qname, co, true); | 886 set(self.wanted, qclass, qtype, qname, co, true); |
| 872 end | 887 end |
| 873 | 888 |
| 874 if timer and self.timeout then | 889 if have_timer and self.timeout then |
| 875 local num_servers = #self.server; | 890 local num_servers = #self.server; |
| 876 local i = 1; | 891 local i = 1; |
| 877 timer.add_task(self.timeout, function () | 892 timer.add_task(self.timeout, function () |
| 878 if get(self.wanted, qclass, qtype, qname, co) then | 893 if get(self.wanted, qclass, qtype, qname, co) then |
| 879 if i < num_servers then | 894 log("debug", "DNS request timeout %d/%d", i, num_servers) |
| 880 i = i + 1; | 895 i = i + 1; |
| 881 self:servfail(conn); | 896 self:servfail(self.socket[o.server]); |
| 882 o.server = self.best_server; | 897 -- end |
| 883 conn, err = self:getsocket(o.server); | 898 end |
| 884 if conn then | 899 -- Still outstanding? (i.e. retried) |
| 885 conn:send(o.packet); | 900 if get(self.wanted, qclass, qtype, qname, co) then |
| 886 return self.timeout; | 901 return self.timeout; -- Then wait |
| 887 end | |
| 888 end | |
| 889 -- Tried everything, failed | |
| 890 self:cancel(qclass, qtype, qname); | |
| 891 end | 902 end |
| 892 end) | 903 end) |
| 893 end | 904 end |
| 894 return true; | 905 return true; |
| 895 end | 906 end |
| 902 -- Socket is dead now | 913 -- Socket is dead now |
| 903 sock = self:voidsocket(sock); | 914 sock = self:voidsocket(sock); |
| 904 | 915 |
| 905 -- Find all requests to the down server, and retry on the next server | 916 -- Find all requests to the down server, and retry on the next server |
| 906 self.time = socket.gettime(); | 917 self.time = socket.gettime(); |
| 918 log("debug", "servfail %d (of %d)", num, #self.server); | |
| 907 for id,queries in pairs(self.active) do | 919 for id,queries in pairs(self.active) do |
| 908 for question,o in pairs(queries) do | 920 for question,o in pairs(queries) do |
| 909 if o.server == num then -- This request was to the broken server | 921 if o.server == num then -- This request was to the broken server |
| 910 o.server = o.server + 1 -- Use next server | 922 o.server = o.server + 1 -- Use next server |
| 911 if o.server > #self.server then | 923 if o.server > #self.server then |
| 912 o.server = 1; | 924 o.server = 1; |
| 913 end | 925 end |
| 914 | 926 |
| 915 o.retries = (o.retries or 0) + 1; | 927 o.retries = (o.retries or 0) + 1; |
| 916 if o.retries >= #self.server then | 928 local retried; |
| 917 --print('timeout'); | 929 if o.retries < #self.server then |
| 930 sock, err = self:getsocket(o.server); | |
| 931 if sock then | |
| 932 retried = true; | |
| 933 if self.retry_jitter then | |
| 934 local delay = self.delays[((o.retries-1)%#self.delays)+1] + (math.random()*self.retry_jitter); | |
| 935 log("debug", "retry %d in %0.2fs", o.retries, delay); | |
| 936 timer.add_task(delay, function () | |
| 937 sock:send(o.packet); | |
| 938 end); | |
| 939 else | |
| 940 log("debug", "retry %d (immediate)", o.retries); | |
| 941 sock:send(o.packet); | |
| 942 end | |
| 943 end | |
| 944 end | |
| 945 if not retried then | |
| 946 log("debug", 'tried all servers, giving up'); | |
| 947 self:cancel(o.qclass, o.qtype, o.qname); | |
| 918 queries[question] = nil; | 948 queries[question] = nil; |
| 919 else | |
| 920 sock, err = self:getsocket(o.server); | |
| 921 if sock then sock:send(o.packet); end | |
| 922 end | 949 end |
| 923 end | 950 end |
| 924 end | 951 end |
| 925 if next(queries) == nil then | 952 if next(queries) == nil then |
| 926 self.active[id] = nil; | 953 self.active[id] = nil; |
| 1162 return r; | 1189 return r; |
| 1163 end | 1190 end |
| 1164 | 1191 |
| 1165 local _resolver = dns.resolver(); | 1192 local _resolver = dns.resolver(); |
| 1166 dns._resolver = _resolver; | 1193 dns._resolver = _resolver; |
| 1194 _resolver.jitter, _resolver.retry_jitter = false, false; | |
| 1167 | 1195 |
| 1168 function dns.lookup(...) -- - - - - - - - - - - - - - - - - - - - - lookup | 1196 function dns.lookup(...) -- - - - - - - - - - - - - - - - - - - - - lookup |
| 1169 return _resolver:lookup(...); | 1197 return _resolver:lookup(...); |
| 1170 end | 1198 end |
| 1171 | 1199 |
