summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/users.h36
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp10
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp3
-rw-r--r--src/modules/m_cgiirc.cpp4
-rw-r--r--src/modules/m_dnsbl.cpp2
-rw-r--r--src/stats.cpp4
-rw-r--r--src/user_resolver.cpp6
-rw-r--r--src/usermanager.cpp20
-rw-r--r--src/userprocess.cpp2
-rw-r--r--src/users.cpp61
10 files changed, 78 insertions, 70 deletions
diff --git a/include/users.h b/include/users.h
index ed649f1b9..5cf7669af 100644
--- a/include/users.h
+++ b/include/users.h
@@ -140,7 +140,7 @@ struct CoreExport ConnectClass : public refcountbase
/** Create a new connect class with inherited settings.
*/
ConnectClass(ConfigTag* tag, char type, const std::string& mask, const ConnectClass& parent);
-
+
/** Update the settings in this block to match the given block */
void Update(const ConnectClass* newSettings);
@@ -149,7 +149,7 @@ struct CoreExport ConnectClass : public refcountbase
const std::string& GetPass() { return pass; }
const std::string& GetHost() { return host; }
const int GetPort() { return port; }
-
+
/** Returns the registration timeout
*/
time_t GetRegTimeout()
@@ -213,7 +213,7 @@ struct CoreExport ConnectClass : public refcountbase
* connection is stored here primarily, from the user's socket ID (file descriptor) through to the
* user's nickname and hostname.
*/
-class CoreExport User : public StreamSocket
+class CoreExport User : public Extensible
{
private:
/** Cached nick!ident@dhost value using the displayed hostname
@@ -706,14 +706,28 @@ class CoreExport User : public StreamSocket
*/
void ShowRULES();
- virtual void OnDataReady();
- virtual void OnError(BufferedSocketError error);
/** Default destructor
*/
virtual ~User();
virtual CullResult cull();
};
+class CoreExport UserIOHandler : public StreamSocket
+{
+ public:
+ LocalUser* const user;
+ UserIOHandler(LocalUser* me) : user(me) {}
+ void OnDataReady();
+ void OnError(BufferedSocketError error);
+
+ /** 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 LocalUser : public User
{
/** A list of channels the user has a pending invite to.
@@ -726,6 +740,8 @@ class CoreExport LocalUser : public User
LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
CullResult cull();
+ UserIOHandler eh;
+
/** Stats counter for bytes inbound
*/
int bytes_in;
@@ -797,18 +813,10 @@ class CoreExport LocalUser : public User
*/
void 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);
-
/** 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
*/
@@ -859,6 +867,8 @@ class CoreExport LocalUser : public User
* @return True if the user can set or unset this mode.
*/
bool HasModePermission(unsigned char mode, ModeType type);
+
+ inline int GetFd() { return eh.GetFd(); }
};
class CoreExport RemoteUser : public User
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index d4422a3de..bd22404b3 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -106,11 +106,11 @@ class CommandStartTLS : public SplitCommand
}
else
{
- if (!user->GetIOHook())
+ if (!user->eh.GetIOHook())
{
user->WriteNumeric(670, "%s :STARTTLS successful, go ahead with TLS handshake", user->nick.c_str());
- user->AddIOHook(creator);
- creator->OnStreamSocketAccept(user, NULL, NULL);
+ user->eh.AddIOHook(creator);
+ creator->OnStreamSocketAccept(&user->eh, NULL, NULL);
}
else
user->WriteNumeric(691, "%s :STARTTLS failure", user->nick.c_str());
@@ -129,6 +129,7 @@ class ModuleSSLGnuTLS : public Module
std::string keyfile;
std::string certfile;
+
std::string cafile;
std::string crlfile;
std::string sslports;
@@ -298,12 +299,11 @@ class ModuleSSLGnuTLS : public Module
{
LocalUser* user = IS_LOCAL(static_cast<User*>(item));
- if (user && user->GetIOHook() == this)
+ if (user && user->eh.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.
ServerInstance->Users->QuitUser(user, "SSL module unloading");
- user->DelIOHook();
}
}
}
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index 61b54eceb..5eac93af6 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -250,12 +250,11 @@ class ModuleSSLOpenSSL : public Module
{
LocalUser* user = IS_LOCAL((User*)item);
- if (user && user->GetIOHook() == this)
+ if (user && user->eh.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.
ServerInstance->Users->QuitUser(user, "SSL module unloading");
- user->DelIOHook();
}
}
}
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index cc1e34368..07cf3c376 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -112,7 +112,7 @@ class CGIResolver : public Resolver
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
- if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
+ if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
{
if (notify)
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick.c_str(), them->host.c_str(), result.c_str(), typ.c_str());
@@ -129,7 +129,7 @@ class CGIResolver : public Resolver
virtual void OnError(ResolverError e, const std::string &errormessage)
{
- if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
+ if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
{
if (notify)
ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str());
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 486a816da..d6622dc77 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -63,7 +63,7 @@ class DNSBLResolver : public Resolver
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
- if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
+ if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
{
// Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d
if(result.length())
diff --git a/src/stats.cpp b/src/stats.cpp
index fa11758f9..e8173e655 100644
--- a/src/stats.cpp
+++ b/src/stats.cpp
@@ -250,7 +250,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results)
for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); 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));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->eh.getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age));
}
break;
@@ -260,7 +260,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results)
for (std::vector<LocalUser*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); 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));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->eh.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 8a2bc71ea..b7c17a85a 100644
--- a/src/user_resolver.cpp
+++ b/src/user_resolver.cpp
@@ -23,7 +23,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,
{
UserResolver *res_forward; // for forward-resolution
- if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
+ if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh))
{
this->bound_user->stored_host = result;
try
@@ -50,7 +50,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,
ServerInstance->Logs->Log("RESOLVER", DEBUG,"Error in resolver: %s",e.GetReason());
}
}
- else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
+ else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh))
{
/* Both lookups completed */
@@ -118,7 +118,7 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,
void UserResolver::OnError(ResolverError e, const std::string &errormessage)
{
- if (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user)
+ if (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh)
{
this->bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), this->bound_user->GetIPString());
this->bound_user->dns_done = true;
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index 6315f059d..1e3e9fa72 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -32,15 +32,16 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs
ServerInstance->SNO->WriteToSnoMask('a', "WARNING *** Duplicate UUID allocated!");
return;
}
+ UserIOHandler* eh = &New->eh;
/* Give each of the modules an attempt to hook the user for I/O */
- FOREACH_MOD(I_OnHookIO, OnHookIO(New, via));
+ FOREACH_MOD(I_OnHookIO, OnHookIO(eh, via));
- if (New->GetIOHook())
+ if (eh->GetIOHook())
{
try
{
- New->GetIOHook()->OnStreamSocketAccept(New, client, server);
+ eh->GetIOHook()->OnStreamSocketAccept(eh, client, server);
}
catch (CoreException& modexcept)
{
@@ -127,7 +128,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs
}
}
- if (!ServerInstance->SE->AddFd(New, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE))
+ if (!ServerInstance->SE->AddFd(eh, FD_WANT_FAST_READ | FD_WANT_EDGE_WRITE))
{
ServerInstance->Logs->Log("USERS", DEBUG,"Internal error on new connection");
this->QuitUser(New, "Internal error handling connection");
@@ -192,12 +193,13 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
{
LocalUser* lu = IS_LOCAL(user);
FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(lu));
- lu->DoWrite();
- if (lu->GetIOHook())
+ UserIOHandler* eh = &lu->eh;
+ eh->DoWrite();
+ if (eh->GetIOHook())
{
try
{
- lu->GetIOHook()->OnStreamSocketClose(lu);
+ eh->GetIOHook()->OnStreamSocketClose(eh);
}
catch (CoreException& modexcept)
{
@@ -205,8 +207,8 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
}
}
- ServerInstance->SE->DelFd(lu);
- lu->Close();
+ ServerInstance->SE->DelFd(eh);
+ eh->Close();
}
/*
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 4cc3f0a88..8aa76a1fd 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -58,7 +58,7 @@ void InspIRCd::DoBackgroundUserStuff()
if (curr->Penalty)
{
curr->Penalty--;
- curr->OnDataReady();
+ curr->eh.OnDataReady();
}
switch (curr->registered)
diff --git a/src/users.cpp b/src/users.cpp
index 14edf649f..ec6fd0571 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -240,13 +240,13 @@ User::User(const std::string &uid, const std::string& sid, int type)
}
LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr)
- : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL)
+ : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this)
{
bytes_in = bytes_out = cmds_in = cmds_out = 0;
server_sa.sa.sa_family = AF_UNSPEC;
Penalty = 0;
lastping = nping = 0;
- SetFd(myfd);
+ eh.SetFd(myfd);
memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs));
memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs));
}
@@ -495,29 +495,25 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy)
return false;
}
-void User::OnDataReady()
+void UserIOHandler::OnDataReady()
{
-}
-
-void LocalUser::OnDataReady()
-{
- if (quitting)
+ if (user->quitting)
return;
- if (recvq.length() > MyClass->GetRecvqMax() && !HasPrivPermission("users/flood/increased-buffers"))
+ if (recvq.length() > user->MyClass->GetRecvqMax() && !user->HasPrivPermission("users/flood/increased-buffers"))
{
- ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
+ ServerInstance->Users->QuitUser(user, "RecvQ exceeded");
ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",
- nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax());
+ user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax());
}
unsigned long sendqmax = ULONG_MAX;
- if (!HasPrivPermission("users/flood/increased-buffers"))
- sendqmax = MyClass->GetSendqSoftMax();
- int penaltymax = MyClass->GetPenaltyThreshold();
- if (penaltymax == 0 || HasPrivPermission("users/flood/no-fakelag"))
+ if (!user->HasPrivPermission("users/flood/increased-buffers"))
+ sendqmax = user->MyClass->GetSendqSoftMax();
+ int penaltymax = user->MyClass->GetPenaltyThreshold();
+ if (penaltymax == 0 || user->HasPrivPermission("users/flood/no-fakelag"))
penaltymax = INT_MAX;
- while (Penalty < penaltymax && getSendQSize() < sendqmax)
+ while (user->Penalty < penaltymax && getSendQSize() < sendqmax)
{
std::string line;
line.reserve(MAXBUF);
@@ -546,29 +542,30 @@ eol_found:
// TODO should this be moved to when it was inserted in recvq?
ServerInstance->stats->statsRecv += qpos;
- this->bytes_in += qpos;
- this->cmds_in++;
+ user->bytes_in += qpos;
+ user->cmds_in++;
- ServerInstance->Parser->ProcessBuffer(line, this);
- if (quitting)
+ ServerInstance->Parser->ProcessBuffer(line, user);
+ if (user->quitting)
return;
}
// Add pseudo-penalty so that we continue processing after sendq recedes
- if (Penalty == 0 && getSendQSize() >= sendqmax)
- Penalty++;
+ if (user->Penalty == 0 && getSendQSize() >= sendqmax)
+ user->Penalty++;
}
-void LocalUser::AddWriteBuf(const std::string &data)
+void UserIOHandler::AddWriteBuf(const std::string &data)
{
- if (!quitting && getSendQSize() + data.length() > MyClass->GetSendqHardMax() && !HasPrivPermission("users/flood/increased-buffers"))
+ if (!user->quitting && getSendQSize() + data.length() > user->MyClass->GetSendqHardMax() &&
+ !user->HasPrivPermission("users/flood/increased-buffers"))
{
/*
* Quit the user FIRST, because otherwise we could recurse
* here and hit the same limit.
*/
- ServerInstance->Users->QuitUser(this, "SendQ exceeded");
+ ServerInstance->Users->QuitUser(user, "SendQ exceeded");
ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ exceeds connect class maximum of %lu",
- nick.c_str(), MyClass->GetSendqHardMax());
+ user->nick.c_str(), user->MyClass->GetSendqHardMax());
return;
}
@@ -578,9 +575,9 @@ void LocalUser::AddWriteBuf(const std::string &data)
WriteData(data);
}
-void User::OnError(BufferedSocketError)
+void UserIOHandler::OnError(BufferedSocketError)
{
- ServerInstance->Users->QuitUser(this, getError());
+ ServerInstance->Users->QuitUser(user, getError());
}
CullResult User::cull()
@@ -607,7 +604,7 @@ CullResult LocalUser::cull()
else
ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector");
- Close();
+ eh.cull();
return User::cull();
}
@@ -1001,7 +998,7 @@ void User::Write(const char *text, ...)
void LocalUser::Write(const std::string& text)
{
- if (!ServerInstance->SE->BoundsCheckFd(this))
+ if (!ServerInstance->SE->BoundsCheckFd(&eh))
return;
if (text.length() > MAXBUF - 2)
@@ -1014,8 +1011,8 @@ void LocalUser::Write(const std::string& text)
ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%s] O %s", uuid.c_str(), text.c_str());
- this->AddWriteBuf(text);
- this->AddWriteBuf(wide_newline);
+ eh.AddWriteBuf(text);
+ eh.AddWriteBuf(wide_newline);
ServerInstance->stats->statsSent += text.length() + 2;
this->bytes_out += text.length() + 2;