Skip to content

Commit

Permalink
Fix crash when combining +P with a 3rd party module, or actually
Browse files Browse the repository at this point in the history
any parameter channel mode module loaded after channeldb.
Reported by GaMbiTo, with help from PeGaSuS, Gottem and k4be
in https://bugs.unrealircd.org/view.php?id=5669

It is not safe to call channel mode parameter functions when
unloading modules. Makes sense I think.

We now no longer write the db on rehash, which is something i
didn't like anyway (wasted CPU cycles). The problem was that
one could not just scratch the write db call, as otherwise if
someone rehashes every minute would cause the db never to
be saved. This is because on each rehash the event to write
the db gets rescheduled to +5 minutes in the future.
We now work around that in the same way as connthrottle does.
Obviously it would be better to make the event system itself
deal with this, but that is (way) too much for now.
  • Loading branch information
syzop committed May 9, 2020
1 parent 4832559 commit 8d2e05f
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/modules/channeldb.c
Expand Up @@ -67,7 +67,7 @@ struct cfgstruct {
};
static struct cfgstruct cfg;

static int channeldb_loaded = 0;
static long channeldb_next_event = 0;

MOD_TEST()
{
Expand All @@ -80,7 +80,7 @@ MOD_INIT()
{
MARK_AS_OFFICIAL_MODULE(modinfo);

LoadPersistentInt(modinfo, channeldb_loaded);
LoadPersistentLong(modinfo, channeldb_next_event);

setcfg();

Expand All @@ -90,7 +90,7 @@ MOD_INIT()

MOD_LOAD()
{
if (!channeldb_loaded)
if (!channeldb_next_event)
{
/* If this is the first time that our module is loaded, then read the database. */
if (!read_channeldb())
Expand All @@ -102,9 +102,9 @@ MOD_LOAD()
else
config_warn("[channeldb] Failed to rename database from %s to %s: %s", cfg.database, fname, strerror(errno));
}
channeldb_loaded = 1;
channeldb_next_event = TStime() + CHANNELDB_SAVE_EVERY;
}
EventAdd(modinfo->handle, "channeldb_write_channeldb", write_channeldb_evt, NULL, CHANNELDB_SAVE_EVERY*1000, 0);
EventAdd(modinfo->handle, "channeldb_write_channeldb", write_channeldb_evt, NULL, 1000, 0);
if (ModuleGetError(modinfo->handle) != MODERR_NOERROR)
{
config_error("A critical error occurred when loading module %s: %s", MOD_HEADER.name, ModuleGetErrorStr(modinfo->handle));
Expand All @@ -115,9 +115,8 @@ MOD_LOAD()

MOD_UNLOAD()
{
write_channeldb();
freecfg();
SavePersistentInt(modinfo, channeldb_loaded);
SavePersistentLong(modinfo, channeldb_next_event);
return MOD_SUCCESS;
}

Expand Down Expand Up @@ -191,6 +190,9 @@ int channeldb_configrun(ConfigFile *cf, ConfigEntry *ce, int type)

EVENT(write_channeldb_evt)
{
if (channeldb_next_event > TStime())
return;
channeldb_next_event = TStime() + CHANNELDB_SAVE_EVERY;
write_channeldb();
}

Expand Down

0 comments on commit 8d2e05f

Please sign in to comment.