Merge pull request #149 from attilamolnar/insp12+spanningtreefixes

[1.2] Fix a number of issues in m_spanningtree
This commit is contained in:
Robin Burchell 2012-06-12 04:55:03 -07:00
commit 99d6f092e4
21 changed files with 178 additions and 289 deletions

View File

@ -34,21 +34,13 @@ bool TreeSocket::Admin(const std::string &prefix, std::deque<std::string> &param
if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
{
/* It's for our server */
string_list results;
User* source = this->ServerInstance->FindNick(prefix);
if (source)
{
std::deque<std::string> par;
par.push_back(prefix);
par.push_back("");
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName;
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName;
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick;
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail;
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail);
}
}
else

View File

@ -35,11 +35,11 @@ std::string TreeSocket::MyCapabilities()
std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(VF_COMMON);
std::string capabilities;
sort(modlist.begin(),modlist.end());
for (unsigned int i = 0; i < modlist.size(); i++)
for (std::vector<std::string>::const_iterator i = modlist.begin(); i != modlist.end(); ++i)
{
if (i)
if (i != modlist.begin())
capabilities = capabilities + ",";
capabilities = capabilities + modlist[i];
capabilities = capabilities + *i;
}
return capabilities;
}

View File

@ -26,14 +26,11 @@
/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */
/** remote MOTD. leet, huh? */
bool TreeSocket::Encap(const std::string &prefix, std::deque<std::string> &params)
{
if (params.size() > 1)
{
if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0]))
if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
{
Event event((char*) &params, (Module*)this->Utils->Creator, "encap_received");
event.Send(ServerInstance);
@ -41,12 +38,21 @@ bool TreeSocket::Encap(const std::string &prefix, std::deque<std::string> &param
params[params.size() - 1] = ":" + params[params.size() - 1];
if (params[0].find('*') != std::string::npos)
if (params[0].find_first_of("*?") != std::string::npos)
{
Utils->DoOneToAllButSender(prefix, "ENCAP", params, prefix);
}
else
Utils->DoOneToOne(prefix, "ENCAP", params, params[0]);
{
/* Only forward when the route to the target is not the same as the sender.
* This occurs with 1.2.9 and older servers, as they broadcast ENCAP even when
* it is targetted to a single server only.
* If we were the only target of this ENCAP, it won't be propagated.
*/
TreeServer* routeserver = Utils->BestRouteTo(params[0]);
if ((routeserver) && (routeserver->GetSocket() != this))
Utils->DoOneToOne(prefix, "ENCAP", params, params[0]);
}
}
return true;
}

View File

