[FIX] Kill Parsee on unexcepted stream closure

This commit is contained in:
LDA 2024-10-20 12:53:07 +02:00
commit 02a89270c0
6 changed files with 49 additions and 15 deletions

View file

@ -92,14 +92,19 @@ restricted to Parsee admins, with permission from MUC owners, too
be false by default. be false by default.
- Currently, MUC owners may kick Parsee out, with the effect of unlinking the - Currently, MUC owners may kick Parsee out, with the effect of unlinking the
MUC. MUC.
- Rewrite the XMPP command management to actually be aware of context, instead of
being a baked-in X-macro. It could be useful for MUC admins, which may use commands
specifically within the MUC's own context rather than the global Parsee context(for
Parsee admins).
- Look at XEPS-TBD.TXT for XEPs to be done - Look at XEPS-TBD.TXT for XEPs to be done
- Add a MUC server to Parsee, such that it may be able to hook onto it and therefore - Add a MUC server to Parsee, such that it may be able to hook onto it and therefore
support XMPP->Matrix bridging. support XMPP->Matrix bridging.
- Manage MUC DMs in a reasonable manner. Thanks `@freeoffers4u:matrix.org` for being - Manage MUC DMs in a reasonable manner. Thanks `@freeoffers4u:matrix.org` for being
a fucking annoyance and DMing an old Parsee semi-anon user for no clear reason. a fucking annoyance and DMing an old Parsee semi-anon user for no clear reason.
- Make Parsee cope well with unexcepted stream closures (e.g: with an XMPP server - Make Parsee cope with stream closures(i.e: XMPP server turning off) better. As of
turning off, etc...). Shutting it off seems like an easy solution, but would go now, it just kills itself when that happens, instead of trying to negociate a new
against principles. connection, which would be a better method that would actually fit Parsee's own
principles.
## DONATING/CONTRIBUTING ## DONATING/CONTRIBUTING
If you know things about XMPP or Matrix, yet aren't familiar with C99, or just If you know things about XMPP or Matrix, yet aren't familiar with C99, or just

View file

@ -265,8 +265,9 @@ Main(Array *args, HashMap *env)
} }
server = HttpServerCreate(&conf); server = HttpServerCreate(&conf);
((ParseeData *) conf.handlerArgs)->server = server;
if (!ParseeInitialiseSignals(server, xmpp_thr, jabber)) if (!ParseeInitialiseSignals(conf.handlerArgs, xmpp_thr))
{ {
goto end; goto end;
} }

View file

@ -32,6 +32,9 @@ ParseeInitData(XMPPComponent *comp)
data->oid_servers = HashMapCreate(); data->oid_servers = HashMapCreate();
pthread_mutex_init(&data->oidl, NULL); pthread_mutex_init(&data->oidl, NULL);
data->halted = false;
pthread_mutex_init(&data->halt_lock, NULL);
if (data->config->db_size) if (data->config->db_size)
{ {
data->db = DbOpenLMDB(data->config->db_path, data->config->db_size); data->db = DbOpenLMDB(data->config->db_path, data->config->db_size);
@ -109,6 +112,7 @@ ParseeFreeData(ParseeData *data)
} }
HashMapFree(data->oid_servers); HashMapFree(data->oid_servers);
pthread_mutex_destroy(&data->oidl); pthread_mutex_destroy(&data->oidl);
pthread_mutex_destroy(&data->halt_lock);
Free(data->id); Free(data->id);
XMPPEndCompStream(data->jabber); XMPPEndCompStream(data->jabber);
DbClose(data->db); DbClose(data->db);

View file

