+ ConnectClass *found = NULL;
+
+ if (!IS_LOCAL(this))
+ return NULL;
+
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Setting connect class for UID %s", this->uuid.c_str());
+
+ if (!explicit_name.empty())
+ {
+ for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
+ {
+ ConnectClass* c = *i;
+
+ if (explicit_name == c->name)
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Explicitly set to %s", explicit_name.c_str());
+ found = c;
+ }
+ }
+ }
+ else
+ {
+ for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
+ {
+ ConnectClass* c = *i;
+
+ if (c->type == CC_ALLOW)
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "ALLOW %s %d %s", c->host.c_str(), c->GetPort(), c->GetName().c_str());
+ }
+ else
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "DENY %s %d %s", c->GetHost().c_str(), c->GetPort(), c->GetName().c_str());
+ }
+
+ /* check if host matches.. */
+ if (c->GetHost().length() && !InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) &&
+ !InspIRCd::MatchCIDR(this->host, c->GetHost(), NULL))
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "No host match (for %s)", c->GetHost().c_str());
+ continue;
+ }
+
+ /*
+ * deny change if change will take class over the limit check it HERE, not after we found a matching class,
+ * because we should attempt to find another class if this one doesn't match us. -- w00t
+ */
+ if (c->limit && (c->RefCount >= c->limit))
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "OOPS: Connect class limit (%lu) hit, denying", c->limit);
+ continue;
+ }
+
+ /* if it requires a port ... */
+ if (c->GetPort())
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Requires port (%d)", c->GetPort());
+
+ /* and our port doesn't match, fail. */
+ if (this->GetServerPort() != c->GetPort())
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Port match failed (%d)", this->GetServerPort());
+ continue;
+ }
+ }
+
+ /* we stop at the first class that meets ALL critera. */
+ found = c;
+ break;
+ }
+ }
+
+ /*
+ * Okay, assuming we found a class that matches.. switch us into that class, keeping refcounts up to date.
+ */
+ if (found)