@ -43,7 +43,7 @@
/* $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(InspIRCd* Me)
: Module(Me), max_local(0), max_global(0)
: Module(Me), max_local(0), max_global(0), loopCall(false)
{
ServerInstance->Modules->UseInterface("BufferedSocketHook");
Utils = new SpanningTreeUtilities(ServerInstance, this);
@ -67,7 +67,6 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me)
delete ServerInstance->PI;
ServerInstance->PI = new SpanningTreeProtocolInterface(this, Utils, ServerInstance);
loopCall = false;
for (std::vector<User*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)
{
@ -486,110 +485,47 @@ void ModuleSpanningTree::OnWallops(User* user, const std::string &text)
}
}
void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
void ModuleSpanningTree::LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type)
{
/* Server origin */
if (user == NULL)
return;
if (target_type == TYPE_USER)
{
User* d = (User*)dest;
if ((d->GetFd() < 0) && (IS_LOCAL(user)))
if (IS_REMOTE(d))
{
std::deque<std::string> params;
params.clear();
params.push_back(d->uuid);
params.push_back(":"+text);
Utils->DoOneToOne(user->uuid,"NOTICE",params,d->server);
Utils->DoOneToOne(user->uuid, message_type, params, d->server);
}
}
else if (target_type == TYPE_CHANNEL)
{
if (IS_LOCAL(user))
Channel *c = (Channel*)dest;
if (c)
{
Channel *c = (Channel*)dest;
if (c)
{
std::string cname = c->name;
if (status)
cname = status + cname;
TreeServerList list;
Utils->GetListOfServersForChannel(c,list,status,exempt_list);
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
{
TreeSocket* Sock = i->second->GetSocket();
if (Sock)
Sock->WriteLine(":"+std::string(user->uuid)+" NOTICE "+cname+" :"+text);
}
}
Utils->SendChannelMessage(user->uuid, c, text, status, exempt_list, message_type);
}
}
else if (target_type == TYPE_SERVER)
{
if (IS_LOCAL(user))
{
char* target = (char*)dest;
std::deque<std::string> par;
par.push_back(target);
par.push_back(":"+text);
Utils->DoOneToMany(user->uuid,"NOTICE",par);
}
char* target = (char*)dest;
std::deque<std::string> par;
par.push_back(target);
par.push_back(":"+text);
Utils->DoOneToMany(user->uuid, message_type, par);
}
}
void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
{
if ((user) && (IS_LOCAL(user)))
LocalMessage(user, dest, target_type, text, status, exempt_list, "NOTICE");
}
void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
{
/* Server origin */
if (user == NULL)
return;
if (target_type == TYPE_USER)
{
// route private messages which are targetted at clients only to the server
// which needs to receive them
User* d = (User*)dest;
if ((d->GetFd() < 0) && (IS_LOCAL(user)))
{
std::deque<std::string> params;
params.clear();
params.push_back(d->uuid);
params.push_back(":"+text);
Utils->DoOneToOne(user->uuid,"PRIVMSG",params,d->server);
}
}
else if (target_type == TYPE_CHANNEL)
{
if (IS_LOCAL(user))
{
Channel *c = (Channel*)dest;
if (c)
{
std::string cname = c->name;
if (status)
cname = status + cname;
TreeServerList list;
Utils->GetListOfServersForChannel(c,list,status,exempt_list);
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
{
TreeSocket* Sock = i->second->GetSocket();
if (Sock)
Sock->WriteLine(":"+std::string(user->uuid)+" PRIVMSG "+cname+" :"+text);
}
}
}
}
else if (target_type == TYPE_SERVER)
{
if (IS_LOCAL(user))
{
char* target = (char*)dest;
std::deque<std::string> par;
par.push_back(target);
par.push_back(":"+text);
Utils->DoOneToMany(user->uuid,"PRIVMSG",par);
}
}
if ((user) && (IS_LOCAL(user)))
LocalMessage(user, dest, target_type, text, status, exempt_list, "PRIVMSG");
}
void ModuleSpanningTree::OnBackgroundTimer(time_t curtime)
@ -611,7 +547,7 @@ void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool sync, boo
params.push_back(channel->name);
params.push_back(ConvToStr(channel->age));
params.push_back(std::string("+") + channel->ChanModes(true));
params.push_back(ServerInstance->Modes->ModeString(user, channel, false)+","+std::string(user->uuid));
params.push_back(ServerInstance->Modes->ModeString(user, channel, false) + "," + user->uuid);
Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params);
}
}
@ -638,7 +574,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
Utils->DoOneToMany(user->uuid,"FNAME",params);
}
void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
{
if (IS_LOCAL(user))
{
@ -660,8 +596,8 @@ void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const
{
params.push_back(":"+oper_message);
Utils->DoOneToMany(user->uuid,"OPERQUIT",params);
params.clear();
}
params.clear();
params.push_back(":"+reason);
Utils->DoOneToMany(user->uuid,"QUIT",params);
}
@ -789,22 +725,17 @@ void ModuleSpanningTree::OnAddLine(User* user, XLine *x)
if (!x->IsBurstable() || loopCall)
return;
char data[MAXBUF];
snprintf(data,MAXBUF,"%s %s %s %lu %lu :%s", x->type.c_str(), x->Displayable(),
ServerInstance->Config->ServerName, (unsigned long)x->set_time, (unsigned long)x->duration, x->reason);
std::deque<std::string> params;
params.push_back(data);
params.push_back(x->type);
params.push_back(x->Displayable());
params.push_back(ServerInstance->Config->ServerName);
params.push_back(ConvToStr(x->set_time));
params.push_back(ConvToStr(x->duration));
params.push_back(":" + std::string(x->reason));
if (!user)
{
/* Server-set lines */
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ADDLINE", params);
}
else if (IS_LOCAL(user))
{
/* User-set lines */
Utils->DoOneToMany(user->uuid, "ADDLINE", params);
}
/* Server-set lines doesn't have a setter user */
const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID();
Utils->DoOneToMany(source, "ADDLINE", params);
}
void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
@ -812,21 +743,13 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
if (!x->IsBurstable() || loopCall)
return;
char data[MAXBUF];
snprintf(data,MAXBUF,"%s %s", x->type.c_str(), x->Displayable());
std::deque<std::string> params;
params.push_back(data);
params.push_back(x->type);
params.push_back(x->Displayable());
if (!user)
{
/* Server-unset lines */
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "DELLINE", params);
}
else if (IS_LOCAL(user))
{
/* User-unset lines */
Utils->DoOneToMany(user->uuid, "DELLINE", params);
}
/* Server-set lines doesn't have a setter user */
const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID();
Utils->DoOneToMany(source, "DELLINE", params);
}
void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::deque<std::string> &text, const std::deque<TranslateType> &translate)
@ -834,7 +757,6 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
{
std::deque<std::string> params;
std::string command;
std::string output_text;
ServerInstance->Parser->TranslateUIDs(translate, text, output_text);
@ -844,7 +766,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
User* u = (User*)dest;
params.push_back(u->uuid);
params.push_back(output_text);
command = "MODE";
Utils->DoOneToMany(user->uuid, "MODE", params);
}
else
{
@ -852,10 +774,8 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
params.push_back(c->name);
params.push_back(ConvToStr(c->age));
params.push_back(output_text);
command = "FMODE";
Utils->DoOneToMany(user->uuid, "FMODE", params);
}
Utils->DoOneToMany(user->uuid, command, params);
}
}
@ -863,18 +783,10 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
{
if (IS_LOCAL(user))
{
if (awaymsg.empty())
{
std::deque<std::string> params;
params.clear();
Utils->DoOneToMany(user->uuid,"AWAY",params);
}
else
{
std::deque<std::string> params;
std::deque<std::string> params;
if (!awaymsg.empty())
params.push_back(":" + awaymsg);
Utils->DoOneToMany(user->uuid,"AWAY",params);
}
Utils->DoOneToMany(user->uuid,"AWAY",params);
}
return 0;

View File

@ -58,6 +58,7 @@ class ModuleSpanningTree : public Module
SpanningTreeUtilities* Utils;
void RedoConfig(Module* mod, const std::string &name);
void LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type);
public:
CacheRefreshTimer *RefreshTimer;

