diff options
-rw-r--r-- | include/modules.h | 19 | ||||
-rw-r--r-- | src/commands.cpp | 1 | ||||
-rw-r--r-- | src/inspircd.cpp | 22 | ||||
-rw-r--r-- | src/modules.cpp | 2 |
4 files changed, 41 insertions, 3 deletions
diff --git a/include/modules.h b/include/modules.h index 7f4cc96be..451c939ef 100644 --- a/include/modules.h +++ b/include/modules.h @@ -395,6 +395,25 @@ class Module : public classbase * method returns, it will be passed an invalid pointer to the user object and crash!) */ virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user); + + /** Called to check if a user who is connecting can now be allowed to register + * If any modules return false for this function, the user is held in the waiting + * state until all modules return true. For example a module which implements ident + * lookups will continue to return false for a user until their ident lookup is completed. + * Note that the registration timeout for a user overrides these checks, if the registration + * timeout is reached, the user is disconnected even if modules report that the user is + * not ready to connect. + */ + virtual bool OnCheckReady(userrec* user); + + /** Called whenever a user is about to register their connection (e.g. before the user + * is sent the MOTD etc). Modules can use this method if they are performing a function + * which must be done before the actual connection is completed (e.g. ident lookups, + * dnsbl lookups, etc). + * Note that you should NOT delete the user record here by causing a disconnection! + * Use OnUserConnect for that instead. + */ + virtual void OnUserRegister(userrec* user); }; diff --git a/src/commands.cpp b/src/commands.cpp index 951c2281b..7d77a6a2b 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1764,6 +1764,7 @@ void handle_nick(char **parameters, int pcnt, userrec *user) user->dns_done = (!lookup_dns(user->nick)); if (user->dns_done) log(DEBUG,"Aborting dns lookup of %s because dns server experienced a failure.",user->nick); + FOREACH_MOD OnUserRegister(userrec* user); } if (user->registered == 3) { diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 273259019..badf284e7 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -2575,11 +2575,27 @@ void FullConnectUser(userrec* user) NetSendToAll(buffer); } + +// this returns 1 when all modules are satisfied that the user should be allowed onto the irc server +// (until this returns true, a user will block in the waiting state, waiting to connect up to the +// registration timeout maximum seconds) +bool AllModulesReportReady(userrec* user) +{ + for (int i = 0; i <= MODCOUNT; i++) { + int res = modules[i]->OnCheckReady(user); + if (!res) { + return false; + } + } + } + return true; +} + /* shows the message of the day, and any other on-logon stuff */ void ConnectUser(userrec *user) { // dns is already done, things are fast. no need to wait for dns to complete just pass them straight on - if ((user->dns_done) && (user->registered >= 3)) + if ((user->dns_done) && (user->registered >= 3) && (AllModulesReportReady(user))) { FullConnectUser(user); } @@ -3906,13 +3922,13 @@ int InspIRCd(void) kill_link(count2->second,"Registration timeout"); goto label; } - if ((TIME > count2->second->signon) && (count2->second->registered == 3)) + if ((TIME > count2->second->signon) && (count2->second->registered == 3) && (AllModulesReportReady(user))) { count2->second->dns_done = true; FullConnectUser(count2->second); goto label; } - if ((count2->second->dns_done) && (count2->second->registered == 3)) // both NICK and USER... and DNS + if ((count2->second->dns_done) && (count2->second->registered == 3) && AllModulesReportReady(user))) // both NICK and USER... and DNS { FullConnectUser(count2->second); goto label; diff --git a/src/modules.cpp b/src/modules.cpp index 6ff60b208..12dccdade 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -333,6 +333,8 @@ void Module::OnLoadModule(Module* mod,std::string name) { }; void Module::OnBackgroundTimer(time_t curtime) { }; void Module::OnSendList(userrec* user, chanrec* channel, char mode) { }; int Module::OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user) { return 0; }; +bool Module::OnCheckReady(userrec* user) { return true; }; +void Module::OnUserRegister(userrec* user) { }; // server is a wrapper class that provides methods to all of the C-style // exports in the core |