comparison mod_bidi/mod_bidi.lua @ 1121:c714ed7de4ee

mod_bidi: Clean up and use 0.9+ routing APIs
author Kim Alvefur <zash@zash.se>
date Fri, 02 Aug 2013 17:35:39 +0200
parents 4e235e565693
children 6094d57c5387
comparison
equal deleted inserted replaced
1120:fc26a33fc2f3 1121:c714ed7de4ee
2 -- http://xmpp.org/extensions/xep-0288.html 2 -- http://xmpp.org/extensions/xep-0288.html
3 -- Copyright (C) 2013 Kim Alvefur 3 -- Copyright (C) 2013 Kim Alvefur
4 -- 4 --
5 -- This file is MIT/X11 licensed. 5 -- This file is MIT/X11 licensed.
6 -- 6 --
7 local s2smanager = require"core.s2smanager";
8 local add_filter = require "util.filters".add_filter; 7 local add_filter = require "util.filters".add_filter;
9 local st = require "util.stanza"; 8 local st = require "util.stanza";
10 local jid_split = require"util.jid".prepped_split; 9 local jid_split = require"util.jid".prepped_split;
11 10 local core_process_stanza = prosody.core_process_stanza;
11 local traceback = debug.traceback;
12 local hosts = hosts;
12 local xmlns_bidi_feature = "urn:xmpp:features:bidi" 13 local xmlns_bidi_feature = "urn:xmpp:features:bidi"
13 local xmlns_bidi = "urn:xmpp:bidi"; 14 local xmlns_bidi = "urn:xmpp:bidi";
14 local noop = function () end 15 local bidi_sessions = module:shared"sessions";
15 local core_process_stanza = prosody.core_process_stanza or core_process_stanza;
16 local traceback = debug.traceback;
17 16
18 local function handleerr(err) log("error", "Traceback[s2s]: %s: %s", tostring(err), traceback()); end 17 local function handleerr(err) log("error", "Traceback[s2s]: %s: %s", tostring(err), traceback()); end
19 local function handlestanza(session, stanza) 18 local function handlestanza(session, stanza)
20 if stanza.attr.xmlns == "jabber:client" then --COMPAT: Prosody pre-0.6.2 may send jabber:client 19 if stanza.attr.xmlns == "jabber:client" then --COMPAT: Prosody pre-0.6.2 may send jabber:client
21 stanza.attr.xmlns = nil; 20 stanza.attr.xmlns = nil;
25 return xpcall(function () return core_process_stanza(session, stanza) end, handleerr); 24 return xpcall(function () return core_process_stanza(session, stanza) end, handleerr);
26 end 25 end
27 end 26 end
28 27
29 local function new_bidi(origin) 28 local function new_bidi(origin)
30 local bidi_session, remote_host; 29 if origin.type == "s2sin" then -- then we create an "outgoing" bidirectional session
31 origin.log("debug", "Creating bidirectional session wrapper");
32 if origin.direction == "incoming" then -- then we create an "outgoing" bidirectional session
33 local conflicting_session = hosts[origin.to_host].s2sout[origin.from_host] 30 local conflicting_session = hosts[origin.to_host].s2sout[origin.from_host]
34 if conflicting_session then 31 if conflicting_session then
35 conflicting_session.log("info", "We already have an outgoing connection to %s, closing it...", origin.from_host); 32 conflicting_session.log("info", "We already have an outgoing connection to %s, closing it...", origin.from_host);
36 conflicting_session:close{ condition = "conflict", text = "Replaced by bidirectional stream" } 33 conflicting_session:close{ condition = "conflict", text = "Replaced by bidirectional stream" }
37 s2smanager.destroy_session(conflicting_session); 34 s2smanager.destroy_session(conflicting_session);
38 end 35 end
39 remote_host = origin.from_host; 36 bidi_sessions[origin.from_host] = origin;
40 bidi_session = s2smanager.new_outgoing(origin.to_host, origin.from_host) 37 elseif origin.type == "s2sout" then -- handle incoming stanzas correctly
41 else -- outgoing -- then we create an "incoming" bidirectional session 38 local bidi_session = {
39 type = "s2sin";
40 is_bidi = true; orig_session = origin;
41 to_host = origin.from_host;
42 from_host = origin.to_host;
43 hosts = {};
44 }
45 origin.bidi_session = bidi_session;
46 setmetatable(bidi_session, { __index = origin });
47 module:fire_event("s2s-authenticated", { session = bidi_session, host = origin.to_host });
42 remote_host = origin.to_host; 48 remote_host = origin.to_host;
43 bidi_session = s2smanager.new_incoming(origin.conn)
44 bidi_session.to_host = origin.from_host;
45 bidi_session.from_host = origin.to_host;
46 add_filter(origin, "stanzas/in", function(stanza) 49 add_filter(origin, "stanzas/in", function(stanza)
47 if stanza.attr.xmlns ~= nil then return stanza end 50 if stanza.attr.xmlns ~= nil then return stanza end
48 local _, host = jid_split(stanza.attr.from); 51 local _, host = jid_split(stanza.attr.from);
49 if host ~= remote_host then return stanza end 52 if host ~= remote_host then return stanza end
50 handlestanza(bidi_session, stanza); 53 handlestanza(bidi_session, stanza);
51 end, 1); 54 end, 1);
52 end 55 end
53 origin.bidi_session = bidi_session; 56 end
54 bidi_session.sends2s = origin.sends2s;
55 bidi_session.bounce_sendq = noop;
56 bidi_session.notopen = nil;
57 bidi_session.is_bidi = true;
58 bidi_session.bidi_session = false;
59 bidi_session.orig_session = origin;
60 bidi_session.secure = origin.secure;
61 bidi_session.cert_identity_status = origin.cert_identity_status;
62 bidi_session.cert_chain_status = origin.cert_chain_status;
63 bidi_session.close = function(...)
64 return origin.close(...);
65 end
66 57
67 bidi_session.log("info", "Bidirectional session established"); 58 module:hook("route/remote", function(event)
68 module:fire_event("s2s-authenticated", { session = bidi_session, host = remote_host }); 59 local from_host, to_host, stanza = event.from_host, event.to_host, event.stanza;
69 return bidi_session; 60 if from_host ~= module.host then return end
70 end 61 local to_session = bidi_sessions[to_host]
62 if not to_session then return end
63 return to_session.sends2s(stanza);
64 end, -2);
71 65
72 -- Incoming s2s 66 -- Incoming s2s
73 module:hook("s2s-stream-features", function(event) 67 module:hook("s2s-stream-features", function(event)
74 local origin, features = event.origin, event.features; 68 local origin, features = event.origin, event.features;
75 if not origin.is_bidi and not hosts[module.host].s2sout[origin.from_host] then 69 if not origin.is_bidi and not hosts[module.host].s2sout[origin.from_host] then
109 module:hook("s2sin-established", enable_bidi); 103 module:hook("s2sin-established", enable_bidi);
110 module:hook("s2sout-established", enable_bidi); 104 module:hook("s2sout-established", enable_bidi);
111 105
112 function disable_bidi(event) 106 function disable_bidi(event)
113 local session = event.session; 107 local session = event.session;
114 if session.bidi_session then 108 if session.type == "s2sin" then -- then we create an "outgoing" bidirectional session
115 local bidi_session = session.bidi_session; 109 bidi_sessions[session.from_host] = nil;
116 session.bidi_session, bidi_session.orig_session = nil, nil;
117 session.log("debug", "Tearing down bidirectional stream");
118 s2smanager.destroy_session(bidi_session, event.reason);
119 elseif session.orig_session then
120 local orig_session = session.orig_session;
121 orig_session.bidi_session, session.orig_session = nil, nil;
122 orig_session.log("debug", "Tearing down bidirectional stream");
123 s2smanager.destroy_session(orig_session, event.reason);
124 end 110 end
125 end 111 end
126 112
127 module:hook("s2sin-destroyed", disable_bidi); 113 module:hook("s2sin-destroyed", disable_bidi);
128 module:hook("s2sout-destroyed", disable_bidi); 114 module:hook("s2sout-destroyed", disable_bidi);