View File

@ -48,7 +48,7 @@ bool TreeSocket::MetaData(const std::string &prefix, std::deque<std::string> &pa
FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(TYPE_CHANNEL,c,params[1],params[2]));
}
}
else if (*(params[0].c_str()) != '#')
else
{
User* u = this->ServerInstance->FindNick(params[0]);
if (u)

View File

@ -41,41 +41,35 @@ bool TreeSocket::Modules(const std::string &prefix, std::deque<std::string> &par
}
char strbuf[MAXBUF];
std::deque<std::string> par;
par.push_back(prefix);
par.push_back("");
User* source = this->ServerInstance->FindNick(prefix);
if (!source)
return true;
std::vector<std::string> module_names = ServerInstance->Modules->GetAllModuleNames(0);
for (unsigned int i = 0; i < module_names.size(); i++)
for (std::vector<std::string>::const_iterator i = module_names.begin(); i != module_names.end(); ++i)
{
Module* m = ServerInstance->Modules->Find(module_names[i]);
Module* m = ServerInstance->Modules->Find(*i);
Version V = m->GetVersion();
if (IS_OPER(source))
{
std::string flags("Svsc");
std::string flags("Svsc");
int pos = 0;
for (int mult = 1; mult <= VF_SERVICEPROVIDER; mult *= 2, ++pos)
if (!(V.Flags & mult))
flags[pos] = '-';
snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, module_names[i].c_str(), flags.c_str(), V.version.c_str());
snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, i->c_str(), flags.c_str(), V.version.c_str());
}
else
{
snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), module_names[i].c_str());
snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), i->c_str());
}
par[1] = strbuf;
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server);
ServerInstance->PI->PushToClient(source, std::string(strbuf));
}
snprintf(strbuf, MAXBUF, "::%s 703 %s :End of MODULES list", ServerInstance->Config->ServerName, source->nick.c_str());
par[1] = strbuf;
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server);
ServerInstance->PI->PushToClient(source, std::string(strbuf));
return true;
}

