* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * InspIRCd: (C) 2002-2010 InspIRCd Development Team
* See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
#include "treeserver.h"
#include "link.h"
#include "treesocket.h"
-#include "rconnect.h"
-#include "rsquit.h"
+#include "commands.h"
#include "protocolinterface.h"
-/* $ModDep: m_spanningtree/cachetimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h m_spanningtree/protocolinterface.h */
-
ModuleSpanningTree::ModuleSpanningTree()
- : max_local(0), max_global(0)
{
- ServerInstance->Modules->UseInterface("BufferedSocketHook");
Utils = new SpanningTreeUtilities(this);
- command_rconnect = new CommandRConnect(this, Utils);
- ServerInstance->AddCommand(command_rconnect);
- command_rsquit = new CommandRSQuit(this, Utils);
- ServerInstance->AddCommand(command_rsquit);
+ commands = new SpanningTreeCommands(this);
+ RefreshTimer = NULL;
+}
+
+SpanningTreeCommands::SpanningTreeCommands(ModuleSpanningTree* module)
+ : rconnect(module, module->Utils), rsquit(module, module->Utils),
+ svsjoin(module), svspart(module), svsnick(module), metadata(module),
+ uid(module), opertype(module), fjoin(module), fmode(module), ftopic(module),
+ fhost(module), fident(module), fname(module)
+{
+}
+
+void ModuleSpanningTree::init()
+{
+ ServerInstance->Modules->AddService(commands->rconnect);
+ ServerInstance->Modules->AddService(commands->rsquit);
+ ServerInstance->Modules->AddService(commands->svsjoin);
+ ServerInstance->Modules->AddService(commands->svspart);
+ ServerInstance->Modules->AddService(commands->svsnick);
+ ServerInstance->Modules->AddService(commands->metadata);
+ ServerInstance->Modules->AddService(commands->uid);
+ ServerInstance->Modules->AddService(commands->opertype);
+ ServerInstance->Modules->AddService(commands->fjoin);
+ ServerInstance->Modules->AddService(commands->fmode);
+ ServerInstance->Modules->AddService(commands->ftopic);
+ ServerInstance->Modules->AddService(commands->fhost);
+ ServerInstance->Modules->AddService(commands->fident);
+ ServerInstance->Modules->AddService(commands->fname);
RefreshTimer = new CacheRefreshTimer(Utils);
ServerInstance->Timers->AddTimer(RefreshTimer);
Current->GetDesc().c_str());
}
-int ModuleSpanningTree::CountLocalServs()
-{
- return Utils->TreeRoot->ChildCount();
-}
-
int ModuleSpanningTree::CountServs()
{
return Utils->serverlist.size();
return;
}
-void ModuleSpanningTree::HandleLusers(const std::vector<std::string>& parameters, User* user)
-{
- unsigned int n_users = ServerInstance->Users->UserCount();
-
- /* Only update these when someone wants to see them, more efficient */
- if ((unsigned int)ServerInstance->Users->LocalUserCount() > max_local)
- max_local = ServerInstance->Users->LocalUserCount();
- if (n_users > max_global)
- max_global = n_users;
-
- unsigned int ulined_count = 0;
- unsigned int ulined_local_count = 0;
-
- /* If ulined are hidden and we're not an oper, count the number of ulined servers hidden,
- * locally and globally (locally means directly connected to us)
- */
- if ((Utils->HideULines) && (!IS_OPER(user)))
- {
- for (server_hash::iterator q = Utils->serverlist.begin(); q != Utils->serverlist.end(); q++)
- {
- if (ServerInstance->ULine(q->second->GetName().c_str()))
- {
- ulined_count++;
- if (q->second->GetParent() == Utils->TreeRoot)
- ulined_local_count++;
- }
- }
- }
- user->WriteNumeric(251, "%s :There are %d users and %d invisible on %d servers",user->nick.c_str(),
- n_users-ServerInstance->Users->ModeCount('i'),
- ServerInstance->Users->ModeCount('i'),
- ulined_count ? this->CountServs() - ulined_count : this->CountServs());
-
- if (ServerInstance->Users->OperCount())
- user->WriteNumeric(252, "%s %d :operator(s) online",user->nick.c_str(),ServerInstance->Users->OperCount());
-
- if (ServerInstance->Users->UnregisteredUserCount())
- user->WriteNumeric(253, "%s %d :unknown connections",user->nick.c_str(),ServerInstance->Users->UnregisteredUserCount());
-
- if (ServerInstance->ChannelCount())
- user->WriteNumeric(254, "%s %ld :channels formed",user->nick.c_str(),ServerInstance->ChannelCount());
-
- user->WriteNumeric(255, "%s :I have %d clients and %d servers",user->nick.c_str(),ServerInstance->Users->LocalUserCount(),ulined_local_count ? this->CountLocalServs() - ulined_local_count : this->CountLocalServs());
- user->WriteNumeric(265, "%s :Current Local Users: %d Max: %d",user->nick.c_str(),ServerInstance->Users->LocalUserCount(),max_local);
- user->WriteNumeric(266, "%s :Current Global Users: %d Max: %d",user->nick.c_str(),n_users,max_global);
- return;
-}
-
std::string ModuleSpanningTree::TimeToStr(time_t secs)
{
time_t mins_up = secs / 60;
* Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data.
* This prevents lost REMOTECONNECT notices
*/
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
+restart:
for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++)
{
TreeServer *s = i->second;
+
+ if (s->GetSocket() && s->GetSocket()->GetLinkState() == DYING)
+ {
+ s->GetSocket()->Close();
+ goto restart;
+ }
// Fix for bug #792, do not ping servers that are not connected yet!
// Remote servers have Socket == NULL and local connected servers have
if (sock)
{
sock->SendError("Ping timeout");
- sock->Squit(s,"Ping timeout");
- ServerInstance->SE->DelFd(sock);
sock->Close();
- return;
+ goto restart;
}
}
}
if (ipvalid)
{
/* Gave a hook, but it wasnt one we know */
- TreeSocket* newsocket = new TreeSocket(Utils, x->IPAddr, x->Port, x->Timeout ? x->Timeout : 10,
- x->Name.c_str(), x->Bind, y, x->Hook);
+ TreeSocket* newsocket = new TreeSocket(Utils, x, y, x->IPAddr);
if (newsocket->GetFd() > -1)
{
/* Handled automatically on success */
std::pair<std::string, int> p = i->second;
std::map<TreeSocket*, std::pair<std::string, int> >::iterator me = i;
i++;
- if (curtime > s->age + p.second)
+ if (s->GetLinkState() == DYING)
+ {
+ Utils->timeoutlist.erase(me);
+ s->Close();
+ }
+ else if (curtime > s->age + p.second)
{
ServerInstance->SNO->WriteToSnoMask('l',"CONNECT: Error connecting \002%s\002 (timeout of %d seconds)",p.first.c_str(),p.second);
Utils->timeoutlist.erase(me);
s->Close();
- ServerInstance->GlobalCulls.AddItem(s);
}
}
}
params.push_back(":"+std::string(user->fullname));
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "UID", params);
+ if (IS_OPER(user))
+ {
+ params.clear();
+ params.push_back(user->oper->name);
+ Utils->DoOneToMany(user->uuid,"OPERTYPE",params);
+ }
+
for(Extensible::ExtensibleStore::const_iterator i = user->GetExtList().begin(); i != user->GetExtList().end(); i++)
{
ExtensionItem* item = i->first;
void ModuleSpanningTree::OnLoadModule(Module* mod)
{
- this->RedoConfig(mod);
+ std::string data;
+ data.push_back('+');
+ data.append(mod->ModuleSourceFile);
+ Version v = mod->GetVersion();
+ if (!v.link_data.empty())
+ {
+ data.push_back('=');
+ data.append(v.link_data);
+ }
+ ServerInstance->PI->SendMetaData(NULL, "modules", data);
}
void ModuleSpanningTree::OnUnloadModule(Module* mod)
{
- this->RedoConfig(mod);
+ ServerInstance->PI->SendMetaData(NULL, "modules", "-" + mod->ModuleSourceFile);
+
+ unsigned int items = Utils->TreeRoot->ChildCount();
+ for(unsigned int x = 0; x < items; x++)
+ {
+ TreeServer* srv = Utils->TreeRoot->GetChild(x);
+ TreeSocket* sock = srv->GetSocket();
+ if (sock && sock->GetIOHook() == mod)
+ {
+ sock->SendError("SSL module unloaded");
+ sock->Close();
+ }
+ }
}
void ModuleSpanningTree::RedoConfig(Module* mod)
{
- /* If m_sha256.so is loaded (we use this for HMAC) or any module implementing a BufferedSocket interface is loaded,
- * then we need to re-read our config again taking this into account.
- */
- modulelist* ml = ServerInstance->Modules->FindInterface("BufferedSocketHook");
- bool IsBufferSocketModule = false;
-
- /* Did we find any modules? */
- if (ml && std::find(ml->begin(), ml->end(), mod) != ml->end())
- IsBufferSocketModule = true;
-
- if (mod->ModuleSourceFile == "m_sha256.so" || IsBufferSocketModule)
- {
- Utils->ReadConfiguration();
- }
}
// note: the protocol does not allow direct umode +o except
// locally.
void ModuleSpanningTree::OnOper(User* user, const std::string &opertype)
{
- if (IS_LOCAL(user))
- {
- parameterlist params;
- params.push_back(opertype);
- Utils->DoOneToMany(user->uuid,"OPERTYPE",params);
- }
+ if (user->registered != REG_ALL || !IS_LOCAL(user))
+ return;
+ parameterlist params;
+ params.push_back(opertype);
+ Utils->DoOneToMany(user->uuid,"OPERTYPE",params);
}
void ModuleSpanningTree::OnAddLine(User* user, XLine *x)
{
Utils->cull();
ServerInstance->Timers->DelTimer(RefreshTimer);
- ServerInstance->Modules->DoneWithInterface("BufferedSocketHook");
return this->Module::cull();
}
/* This will also free the listeners */
delete Utils;
- delete command_rconnect;
- delete command_rsquit;
+ delete commands;
}
Version ModuleSpanningTree::GetVersion()