diff options
-rw-r--r-- | include/configreader.h | 25 | ||||
-rw-r--r-- | include/inspircd.h | 27 | ||||
-rw-r--r-- | include/socketengine.h | 3 | ||||
-rw-r--r-- | include/users.h | 36 | ||||
-rw-r--r-- | src/command_parse.cpp | 6 | ||||
-rw-r--r-- | src/commands.cpp | 2 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 16 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 15 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_spanningtree/override_whois.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_testnet.cpp | 4 | ||||
-rw-r--r-- | src/modules/ssl.h | 6 | ||||
-rw-r--r-- | src/usermanager.cpp | 15 | ||||
-rw-r--r-- | src/users.cpp | 52 |
15 files changed, 101 insertions, 116 deletions
diff --git a/include/configreader.h b/include/configreader.h index 4b42bcd43..4b425e03b 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -598,4 +598,29 @@ class CoreExport ServerConfig }; +/** The background thread for config reading, so that reading from executable includes + * does not block. + */ +class CoreExport ConfigReaderThread : public Thread +{ + ServerConfig* Config; + volatile bool done; + public: + const std::string TheUserUID; + ConfigReaderThread(const std::string &useruid) + : Config(new ServerConfig), done(false), TheUserUID(useruid) + { + } + + virtual ~ConfigReaderThread() + { + delete Config; + } + + void Run(); + /** Run in the main thread to apply the configuration */ + void Finish(); + bool IsDone() { return done; } +}; + #endif diff --git a/include/inspircd.h b/include/inspircd.h index a183e1ded..2b6fc579a 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -79,10 +79,10 @@ CoreExport extern InspIRCd* ServerInstance; #include "filelogger.h" #include "caller.h" #include "modules.h" +#include "threadengine.h" #include "configreader.h" #include "inspstring.h" #include "protocol.h" -#include "threadengine.h" #ifndef PATH_MAX #warning Potentially broken system, PATH_MAX undefined @@ -240,31 +240,6 @@ DEFINE_HANDLER2(IsChannelHandler, bool, const char*, size_t); DEFINE_HANDLER1(IsSIDHandler, bool, const std::string&); DEFINE_HANDLER1(RehashHandler, void, const std::string&); -/** The background thread for config reading, so that reading from executable includes - * does not block. - */ -class CoreExport ConfigReaderThread : public Thread -{ - ServerConfig* Config; - volatile bool done; - public: - const std::string TheUserUID; - ConfigReaderThread(const std::string &useruid) - : Config(new ServerConfig), done(false), TheUserUID(useruid) - { - } - - virtual ~ConfigReaderThread() - { - delete Config; - } - - void Run(); - /** Run in the main thread to apply the configuration */ - void Finish(); - bool IsDone() { return done; } -}; - /** The main class of the irc server. * This class contains instances of all the other classes in this software. * Amongst other things, it contains a ModeParser, a DNS object, a CommandParser diff --git a/include/socketengine.h b/include/socketengine.h index e0512b3aa..01f66ef21 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -133,9 +133,6 @@ enum EventMask FD_TRIAL_NOTE_MASK = 0x5000 }; -class InspIRCd; -class Module; - /** This class is a basic I/O handler class. * Any object which wishes to receive basic I/O events * from the socketengine must derive from this class and diff --git a/include/users.h b/include/users.h index 0fc6e3723..48f2b470c 100644 --- a/include/users.h +++ b/include/users.h @@ -56,6 +56,12 @@ enum RegistrationState { REG_ALL = 7 /* REG_NICKUSER plus next bit along */ }; +enum UserType { + USERTYPE_LOCAL = 1, + USERTYPE_REMOTE = 2, + USERTYPE_SERVER = 3 +}; + /** Holds information relevent to <connect allow> and <connect deny> tags in the config file. */ struct CoreExport ConnectClass : public refcountbase @@ -357,6 +363,9 @@ class CoreExport User : public StreamSocket */ unsigned int lastping:1; + /** What type of user is this? */ + const unsigned int usertype:2; + /** Get client IP string from sockaddr, using static internal buffer * @return The IP string */ @@ -371,13 +380,10 @@ class CoreExport User : public StreamSocket */ bool SetClientIP(const char* sip); - /** Default constructor + /** Constructor * @throw CoreException if the UID allocated to the user already exists - * @param Instance Creator instance - * @param uid User UUID, or empty to allocate one automatically - * @param srv Server that this user is from */ - User(const std::string &uid, const std::string& srv); + User(const std::string &uid, const std::string& srv, int objtype); /** Check if the user matches a G or K line, and disconnect them if they do. * @param doZline True if ZLines should be checked (if IP has changed since initial connect) @@ -708,14 +714,6 @@ class CoreExport User : public StreamSocket virtual CullResult cull(); }; -/** Represents a non-local user. - * (in fact, any FD less than -1 does) - */ -#define FD_MAGIC_NUMBER -42 -/** Represents a fake user (i.e. a server) - */ -#define FD_FAKEUSER_NUMBER -7 - class CoreExport LocalUser : public User { /** A list of channels the user has a pending invite to. @@ -866,9 +864,8 @@ class CoreExport LocalUser : public User class CoreExport RemoteUser : public User { public: - RemoteUser(const std::string& uid, const std::string& srv) : User(uid, srv) + RemoteUser(const std::string& uid, const std::string& srv) : User(uid, srv, USERTYPE_REMOTE) { - SetFd(FD_MAGIC_NUMBER); } virtual void SendText(const std::string& line); }; @@ -876,9 +873,8 @@ class CoreExport RemoteUser : public User class CoreExport FakeUser : public User { public: - FakeUser(const std::string &uid, const std::string& srv) : User(uid, srv) + FakeUser(const std::string &uid, const std::string& srv) : User(uid, srv, USERTYPE_SERVER) { - SetFd(FD_FAKEUSER_NUMBER); nick = srv; } @@ -892,17 +888,17 @@ class CoreExport FakeUser : public User /** Is a local user */ inline LocalUser* IS_LOCAL(User* u) { - return u->GetFd() > -1 ? static_cast<LocalUser*>(u) : NULL; + return u->usertype == USERTYPE_LOCAL ? static_cast<LocalUser*>(u) : NULL; } /** Is a remote user */ inline RemoteUser* IS_REMOTE(User* u) { - return u->GetFd() == FD_MAGIC_NUMBER ? static_cast<RemoteUser*>(u) : NULL; + return u->usertype == USERTYPE_REMOTE ? static_cast<RemoteUser*>(u) : NULL; } /** Is a server fakeuser */ inline FakeUser* IS_SERVER(User* u) { - return u->GetFd() == FD_FAKEUSER_NUMBER ? static_cast<FakeUser*>(u) : NULL; + return u->usertype == USERTYPE_SERVER ? static_cast<FakeUser*>(u) : NULL; } /** Is an oper */ #define IS_OPER(x) (x->oper) diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 883507058..772b23117 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -412,8 +412,8 @@ bool CommandParser::ProcessBuffer(std::string &buffer,User *user) if (!user || buffer.empty()) return true; - ServerInstance->Logs->Log("USERINPUT", DEBUG, "C[%d] I :%s %s", - user->GetFd(), user->nick.c_str(), buffer.c_str()); + ServerInstance->Logs->Log("USERINPUT", DEBUG, "C[%s] I :%s %s", + user->uuid.c_str(), user->nick.c_str(), buffer.c_str()); return ProcessCommand(user,buffer); } @@ -428,7 +428,7 @@ bool CommandParser::AddCommand(Command *f) return false; } -CommandParser::CommandParser() +CommandParser::CommandParser() { para.resize(128); } diff --git a/src/commands.cpp b/src/commands.cpp index a1a190502..9de3bbead 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -117,7 +117,7 @@ CmdResult SplitCommand::Handle(const std::vector<std::string>& parms, User* u) return HandleRemote(parms, IS_REMOTE(u)); if (IS_SERVER(u)) return HandleServer(parms, IS_SERVER(u)); - ServerInstance->Logs->Log("COMMAND", ERROR, "Unknown user type in command (fd=%d)!", u->GetFd()); + ServerInstance->Logs->Log("COMMAND", ERROR, "Unknown user type in command (uuid=%s)!", u->uuid.c_str()); return CMD_INVALID; } diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 25b47c2fe..95beff3aa 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -86,15 +86,15 @@ public: issl_status status; }; -class CommandStartTLS : public Command +class CommandStartTLS : public SplitCommand { public: - CommandStartTLS (Module* mod) : Command(mod, "STARTTLS") + CommandStartTLS (Module* mod) : SplitCommand(mod, "STARTTLS") { works_before_reg = true; } - CmdResult Handle (const std::vector<std::string> ¶meters, User *user) + CmdResult HandleLocal(const std::vector<std::string> ¶meters, LocalUser *user) { /* changed from == REG_ALL to catch clients sending STARTTLS * after NICK and USER but before OnUserConnect completes and @@ -158,7 +158,7 @@ class ModuleSSLGnuTLS : public Module // Void return, guess we assume success gnutls_certificate_set_dh_params(x509_cred, dh_params); - Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, + Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnUserConnect, I_OnEvent, I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); @@ -296,9 +296,9 @@ class ModuleSSLGnuTLS : public Module { if(target_type == TYPE_USER) { - User* user = static_cast<User*>(item); + LocalUser* user = IS_LOCAL(static_cast<User*>(item)); - if (user->GetIOHook() == this) + if (user && user->GetIOHook() == this) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. @@ -547,10 +547,8 @@ class ModuleSSLGnuTLS : public Module } } - void OnPostConnect(User* user) + void OnUserConnect(LocalUser* user) { - // This occurs AFTER OnUserConnect so we can be sure the - // protocol module has propagated the NICK message. if (user->GetIOHook() == this) { if (sessions[user->GetFd()].sess) diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 25d1cd9dd..61b54eceb 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -125,9 +125,7 @@ class ModuleSSLOpenSSL : public Module // Needs the flag as it ignores a plain /rehash OnModuleRehash(NULL,"ssl"); - Implementation eventlist[] = { - I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnPostConnect, - I_OnHookIO }; + Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } @@ -250,9 +248,9 @@ class ModuleSSLOpenSSL : public Module { if (target_type == TYPE_USER) { - User* user = (User*)item; + LocalUser* user = IS_LOCAL((User*)item); - if (user->GetIOHook() == this) + if (user && user->GetIOHook() == this) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. @@ -597,13 +595,6 @@ class ModuleSSLOpenSSL : public Module X509_free(cert); SSLCertSubmission(user, this, sslinfo, certinfo); } - - void Prioritize() - { - Module* server = ServerInstance->Modules->Find("m_spanningtree.so"); - ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIORITY_AFTER, &server); - } - }; static int error_callback(const char *str, size_t len, void *u) diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 5f8cfeca7..49a96c42d 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -103,10 +103,10 @@ class CGIResolver : public Resolver { std::string typ; int theirfd; - User* them; + LocalUser* them; bool notify; public: - CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, User* u, int userfd, const std::string &type, bool &cached) + CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u, int userfd, const std::string &type, bool &cached) : Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { } virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index d14f0ebe4..8da34af53 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -490,7 +490,7 @@ void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, c if (target_type == TYPE_USER) { User* d = (User*)dest; - if ((d->GetFd() < 0) && (IS_LOCAL(user))) + if (!IS_LOCAL(d) && IS_LOCAL(user)) { parameterlist params; params.push_back(d->uuid); @@ -543,7 +543,7 @@ void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, // route private messages which are targetted at clients only to the server // which needs to receive them User* d = (User*)dest; - if ((d->GetFd() < 0) && (IS_LOCAL(user))) + if (!IS_LOCAL(d) && (IS_LOCAL(user))) { parameterlist params; params.push_back(d->uuid); diff --git a/src/modules/m_spanningtree/override_whois.cpp b/src/modules/m_spanningtree/override_whois.cpp index ee3be53fd..db75973d1 100644 --- a/src/modules/m_spanningtree/override_whois.cpp +++ b/src/modules/m_spanningtree/override_whois.cpp @@ -29,7 +29,7 @@ ModResult ModuleSpanningTree::HandleRemoteWhois(const std::vector<std::string>& if ((IS_LOCAL(user)) && (parameters.size() > 1)) { User* remote = ServerInstance->FindNick(parameters[1]); - if ((remote) && (remote->GetFd() < 0)) + if (remote && !IS_LOCAL(remote)) { parameterlist params; params.push_back(remote->uuid); diff --git a/src/modules/m_testnet.cpp b/src/modules/m_testnet.cpp index 7f825a728..e467923c9 100644 --- a/src/modules/m_testnet.cpp +++ b/src/modules/m_testnet.cpp @@ -36,10 +36,10 @@ class CommandTest : public Command { IS_LOCAL(user)->Penalty += 100; } - else if (parameters[0] == "shutdown") + else if (parameters[0] == "shutdown" && IS_LOCAL(user)) { int i = parameters.size() > 1 ? atoi(parameters[1].c_str()) : 2; - ServerInstance->SE->Shutdown(user->GetFd(), i); + ServerInstance->SE->Shutdown(IS_LOCAL(user)->GetFd(), i); } return CMD_SUCCESS; } diff --git a/src/modules/ssl.h b/src/modules/ssl.h index 39a7ef5f6..3bc78cf98 100644 --- a/src/modules/ssl.h +++ b/src/modules/ssl.h @@ -128,6 +128,12 @@ struct SSLCertificateRequest : public Request Send(); } + SSLCertificateRequest(Extensible* e, Module* Me, Module* info = ServerInstance->Modules->Find("m_sslinfo.so")) + : Request(Me, info, "GET_CERT"), item(e), cert(NULL) + { + Send(); + } + std::string GetFingerprint() { if (cert) diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 06d6ad1cd..f620a264d 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -195,13 +195,14 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char if (IS_LOCAL(user)) { - FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(IS_LOCAL(user))); - user->DoWrite(); - if (user->GetIOHook()) + LocalUser* lu = IS_LOCAL(user); + FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(lu)); + lu->DoWrite(); + if (lu->GetIOHook()) { try { - user->GetIOHook()->OnStreamSocketClose(user); + lu->GetIOHook()->OnStreamSocketClose(lu); } catch (CoreException& modexcept) { @@ -209,10 +210,8 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char } } - ServerInstance->SE->DelFd(user); - user->Close(); - // user->Close() will set fd to -1; this breaks IS_LOCAL. Fix - user->SetFd(INT_MAX); + ServerInstance->SE->DelFd(lu); + lu->Close(); } /* diff --git a/src/users.cpp b/src/users.cpp index cf2d11a0a..58c105047 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -221,14 +221,13 @@ void User::DecrementModes() } } -User::User(const std::string &uid, const std::string& sid) - : uuid(uid), server(sid) +User::User(const std::string &uid, const std::string& sid, int type) + : uuid(uid), server(sid), usertype(type) { age = ServerInstance->Time(); signon = idle_lastmsg = 0; registered = 0; quietquit = quitting = exempt = dns_done = false; - fd = -1; client_sa.sa.sa_family = AF_UNSPEC; ServerInstance->Logs->Log("USERS", DEBUG, "New UUID for user: %s", uuid.c_str()); @@ -240,7 +239,7 @@ User::User(const std::string &uid, const std::string& sid) throw CoreException("Duplicate UUID "+std::string(uuid)+" in User constructor"); } -LocalUser::LocalUser() : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName) +LocalUser::LocalUser() : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL) { bytes_in = bytes_out = cmds_in = cmds_out = 0; server_sa.sa.sa_family = AF_UNSPEC; @@ -585,8 +584,6 @@ CullResult User::cull() if (!quitting) ServerInstance->Users->QuitUser(this, "Culled without QuitUser"); PurgeEmptyChannels(); - if (IS_LOCAL(this) && fd != INT_MAX) - Close(); this->InvalidateCache(); this->DecrementModes(); @@ -605,6 +602,7 @@ CullResult LocalUser::cull() if (client_sa.sa.sa_family != AF_UNSPEC) ServerInstance->Users->RemoveCloneCounts(this); + Close(); return User::cull(); } @@ -1174,10 +1172,10 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { - User* u = i->first; - if (IS_LOCAL(u) && !u->quitting) + LocalUser* u = IS_LOCAL(i->first); + if (u && !u->quitting) { - already_sent[u->fd] = uniq_id; + already_sent[u->GetFd()] = uniq_id; if (i->second) u->Write(line); } @@ -1188,10 +1186,10 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) const UserMembList* ulist = c->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { - User* u = i->first; - if (IS_LOCAL(u) && !u->quitting && already_sent[u->fd] != uniq_id) + LocalUser* u = IS_LOCAL(i->first); + if (u && !u->quitting && already_sent[u->GetFd()] != uniq_id) { - already_sent[u->fd] = uniq_id; + already_sent[u->GetFd()] = uniq_id; u->Write(line); } } @@ -1220,10 +1218,10 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { - User* u = i->first; - if (IS_LOCAL(u) && !u->quitting) + LocalUser* u = IS_LOCAL(i->first); + if (u && !u->quitting) { - already_sent[u->fd] = uniq_id; + already_sent[u->GetFd()] = uniq_id; if (i->second) u->Write(IS_OPER(u) ? out2 : out1); } @@ -1233,10 +1231,10 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op const UserMembList* ulist = (*v)->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { - User* u = i->first; - if (IS_LOCAL(u) && !u->quitting && (already_sent[u->fd] != uniq_id)) + LocalUser* u = IS_LOCAL(i->first); + if (u && !u->quitting && (already_sent[u->GetFd()] != uniq_id)) { - already_sent[u->fd] = uniq_id; + already_sent[u->GetFd()] = uniq_id; u->Write(IS_OPER(u) ? out2 : out1); } } @@ -1357,17 +1355,17 @@ void User::DoHostCycle(const std::string &quitline) for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { - User* u = i->first; - if (IS_LOCAL(u) && !u->quitting) + LocalUser* u = IS_LOCAL(i->first); + if (u && !u->quitting) { if (i->second) { - already_sent[u->fd] = seen_id; + already_sent[u->GetFd()] = seen_id; u->Write(quitline); } else { - already_sent[u->fd] = silent_id; + already_sent[u->GetFd()] = silent_id; } } } @@ -1389,16 +1387,16 @@ void User::DoHostCycle(const std::string &quitline) const UserMembList *ulist = c->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { - User* u = i->first; - if (u == this || !IS_LOCAL(u)) + LocalUser* u = IS_LOCAL(i->first); + if (u == NULL || u == this) continue; - if (already_sent[u->fd] == silent_id) + if (already_sent[u->GetFd()] == silent_id) continue; - if (already_sent[u->fd] != seen_id) + if (already_sent[u->GetFd()] != seen_id) { u->Write(quitline); - already_sent[i->first->fd] = seen_id; + already_sent[u->GetFd()] = seen_id; } u->Write(joinline); if (modeline.length() > 0) |