summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/users.h151
-rw-r--r--src/commands.cpp8
-rw-r--r--src/commands/cmd_who.cpp2
-rw-r--r--src/modules/m_check.cpp9
-rw-r--r--src/modules/m_close.cpp2
-rw-r--r--src/modules/m_hostchange.cpp3
-rw-r--r--src/modules/m_httpd_stats.cpp6
-rw-r--r--src/modules/m_ident.cpp6
-rw-r--r--src/modules/m_services_account.cpp4
-rw-r--r--src/stats.cpp4
-rw-r--r--src/user_resolver.cpp2
-rw-r--r--src/users.cpp58
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 &parameter, 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 &parameter, 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];