#include "socketengine.h"
#include "wildcard.h"
#include "xline.h"
+#include "bancache.h"
#include "commands/cmd_whowas.h"
static unsigned long already_sent[MAX_DESCRIPTORS] = {0};
age = ServerInstance->Time(true);
Penalty = 0;
lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
- ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
+ ChannelCount = timeout = bytes_in = bytes_out = cmds_in = cmds_out = 0;
OverPenalty = ExemptFromPenalty = muted = exempt = haspassed = dns_done = false;
fd = -1;
recvq.clear();
if (a.length())
recvq.append(a);
- if (recvq.length() > (unsigned)this->recvqmax)
+ if (this->MyClass && (recvq.length() > this->MyClass->GetRecvqMax()))
{
this->SetWriteError("RecvQ exceeded");
- ServerInstance->WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->recvqmax);
+ ServerInstance->WriteOpers("*** User %s RecvQ of %d exceeds connect class maximum of %d",this->nick,recvq.length(),this->MyClass->GetRecvqMax());
return false;
}
if (*this->GetWriteError())
return;
- if (sendq.length() + data.length() > (unsigned)this->sendqmax)
+ if (this->MyClass && (sendq.length() + data.length() > this->MyClass->GetSendqMax()))
{
/*
* Fix by brain - Set the error text BEFORE calling writeopers, because
* to repeatedly add the text to the sendq!
*/
this->SetWriteError("SendQ exceeded");
- ServerInstance->WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->sendqmax);
+ ServerInstance->WriteOpers("*** User %s SendQ of %d exceeds connect class maximum of %d",this->nick,sendq.length() + data.length(),this->MyClass->GetSendqMax());
return;
}
return;
}
#endif
+ /*
+ * even with bancache, we still have to keep User::exempt current.
+ * besides that, if we get a positive bancache hit, we still won't fuck
+ * them over if they are exempt. -- w00t
+ */
+ New->exempt = (Instance->XLines->MatchesLine("E",New) != NULL);
- New->exempt = (Instance->XLines->matches_exception(New) != NULL);
- if (!New->exempt)
+ if (BanCacheHit *b = Instance->BanCache->GetHit(New->GetIPString()))
{
- ZLine* r = Instance->XLines->matches_zline(ipaddr);
- if (r)
+ if (!b->Type.empty() && !New->exempt)
{
- char reason[MAXBUF];
+ /* user banned */
+ Instance->Log(DEBUG, std::string("BanCache: Positive hit for ") + New->GetIPString());
if (*Instance->Config->MoronBanner)
New->WriteServ("NOTICE %s :*** %s", New->nick, Instance->Config->MoronBanner);
- snprintf(reason,MAXBUF,"Z-Lined: %s",r->reason);
- User::QuitUser(Instance, New, reason);
+ User::QuitUser(Instance, New, b->Reason);
return;
}
+ else
+ {
+ Instance->Log(DEBUG, std::string("BanCache: Negative hit for ") + New->GetIPString());
+ }
+ }
+ else
+ {
+ if (!New->exempt)
+ {
+ XLine* r = Instance->XLines->MatchesLine("Z",New);
+
+ if (r)
+ {
+ r->Apply(New);
+ return;
+ }
+ }
}
if (socket > -1)
return;
}
- this->pingmax = a->GetPingTime();
this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout;
this->timeout = ServerInstance->Time() + a->GetRegTimeout();
- this->flood = a->GetFlood();
- this->threshold = a->GetThreshold();
- this->sendqmax = a->GetSendqMax();
- this->recvqmax = a->GetRecvqMax();
this->MaxChans = a->GetMaxChans();
}
/* Check the password, if one is required by the user's connect class.
* This CANNOT be in CheckClass(), because that is called prior to PASS as well!
*/
- if ((!this->MyClass->GetPass().empty()) && (!this->haspassed))
+ if (this->MyClass && !this->MyClass->GetPass().empty() && !this->haspassed)
{
User::QuitUser(ServerInstance, this, "Invalid password");
return;
}
-
+
if (!this->exempt)
{
- GLine* r = ServerInstance->XLines->matches_gline(this);
+ GLine *r = (GLine *)ServerInstance->XLines->MatchesLine("G", this);
if (r)
{
this->muted = true;
- char reason[MAXBUF];
- if (*ServerInstance->Config->MoronBanner)
- this->WriteServ("NOTICE %s :*** %s", this->nick, ServerInstance->Config->MoronBanner);
- snprintf(reason,MAXBUF,"G-Lined: %s",r->reason);
- User::QuitUser(ServerInstance, this, reason);
+ r->Apply(this);
return;
}
- KLine* n = ServerInstance->XLines->matches_kline(this);
+ KLine *n = (KLine *)ServerInstance->XLines->MatchesLine("K", this);
if (n)
{
this->muted = true;
- char reason[MAXBUF];
- if (*ServerInstance->Config->MoronBanner)
- this->WriteServ("NOTICE %s :*** %s", this, ServerInstance->Config->MoronBanner);
- snprintf(reason,MAXBUF,"K-Lined: %s",n->reason);
- User::QuitUser(ServerInstance, this, reason);
+ n->Apply(this);
return;
}
}
FOREACH_MOD(I_OnPostConnect,OnPostConnect(this));
ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d: %s!%s@%s [%s] [%s]", this->GetPort(), this->nick, this->ident, this->host, this->GetIPString(), this->fullname);
+
+ ServerInstance->Log(DEBUG, "BanCache: Adding NEGATIVE hit for %s", this->GetIPString());
+ ServerInstance->BanCache->AddHit(this->GetIPString(), "", "");
}
/** User::UpdateNick()
return false;
}
- if (ServerInstance->XLines->matches_qline(newnick))
+ if (ServerInstance->XLines->MatchesLine("Q",newnick))
{
ServerInstance->stats->statsCollisions++;
return false;
{
for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
{
- if (explicit_name == i->GetName())
+ ConnectClass* c = *i;
+
+ if (explicit_name == c->GetName() && !c->GetDisabled())
{
- found = &(*i);
+ found = c;
}
}
}
{
for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
{
- if (((match(this->GetIPString(),i->GetHost().c_str(),true)) || (match(this->host,i->GetHost().c_str()))))
+ ConnectClass* c = *i;
+
+ if (((match(this->GetIPString(),c->GetHost().c_str(),true)) || (match(this->host,c->GetHost().c_str()))))
{
- if (i->GetPort())
+ if (c->GetPort())
{
- if (this->GetPort() == i->GetPort())
+ if (this->GetPort() == c->GetPort() && !c->GetDisabled())
{
- found = &(*i);
+ found = c;
}
else
continue;
}
else
{
- found = &(*i);
+ if (!c->GetDisabled())
+ found = c;
}
}
}
/* ensure we don't fuck things up refcount wise, only remove them from a class if we find a new one :P */
if (found)
{
+ /* deny change if change will take class over the limit */
+ if (found->limit && (found->RefCount + 1 >= found->limit))
+ {
+ ServerInstance->Log(DEBUG, "OOPS: Connect class limit (%u) hit, denying", found->limit);
+ return this->MyClass;
+ }
+
/* should always be valid, but just in case .. */
if (this->MyClass)
{
- ServerInstance->Log(DEBUG, "Untying user from connect class -- refcount: %u", this->MyClass->RefCount);
+ if (found == this->MyClass) // no point changing this shit :P
+ return this->MyClass;
this->MyClass->RefCount--;
+ ServerInstance->Log(DEBUG, "Untying user from connect class -- refcount: %u", this->MyClass->RefCount);
}
this->MyClass = found;
this->MyClass->RefCount++;
- ServerInstance->Log(DEBUG, "User tied to class -- connect refcount now: %u", this->MyClass->RefCount);
+ ServerInstance->Log(DEBUG, "User tied to new class -- connect refcount now: %u", this->MyClass->RefCount);
}
return this->MyClass;
if (i2 != ServerInstance->chanlist->end())
{
FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
- DELETE(i2->second);
+ delete i2->second;
ServerInstance->chanlist->erase(i2);
this->chans.erase(*n);
}