Blob Blame History Raw
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