@ -6,39 +6,40 @@
#include <XMPP.h> #include <XMPP.h>
static HttpServer *server = NULL; static ParseeData *data;
static pthread_t xmpp_thr; static pthread_t xmpp_thr;
static XMPPComponent *jabber = NULL;
static void static void
SignalHandler(int signal) SignalHandler(int signal)
{ {
if (server && (signal == SIGTERM || signal == SIGINT)) if (data->server && (signal == SIGTERM || signal == SIGINT))
{ {
Log(LOG_INFO, "Killing thread..."); Log(LOG_INFO, "Killing thread...");
XMPPFinishCompStream(jabber);
pthread_mutex_lock(&data->halt_lock);
data->halted = true;
pthread_mutex_unlock(&data->halt_lock);
XMPPFinishCompStream(data->jabber);
pthread_join(xmpp_thr, NULL); pthread_join(xmpp_thr, NULL);
Log(LOG_INFO, "Stopping server..."); Log(LOG_INFO, "Stopping server...");
HttpServerStop(server); HttpServerStop(data->server);
return; return;
} }
if (signal == SIGPIPE) if (signal == SIGPIPE)
{ {
Log(LOG_DEBUG, "Caught a SIGPIPE..."); Log(LOG_DEBUG, "Caught a SIGPIPE...");
XMPPFinishCompStream(jabber);
pthread_join(xmpp_thr, NULL);
return; return;
} }
} }
bool bool
ParseeInitialiseSignals(HttpServer *s, pthread_t xmpp, XMPPComponent *j) ParseeInitialiseSignals(ParseeData *d, pthread_t xmpp)
{ {
struct sigaction sa; struct sigaction sa;
server = s; data = d;
xmpp_thr = xmpp; xmpp_thr = xmpp;
jabber = j;
sigfillset(&sa.sa_mask); sigfillset(&sa.sa_mask);
sa.sa_handler = SignalHandler; sa.sa_handler = SignalHandler;

View file

@ -136,6 +136,8 @@ ParseeXMPPThread(void *argp)
XMLElement *stanza = NULL; XMLElement *stanza = NULL;
HashMap *await_table2; HashMap *await_table2;
size_t i; size_t i;
bool error = false;
/* Initialise the await table */ /* Initialise the await table */
await_table = HashMapCreate(); await_table = HashMapCreate();
@ -243,6 +245,14 @@ ParseeXMPPThread(void *argp)
* few threads to be busy, while the rest of Parsee works. */ * few threads to be busy, while the rest of Parsee works. */
PushStanza(&info, stanza); PushStanza(&info, stanza);
} }
pthread_mutex_lock(&args->halt_lock);
if (!args->halted)
{
Log(LOG_WARNING, "XMPP server is closing stream...");
Log(LOG_WARNING, "Stopping %s...", NAME);
error = true;
}
pthread_mutex_unlock(&args->halt_lock);
info.running = false; info.running = false;
for (i = 0; i < info.available_dispatchers; i++) for (i = 0; i < info.available_dispatchers; i++)
@ -278,6 +288,10 @@ ParseeXMPPThread(void *argp)
DestroyPEPManager(info.pep_manager); DestroyPEPManager(info.pep_manager);
XMPPFreeManager(info.m); XMPPFreeManager(info.m);
if (error)
{
HttpServerStop(args->server); /* minor trolling */
}
return NULL; return NULL;
} }

View file

@ -60,6 +60,7 @@ typedef struct ParseeData {
HttpRouter *router; HttpRouter *router;
CommandRouter *handler; CommandRouter *handler;
HttpServer *server;
XMPPComponent *jabber; XMPPComponent *jabber;
Db *db; Db *db;
@ -69,6 +70,10 @@ typedef struct ParseeData {
HashMap *oid_servers; HashMap *oid_servers;
pthread_mutex_t oidl; pthread_mutex_t oidl;
/* If Parsee was intentionally halted */
bool halted;
pthread_mutex_t halt_lock;
} ParseeData; } ParseeData;
typedef struct Argument { typedef struct Argument {
@ -285,7 +290,11 @@ extern bool ParseeGetDMOrigin(ParseeData *data, char *chat_id, char *ev, char **
/* Sends presence requests for every MUC around as a fake JID */ /* Sends presence requests for every MUC around as a fake JID */
extern void ParseeSendPresence(ParseeData *); extern void ParseeSendPresence(ParseeData *);
extern bool ParseeInitialiseSignals(HttpServer *, pthread_t, XMPPComponent *); /** Initialises signal-handling code within Parsee.
* --------------------
* Modifies: the signal handler
* Returns: whenever it has properly been setup */
extern bool ParseeInitialiseSignals(ParseeData *data, pthread_t xmpp);
/* Job used to cleanup Parsee data that isn't necessary anymore. */ /* Job used to cleanup Parsee data that isn't necessary anymore. */
extern void ParseeCleanup(void *data); extern void ParseeCleanup(void *data);