View File

@ -36,33 +36,24 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque<std::string> &params
if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
{
/* It's for our server */
string_list results;
User* source = this->ServerInstance->FindNick(prefix);
if (source)
{
std::deque<std::string> par;
par.push_back(prefix);
par.push_back("");
if (!ServerInstance->Config->MOTD.size())
{
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing.";
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing.");
return true;
}
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day";
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day");
for (unsigned int i = 0; i < ServerInstance->Config->MOTD.size(); i++)
std::string lineprefix = std::string("::") + ServerInstance->Config->ServerName + " 372 " + source->nick + " :- ";
for (file_cache::const_iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); ++i)
{
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 372 "+source->nick+" :- "+ServerInstance->Config->MOTD[i];
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, lineprefix + *i);
}
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day.";
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day.");
}
}
else
@ -75,4 +66,3 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque<std::string> &params
}
return true;
}

View File

@ -36,15 +36,12 @@
*/
void TreeSocket::DoBurst(TreeServer* s)
{
std::string name = s->GetName();
std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time());
std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST";
this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).",
name.c_str(),
s->GetName().c_str(),
this->auth_fingerprint ? "SSL Fingerprint and " : "",
this->auth_challenge ? "challenge-response" : "plaintext password");
this->CleanNegotiationInfo();
this->WriteLine(burst);
this->WriteLine(":" + ServerInstance->Config->GetSID() + " BURST " + ConvToStr(ServerInstance->Time()));
/* send our version string */
this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString());
/* Send server tree */
@ -55,8 +52,8 @@ void TreeSocket::DoBurst(TreeServer* s)
this->SendChannelModes(s);
this->SendXLines(s);
FOREACH_MOD_I(this->ServerInstance,I_OnSyncOtherMetaData,OnSyncOtherMetaData((Module*)Utils->Creator,(void*)this));
this->WriteLine(endburst);
this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2.");
this->WriteLine(":" + ServerInstance->Config->GetSID() + " ENDBURST");
this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+s->GetName()+"\2.");
}
/** Recursively send the server tree with distances as hops.
@ -229,9 +226,9 @@ void TreeSocket::SendChannelModes(TreeServer* Current)
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,(Module*)Utils->Creator,(void*)this));
list.clear();
c->second->GetExtList(list);
for (unsigned int j = 0; j < list.size(); j++)
for (std::deque<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
{
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,list[j]));
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,*i));
}
}
}
@ -277,9 +274,9 @@ void TreeSocket::SendUsers(TreeServer* Current)
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this));
list.clear();
u->second->GetExtList(list);
for (unsigned int j = 0; j < list.size(); j++)
for (std::deque<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
{
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,list[j]));
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,*i));
}
}
}

View File

@ -78,18 +78,17 @@ int ModuleSpanningTree::OnStats(char statschar, User* user, string_list &results
if (statschar == 'p')
{
/* show all server ports, after showing client ports. -- w00t */
for (unsigned int i = 0; i < Utils->Bindings.size(); i++)
for (std::vector<ServerSocketListener*>::const_iterator i = Utils->Bindings.begin(); i != Utils->Bindings.end(); ++i)
{
std::string ip = Utils->Bindings[i]->GetIP();
std::string ip = (*i)->GetIP();
if (ip.empty())
ip = "*";
std::string transport("plaintext");
if (Utils->Bindings[i]->GetIOHook())
transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->GetIOHook()).Send();
if ((*i)->GetIOHook())
transport = BufferedSocketNameRequest(this, (*i)->GetIOHook()).Send();
results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->GetPort())+
results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr((*i)->GetPort())+
" (server, " + transport + ")");
}
}

