core/stanza_router.lua

changeset 468
ab49cb6d0e92
parent 438
193f9dd64f17
child 519
cccd610a0ef9
equal deleted inserted replaced
465:9ab51c483cf3 468:ab49cb6d0e92
15 local modules_handle_stanza = require "core.modulemanager".handle_stanza; 15 local modules_handle_stanza = require "core.modulemanager".handle_stanza;
16 local component_handle_stanza = require "core.componentmanager".handle_stanza; 16 local component_handle_stanza = require "core.componentmanager".handle_stanza;
17 17
18 local handle_outbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_outbound_presence_subscriptions_and_probes; 18 local handle_outbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_outbound_presence_subscriptions_and_probes;
19 local handle_inbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_inbound_presence_subscriptions_and_probes; 19 local handle_inbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_inbound_presence_subscriptions_and_probes;
20 local handle_normal_presence = require "core.presencemanager".handle_normal_presence;
20 21
21 local format = string.format; 22 local format = string.format;
22 local tostring = tostring; 23 local tostring = tostring;
23 local t_concat = table.concat; 24 local t_concat = table.concat;
24 local t_insert = table.insert; 25 local t_insert = table.insert;
103 if origin.type == "c2s" or origin.type == "c2s_unauthed" then 104 if origin.type == "c2s" or origin.type == "c2s_unauthed" then
104 local session = origin; 105 local session = origin;
105 106
106 if stanza.name == "presence" and origin.roster then 107 if stanza.name == "presence" and origin.roster then
107 if stanza.attr.type == nil or stanza.attr.type == "unavailable" then 108 if stanza.attr.type == nil or stanza.attr.type == "unavailable" then
108 for jid in pairs(origin.roster) do -- broadcast to all interested contacts 109 handle_normal_presence(origin, stanza, core_route_stanza);
109 local subscription = origin.roster[jid].subscription;
110 if subscription == "both" or subscription == "from" then
111 stanza.attr.to = jid;
112 core_route_stanza(origin, stanza);
113 end
114 end
115 local node, host = jid_split(stanza.attr.from);
116 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast to all resources
117 if res ~= origin and res.full_jid then -- to resource. FIXME is res.full_jid the correct check? Maybe it should be res.presence
118 stanza.attr.to = res.full_jid;
119 core_route_stanza(origin, stanza);
120 end
121 end
122 if stanza.attr.type == nil and not origin.presence then -- initial presence
123 local probe = st.presence({from = origin.full_jid, type = "probe"});
124 for jid in pairs(origin.roster) do -- probe all contacts we are subscribed to
125 local subscription = origin.roster[jid].subscription;
126 if subscription == "both" or subscription == "to" then
127 probe.attr.to = jid;
128 core_route_stanza(origin, probe);
129 end
130 end
131 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast from all available resources
132 if res ~= origin and res.presence then
133 res.presence.attr.to = origin.full_jid;
134 core_route_stanza(res, res.presence);
135 res.presence.attr.to = nil;
136 end
137 end
138 if origin.roster.pending then -- resend incoming subscription requests
139 for jid in pairs(origin.roster.pending) do
140 origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original?
141 end
142 end
143 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host});
144 for jid, item in pairs(origin.roster) do -- resend outgoing subscription requests
145 if item.ask then
146 request.attr.to = jid;
147 core_route_stanza(origin, request);
148 end
149 end
150 for _, msg in ipairs(offlinemanager.load(node, host) or {}) do
151 origin.send(msg); -- FIXME do we need to modify to/from in any way?
152 end
153 offlinemanager.deleteAll(node, host);
154 end
155 origin.priority = 0;
156 if stanza.attr.type == "unavailable" then
157 origin.presence = nil;
158 else
159 origin.presence = stanza;
160 local priority = stanza:child_with_name("priority");
161 if priority and #priority > 0 then
162 priority = t_concat(priority);
163 if s_find(priority, "^[+-]?[0-9]+$") then
164 priority = tonumber(priority);
165 if priority < -128 then priority = -128 end
166 if priority > 127 then priority = 127 end
167 origin.priority = priority;
168 end
169 end
170 end
171 stanza.attr.to = nil; -- reset it
172 else 110 else
173 log("warn", "Unhandled c2s presence: %s", tostring(stanza)); 111 log("warn", "Unhandled c2s presence: %s", tostring(stanza));
174 if (stanza.attr.xmlns == "jabber:client" or stanza.attr.xmlns == "jabber:server") and stanza.attr.type ~= "error" then 112 if (stanza.attr.xmlns == "jabber:client" or stanza.attr.xmlns == "jabber:server") and stanza.attr.type ~= "error" then
175 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); -- FIXME correct error? 113 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); -- FIXME correct error?
176 end 114 end
302 else 240 else
303 log("warn", "received stanza from unhandled connection type: %s", origin.type); 241 log("warn", "received stanza from unhandled connection type: %s", origin.type);
304 end 242 end
305 stanza.attr.to = to; -- reset 243 stanza.attr.to = to; -- reset
306 end 244 end
307
308 function handle_stanza_toremote(stanza)
309 log("error", "Stanza bound for remote host, but s2s is not implemented");
310 end
311
312

mercurial