aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/mod_c2s.lua28
-rw-r--r--plugins/mod_s2s.lua27
-rw-r--r--plugins/mod_smacks.lua18
-rw-r--r--util-src/pposix.c32
4 files changed, 75 insertions, 30 deletions
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua
index 09d4be08..e29ea6a0 100644
--- a/plugins/mod_c2s.lua
+++ b/plugins/mod_c2s.lua
@@ -45,6 +45,7 @@ local hosts = prosody.hosts;
local stream_callbacks = { default_ns = "jabber:client" };
local listener = {};
local runner_callbacks = {};
+local session_events = {};
local m_tls_params = module:metric(
"counter", "encrypted", "",
@@ -76,11 +77,11 @@ local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'};
function stream_callbacks.streamopened(session, attr)
-- run _streamopened in async context
- session.thread:run({ stream = "opened", attr = attr });
+ session.thread:run({ event = "streamopened", attr = attr });
end
-function stream_callbacks._streamopened(session, attr)
- local send = session.send;
+function session_events.streamopened(session, event)
+ local send, attr = session.send, event.attr;
if not attr.to then
session:close{ condition = "improper-addressing",
text = "A 'to' attribute is required on stream headers" };
@@ -162,14 +163,19 @@ end
function stream_callbacks.streamclosed(session, attr)
-- run _streamclosed in async context
- session.thread:run({ stream = "closed", attr = attr });
+ session.thread:run({ event = "streamclosed", attr = attr });
end
-function stream_callbacks._streamclosed(session)
+function session_events.streamclosed(session)
session.log("debug", "Received </stream:stream>");
session:close(false);
end
+function session_events.callback(session, event)
+ session.log("debug", "Running session callback %s", event.name);
+ event.callback(session, event);
+end
+
function stream_callbacks.error(session, error, data)
if error == "no-stream" then
session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}")));
@@ -350,13 +356,11 @@ function listener.onconnect(conn)
session.stream:reset();
end
- session.thread = runner(function (stanza)
- if st.is_stanza(stanza) then
- core_process_stanza(session, stanza);
- elseif stanza.stream == "opened" then
- stream_callbacks._streamopened(session, stanza.attr);
- elseif stanza.stream == "closed" then
- stream_callbacks._streamclosed(session, stanza.attr);
+ session.thread = runner(function (item)
+ if st.is_stanza(item) then
+ core_process_stanza(session, item);
+ else
+ session_events[item.event](session, item);
end
end, runner_callbacks, session);
diff --git a/plugins/mod_s2s.lua b/plugins/mod_s2s.lua
index 638ace3d..8eb1565e 100644
--- a/plugins/mod_s2s.lua
+++ b/plugins/mod_s2s.lua
@@ -89,6 +89,7 @@ local m_tls_params = module:metric(
local sessions = module:shared("sessions");
local runner_callbacks = {};
+local session_events = {};
local listener = {};
@@ -469,10 +470,11 @@ local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams";
function stream_callbacks.streamopened(session, attr)
-- run _streamopened in async context
- session.thread:run({ stream = "opened", attr = attr });
+ session.thread:run({ event = "streamopened", attr = attr });
end
-function stream_callbacks._streamopened(session, attr)
+function session_events.streamopened(session, event)
+ local attr = event.attr;
session.version = tonumber(attr.version) or 0;
session.had_stream = true; -- Had a stream opened at least once
@@ -613,14 +615,19 @@ function stream_callbacks._streamopened(session, attr)
end
end
-function stream_callbacks._streamclosed(session)
+function session_events.streamclosed(session)
(session.log or log)("debug", "Received </stream:stream>");
session:close(false);
end
+function session_events.callback(session, event)
+ session.log("debug", "Running session callback %s", event.name);
+ event.callback(session, event);
+end
+
function stream_callbacks.streamclosed(session, attr)
-- run _streamclosed in async context
- session.thread:run({ stream = "closed", attr = attr });
+ session.thread:run({ event = "streamclosed", attr = attr });
end
-- Some stream conditions indicate a problem on our end, e.g. that we sent
@@ -784,13 +791,11 @@ end
local function initialize_session(session)
local stream = new_xmpp_stream(session, stream_callbacks, stanza_size_limit);
- session.thread = runner(function (stanza)
- if st.is_stanza(stanza) then
- core_process_stanza(session, stanza);
- elseif stanza.stream == "opened" then
- stream_callbacks._streamopened(session, stanza.attr);
- elseif stanza.stream == "closed" then
- stream_callbacks._streamclosed(session, stanza.attr);
+ session.thread = runner(function (item)
+ if st.is_stanza(item) then
+ core_process_stanza(session, item);
+ else
+ session_events[item.event](session, item);
end
end, runner_callbacks, session);
diff --git a/plugins/mod_smacks.lua b/plugins/mod_smacks.lua
index 2b131031..65d410e0 100644
--- a/plugins/mod_smacks.lua
+++ b/plugins/mod_smacks.lua
@@ -541,13 +541,17 @@ module:hook("pre-resource-unbind", function (event)
return
end
- prosody.main_thread:run(function ()
- session.log("debug", "Destroying session for hibernating too long");
- save_old_session(session);
- session.resumption_token = nil;
- sessionmanager.destroy_session(session, "Hibernating too long");
- sessions_expired(1);
- end);
+ session.thread:run({
+ event = "callback";
+ name = "mod_smacks/destroy_hibernating";
+ callback = function ()
+ session.log("debug", "Destroying session for hibernating too long");
+ save_old_session(session);
+ session.resumption_token = nil;
+ sessionmanager.destroy_session(session, "Hibernating too long");
+ sessions_expired(1);
+ end;
+ });
end);
if session.conn then
local conn = session.conn;
diff --git a/util-src/pposix.c b/util-src/pposix.c
index 23afd7b1..502e5326 100644
--- a/util-src/pposix.c
+++ b/util-src/pposix.c
@@ -694,6 +694,37 @@ static int lc_pipe(lua_State *L) {
return 2;
}
+/* This helper function is adapted from Lua 5.3's liolib.c */
+static int stdio_fclose (lua_State *L) {
+ int res = -1;
+ luaL_Stream *p = ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE));
+ if (p->f == NULL) {
+ return 0;
+ }
+ res = fclose(p->f);
+ p->f = NULL;
+ return luaL_fileresult(L, (res == 0), NULL);
+}
+
+static int lc_fdopen(lua_State *L) {
+ int fd = luaL_checkinteger(L, 1);
+ const char *mode = luaL_checkstring(L, 2);
+
+ luaL_Stream *file = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
+ file->closef = stdio_fclose;
+ file->f = fdopen(fd, mode);
+
+ if (!file->f) {
+ luaL_pushfail(L);
+ lua_pushstring(L, strerror(errno));
+ return 2;
+ }
+
+ luaL_getmetatable(L, LUA_FILEHANDLE);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
static int lc_uname(lua_State *L) {
struct utsname uname_info;
@@ -911,6 +942,7 @@ int luaopen_prosody_util_pposix(lua_State *L) {
{ "mkdir", lc_mkdir },
{ "pipe", lc_pipe },
+ { "fdopen", lc_fdopen },
{ "setrlimit", lc_setrlimit },
{ "getrlimit", lc_getrlimit },