View File

@ -45,7 +45,6 @@ void ModuleSpanningTree::OnPostCommand(const std::string &command, const std::ve
// to have any special provision in place for remote
// commands and linking protocols.
std::deque<std::string> params;
params.clear();
unsigned int n_translate = thiscmd->translation.size();
TranslateType translate_to;

View File

@ -48,7 +48,14 @@ void SpanningTreeProtocolInterface::GetServerList(ProtoServerList &sl)
void SpanningTreeProtocolInterface::SendEncapsulatedData(parameterlist &encap)
{
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap);
if (encap.size() < 2)
return;
const std::string& target = encap[0];
if (target.find_first_of("*?") == std::string::npos)
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "ENCAP", encap, target);
else
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap);
}
void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags type, const std::string &key, const std::string &data)
@ -63,12 +70,10 @@ void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags t
case TYPE_CHANNEL:
params.push_back(((Channel*)target)->name);
break;
case TYPE_OTHER:
case TYPE_SERVER:
params.push_back("*");
break;
default:
throw CoreException("I don't know how to handle TYPE_OTHER.");
break;
}
params.push_back(key);
params.push_back(":" + data);
@ -144,57 +149,32 @@ void SpanningTreeProtocolInterface::PushToClient(User* target, const std::string
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", p, target->server);
}
void SpanningTreeProtocolInterface::SendChannel(Channel* target, char status, const std::string &text)
{
std::string cname = target->name;
if (status)
cname = status + cname;
TreeServerList list;
CUList exempt_list;
Utils->GetListOfServersForChannel(target,list,status,exempt_list);
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
{
TreeSocket* Sock = i->second->GetSocket();
if (Sock)
Sock->WriteLine(text);
}
}
void SpanningTreeProtocolInterface::SendChannelPrivmsg(Channel* target, char status, const std::string &text)
{
SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" PRIVMSG "+target->name+" :"+text);
CUList exempt_list;
Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "PRIVMSG");
}
void SpanningTreeProtocolInterface::SendChannelNotice(Channel* target, char status, const std::string &text)
{
SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" NOTICE "+target->name+" :"+text);
CUList exempt_list;
Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "NOTICE");
}
void SpanningTreeProtocolInterface::SendUserPrivmsg(User* target, const std::string &text)
{
TreeServer* serv = Utils->FindServer(target->server);
if (serv)
{
TreeSocket* sock = serv->GetSocket();
if (sock)
{
sock->WriteLine(":" + ServerInstance->Config->GetSID() + " PRIVMSG " + target->nick + " :"+text);
}
}
parameterlist p;
p.push_back(target->uuid);
p.push_back(":" + text);
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PRIVMSG", p, target->server);
}
void SpanningTreeProtocolInterface::SendUserNotice(User* target, const std::string &text)
{
TreeServer* serv = Utils->FindServer(target->server);
if (serv)
{
TreeSocket* sock = serv->GetSocket();
if (sock)
{
sock->WriteLine(":" + ServerInstance->Config->GetSID() + " NOTICE " + target->nick + " :"+text);
}
}
parameterlist p;
p.push_back(target->uuid);
p.push_back(":" + text);
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "NOTICE", p, target->server);
}
void SpanningTreeProtocolInterface::Introduce(User* user)

View File

