mirror of
https://github.com/bjc/prosody.git
synced 2025-04-06 22:57:38 +03:00
General fixes for s2s, to make it more robust (I hope), sending data to remote hosts sane (s2ssession.send() works as expected), recycle outgoing dialback connections, etc.
This commit is contained in:
parent
40726a8a0a
commit
7a2fc45f65
2 changed files with 41 additions and 23 deletions
|
@ -3,6 +3,7 @@ local hosts = hosts;
|
||||||
local sessions = sessions;
|
local sessions = sessions;
|
||||||
local socket = require "socket";
|
local socket = require "socket";
|
||||||
local format = string.format;
|
local format = string.format;
|
||||||
|
local t_insert = table.insert;
|
||||||
local tostring, pairs, ipairs, getmetatable, print, newproxy, error, tonumber
|
local tostring, pairs, ipairs, getmetatable, print, newproxy, error, tonumber
|
||||||
= tostring, pairs, ipairs, getmetatable, print, newproxy, error, tonumber;
|
= tostring, pairs, ipairs, getmetatable, print, newproxy, error, tonumber;
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ local md5_hash = require "util.hashes".md5;
|
||||||
|
|
||||||
local dialback_secret = "This is very secret!!! Ha!";
|
local dialback_secret = "This is very secret!!! Ha!";
|
||||||
|
|
||||||
local srvmap = { ["gmail.com"] = "talk.google.com", ["identi.ca"] = "longlance.controlezvous.ca" };
|
local srvmap = { ["gmail.com"] = "talk.google.com", ["identi.ca"] = "longlance.controlezvous.ca", ["cdr.se"] = "jabber.cdr.se" };
|
||||||
|
|
||||||
module "s2smanager"
|
module "s2smanager"
|
||||||
|
|
||||||
|
@ -28,10 +29,19 @@ function connect_host(from_host, to_host)
|
||||||
end
|
end
|
||||||
|
|
||||||
function send_to_host(from_host, to_host, data)
|
function send_to_host(from_host, to_host, data)
|
||||||
if hosts[to_host] then
|
local host = hosts[to_host];
|
||||||
|
if host then
|
||||||
-- Write to connection
|
-- Write to connection
|
||||||
hosts[to_host].sends2s(data);
|
if host.type == "s2sout_unauthed" and not host.notopen and not host.dialback_key then
|
||||||
log("debug", "stanza sent over s2s");
|
log("debug", "trying to send over unauthed s2sout to "..to_host..", authing it now...");
|
||||||
|
initiate_dialback(host);
|
||||||
|
if not host.sendq then host.sendq = { data };
|
||||||
|
else t_insert(host.sendq, data); end
|
||||||
|
else
|
||||||
|
log("debug", "going to send stanza to "..to_host.." from "..from_host);
|
||||||
|
hosts[to_host].sends2s(data);
|
||||||
|
log("debug", "stanza sent over "..hosts[to_host].type);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
log("debug", "opening a new outgoing connection for this stanza");
|
log("debug", "opening a new outgoing connection for this stanza");
|
||||||
local host_session = new_outgoing(from_host, to_host);
|
local host_session = new_outgoing(from_host, to_host);
|
||||||
|
@ -61,7 +71,6 @@ end
|
||||||
function new_outgoing(from_host, to_host)
|
function new_outgoing(from_host, to_host)
|
||||||
local host_session = { to_host = to_host, from_host = from_host, notopen = true, type = "s2sout_unauthed", direction = "outgoing" };
|
local host_session = { to_host = to_host, from_host = from_host, notopen = true, type = "s2sout_unauthed", direction = "outgoing" };
|
||||||
hosts[to_host] = host_session;
|
hosts[to_host] = host_session;
|
||||||
|
|
||||||
local cl = connlisteners_get("xmppserver");
|
local cl = connlisteners_get("xmppserver");
|
||||||
|
|
||||||
local conn, handler = socket.tcp()
|
local conn, handler = socket.tcp()
|
||||||
|
@ -113,13 +122,11 @@ function streamopened(session, attr)
|
||||||
send(format("<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' id='%s' from='%s'>", session.streamid, session.to_host));
|
send(format("<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' id='%s' from='%s'>", session.streamid, session.to_host));
|
||||||
elseif session.direction == "outgoing" then
|
elseif session.direction == "outgoing" then
|
||||||
-- If we are just using the connection for verifying dialback keys, we won't try and auth it
|
-- If we are just using the connection for verifying dialback keys, we won't try and auth it
|
||||||
|
if not attr.id then error("stream response did not give us a streamid!!!"); end
|
||||||
|
session.streamid = attr.id;
|
||||||
|
|
||||||
if not session.dialback_verifying then
|
if not session.dialback_verifying then
|
||||||
-- generate dialback key
|
initiate_dialback(session);
|
||||||
if not attr.id then error("stream response did not give us a streamid!!!"); end
|
|
||||||
session.streamid = attr.id;
|
|
||||||
session.dialback_key = generate_dialback(session.streamid, session.to_host, session.from_host);
|
|
||||||
session.sends2s(format("<db:result from='%s' to='%s'>%s</db:result>", session.from_host, session.to_host, session.dialback_key));
|
|
||||||
session.log("info", "sent dialback key on outgoing s2s stream");
|
|
||||||
else
|
else
|
||||||
mark_connected(session);
|
mark_connected(session);
|
||||||
end
|
end
|
||||||
|
@ -139,6 +146,13 @@ function streamopened(session, attr)
|
||||||
session.notopen = nil;
|
session.notopen = nil;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function initiate_dialback(session)
|
||||||
|
-- generate dialback key
|
||||||
|
session.dialback_key = generate_dialback(session.streamid, session.to_host, session.from_host);
|
||||||
|
session.sends2s(format("<db:result from='%s' to='%s'>%s</db:result>", session.from_host, session.to_host, session.dialback_key));
|
||||||
|
session.log("info", "sent dialback key on outgoing s2s stream");
|
||||||
|
end
|
||||||
|
|
||||||
function generate_dialback(id, to, from)
|
function generate_dialback(id, to, from)
|
||||||
return md5_hash(id..to..from..dialback_secret); -- FIXME: See XEP-185 and XEP-220
|
return md5_hash(id..to..from..dialback_secret); -- FIXME: See XEP-185 and XEP-220
|
||||||
end
|
end
|
||||||
|
@ -167,18 +181,22 @@ function mark_connected(session)
|
||||||
|
|
||||||
local from, to = session.from_host, session.to_host;
|
local from, to = session.from_host, session.to_host;
|
||||||
|
|
||||||
session.log("debug", session.direction.." s2s connection "..session.from_host.."->"..session.to_host.." is now complete");
|
session.log("debug", session.direction.." s2s connection "..from.."->"..to.." is now complete");
|
||||||
|
|
||||||
local send_to_host = send_to_host;
|
local send_to_host = send_to_host;
|
||||||
function session.send(data) send_to_host(from, to, data); end
|
function session.send(data) send_to_host(to, from, data); end
|
||||||
|
|
||||||
if sendq then
|
|
||||||
session.log("debug", "sending queued stanzas across new outgoing connection to "..session.to_host);
|
if session.direction == "outgoing" then
|
||||||
for i, data in ipairs(sendq) do
|
hosts[to] = session;
|
||||||
send(data);
|
if sendq then
|
||||||
sendq[i] = nil;
|
session.log("debug", "sending queued stanzas across new outgoing connection to "..session.to_host);
|
||||||
|
for i, data in ipairs(sendq) do
|
||||||
|
send(data);
|
||||||
|
sendq[i] = nil;
|
||||||
|
end
|
||||||
|
session.sendq = nil;
|
||||||
end
|
end
|
||||||
session.sendq = nil;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ local jid_split = require "util.jid".split;
|
||||||
local print = print;
|
local print = print;
|
||||||
|
|
||||||
function core_process_stanza(origin, stanza)
|
function core_process_stanza(origin, stanza)
|
||||||
log("debug", "Received: "..tostring(stanza))
|
log("debug", "Received["..origin.type.."]: "..tostring(stanza))
|
||||||
-- TODO verify validity of stanza (as well as JID validity)
|
-- TODO verify validity of stanza (as well as JID validity)
|
||||||
if stanza.name == "iq" and not(#stanza.tags == 1 and stanza.tags[1].attr.xmlns) then
|
if stanza.name == "iq" and not(#stanza.tags == 1 and stanza.tags[1].attr.xmlns) then
|
||||||
if stanza.attr.type == "set" or stanza.attr.type == "get" then
|
if stanza.attr.type == "set" or stanza.attr.type == "get" then
|
||||||
|
@ -137,9 +137,9 @@ function core_handle_stanza(origin, stanza)
|
||||||
origin.from_host = attr.from;
|
origin.from_host = attr.from;
|
||||||
origin.to_host = attr.to;
|
origin.to_host = attr.to;
|
||||||
origin.dialback_key = stanza[1];
|
origin.dialback_key = stanza[1];
|
||||||
log("debug", "asking %s if key %s belongs to them", attr.from, stanza[1]);
|
log("debug", "asking %s if key %s belongs to them", origin.from_host, origin.dialback_key);
|
||||||
send_s2s(attr.to, attr.from, format("<db:verify from='%s' to='%s' id='%s'>%s</db:verify>", attr.to, attr.from, origin.streamid, stanza[1]));
|
send_s2s(origin.to_host, origin.from_host, format("<db:verify from='%s' to='%s' id='%s'>%s</db:verify>", origin.to_host, origin.from_host, origin.streamid, origin.dialback_key));
|
||||||
hosts[attr.from].dialback_verifying = origin;
|
hosts[origin.from_host].dialback_verifying = origin;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif origin.type == "s2sout_unauthed" or origin.type == "s2sout" then
|
elseif origin.type == "s2sout_unauthed" or origin.type == "s2sout" then
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue