Backport of upstream ticket "DNS lacks IPv6 support" (https://prosody.im/issues/issue/352)
using:
- https://hg.prosody.im/0.10/rev/e108c3f97f26
- https://hg.prosody.im/0.10/rev/0200945313c9
- https://hg.prosody.im/0.10/rev/6eebd5808fbc
--- prosody-0.9.8/net/dns.lua 2015-03-24 20:18:04.000000000 +0100
+++ prosody-0.9.8/net/dns.lua.dns-ipv6 2015-09-11 21:46:39.000000000 +0200
@@ -14,6 +14,7 @@
local socket = require "socket";
local timer = require "util.timer";
+local new_ip = require "util.ip".new_ip;
local _, windows = pcall(require, "util.windows");
local is_windows = (_ and windows) or os.getenv("WINDIR");
@@ -599,11 +600,12 @@
if resolv_conf then
for line in resolv_conf:lines() do
line = line:gsub("#.*$", "")
- :match('^%s*nameserver%s+(.*)%s*$');
+ :match('^%s*nameserver%s+([%x:%.]*)%s*$');
if line then
- line:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]", function (address)
- self:addnameserver(address)
- end);
+ local ip = new_ip(line);
+ if ip then
+ self:addnameserver(ip.addr);
+ end
end
end
end
@@ -623,7 +625,12 @@
if sock then return sock; end
local ok, err;
- sock, err = socket.udp();
+ local peer = self.server[servernum];
+ if peer:find(":") then
+ sock, err = socket.udp6();
+ else
+ sock, err = socket.udp();
+ end
if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end
if not sock then
return nil, err;
@@ -636,7 +643,7 @@
-- if so, try the next server
ok, err = sock:setsockname('*', 0);
if not ok then return self:servfail(sock, err); end
- ok, err = sock:setpeername(self.server[servernum], 53);
+ sock:setpeername(peer, 53);
if not ok then return self:servfail(sock, err); end
return sock;
end
--- prosody-0.9.8/util/ip.lua 2015-03-24 20:18:04.000000000 +0100
+++ prosody-0.9.8/util/ip.lua.dns-ipv6 2015-09-11 21:42:26.000000000 +0200
@@ -12,7 +12,17 @@
local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011", ["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111", ["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011", ["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111" };
local function new_ip(ipStr, proto)
- if proto ~= "IPv4" and proto ~= "IPv6" then
+ if not proto then
+ local sep = ipStr:match("^%x+(.)");
+ if sep == ":" or (not(sep) and ipStr:sub(1,1) == ":") then
+ proto = "IPv6"
+ elseif sep == "." then
+ proto = "IPv4"
+ end
+ if not proto then
+ return nil, "invalid address";
+ end
+ elseif proto ~= "IPv4" and proto ~= "IPv6" then
return nil, "invalid protocol";
end
if proto == "IPv6" and ipStr:find('.', 1, true) then