@ -27,7 +27,6 @@ class SpanningTreeProtocolInterface : public ProtocolInterface
{
SpanningTreeUtilities* Utils;
ModuleSpanningTree* Module;
void SendChannel(Channel* target, char status, const std::string &text);
public:
SpanningTreeProtocolInterface(ModuleSpanningTree* mod, SpanningTreeUtilities* util, InspIRCd* Instance) : ProtocolInterface(Instance), Utils(util), Module(mod) { }
virtual ~SpanningTreeProtocolInterface() { }

View File

@ -53,7 +53,11 @@ CmdResult CommandRSQuit::Handle (const std::vector<std::string>& parameters, Use
if (server_target == Utils->TreeRoot)
{
NoticeUser(user, "*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)");
std::string msg = ":"+std::string(ServerInstance->Config->ServerName)+" NOTICE "+user->nick+" :*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)";
if (IS_LOCAL(user))
user->Write(msg);
else
ServerInstance->PI->PushToClient(user, ":" + msg);
return CMD_FAILURE;
}
@ -76,20 +80,3 @@ CmdResult CommandRSQuit::Handle (const std::vector<std::string>& parameters, Use
return CMD_SUCCESS;
}
// XXX use protocol interface instead of rolling our own :)
void CommandRSQuit::NoticeUser(User* user, const std::string &msg)
{
if (IS_LOCAL(user))
{
user->WriteServ("NOTICE %s :%s",user->nick.c_str(),msg.c_str());
}
else
{
std::deque<std::string> params;
params.push_back(user->nick);
params.push_back("NOTICE "+ConvToStr(user->nick)+" :"+msg);
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", params, user->server);
}
}

View File

@ -20,7 +20,7 @@
#ifndef __RSQUIT_H__
#define __RSQUIT_H__
/** Handle /RCONNECT
/** Handle /RSQUIT
*/
class CommandRSQuit : public Command
{
@ -29,7 +29,6 @@ class CommandRSQuit : public Command
public:
CommandRSQuit (InspIRCd* Instance, Module* Callback, SpanningTreeUtilities* Util);
CmdResult Handle (const std::vector<std::string>& parameters, User *user);
void NoticeUser(User* user, const std::string &msg);
};
#endif

View File

@ -47,14 +47,10 @@ bool TreeSocket::Stats(const std::string &prefix, std::deque<std::string> &param
User* source = this->ServerInstance->FindNick(prefix);
if (source)
{
std::deque<std::string> par;
par.push_back(prefix);
par.push_back("");
DoStats(this->ServerInstance, *(params[0].c_str()), source, results);
for (size_t i = 0; i < results.size(); i++)
for (string_list::const_iterator i = results.begin(); i != results.end(); ++i)
{
par[1] = "::" + results[i];
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
ServerInstance->PI->PushToClient(source, "::" + *i);
}
}
}

View File

@ -50,7 +50,18 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, std::deque<std::string>
/* only join if it's local, otherwise just pass it on! */
if (IS_LOCAL(u))
Channel::JoinUser(this->ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time());
Utils->DoOneToAllButSender(prefix,"SVSJOIN",params,prefix);
else
{
/* Only forward when the route to the target is not the same as the sender.
* This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART,
* so we can end up here with a user who is reachable via the sender.
* If that's the case, just drop the command.
*/
TreeServer* routeserver = Utils->BestRouteTo(u->server);
if ((routeserver) && (routeserver->GetSocket() != this))
Utils->DoOneToOne(prefix,"SVSJOIN",params,u->server);
}
return true;
}

View File

@ -37,21 +37,30 @@ bool TreeSocket::ServicePart(const std::string &prefix, std::deque<std::string>
if (params.size() < 2)
return true;
std::string reason = "Services forced part";
if (params.size() == 3)
reason = params[2];
User* u = this->ServerInstance->FindNick(params[0]);
Channel* c = this->ServerInstance->FindChan(params[1]);
if (u)
if (u && c)
{
/* only part if it's local, otherwise just pass it on! */
if (IS_LOCAL(u))
{
std::string reason;
reason = (params.size() == 3) ? params[2] : "Services forced part";
if (!c->PartUser(u, reason))
delete c;
Utils->DoOneToAllButSender(prefix,"SVSPART",params,prefix);
}
else
{
/* Only forward when the route to the target is not the same as the sender.
* This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART,
* so we can end up here with a user who is reachable via the sender.
* If that's the case, just drop the command.
*/
TreeServer* routeserver = Utils->BestRouteTo(u->server);
if ((routeserver) && (routeserver->GetSocket() != this))
Utils->DoOneToOne(prefix,"SVSPART",params,u->server);
}
}
return true;

View File

@ -38,7 +38,7 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque<std::string> &pa
*/
if (params.size() < 10)
{
this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + (params.empty() ? "0" : ConvToStr(params.size())) + "!)");
this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + ConvToStr(params.size()) + "!)");
return false;
}

