summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-12 22:30:27 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-12 22:30:27 +0000
commit69e28c67dddd8b74ee4c321667d286111e09e5da (patch)
treeb5de7bc4ab8abfc93b1adc0721f62ba5d54e5760
parent39cf323606a311b3b7f59a9c9f39a21d42520c24 (diff)
Remove possible references to deleted User objects due to DNS lookups
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12445 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/users.h15
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp10
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp8
-rw-r--r--src/modules/m_cgiirc.cpp18
-rw-r--r--src/modules/m_dnsbl.cpp13
-rw-r--r--src/modules/m_testnet.cpp5
-rw-r--r--src/user_resolver.cpp53
-rw-r--r--src/users.cpp71
8 files changed, 79 insertions, 114 deletions
diff --git a/include/users.h b/include/users.h
index 6b891d7da..ed7b6bf5e 100644
--- a/include/users.h
+++ b/include/users.h
@@ -712,6 +712,8 @@ class CoreExport UserIOHandler : public StreamSocket
void AddWriteBuf(const std::string &data);
};
+typedef unsigned int already_sent_t;
+
class CoreExport LocalUser : public User
{
/** A list of channels the user has a pending invite to.
@@ -776,6 +778,9 @@ class CoreExport LocalUser : public User
*/
unsigned int CommandFloodPenalty;
+ static already_sent_t already_sent_id;
+ already_sent_t already_sent;
+
/** Stored reverse lookup from res_forward. Should not be used after resolution.
*/
std::string stored_host;
@@ -851,8 +856,6 @@ 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
@@ -904,12 +907,8 @@ inline FakeUser* IS_SERVER(User* u)
class CoreExport UserResolver : public Resolver
{
private:
- /** User this class is 'attached' to.
- */
- LocalUser* bound_user;
- /** File descriptor teh lookup is bound to
- */
- int bound_fd;
+ /** UUID we are looking up */
+ std::string uuid;
/** True if the lookup is forward, false if is a reverse lookup
*/
bool fwd;
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index c2dc4c878..243c8e28e 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -572,13 +572,13 @@ class ModuleSSLGnuTLS : public Module
{
if (user->eh.GetIOHook() == this)
{
- if (sessions[user->GetFd()].sess)
+ if (sessions[user->eh.GetFd()].sess)
{
- ssl_cert* cert = sessions[user->GetFd()].cert;
+ ssl_cert* cert = sessions[user->eh.GetFd()].cert;
SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), cert);
- std::string cipher = gnutls_kx_get_name(gnutls_kx_get(sessions[user->GetFd()].sess));
- cipher.append("-").append(gnutls_cipher_get_name(gnutls_cipher_get(sessions[user->GetFd()].sess))).append("-");
- cipher.append(gnutls_mac_get_name(gnutls_mac_get(sessions[user->GetFd()].sess)));
+ std::string cipher = gnutls_kx_get_name(gnutls_kx_get(sessions[user->eh.GetFd()].sess));
+ cipher.append("-").append(gnutls_cipher_get_name(gnutls_cipher_get(sessions[user->eh.GetFd()].sess))).append("-");
+ cipher.append(gnutls_mac_get_name(gnutls_mac_get(sessions[user->eh.GetFd()].sess)));
if (cert->fingerprint.empty())
user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), cipher.c_str());
else
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index 018d7351e..7d46cf66a 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -240,13 +240,13 @@ class ModuleSSLOpenSSL : public Module
{
if (user->eh.GetIOHook() == this)
{
- if (sessions[user->GetFd()].sess)
+ if (sessions[user->eh.GetFd()].sess)
{
- SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), sessions[user->GetFd()].cert);
+ SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), sessions[user->eh.GetFd()].cert);
- if (!sessions[user->GetFd()].cert->fingerprint.empty())
+ if (!sessions[user->eh.GetFd()].cert->fingerprint.empty())
user->WriteServ("NOTICE %s :*** You are connected using SSL fingerprint %s",
- user->nick.c_str(), sessions[user->GetFd()].cert->fingerprint.c_str());
+ user->nick.c_str(), sessions[user->eh.GetFd()].cert->fingerprint.c_str());
}
}
}
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index 27309e677..618eec9f5 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -102,17 +102,17 @@ class CommandWebirc : public Command
class CGIResolver : public Resolver
{
std::string typ;
- int theirfd;
- LocalUser* them;
+ std::string theiruid;
bool notify;
public:
- 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) { }
+ CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u, const std::string &type, bool &cached)
+ : Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theiruid(u->uuid), notify(NotifyOpers) { }
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
- if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
+ User* them = ServerInstance->FindUUID(theiruid);
+ if (them)
{
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());
@@ -128,7 +128,9 @@ class CGIResolver : public Resolver
virtual void OnError(ResolverError e, const std::string &errormessage)
{
- if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
+ User* them = ServerInstance->FindUUID(theiruid);
+ if (them)
+ if (them)
{
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());
@@ -298,7 +300,7 @@ public:
{
bool cached;
- CGIResolver* r = new CGIResolver(this, NotifyOpers, user->password, false, user, user->GetFd(), "PASS", cached);
+ CGIResolver* r = new CGIResolver(this, NotifyOpers, user->password, false, user, "PASS", cached);
ServerInstance->AddResolver(r, cached);
}
catch (...)
@@ -349,7 +351,7 @@ public:
{
bool cached;
- CGIResolver* r = new CGIResolver(this, NotifyOpers, newipstr, false, user, user->GetFd(), "IDENT", cached);
+ CGIResolver* r = new CGIResolver(this, NotifyOpers, newipstr, false, user, "IDENT", cached);
ServerInstance->AddResolver(r, cached);
}
catch (...)
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 8fa627ab8..818450b79 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -45,17 +45,15 @@ class DNSBLConfEntry
*/
class DNSBLResolver : public Resolver
{
- int theirfd;
- LocalUser* them;
+ std::string theiruid;
DNSBLConfEntry *ConfEntry;
public:
- DNSBLResolver(Module *me, const std::string &hostname, LocalUser* u, int userfd, DNSBLConfEntry *conf, bool &cached)
+ DNSBLResolver(Module *me, const std::string &hostname, LocalUser* u, DNSBLConfEntry *conf, bool &cached)
: Resolver(hostname, DNS_QUERY_A, cached, me)
{
- theirfd = userfd;
- them = u;
+ theiruid = u->uuid;
ConfEntry = conf;
}
@@ -63,7 +61,8 @@ class DNSBLResolver : public Resolver
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
- if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
+ User* them = ServerInstance->FindUUID(theiruid);
+ if (them)
{
// Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d
if(result.length())
@@ -352,7 +351,7 @@ class ModuleDNSBL : public Module
/* now we'd need to fire off lookups for `hostname'. */
bool cached;
- DNSBLResolver *r = new DNSBLResolver(this, hostname, user, user->GetFd(), *i, cached);
+ DNSBLResolver *r = new DNSBLResolver(this, hostname, user, *i, cached);
ServerInstance->AddResolver(r, cached);
}
diff --git a/src/modules/m_testnet.cpp b/src/modules/m_testnet.cpp
index 43c06978b..cd57cb52b 100644
--- a/src/modules/m_testnet.cpp
+++ b/src/modules/m_testnet.cpp
@@ -194,11 +194,6 @@ class CommandTest : public Command
{
IS_LOCAL(user)->CommandFloodPenalty += atoi(parameters[1].c_str());
}
- else if (parameters[0] == "shutdown" && IS_LOCAL(user))
- {
- int i = parameters.size() > 1 ? atoi(parameters[1].c_str()) : 2;
- ServerInstance->SE->Shutdown(IS_LOCAL(user)->GetFd(), i);
- }
else if (parameters[0] == "check")
{
checkall(creator);
diff --git a/src/user_resolver.cpp b/src/user_resolver.cpp
index 5180d670a..156bb9828 100644
--- a/src/user_resolver.cpp
+++ b/src/user_resolver.cpp
@@ -13,26 +13,26 @@
#include "inspircd.h"
UserResolver::UserResolver(LocalUser* user, std::string to_resolve, QueryType qt, bool &cache) :
- Resolver(to_resolve, qt, cache, NULL), bound_user(user)
+ Resolver(to_resolve, qt, cache, NULL), uuid(user->uuid)
{
this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
- this->bound_fd = user->GetFd();
}
void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
UserResolver *res_forward; // for forward-resolution
+ LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
- if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh))
+ if ((!this->fwd) && bound_user)
{
- this->bound_user->stored_host = result;
+ bound_user->stored_host = result;
try
{
/* Check we didnt time out */
- if (this->bound_user->registered != REG_ALL)
+ if (bound_user->registered != REG_ALL)
{
bool lcached = false;
- if (this->bound_user->client_sa.sa.sa_family == AF_INET6)
+ if (bound_user->client_sa.sa.sa_family == AF_INET6)
{
/* IPV6 forward lookup */
res_forward = new UserResolver(bound_user, result, DNS_QUERY_AAAA, lcached);
@@ -50,11 +50,11 @@ 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) == &bound_user->eh))
+ else if ((this->fwd) && bound_user)
{
/* Both lookups completed */
- irc::sockets::sockaddrs* user_ip = &this->bound_user->client_sa;
+ irc::sockets::sockaddrs* user_ip = &bound_user->client_sa;
bool rev_match = false;
if (user_ip->sa.sa_family == AF_INET6)
{
@@ -75,54 +75,55 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,
if (rev_match)
{
- std::string hostname = this->bound_user->stored_host;
+ std::string hostname = bound_user->stored_host;
if (hostname.length() < 65)
{
/* Check we didnt time out */
- if ((this->bound_user->registered != REG_ALL) && (!this->bound_user->dns_done))
+ if ((bound_user->registered != REG_ALL) && (!bound_user->dns_done))
{
/* Hostnames starting with : are not a good thing (tm) */
if (hostname[0] == ':')
hostname.insert(0, "0");
- this->bound_user->WriteServ("NOTICE Auth :*** Found your hostname (%s)%s", hostname.c_str(), (cached ? " -- cached" : ""));
- this->bound_user->dns_done = true;
- this->bound_user->dhost.assign(hostname, 0, 64);
- this->bound_user->host.assign(hostname, 0, 64);
+ bound_user->WriteServ("NOTICE Auth :*** Found your hostname (%s)%s", hostname.c_str(), (cached ? " -- cached" : ""));
+ bound_user->dns_done = true;
+ bound_user->dhost.assign(hostname, 0, 64);
+ bound_user->host.assign(hostname, 0, 64);
/* Invalidate cache */
- this->bound_user->InvalidateCache();
+ bound_user->InvalidateCache();
}
}
else
{
- if (!this->bound_user->dns_done)
+ if (!bound_user->dns_done)
{
- this->bound_user->WriteServ("NOTICE Auth :*** Your hostname is longer than the maximum of 64 characters, using your IP address (%s) instead.", this->bound_user->GetIPString());
- this->bound_user->dns_done = true;
+ bound_user->WriteServ("NOTICE Auth :*** Your hostname is longer than the maximum of 64 characters, using your IP address (%s) instead.", bound_user->GetIPString());
+ bound_user->dns_done = true;
}
}
}
else
{
- if (!this->bound_user->dns_done)
+ if (!bound_user->dns_done)
{
- this->bound_user->WriteServ("NOTICE Auth :*** Your hostname does not match up with your IP address. Sorry, using your IP address (%s) instead.", this->bound_user->GetIPString());
- this->bound_user->dns_done = true;
+ bound_user->WriteServ("NOTICE Auth :*** Your hostname does not match up with your IP address. Sorry, using your IP address (%s) instead.", bound_user->GetIPString());
+ bound_user->dns_done = true;
}
}
// Save some memory by freeing this up; it's never used again in the user's lifetime.
- this->bound_user->stored_host.resize(0);
+ bound_user->stored_host.resize(0);
}
}
void UserResolver::OnError(ResolverError e, const std::string &errormessage)
{
- if (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh)
+ LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
+ if (bound_user)
{
- 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;
- this->bound_user->stored_host.resize(0);
+ bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), bound_user->GetIPString());
+ bound_user->dns_done = true;
+ bound_user->stored_host.resize(0);
ServerInstance->stats->statsDnsBad++;
}
}
diff --git a/src/users.cpp b/src/users.cpp
index 1a9c2da18..89a064b1f 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -18,37 +18,7 @@
#include "bancache.h"
#include "commands/cmd_whowas.h"
-typedef unsigned int uniq_id_t;
-class sent
-{
- uniq_id_t uniq_id;
- uniq_id_t* array;
- void init()
- {
- if (!array)
- array = new uniq_id_t[ServerInstance->SE->GetMaxFds()];
- memset(array, 0, ServerInstance->SE->GetMaxFds() * sizeof(uniq_id_t));
- uniq_id++;
- }
- public:
- sent() : uniq_id(static_cast<uniq_id_t>(-1)), array(NULL) {}
- inline uniq_id_t operator++()
- {
- if (++uniq_id == 0)
- init();
- return uniq_id;
- }
- inline uniq_id_t& operator[](int i)
- {
- return array[i];
- }
- ~sent()
- {
- delete[] array;
- }
-};
-
-static sent already_sent;
+already_sent_t LocalUser::already_sent_id = 0;
std::string User::ProcessNoticeMasks(const char *sm)
{
@@ -222,12 +192,11 @@ 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), eh(this)
+ : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this),
+ bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0),
+ already_sent(0)
{
- bytes_in = bytes_out = cmds_in = cmds_out = 0;
- server_sa.sa.sa_family = AF_UNSPEC;
- CommandFloodPenalty = 0;
- lastping = nping = 0;
+ lastping = 0;
eh.SetFd(myfd);
memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs));
memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs));
@@ -1193,7 +1162,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
if (this->registered != REG_ALL || quitting)
return;
- uniq_id_t uniq_id = ++already_sent;
+ LocalUser::already_sent_id++;
UserChanList include_c(chans);
std::map<User*,bool> exceptions;
@@ -1207,7 +1176,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
LocalUser* u = IS_LOCAL(i->first);
if (u && !u->quitting)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = LocalUser::already_sent_id;
if (i->second)
u->Write(line);
}
@@ -1219,9 +1188,9 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && already_sent[u->GetFd()] != uniq_id)
+ if (u && !u->quitting && u->already_sent != LocalUser::already_sent_id)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = LocalUser::already_sent_id;
u->Write(line);
}
}
@@ -1236,7 +1205,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
if (this->registered != REG_ALL)
return;
- uniq_id_t uniq_id = ++already_sent;
+ already_sent_t uniq_id = ++LocalUser::already_sent_id;
snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str());
snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str());
@@ -1253,7 +1222,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
LocalUser* u = IS_LOCAL(i->first);
if (u && !u->quitting)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = uniq_id;
if (i->second)
u->Write(IS_OPER(u) ? out2 : out1);
}
@@ -1264,9 +1233,9 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && (already_sent[u->GetFd()] != uniq_id))
+ if (u && !u->quitting && (u->already_sent != uniq_id))
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = uniq_id;
u->Write(IS_OPER(u) ? out2 : out1);
}
}
@@ -1377,8 +1346,8 @@ void User::DoHostCycle(const std::string &quitline)
if (!ServerInstance->Config->CycleHosts)
return;
- uniq_id_t silent_id = ++already_sent;
- uniq_id_t seen_id = ++already_sent;
+ already_sent_t silent_id = ++LocalUser::already_sent_id;
+ already_sent_t seen_id = ++LocalUser::already_sent_id;
UserChanList include_c(chans);
std::map<User*,bool> exceptions;
@@ -1392,12 +1361,12 @@ void User::DoHostCycle(const std::string &quitline)
{
if (i->second)
{
- already_sent[u->GetFd()] = seen_id;
+ u->already_sent = seen_id;
u->Write(quitline);
}
else
{
- already_sent[u->GetFd()] = silent_id;
+ u->already_sent = silent_id;
}
}
}
@@ -1422,13 +1391,13 @@ void User::DoHostCycle(const std::string &quitline)
LocalUser* u = IS_LOCAL(i->first);
if (u == NULL || u == this)
continue;
- if (already_sent[u->GetFd()] == silent_id)
+ if (u->already_sent == silent_id)
continue;
- if (already_sent[u->GetFd()] != seen_id)
+ if (u->already_sent != seen_id)
{
u->Write(quitline);
- already_sent[u->GetFd()] = seen_id;
+ u->already_sent = seen_id;
}
u->Write(joinline);
if (modeline.length() > 0)