diff options
-rw-r--r-- | include/users.h | 151 | ||||
-rw-r--r-- | src/commands.cpp | 8 | ||||
-rw-r--r-- | src/commands/cmd_who.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_check.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_close.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_hostchange.cpp | 3 | ||||
-rw-r--r-- | src/modules/m_httpd_stats.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_ident.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_services_account.cpp | 4 | ||||
-rw-r--r-- | src/stats.cpp | 4 | ||||
-rw-r--r-- | src/user_resolver.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 58 |
12 files changed, 139 insertions, 116 deletions
diff --git a/include/users.h b/include/users.h index fcdc5b374..0be98f3bf 100644 --- a/include/users.h +++ b/include/users.h @@ -286,22 +286,6 @@ class CoreExport User : public StreamSocket */ std::string host; - /** Stats counter for bytes inbound - */ - int bytes_in; - - /** Stats counter for bytes outbound - */ - int bytes_out; - - /** Stats counter for commands inbound - */ - int cmds_in; - - /** Stats counter for commands outbound - */ - int cmds_out; - /** Time the connection was last pinged */ time_t lastping; @@ -324,15 +308,15 @@ class CoreExport User : public StreamSocket */ time_t nping; - /** Stored reverse lookup from res_forward. Should not be used after resolution. + /** Client address that the user is connected from. + * Do not modify this value directly, use SetClientIP() to change it + * Port is not valid for remote users. */ - std::string stored_host; + irc::sockets::sockaddrs client_sa; - /** Starts a DNS lookup of the user's IP. - * This will cause two UserResolver classes to be instantiated. - * When complete, these objects set User::dns_done to true. + /** Stored reverse lookup from res_forward. Should not be used after resolution. */ - void StartDNSLookup(); + std::string stored_host; /** The users nickname. * An invalid nickname indicates an unregistered connection prior to the NICK command. @@ -439,32 +423,16 @@ class CoreExport User : public StreamSocket */ unsigned int exempt:1; - /** Server address and port that this user is connected to. - * If unknown, address family is AF_UNKNOWN - */ - irc::sockets::sockaddrs server_sa; - /** Client address that the user is connected from. - * Port number is only valid if local. - * - * Do not modify this value directly, use SetClientIP() to change it + /** Get client IP string from sockaddr, using static internal buffer + * @return The IP string */ - irc::sockets::sockaddrs client_sa; + const char* GetIPString(); /** Sets the client IP for this user * @return true if the conversion was successful */ bool SetClientIP(const char* sip); - /** - * @return The port number of this user. - */ - int GetServerPort(); - - /** Get client IP string from sockaddr, using static internal buffer - * @return The IP string - */ - const char* GetIPString(); - /** Get a CIDR mask from the IP of this user, using a static internal buffer. * e.g., GetCIDRMask(16) for 223.254.214.52 returns 223.254.0.0/16 * This may be used for CIDR clone detection, etc. @@ -595,13 +563,6 @@ class CoreExport User : public StreamSocket */ bool HasModePermission(unsigned char mode, ModeType type); - /** Adds to the user's write buffer. - * You may add any amount of text up to this users sendq value, if you exceed the - * sendq value, the user will be removed, and further buffer adds will be dropped. - * @param data The data to add to the write buffer - */ - void AddWriteBuf(const std::string &data); - /** Returns the list of channels this user has been invited to but has not yet joined. * @return A list of channels the user is invited to */ @@ -664,14 +625,14 @@ class CoreExport User : public StreamSocket /** Write text to this user, appending CR/LF. Works on local users only. * @param text A std::string to send to the user */ - void Write(const std::string &text); + virtual void Write(const std::string &text); /** Write text to this user, appending CR/LF. * Works on local users only. * @param text The format string for text to send to the user * @param ... POD-type format arguments */ - void Write(const char *text, ...) CUSTOM_PRINTF(2, 3); + virtual void Write(const char *text, ...) CUSTOM_PRINTF(2, 3); /** Write text to this user, appending CR/LF and prepending :server.name * Works on local users only. @@ -842,9 +803,8 @@ class CoreExport User : public StreamSocket */ void IncreasePenalty(int increase); - void OnDataReady(); - void OnError(BufferedSocketError error); - + virtual void OnDataReady(); + virtual void OnError(BufferedSocketError error); /** Default destructor */ virtual ~User(); @@ -859,26 +819,42 @@ class CoreExport User : public StreamSocket */ #define FD_FAKEUSER_NUMBER -7 -/* Useful macros */ - -/** Is a local user */ -#define IS_LOCAL(x) (x->GetFd() > -1) -/** Is a remote user */ -#define IS_REMOTE(x) (x->GetFd() < 0) -/** Is a fake user */ -#define IS_SERVER(x) (x->GetFd() == FD_FAKEUSER_NUMBER) -/** Is a module created user */ -#define IS_MODULE_CREATED(x) (x->GetFd() == FD_MAGIC_NUMBER) -/** Is an oper */ -#define IS_OPER(x) (!x->oper.empty()) -/** Is away */ -#define IS_AWAY(x) (!x->awaymsg.empty()) - class CoreExport LocalUser : public User { public: LocalUser(); - virtual void SendText(const std::string& line); + CullResult cull(); + + /** Stats counter for bytes inbound + */ + int bytes_in; + + /** Stats counter for bytes outbound + */ + int bytes_out; + + /** Stats counter for commands inbound + */ + int cmds_in; + + /** Stats counter for commands outbound + */ + int cmds_out; + + /** Server address and port that this user is connected to. + */ + irc::sockets::sockaddrs server_sa; + + /** + * @return The port number of this user. + */ + int GetServerPort(); + + /** Starts a DNS lookup of the user's IP. + * This will cause two UserResolver classes to be instantiated. + * When complete, these objects set User::dns_done to true. + */ + void StartDNSLookup(); /** Use this method to fully connect a user. * This will send the message of the day, check G/K/E lines, etc. @@ -890,6 +866,18 @@ class CoreExport LocalUser : public User * @return A reference to this user's current connect class. */ ConnectClass *SetClass(const std::string &explicit_name = ""); + + void OnDataReady(); + void SendText(const std::string& line); + void Write(const std::string& text); + void Write(const char*, ...) CUSTOM_PRINTF(2, 3); + + /** Adds to the user's write buffer. + * You may add any amount of text up to this users sendq value, if you exceed the + * sendq value, the user will be removed, and further buffer adds will be dropped. + * @param data The data to add to the write buffer + */ + void AddWriteBuf(const std::string &data); }; class CoreExport RemoteUser : public User @@ -916,6 +904,27 @@ class CoreExport FakeUser : public User void SetFakeServer(std::string name); }; +/* Faster than dynamic_cast */ +/** Is a local user */ +inline LocalUser* IS_LOCAL(User* u) +{ + return u->GetFd() > -1 ? 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; +} +/** Is a server fakeuser */ +inline FakeUser* IS_SERVER(User* u) +{ + return u->GetFd() == FD_FAKEUSER_NUMBER ? static_cast<FakeUser*>(u) : NULL; +} +/** Is an oper */ +#define IS_OPER(x) (!x->oper.empty()) +/** Is away */ +#define IS_AWAY(x) (!x->awaymsg.empty()) + /** Derived from Resolver, and performs user forward/reverse lookups. */ class CoreExport UserResolver : public Resolver @@ -923,7 +932,7 @@ class CoreExport UserResolver : public Resolver private: /** User this class is 'attached' to. */ - User* bound_user; + LocalUser* bound_user; /** File descriptor teh lookup is bound to */ int bound_fd; @@ -938,7 +947,7 @@ class CoreExport UserResolver : public Resolver * @param qt The query type * @param cache Modified by the constructor if the result was cached */ - UserResolver(User* user, std::string to_resolve, QueryType qt, bool &cache); + UserResolver(LocalUser* user, std::string to_resolve, QueryType qt, bool &cache); /** Called on successful lookup * @param result Result string diff --git a/src/commands.cpp b/src/commands.cpp index 41ba0aada..a1a190502 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -112,11 +112,11 @@ bool InspIRCd::NickMatchesEveryone(const std::string &nick, User* user) CmdResult SplitCommand::Handle(const std::vector<std::string>& parms, User* u) { if (IS_LOCAL(u)) - return HandleLocal(parms, static_cast<LocalUser*>(u)); - if (IS_MODULE_CREATED(u)) - return HandleRemote(parms, static_cast<RemoteUser*>(u)); + return HandleLocal(parms, IS_LOCAL(u)); + if (IS_REMOTE(u)) + return HandleRemote(parms, IS_REMOTE(u)); if (IS_SERVER(u)) - return HandleServer(parms, static_cast<FakeUser*>(u)); + return HandleServer(parms, IS_SERVER(u)); ServerInstance->Logs->Log("COMMAND", ERROR, "Unknown user type in command (fd=%d)!", u->GetFd()); return CMD_INVALID; } diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index a0eeaac3d..da797201b 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -123,7 +123,7 @@ bool CommandWho::whomatch(User* cuser, User* user, const char* matchtext) irc::portparser portrange(matchtext, false); long portno = -1; while ((portno = portrange.GetToken())) - if (portno == user->GetServerPort()) + if (IS_LOCAL(user) && portno == IS_LOCAL(user)->GetServerPort()) { match = true; break; diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp index 0b222ba89..51fee9fe5 100644 --- a/src/modules/m_check.cpp +++ b/src/modules/m_check.cpp @@ -101,12 +101,13 @@ class CommandCheck : public Command user->SendText(checkstr + " opertype " + irc::Spacify(targuser->oper.c_str())); } - if (IS_LOCAL(targuser)) + LocalUser* loctarg = IS_LOCAL(targuser); + if (loctarg) { - user->SendText(checkstr + " clientaddr " + irc::sockets::satouser(&targuser->client_sa)); - user->SendText(checkstr + " serveraddr " + irc::sockets::satouser(&targuser->server_sa)); + user->SendText(checkstr + " clientaddr " + irc::sockets::satouser(&loctarg->client_sa)); + user->SendText(checkstr + " serveraddr " + irc::sockets::satouser(&loctarg->server_sa)); - std::string classname = targuser->GetClass()->name; + std::string classname = loctarg->GetClass()->name; if (!classname.empty()) user->SendText(checkstr + " connectclass " + classname); } diff --git a/src/modules/m_close.cpp b/src/modules/m_close.cpp index 5c0c0188b..3a4ee66f0 100644 --- a/src/modules/m_close.cpp +++ b/src/modules/m_close.cpp @@ -40,7 +40,7 @@ class CommandClose : public Command std::vector<LocalUser*>::reverse_iterator u = ServerInstance->Users->local_users.rbegin(); while (u != ServerInstance->Users->local_users.rend()) { - User* user = *u++; + LocalUser* user = *u++; if (user->registered != REG_ALL) { ServerInstance->Users->QuitUser(user, "Closing all unknown connections per request"); diff --git a/src/modules/m_hostchange.cpp b/src/modules/m_hostchange.cpp index 75260d325..7d998e267 100644 --- a/src/modules/m_hostchange.cpp +++ b/src/modules/m_hostchange.cpp @@ -91,8 +91,9 @@ class ModuleHostChange : public Module return Version("Provides masking of user hostnames in a different way to m_cloaking", VF_VENDOR); } - virtual void OnUserConnect(User* user) + virtual void OnUserConnect(User* iuser) { + LocalUser* user = (LocalUser*)iuser; for (hostchanges_t::iterator i = hostchanges.begin(); i != hostchanges.end(); i++) { if (((InspIRCd::MatchCIDR(user->MakeHost(), i->first)) || (InspIRCd::MatchCIDR(user->MakeHostIP(), i->first)))) diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 5288130ce..3339a9ca8 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -169,8 +169,10 @@ class ModuleHttpStats : public Module if (IS_OPER(u)) data << "<opertype>" << Sanitize(u->oper) << "</opertype>"; data << "<modes>" << u->FormatModes() << "</modes><ident>" << Sanitize(u->ident) << "</ident>"; - if (IS_LOCAL(u)) - data << "<port>" << u->GetServerPort() << "</port><servaddr>" << irc::sockets::satouser(&u->server_sa) << "</servaddr>"; + LocalUser* lu = IS_LOCAL(u); + if (lu) + data << "<port>" << lu->GetServerPort() << "</port><servaddr>" + << irc::sockets::satouser(&lu->server_sa) << "</servaddr>"; data << "<ipaddress>" << u->GetIPString() << "</ipaddress>"; DumpMeta(data, u); diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index 95a0529c9..8df849902 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -74,13 +74,13 @@ class IdentRequestSocket : public EventHandler { private: - User *user; /* User we are attached to */ + LocalUser *user; /* User we are attached to */ bool done; /* True if lookup is finished */ std::string result; /* Holds the ident string if done */ public: time_t age; - IdentRequestSocket(User* u) : user(u), result(u->ident) + IdentRequestSocket(LocalUser* u) : user(u), result(u->ident) { age = ServerInstance->Time(); socklen_t size = 0; @@ -319,7 +319,7 @@ class ModuleIdent : public Module try { - IdentRequestSocket *isock = new IdentRequestSocket(user); + IdentRequestSocket *isock = new IdentRequestSocket(IS_LOCAL(user)); ext.set(user, isock); } catch (ModuleException &e) diff --git a/src/modules/m_services_account.cpp b/src/modules/m_services_account.cpp index 58bacb7c8..568fcafb6 100644 --- a/src/modules/m_services_account.cpp +++ b/src/modules/m_services_account.cpp @@ -27,7 +27,7 @@ class Channel_r : public ModeHandler ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { // only a u-lined server may add or remove the +r mode. - if (IS_REMOTE(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) + if (!IS_LOCAL(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) { // Only change the mode if it's not redundant if ((adding && !channel->IsModeSet('r')) || (!adding && channel->IsModeSet('r'))) @@ -56,7 +56,7 @@ class User_r : public ModeHandler ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) { - if (IS_REMOTE(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) + if (!IS_LOCAL(source) || ServerInstance->ULine(source->nick.c_str()) || ServerInstance->ULine(source->server)) { if ((adding && !dest->IsModeSet('r')) || (!adding && dest->IsModeSet('r'))) { diff --git a/src/stats.cpp b/src/stats.cpp index f695104b0..588953f35 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -249,7 +249,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) results.push_back(sn+" 211 "+user->nick+" :nick[ident@host] sendq cmds_out bytes_out cmds_in bytes_in time_open"); for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { - User* i = *n; + LocalUser* i = *n; results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; @@ -259,7 +259,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) results.push_back(sn+" 211 "+user->nick+" :nick[ident@ip] sendq cmds_out bytes_out cmds_in bytes_in time_open"); for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++) { - User* i = *n; + LocalUser* i = *n; results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age)); } break; diff --git a/src/user_resolver.cpp b/src/user_resolver.cpp index bcf8a6aa3..8a2bc71ea 100644 --- a/src/user_resolver.cpp +++ b/src/user_resolver.cpp @@ -12,7 +12,7 @@ */ #include "inspircd.h" -UserResolver::UserResolver(User* user, std::string to_resolve, QueryType qt, bool &cache) : +UserResolver::UserResolver(LocalUser* user, std::string to_resolve, QueryType qt, bool &cache) : Resolver(to_resolve, qt, cache, NULL), bound_user(user) { this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA); diff --git a/src/users.cpp b/src/users.cpp index 899db8bc6..1643c1a37 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -116,7 +116,7 @@ std::string User::ProcessNoticeMasks(const char *sm) return output; } -void User::StartDNSLookup() +void LocalUser::StartDNSLookup() { try { @@ -227,13 +227,11 @@ User::User(const std::string &uid) age = ServerInstance->Time(); Penalty = 0; lastping = signon = idle_lastmsg = nping = registered = 0; - bytes_in = bytes_out = cmds_in = cmds_out = 0; quietquit = quitting = exempt = dns_done = false; fd = -1; - server_sa.sa.sa_family = AF_UNSPEC; - client_sa.sa.sa_family = AF_UNSPEC; AllowedPrivs = AllowedOperCommands = NULL; uuid = uid; + client_sa.sa.sa_family = AF_UNSPEC; ServerInstance->Logs->Log("USERS", DEBUG, "New UUID for user: %s", uuid.c_str()); @@ -246,6 +244,8 @@ User::User(const std::string &uid) LocalUser::LocalUser() : User(ServerInstance->GetUID()) { + bytes_in = bytes_out = cmds_in = cmds_out = 0; + server_sa.sa.sa_family = AF_UNSPEC; } User::~User() @@ -503,6 +503,10 @@ bool User::HasPrivPermission(const std::string &privstr, bool noisy) void User::OnDataReady() { +} + +void LocalUser::OnDataReady() +{ if (quitting) return; @@ -560,11 +564,8 @@ eol_found: Penalty++; } -void User::AddWriteBuf(const std::string &data) +void LocalUser::AddWriteBuf(const std::string &data) { - // Don't bother sending text to remote users! - if (IS_REMOTE(this)) - return; if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers")) { /* @@ -598,17 +599,8 @@ CullResult User::cull() return Extensible::cull(); } PurgeEmptyChannels(); - if (IS_LOCAL(this)) - { - if (fd != INT_MAX) - Close(); - - std::vector<LocalUser*>::iterator x = find(ServerInstance->Users->local_users.begin(),ServerInstance->Users->local_users.end(),this); - if (x != ServerInstance->Users->local_users.end()) - ServerInstance->Users->local_users.erase(x); - else - ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); - } + if (IS_LOCAL(this) && fd != INT_MAX) + Close(); if (this->AllowedOperCommands) { @@ -625,14 +617,24 @@ CullResult User::cull() this->InvalidateCache(); this->DecrementModes(); - if (client_sa.sa.sa_family != AF_UNSPEC) - ServerInstance->Users->RemoveCloneCounts(this); - ServerInstance->Users->uuidlist->erase(uuid); uuid.clear(); return Extensible::cull(); } +CullResult LocalUser::cull() +{ + std::vector<LocalUser*>::iterator x = find(ServerInstance->Users->local_users.begin(),ServerInstance->Users->local_users.end(),this); + if (x != ServerInstance->Users->local_users.end()) + ServerInstance->Users->local_users.erase(x); + else + ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector"); + + if (client_sa.sa.sa_family != AF_UNSPEC) + ServerInstance->Users->RemoveCloneCounts(this); + return User::cull(); +} + void User::Oper(const std::string &opertype, const std::string &opername) { if (this->IsModeSet('o')) @@ -964,7 +966,7 @@ bool User::ForceNickChange(const char* newnick) return false; } -int User::GetServerPort() +int LocalUser::GetServerPort() { switch (this->server_sa.sa.sa_family) { @@ -1096,6 +1098,14 @@ static std::string wide_newline("\r\n"); void User::Write(const std::string& text) { +} + +void User::Write(const char *text, ...) +{ +} + +void LocalUser::Write(const std::string& text) +{ if (!ServerInstance->SE->BoundsCheckFd(this)) return; @@ -1119,7 +1129,7 @@ void User::Write(const std::string& text) /** Write() */ -void User::Write(const char *text, ...) +void LocalUser::Write(const char *text, ...) { va_list argsPtr; char textbuffer[MAXBUF]; |