View File

@ -169,9 +169,9 @@ SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningT
SpanningTreeUtilities::~SpanningTreeUtilities()
{
for (unsigned int i = 0; i < Bindings.size(); i++)
for (std::vector<ServerSocketListener*>::iterator i = Bindings.begin(); i != Bindings.end(); ++i)
{
delete Bindings[i];
delete *i;
}
while (TreeRoot->ChildCount())
@ -300,10 +300,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const
{
TreeServer* omitroute = this->BestRouteTo(omit);
std::string FullLine = ":" + prefix + " " + command;
unsigned int words = params.size();
for (unsigned int x = 0; x < words; x++)
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
{
FullLine = FullLine + " " + params[x];
FullLine = FullLine + " " + *i;
}
unsigned int items = this->TreeRoot->ChildCount();
for (unsigned int x = 0; x < items; x++)
@ -326,10 +325,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const
bool SpanningTreeUtilities::DoOneToMany(const std::string &prefix, const std::string &command, std::deque<std::string> &params)
{
std::string FullLine = ":" + prefix + " " + command;
unsigned int words = params.size();
for (unsigned int x = 0; x < words; x++)
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
{
FullLine = FullLine + " " + params[x];
FullLine = FullLine + " " + *i;
}
unsigned int items = this->TreeRoot->ChildCount();
for (unsigned int x = 0; x < items; x++)
@ -365,10 +363,9 @@ bool SpanningTreeUtilities::DoOneToOne(const std::string &prefix, const std::str
if (Route)
{
std::string FullLine = ":" + prefix + " " + command;
unsigned int words = params.size();
for (unsigned int x = 0; x < words; x++)
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
{
FullLine = FullLine + " " + params[x];
FullLine = FullLine + " " + *i;
}
if (Route && Route->GetSocket())
{
@ -472,9 +469,9 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
if (rebind)
{
for (unsigned int i = 0; i < Bindings.size(); i++)
for (std::vector<ServerSocketListener*>::iterator i = Bindings.begin(); i != Bindings.end(); ++i)
{
delete Bindings[i];
delete *i;
}
ServerInstance->BufferedSocketCull();
Bindings.clear();
@ -687,3 +684,20 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name)
}
return NULL;
}
void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type)
{
std::string raw = ":" + prefix + " " + message_type + " ";
if (status)
raw.append(1, status);
raw += target->name + " :" + text;
TreeServerList list;
this->GetListOfServersForChannel(target, list, status, exempt_list);
for (TreeServerList::iterator i = list.begin(); i != list.end(); ++i)
{
TreeSocket* Sock = i->second->GetSocket();
if (Sock)
Sock->WriteLine(raw);
}
}

View File

@ -222,6 +222,10 @@ class SpanningTreeUtilities : public classbase
/** Refresh the IP cache used for allowing inbound connections
*/
void RefreshIPCache();
/** Sends a PRIVMSG or a NOTICE to a channel obeying an exempt list and an optional prefix
*/
void SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type);
};
#endif