aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mod_admin_adhoc.lua85
-rw-r--r--plugins/mod_admin_telnet.lua22
-rw-r--r--plugins/mod_c2s.lua27
-rw-r--r--plugins/mod_dialback.lua2
-rw-r--r--plugins/mod_iq.lua5
-rw-r--r--plugins/mod_message.lua11
-rw-r--r--plugins/mod_presence.lua10
-rw-r--r--plugins/mod_s2s/mod_s2s.lua61
-rw-r--r--plugins/mod_s2s/s2sout.lib.lua129
9 files changed, 197 insertions, 155 deletions
diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua
index b8cb0637..ee89d84f 100644
--- a/plugins/mod_admin_adhoc.lua
+++ b/plugins/mod_admin_adhoc.lua
@@ -27,6 +27,14 @@ local modulemanager = require "modulemanager";
module:depends("adhoc");
local adhoc_new = module:require "adhoc".new;
+local function generate_error_message(errors)
+ local errmsg = {};
+ for name, err in pairs(errors) do
+ errmsg[#errmsg + 1] = name .. ": " .. err;
+ end
+ return { status = "completed", error = { message = t_concat(errmsg, "\n") } };
+end
+
function add_user_command_handler(self, data, state)
local add_user_layout = dataforms_new{
title = "Adding a User";
@@ -42,9 +50,9 @@ function add_user_command_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = add_user_layout:data(data.form);
- if not fields.accountjid then
- return { status = "completed", error = { message = "You need to specify a JID." } };
+ local fields, err = add_user_layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
local username, host, resource = jid.split(fields.accountjid);
if data.to ~= host then
@@ -85,9 +93,9 @@ function change_user_password_command_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = change_user_password_layout:data(data.form);
- if not fields.accountjid or fields.accountjid == "" or not fields.password then
- return { status = "completed", error = { message = "Please specify username and password" } };
+ local fields, err = change_user_password_layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
local username, host, resource = jid.split(fields.accountjid);
if data.to ~= host then
@@ -126,7 +134,10 @@ function delete_user_command_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = delete_user_layout:data(data.form);
+ local fields, err = delete_user_layout:data(data.form);
+ if err then
+ return generate_error_message(err);
+ end
local failed = {};
local succeeded = {};
for _, aJID in ipairs(fields.accountjids) do
@@ -175,7 +186,10 @@ function end_user_session_handler(self, data, state)
return { status = "canceled" };
end
- local fields = end_user_session_layout:data(data.form);
+ local fields, err = end_user_session_layout:data(data.form);
+ if err then
+ return generate_error_message(err);
+ end
local failed = {};
local succeeded = {};
for _, aJID in ipairs(fields.accountjids) do
@@ -223,9 +237,9 @@ function get_user_password_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = get_user_password_layout:data(data.form);
- if not fields.accountjid then
- return { status = "completed", error = { message = "Please specify a JID." } };
+ local fields, err = get_user_password_layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
local user, host, resource = jid.split(fields.accountjid);
local accountjid = "";
@@ -261,10 +275,10 @@ function get_user_roster_handler(self, data, state)
return { status = "canceled" };
end
- local fields = get_user_roster_layout:data(data.form);
+ local fields, err = get_user_roster_layout:data(data.form);
- if not fields.accountjid then
- return { status = "completed", error = { message = "Please specify a JID" } };
+ if err then
+ return generate_error_message(err);
end
local user, host, resource = jid.split(fields.accountjid);
@@ -323,10 +337,10 @@ function get_user_stats_handler(self, data, state)
return { status = "canceled" };
end
- local fields = get_user_stats_layout:data(data.form);
+ local fields, err = get_user_stats_layout:data(data.form);
- if not fields.accountjid then
- return { status = "completed", error = { message = "Please specify a JID." } };
+ if err then
+ return generate_error_message(err);
end
local user, host, resource = jid.split(fields.accountjid);
@@ -376,7 +390,11 @@ function get_online_users_command_handler(self, data, state)
return { status = "canceled" };
end
- local fields = get_online_users_layout:data(data.form);
+ local fields, err = get_online_users_layout:data(data.form);
+
+ if err then
+ return generate_error_message(err);
+ end
local max_items = nil
if fields.max_items ~= "all" then
@@ -436,11 +454,9 @@ function load_module_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = layout:data(data.form);
- if (not fields.module) or (fields.module == "") then
- return { status = "completed", error = {
- message = "Please specify a module."
- } };
+ local fields, err = layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
if modulemanager.is_loaded(data.to, fields.module) then
return { status = "completed", info = "Module already loaded" };
@@ -453,7 +469,6 @@ function load_module_handler(self, data, state)
'". Error was: "'..tostring(err or "<unspecified>")..'"' } };
end
else
- local modules = array.collect(keys(hosts[data.to].modules)):sort();
return { status = "executing", form = layout }, "executing";
end
end
@@ -470,11 +485,9 @@ function reload_modules_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = layout:data(data.form);
- if #fields.modules == 0 then
- return { status = "completed", error = {
- message = "Please specify a module. (This means your client misbehaved, as this field is required)"
- } };
+ local fields, err = layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
local ok_list, err_list = {}, {};
for _, module in ipairs(fields.modules) do
@@ -538,7 +551,11 @@ function shut_down_service_handler(self, data, state)
return { status = "canceled" };
end
- local fields = shut_down_service_layout:data(data.form);
+ local fields, err = shut_down_service_layout:data(data.form);
+
+ if err then
+ return generate_error_message(err);
+ end
if fields.announcement and #fields.announcement > 0 then
local message = st.message({type = "headline"}, fields.announcement):up()
@@ -566,11 +583,9 @@ function unload_modules_handler(self, data, state)
if data.action == "cancel" then
return { status = "canceled" };
end
- local fields = layout:data(data.form);
- if #fields.modules == 0 then
- return { status = "completed", error = {
- message = "Please specify a module. (This means your client misbehaved, as this field is required)"
- } };
+ local fields, err = layout:data(data.form);
+ if err then
+ return generate_error_message(err);
end
local ok_list, err_list = {}, {};
for _, module in ipairs(fields.modules) do
diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua
index 3390d62e..faf255da 100644
--- a/plugins/mod_admin_telnet.lua
+++ b/plugins/mod_admin_telnet.lua
@@ -76,22 +76,22 @@ end
function console_listener.onincoming(conn, data)
local session = sessions[conn];
- -- Handle data
- (function(session, data)
+ -- Handle data (loop allows us to break to add \0 after response)
+ repeat
local useglobalenv;
-
+
if data:match("^>") then
data = data:gsub("^>", "");
useglobalenv = true;
elseif data == "\004" then
commands["bye"](session, data);
- return;
+ break;
else
local command = data:lower();
command = data:match("^%w+") or data:match("%p");
if commands[command] then
commands[command](session, data);
- return;
+ break;
end
end
@@ -106,7 +106,7 @@ function console_listener.onincoming(conn, data)
err = err:gsub("^:%d+: ", "");
err = err:gsub("'<eof>'", "the end of the line");
session.print("Sorry, I couldn't understand that... "..err);
- return;
+ break;
end
end
@@ -116,26 +116,26 @@ function console_listener.onincoming(conn, data)
if not (ranok or message or useglobalenv) and commands[data:lower()] then
commands[data:lower()](session, data);
- return;
+ break;
end
if not ranok then
session.print("Fatal error while running command, it did not complete");
session.print("Error: "..taskok);
- return;
+ break;
end
if not message then
session.print("Result: "..tostring(taskok));
- return;
+ break;
elseif (not taskok) and message then
session.print("Command completed with a problem");
session.print("Message: "..tostring(message));
- return;
+ break;
end
session.print("OK: "..tostring(message));
- end)(session, data);
+ until true
session.send(string.char(0));
end
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua
index 55c53e2d..75a6f689 100644
--- a/plugins/mod_c2s.lua
+++ b/plugins/mod_c2s.lua
@@ -24,6 +24,7 @@ local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams";
local log = module._log;
local c2s_timeout = module:get_option_number("c2s_timeout");
+local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5);
local opt_keepalives = module:get_option_boolean("tcp_keepalives", false);
local sessions = module:shared("sessions");
@@ -143,8 +144,27 @@ local function session_close(session, reason)
end
end
session.send("</stream:stream>");
- session.conn:close();
- listener.ondisconnect(session.conn, (reason and (reason.text or reason.condition)) or reason or "session closed");
+
+ function session.send() return false; end
+
+ local reason = (reason and (reason.text or reason.condition)) or reason or "session closed";
+ session.log("info", "c2s stream for %s closed: %s", session.full_jid or ("<"..session.ip..">"), reason);
+
+ -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote
+ local conn = session.conn;
+ if reason == "session closed" and not session.notopen and session.type == "c2s" then
+ -- Grace time to process data from authenticated cleanly-closed stream
+ add_task(stream_close_timeout, function ()
+ if not session.destroyed then
+ session.log("warn", "Failed to receive a stream close response, closing connection anyway...");
+ sm_destroy_session(session, reason);
+ conn:close();
+ end
+ end);
+ else
+ sm_destroy_session(session, reason);
+ conn:close();
+ end
end
end
@@ -208,10 +228,9 @@ end
function listener.ondisconnect(conn, err)
local session = sessions[conn];
if session then
- (session.log or log)("info", "Client disconnected: %s", err);
+ (session.log or log)("info", "Client disconnected: %s", err or "connection closed");
sm_destroy_session(session, err);
sessions[conn] = nil;
- session = nil;
end
end
diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua
index 2299c0dc..67be15e3 100644
--- a/plugins/mod_dialback.lua
+++ b/plugins/mod_dialback.lua
@@ -84,7 +84,7 @@ module:hook("stanza/jabber:server:dialback:result", function(event)
origin.from_host = from;
end
if not origin.to_host then
- origin.to_host = nameprep(attr.to);
+ origin.to_host = to;
end
origin.log("debug", "asking %s if key %s belongs to them", from, stanza[1]);
diff --git a/plugins/mod_iq.lua b/plugins/mod_iq.lua
index 6412ad11..8044a533 100644
--- a/plugins/mod_iq.lua
+++ b/plugins/mod_iq.lua
@@ -17,10 +17,7 @@ if module:get_host_type() == "local" then
local origin, stanza = data.origin, data.stanza;
local session = full_sessions[stanza.attr.to];
- if session then
- -- TODO fire post processing event
- session.send(stanza);
- else -- resource not online
+ if not (session and session.send(stanza)) then
if stanza.attr.type == "get" or stanza.attr.type == "set" then
origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
end
diff --git a/plugins/mod_message.lua b/plugins/mod_message.lua
index ebff2fe7..0b0ad8e4 100644
--- a/plugins/mod_message.lua
+++ b/plugins/mod_message.lua
@@ -35,10 +35,13 @@ local function process_to_bare(bare, origin, stanza)
if user then -- some resources are connected
local recipients = user.top_resources;
if recipients then
+ local sent;
for i=1,#recipients do
- recipients[i].send(stanza);
+ sent = recipients[i].send(stanza) or sent;
+ end
+ if sent then
+ return true;
end
- return true;
end
end
-- no resources are online
@@ -65,9 +68,7 @@ module:hook("message/full", function(data)
local origin, stanza = data.origin, data.stanza;
local session = full_sessions[stanza.attr.to];
- if session then
- -- TODO fire post processing event
- session.send(stanza);
+ if session and session.send(stanza) then
return true;
else -- resource not online
return process_to_bare(jid_bare(stanza.attr.to), origin, stanza);
diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua
index 6d039d83..09a6f9f2 100644
--- a/plugins/mod_presence.lua
+++ b/plugins/mod_presence.lua
@@ -352,13 +352,15 @@ module:hook("resource-unbind", function(event)
-- Send unavailable presence
if session.presence then
local pres = st.presence{ type = "unavailable" };
- if not(err) or err == "closed" then err = "connection closed"; end
- pres:tag("status"):text("Disconnected: "..err):up();
+ if err then
+ pres:tag("status"):text("Disconnected: "..err):up();
+ end
session:dispatch_stanza(pres);
elseif session.directed then
local pres = st.presence{ type = "unavailable", from = session.full_jid };
- if not(err) or err == "closed" then err = "connection closed"; end
- pres:tag("status"):text("Disconnected: "..err):up();
+ if err then
+ pres:tag("status"):text("Disconnected: "..err):up();
+ end
for jid in pairs(session.directed) do
pres.attr.to = jid;
core_post_stanza(session, pres, true);
diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua
index f6c20606..f686fcfb 100644
--- a/plugins/mod_s2s/mod_s2s.lua
+++ b/plugins/mod_s2s/mod_s2s.lua
@@ -31,6 +31,7 @@ local cert_verify_identity = require "util.x509".verify_identity;
local s2sout = module:require("s2sout");
local connect_timeout = module:get_option_number("s2s_timeout", 60);
+local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5);
local sessions = module:shared("sessions");
@@ -97,9 +98,10 @@ function route_to_existing_session(event)
log("error", "WARNING! This might, possibly, be a bug, but it might not...");
log("error", "We are going to send from %s instead of %s", tostring(host.from_host), tostring(from_host));
end
- host.sends2s(stanza);
- host.log("debug", "stanza sent over "..host.type);
- return true;
+ if host.sends2s(stanza) then
+ host.log("debug", "stanza sent over "..host.type);
+ return true;
+ end
end
end
end
@@ -291,18 +293,6 @@ function stream_callbacks.streamclosed(session)
session:close();
end
-function stream_callbacks.streamdisconnected(session, err)
- if err and err ~= "closed" and session.direction == "outgoing" and session.notopen then
- (session.log or log)("debug", "s2s connection attempt failed: %s", err);
- if s2sout.attempt_connection(session, err) then
- (session.log or log)("debug", "...so we're going to try another target");
- return true; -- Session lives for now
- end
- end
- (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed"));
- s2s_destroy_session(session, err);
-end
-
function stream_callbacks.error(session, error, data)
if error == "no-stream" then
session:close("invalid-namespace");
@@ -374,11 +364,26 @@ local function session_close(session, reason, remote_reason)
end
end
session.sends2s("</stream:stream>");
- if session.notopen or not session.conn:close() then
- session.conn:close(true); -- Force FIXME: timer?
+
+ function session.sends2s() return false; end
+
+ local reason = remote_reason or (reason and (reason.text or reason.condition)) or reason or "stream closed";
+ session.log("info", "%s s2s stream %s->%s closed: %s", session.direction, session.from_host or "(unknown host)", session.to_host or "(unknown host)", reason);
+
+ -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote
+ local conn = session.conn;
+ if not session.notopen and session.type == "s2sin" then
+ add_task(stream_close_timeout, function ()
+ if not session.destroyed then
+ session.log("warn", "Failed to receive a stream close response, closing connection anyway...");
+ s2s_destroy_session(session, reason);
+ conn:close();
+ end
+ end);
+ else
+ s2s_destroy_session(session, reason);
+ conn:close(); -- Close immediately, as this is an outgoing connection or is not authed
end
- session.conn:close();
- listener.ondisconnect(session.conn, remote_reason or (reason and (reason.text or reason.condition)) or reason or "stream closed");
end
end
@@ -413,11 +418,9 @@ local function initialize_session(session)
return handlestanza(session, stanza);
end
- local conn = session.conn;
add_task(connect_timeout, function ()
- if session.conn ~= conn or session.connecting
- or session.type == "s2sin" or session.type == "s2sout" then
- return; -- Ok, we're connect[ed|ing]
+ if session.type == "s2sin" or session.type == "s2sout" then
+ return; -- Ok, we're connected
end
-- Not connected, need to close session and clean up
(session.log or log)("debug", "Destroying incomplete session %s->%s due to inactivity",
@@ -474,11 +477,17 @@ end
function listener.ondisconnect(conn, err)
local session = sessions[conn];
if session then
- if stream_callbacks.streamdisconnected(session, err) then
- return; -- Connection lives, for now
+ if err and session.direction == "outgoing" and session.notopen then
+ (session.log or log)("debug", "s2s connection attempt failed: %s", err);
+ if s2sout.attempt_connection(session, err) then
+ (session.log or log)("debug", "...so we're going to try another target");
+ return; -- Session lives for now
+ end
end
+ (session.log or log)("debug", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "connection closed"));
+ s2s_destroy_session(session, err);
+ sessions[conn] = nil;
end
- sessions[conn] = nil;
end
function listener.register_outgoing(conn, session)
diff --git a/plugins/mod_s2s/s2sout.lib.lua b/plugins/mod_s2s/s2sout.lib.lua
index 48a49036..d2c6023e 100644
--- a/plugins/mod_s2s/s2sout.lib.lua
+++ b/plugins/mod_s2s/s2sout.lib.lua
@@ -170,92 +170,91 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err)
local IPs = {};
host_session.ip_hosts = IPs;
local handle4, handle6;
- local has_other = false;
+ local have_other_result = not(has_ipv4) or not(has_ipv6) or false;
if has_ipv4 then
- handle4 = adns.lookup(function (reply, err)
- handle4 = nil;
-
- -- COMPAT: This is a compromise for all you CNAME-(ab)users :)
- if not (reply and reply[#reply] and reply[#reply].a) then
- local count = max_dns_depth;
- reply = dns.peek(connect_host, "CNAME", "IN");
- while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do
- log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count);
- reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN");
- count = count - 1;
+ handle4 = adns.lookup(function (reply, err)
+ handle4 = nil;
+
+ -- COMPAT: This is a compromise for all you CNAME-(ab)users :)
+ if not (reply and reply[#reply] and reply[#reply].a) then
+ local count = max_dns_depth;
+ reply = dns.peek(connect_host, "CNAME", "IN");
+ while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do
+ log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count);
+ reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN");
+ count = count - 1;
+ end
end
- end
- -- end of CNAME resolving
+ -- end of CNAME resolving
- if reply and reply[#reply] and reply[#reply].a then
- for _, ip in ipairs(reply) do
- log("debug", "DNS reply for %s gives us %s", connect_host, ip.a);
- IPs[#IPs+1] = new_ip(ip.a, "IPv4");
+ if reply and reply[#reply] and reply[#reply].a then
+ for _, ip in ipairs(reply) do
+ log("debug", "DNS reply for %s gives us %s", connect_host, ip.a);
+ IPs[#IPs+1] = new_ip(ip.a, "IPv4");
+ end
end
- end
- if has_other then
- if #IPs > 0 then
- rfc3484_dest(host_session.ip_hosts, sources);
- for i = 1, #IPs do
- IPs[i] = {ip = IPs[i], port = connect_port};
+ if have_other_result then
+ if #IPs > 0 then
+ rfc3484_dest(host_session.ip_hosts, sources);
+ for i = 1, #IPs do
+ IPs[i] = {ip = IPs[i], port = connect_port};
+ end
+ host_session.ip_choice = 0;
+ s2sout.try_next_ip(host_session);
+ else
+ log("debug", "DNS lookup failed to get a response for %s", connect_host);
+ host_session.ip_hosts = nil;
+ if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can
+ log("debug", "No other records to try for %s - destroying", host_session.to_host);
+ err = err and (": "..err) or "";
+ s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't
+ end
end
- host_session.ip_choice = 0;
- s2sout.try_next_ip(host_session);
else
- log("debug", "DNS lookup failed to get a response for %s", connect_host);
- host_session.ip_hosts = nil;
- if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can
- log("debug", "No other records to try for %s - destroying", host_session.to_host);
- err = err and (": "..err) or "";
- s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't
- end
+ have_other_result = true;
end
- else
- has_other = true;
- end
- end, connect_host, "A", "IN");
+ end, connect_host, "A", "IN");
else
- has_other = true;
+ have_other_result = true;
end
if has_ipv6 then
- handle6 = adns.lookup(function (reply, err)
- handle6 = nil;
+ handle6 = adns.lookup(function (reply, err)
+ handle6 = nil;
- if reply and reply[#reply] and reply[#reply].aaaa then
- for _, ip in ipairs(reply) do
- log("debug", "DNS reply for %s gives us %s", connect_host, ip.aaaa);
- IPs[#IPs+1] = new_ip(ip.aaaa, "IPv6");
+ if reply and reply[#reply] and reply[#reply].aaaa then
+ for _, ip in ipairs(reply) do
+ log("debug", "DNS reply for %s gives us %s", connect_host, ip.aaaa);
+ IPs[#IPs+1] = new_ip(ip.aaaa, "IPv6");
+ end
end
- end
- if has_other then
- if #IPs > 0 then
- rfc3484_dest(host_session.ip_hosts, sources);
- for i = 1, #IPs do
- IPs[i] = {ip = IPs[i], port = connect_port};
+ if have_other_result then
+ if #IPs > 0 then
+ rfc3484_dest(host_session.ip_hosts, sources);
+ for i = 1, #IPs do
+ IPs[i] = {ip = IPs[i], port = connect_port};
+ end
+ host_session.ip_choice = 0;
+ s2sout.try_next_ip(host_session);
+ else
+ log("debug", "DNS lookup failed to get a response for %s", connect_host);
+ host_session.ip_hosts = nil;
+ if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can
+ log("debug", "No other records to try for %s - destroying", host_session.to_host);
+ err = err and (": "..err) or "";
+ s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't
+ end
end
- host_session.ip_choice = 0;
- s2sout.try_next_ip(host_session);
else
- log("debug", "DNS lookup failed to get a response for %s", connect_host);
- host_session.ip_hosts = nil;
- if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can
- log("debug", "No other records to try for %s - destroying", host_session.to_host);
- err = err and (": "..err) or "";
- s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't
- end
+ have_other_result = true;
end
- else
- has_other = true;
- end
- end, connect_host, "AAAA", "IN");
+ end, connect_host, "AAAA", "IN");
else
- has_other = true;
+ have_other_result = true;
end
-
return true;
elseif host_session.ip_hosts and #host_session.ip_hosts > host_session.ip_choice then -- Not our first attempt, and we also have IPs left to try
s2sout.try_next_ip(host_session);