462
|
1 local st = require "util.stanza";
|
|
2 local jid_bare = require "util.jid".bare;
|
|
3 local jid_split = require "util.jid".split;
|
|
4 local xmlns_carbons = "urn:xmpp:carbons:1";
|
|
5 local xmlns_forward = "urn:xmpp:forward:0";
|
|
6 local host_sessions = hosts[module.host].sessions;
|
|
7
|
|
8 -- TODO merge message handlers into one somehow
|
|
9
|
|
10 module:hook("iq/self/"..xmlns_carbons..":enable", function(event)
|
|
11 local origin, stanza = event.origin, event.stanza;
|
|
12 if stanza.attr.type == "set" then
|
|
13 module:log("debug", "%s enabled carbons", origin.full_jid);
|
|
14 origin.want_carbons = true;
|
|
15 origin.send(st.reply(stanza));
|
|
16 return true
|
|
17 end
|
|
18 end);
|
|
19
|
|
20 module:hook("iq/self/"..xmlns_carbons..":disable", function(event)
|
|
21 local origin, stanza = event.origin, event.stanza;
|
|
22 if stanza.attr.type == "set" then
|
|
23 module:log("debug", "%s disabled carbons", origin.full_jid);
|
|
24 origin.want_carbons = nil;
|
|
25 origin.send(st.reply(stanza));
|
|
26 return true
|
|
27 end
|
|
28 end);
|
|
29
|
|
30 function c2s_message_handler(event)
|
|
31 local origin, stanza = event.origin, event.stanza;
|
|
32 local orig_type = stanza.attr.type;
|
|
33 local orig_to = stanza.attr.to;
|
|
34
|
|
35 if not (orig_type == nil
|
|
36 or orig_type == "normal"
|
|
37 or orig_type == "chat") then
|
|
38 return
|
|
39 end
|
|
40
|
|
41 local bare_jid, user_sessions;
|
|
42 if origin.type == "s2s" then
|
|
43 bare_jid = jid_bare(stanza.attr.from);
|
|
44 user_sessions = host_sessions[jid_split(orig_to)];
|
|
45 else
|
|
46 bare_jid = (origin.username.."@"..origin.host)
|
|
47 user_sessions = host_sessions[origin.username];
|
|
48 end
|
|
49
|
|
50 if not stanza:get_child("private", xmlns_carbons)
|
|
51 and not stanza:get_child("forwarded", xmlns_forward) then
|
|
52 user_sessions = user_sessions and user_sessions.sessions;
|
|
53 for resource, session in pairs(user_sessions) do
|
|
54 local full_jid = bare_jid .. "/" .. resource;
|
|
55 if session ~= origin and session.want_carbons then
|
|
56 local msg = st.clone(stanza);
|
|
57 msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
|
|
58 local fwd = st.message{
|
|
59 from = bare_jid,
|
|
60 to = full_jid,
|
|
61 type = orig_type,
|
|
62 }
|
|
63 :tag("forwarded", { xmlns = xmlns_forward })
|
|
64 :tag("received", { xmlns = xmlns_carbons }):up()
|
|
65 :add_child(msg);
|
|
66 core_route_stanza(origin, fwd);
|
|
67 end
|
|
68 end
|
|
69 end
|
|
70 end
|
|
71
|
|
72 function s2c_message_handler(event)
|
|
73 local origin, stanza = event.origin, event.stanza;
|
|
74 local orig_type = stanza.attr.type;
|
|
75 local orig_to = stanza.attr.to;
|
|
76
|
|
77 if not (orig_type == nil
|
|
78 or orig_type == "normal"
|
|
79 or orig_type == "chat") then
|
|
80 return
|
|
81 end
|
|
82
|
|
83 local full_jid, bare_jid = orig_to, jid_bare(orig_to);
|
|
84 local username, hostname, resource = jid_split(full_jid);
|
|
85 local user_sessions = username and host_sessions[username];
|
|
86 if not user_sessions or hostname ~= module.host then
|
|
87 return
|
|
88 end
|
|
89
|
|
90 local no_carbon_to = {};
|
|
91 if resource then
|
|
92 no_carbon_to[resource] = true;
|
|
93 else
|
|
94 local top_resources = user_sessions.top_resources;
|
|
95 for i=1,top_resources do
|
|
96 no_carbon_to[top_resources[i]] = true;
|
|
97 end
|
|
98 end
|
|
99
|
|
100 if not stanza:get_child("private", xmlns_carbons)
|
|
101 and not stanza:get_child("forwarded", xmlns_forward) then
|
|
102 user_sessions = user_sessions and user_sessions.sessions;
|
|
103 for resource, session in pairs(user_sessions) do
|
|
104 local full_jid = bare_jid .. "/" .. resource;
|
|
105 if not no_carbon_to[resource] and session.want_carbons then
|
|
106 local msg = st.clone(stanza);
|
|
107 msg.attr.xmlns = msg.attr.xmlns or "jabber:client";
|
|
108 local fwd = st.message{
|
|
109 from = bare_jid,
|
|
110 to = full_jid,
|
|
111 type = orig_type,
|
|
112 }
|
|
113 :tag("forwarded", { xmlns = xmlns_forward })
|
|
114 :tag("received", { xmlns = xmlns_carbons }):up()
|
|
115 :add_child(msg);
|
|
116 core_route_stanza(origin, fwd);
|
|
117 end
|
|
118 end
|
|
119 end
|
|
120 end
|
|
121
|
|
122 -- Stanzas sent by local clients
|
|
123 module:hook("pre-message/bare", c2s_message_handler, 1);
|
|
124 module:hook("pre-message/full", c2s_message_handler, 1);
|
|
125 -- Stanszas to local clients
|
|
126 module:hook("message/bare", s2c_message_handler, 1); -- this will suck
|
|
127 module:hook("message/full", s2c_message_handler, 1);
|
|
128
|
|
129 module:add_feature(xmlns_carbons);
|