*/
#include "inspircd.h"
-#include "commands/cmd_whois.h"
-#include "commands/cmd_stats.h"
#include "socket.h"
#include "xline.h"
#include "../transport.h"
if (!found)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip);
+ ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip);
ServerInstance->SE->Close(newsock);
return;
}
}
- if (this->GetIOHook())
- {
- this->GetIOHook()->OnRawSocketAccept(newsock, &client, &server);
- }
+ /* we don't need to do anything with the pointer, creating it stores it in the necessary places */
+ TreeSocket* ts = new TreeSocket(Utils, newsock, ip, NULL, Hook);
+
+ if (Hook)
+ Hook->OnStreamSocketAccept(ts, &client, &server);
- /* we don't need a pointer to this, creating it stores it in the necessary places */
- new TreeSocket(this->Utils, this->ServerInstance, newsock, ip, this->GetIOHook());
return;
}
*/
TreeServer* SpanningTreeUtilities::FindServer(const std::string &ServerName)
{
- if (this->ServerInstance->IsSID(ServerName))
+ if (ServerInstance->IsSID(ServerName))
return this->FindServerID(ServerName);
server_hash::iterator iter = serverlist.find(ServerName.c_str());
return (FindServer(ServerName) != NULL);
}
-SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningTree* C) : ServerInstance(Instance), Creator(C)
+SpanningTreeUtilities::SpanningTreeUtilities(ModuleSpanningTree* C) : Creator(C)
{
- Bindings.clear();
-
ServerInstance->Logs->Log("m_spanningtree",DEBUG,"***** Using SID for hash: %s *****", ServerInstance->Config->GetSID().c_str());
- this->TreeRoot = new TreeServer(this, ServerInstance, ServerInstance->Config->ServerName, ServerInstance->Config->ServerDesc, ServerInstance->Config->GetSID());
- this->ServerUser = new FakeUser(ServerInstance, TreeRoot->GetID());
+ this->TreeRoot = new TreeServer(this, ServerInstance->Config->ServerName, ServerInstance->Config->ServerDesc, ServerInstance->Config->GetSID());
+ ServerUser = new FakeUser(TreeRoot->GetID());
this->ReadConfiguration(true);
}
-SpanningTreeUtilities::~SpanningTreeUtilities()
+bool SpanningTreeUtilities::cull()
{
for (unsigned int i = 0; i < Bindings.size(); i++)
{
- delete Bindings[i];
+ Bindings[i]->cull();
}
while (TreeRoot->ChildCount())
if (child_server)
{
TreeSocket* sock = child_server->GetSocket();
- ServerInstance->SE->DelFd(sock);
sock->Close();
}
}
-
- // This avoids a collision on reload
+
ServerUser->uuid = TreeRoot->GetID();
+ if (ServerUser->cull())
+ delete ServerUser;
+ return true;
+}
+
+SpanningTreeUtilities::~SpanningTreeUtilities()
+{
+ for (unsigned int i = 0; i < Bindings.size(); i++)
+ {
+ delete Bindings[i];
+ }
+
delete TreeRoot;
- delete ServerUser;
- ServerInstance->BufferedSocketCull();
}
void SpanningTreeUtilities::AddThisServer(TreeServer* server, TreeServerList &list)
/* returns a list of DIRECT servernames for a specific channel */
void SpanningTreeUtilities::GetListOfServersForChannel(Channel* c, TreeServerList &list, char status, const CUList &exempt_list)
{
- CUList *ulist = c->GetUsers();
+ const UserMembList *ulist = c->GetUsers();
- for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
+ for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
{
if (IS_LOCAL(i->first))
continue;
return;
}
-bool SpanningTreeUtilities::DoOneToAllButSenderRaw(const std::string &data, const std::string &omit, const std::string &prefix, const irc::string &command, std::deque<std::string> ¶ms)
+bool SpanningTreeUtilities::DoOneToAllButSenderRaw(const std::string &data, const std::string &omit, const std::string &prefix, const irc::string &command, parameterlist ¶ms)
{
char pfx = 0;
TreeServer* omitroute = this->BestRouteTo(omit);
User* d = ServerInstance->FindNick(params[0]);
if (d)
{
- std::deque<std::string> par;
+ parameterlist par;
par.push_back(params[0]);
par.push_back(":"+params[1]);
this->DoOneToOne(prefix,command.c_str(),par,d->server);
}
else if (*(params[0].c_str()) == '$')
{
- std::deque<std::string> par;
+ parameterlist par;
par.push_back(params[0]);
par.push_back(":"+params[1]);
this->DoOneToAllButSender(prefix,command.c_str(),par,omitroute->GetName());
return true;
}
-bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const std::string &command, std::deque<std::string> ¶ms, std::string omit)
+bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const std::string &command, parameterlist ¶ms, std::string omit)
{
TreeServer* omitroute = this->BestRouteTo(omit);
std::string FullLine = ":" + prefix + " " + command;
return true;
}
-bool SpanningTreeUtilities::DoOneToMany(const std::string &prefix, const std::string &command, std::deque<std::string> ¶ms)
+bool SpanningTreeUtilities::DoOneToMany(const std::string &prefix, const std::string &command, parameterlist ¶ms)
{
std::string FullLine = ":" + prefix + " " + command;
unsigned int words = params.size();
return true;
}
-bool SpanningTreeUtilities::DoOneToMany(const char* prefix, const char* command, std::deque<std::string> ¶ms)
+bool SpanningTreeUtilities::DoOneToMany(const char* prefix, const char* command, parameterlist ¶ms)
{
std::string spfx = prefix;
std::string scmd = command;
return this->DoOneToMany(spfx, scmd, params);
}
-bool SpanningTreeUtilities::DoOneToAllButSender(const char* prefix, const char* command, std::deque<std::string> ¶ms, std::string omit)
+bool SpanningTreeUtilities::DoOneToAllButSender(const char* prefix, const char* command, parameterlist ¶ms, std::string omit)
{
std::string spfx = prefix;
std::string scmd = command;
return this->DoOneToAllButSender(spfx, scmd, params, omit);
}
-bool SpanningTreeUtilities::DoOneToOne(const std::string &prefix, const std::string &command, std::deque<std::string> ¶ms, std::string target)
+bool SpanningTreeUtilities::DoOneToOne(const std::string &prefix, const std::string &command, parameterlist ¶ms, std::string target)
{
TreeServer* Route = this->BestRouteTo(target);
if (Route)
/* Needs resolving */
bool ipvalid = true;
QueryType start_type = DNS_QUERY_A;
-#ifdef IPV6
start_type = DNS_QUERY_AAAA;
if (strchr(L->IPAddr.c_str(),':'))
{
ipvalid = false;
}
else
-#endif
{
in_addr n;
if (inet_aton(L->IPAddr.c_str(),&n) < 1)
try
{
bool cached;
- SecurityIPResolver* sr = new SecurityIPResolver((Module*)this->Creator, this, ServerInstance, L->IPAddr, *L, cached, start_type);
+ SecurityIPResolver* sr = new SecurityIPResolver(Creator, this, L->IPAddr, *L, cached, start_type);
ServerInstance->AddResolver(sr, cached);
}
catch (...)
void SpanningTreeUtilities::ReadConfiguration(bool rebind)
{
- ConfigReader* Conf = new ConfigReader(ServerInstance);
+ ConfigReader* Conf = new ConfigReader;
/* We don't need to worry about these being *unloaded* on the fly, only loaded,
* because we 'use' the interface locking the module in memory.
{
delete Bindings[i];
}
- ServerInstance->BufferedSocketCull();
Bindings.clear();
for (int j = 0; j < Conf->Enumerate("bind"); j++)
break;
}
- ServerSocketListener *listener = new ServerSocketListener(ServerInstance, this, portno, (char *)IP.c_str());
+ ServerSocketListener *listener = new ServerSocketListener(this, portno, (char *)IP.c_str());
if (listener->GetFd() == -1)
{
delete listener;
}
if (!transport.empty())
- listener->AddIOHook(hooks[transport.c_str()]);
+ listener->Hook = hooks[transport.c_str()];
Bindings.push_back(listener);
}
FlatLinks = Conf->ReadFlag("security","flatlinks",0);
HideULines = Conf->ReadFlag("security","hideulines",0);
AnnounceTSChange = Conf->ReadFlag("options","announcets",0);
+ AllowOptCommon = Conf->ReadFlag("options", "allowmismatch", 0);
ChallengeResponse = !Conf->ReadFlag("security", "disablehmac", 0);
quiet_bursts = Conf->ReadFlag("performance", "quietbursts", 0);
PingWarnTime = Conf->ReadInteger("options", "pingwarning", 0, true);
if (PingWarnTime < 0 || PingWarnTime > PingFreq - 1)
PingWarnTime = 0;
+ AutoconnectBlocks.clear();
LinkBlocks.clear();
ValidIPs.clear();
- for (int j = 0; j < Conf->Enumerate("link"); j++)
+ for (int j = 0; j < Conf->Enumerate("link"); ++j)
{
Link L;
std::string Allow = Conf->ReadValue("link", "allowmask", j);
L.Name = (Conf->ReadValue("link", "name", j)).c_str();
L.AllowMask = Allow;
L.IPAddr = Conf->ReadValue("link", "ipaddr", j);
- L.FailOver = Conf->ReadValue("link", "failover", j).c_str();
L.Port = Conf->ReadInteger("link", "port", j, true);
L.SendPass = Conf->ReadValue("link", "sendpass", j);
L.RecvPass = Conf->ReadValue("link", "recvpass", j);
L.Fingerprint = Conf->ReadValue("link", "fingerprint", j);
- L.AutoConnect = Conf->ReadInteger("link", "autoconnect", j, true);
L.HiddenFromStats = Conf->ReadFlag("link", "statshidden", j);
L.Timeout = Conf->ReadInteger("link", "timeout", j, true);
L.Hook = Conf->ReadValue("link", "transport", j);
}
- // Fix: Only trip autoconnects if this wouldn't delay autoconnect..
- if (L.NextConnectTime > ((time_t)(ServerInstance->Time() + L.AutoConnect)))
- L.NextConnectTime = ServerInstance->Time() + L.AutoConnect;
-
if (L.Name.find('.') == std::string::npos)
throw CoreException("The link name '"+assign(L.Name)+"' is invalid and must contain at least one '.' character");
/* Needs resolving */
bool ipvalid = true;
QueryType start_type = DNS_QUERY_A;
-#ifdef IPV6
start_type = DNS_QUERY_AAAA;
if (strchr(L.IPAddr.c_str(),':'))
{
if (inet_aton(L.IPAddr.c_str(),&n) < 1)
ipvalid = false;
}
-#else
- in_addr n;
- if (inet_aton(L.IPAddr.c_str(),&n) < 1)
- ipvalid = false;
-#endif
if (!ipvalid)
{
try
{
bool cached;
- SecurityIPResolver* sr = new SecurityIPResolver((Module*)this->Creator, this, ServerInstance, L.IPAddr, L, cached, start_type);
+ SecurityIPResolver* sr = new SecurityIPResolver(Creator, this, L.IPAddr, L, cached, start_type);
ServerInstance->AddResolver(sr, cached);
}
catch (...)
LinkBlocks.push_back(L);
}
+
+ for (int j = 0; j < Conf->Enumerate("autoconnect"); ++j)
+ {
+ Autoconnect A;
+ A.Period = Conf->ReadInteger("autoconnect", "period", j, true);
+ A.Server = Conf->ReadValue("autoconnect", "server", j);
+ A.FailOver = Conf->ReadValue("autoconnect", "failover", j).c_str();
+
+ // Fix: Only trip autoconnects if this wouldn't delay autoconnect..
+ if (A.NextConnectTime > ((time_t)(ServerInstance->Time() + A.Period)))
+ A.NextConnectTime = ServerInstance->Time() + A.Period;
+
+ if (A.Period <= 0)
+ {
+ throw CoreException("Invalid configuration for autoconnect, period not a positive integer!");
+ }
+
+ if (A.Server.empty())
+ {
+ throw CoreException("Invalid configuration for autoconnect, server cannot be empty!");
+ }
+
+ AutoconnectBlocks.push_back(A);
+ }
+
delete Conf;
}
-void SpanningTreeUtilities::DoFailOver(Link* x)
+void SpanningTreeUtilities::DoFailOver(Autoconnect* x)
{
- if (x->FailOver.length())
+ if (x && x->FailOver.length())
{
- if (x->FailOver == x->Name)
+ if (x->FailOver == x->Server)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Name.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str());
return;
}
Link* TryThisOne = this->FindLink(x->FailOver.c_str());
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Name.c_str(), TryThisOne->Name.c_str());
- Creator->ConnectServer(TryThisOne);
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str());
+ Creator->ConnectServer(TryThisOne, NULL);
}
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Name.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str());
}
}
}