X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=ca25fe4a689938d2b09bed10e10cfcbf55f66043;hb=f73cbbafe1bbad627e359078988ce570fbf5d0d9;hp=7204c2435dc1be25ef919f5341dd39e5c2c95b1b;hpb=93e3cda102be0870171ecd9ad0d6507566c7ffd1;p=user%2Fhenk%2Fcode%2Finspircd.git
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index 7204c2435..ca25fe4a6 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -452,6 +452,7 @@ class Link
unsigned long AutoConnect;
time_t NextConnectTime;
std::string EncryptionKey;
+ bool HiddenFromStats;
};
/* The usual stuff for inspircd modules,
@@ -634,12 +635,12 @@ class TreeSocket : public InspSocket
{
if (this->LinkState == CONNECTING)
{
- Srv->SendOpers("*** Connection to "+myhost+"["+this->GetIP()+"] established.");
/* we do not need to change state here. */
for (std::vector::iterator x = LinkBlocks.begin(); x < LinkBlocks.end(); x++)
{
if (x->Name == this->myhost)
{
+ Srv->SendOpers("*** Connection to \2"+myhost+"\2["+(x->HiddenFromStats ? "" : this->GetIP())+"] established.");
this->SendCapabilities();
if (x->EncryptionKey != "")
{
@@ -664,6 +665,7 @@ class TreeSocket : public InspSocket
* If that happens the connection hangs here until it's closed. Unlikely
* and rather harmless.
*/
+ Srv->SendOpers("*** Connection to \2"+myhost+"\2 lost link tag(!)");
return true;
}
@@ -853,6 +855,7 @@ class TreeSocket : public InspSocket
time_t ts = atoi(params[1].c_str());
std::string setby = params[2];
std::string topic = params[3];
+ std::string nsource = source;
chanrec* c = Srv->FindChannel(channel);
if (c)
@@ -868,14 +871,25 @@ class TreeSocket : public InspSocket
* update the set time and set nick.
*/
if (oldtopic != topic)
- WriteChannelWithServ((char*)source.c_str(), c, "TOPIC %s :%s", c->name, c->topic);
+ {
+ userrec* user = Srv->FindNick(source);
+ if (!user)
+ {
+ WriteChannelWithServ((char*)source.c_str(), c, "TOPIC %s :%s", c->name, c->topic);
+ }
+ else
+ {
+ WriteChannel(c, user, "TOPIC %s :%s", c->name, c->topic);
+ nsource = user->server;
+ }
+ }
}
}
/* all done, send it on its way */
params[3] = ":" + params[3];
- DoOneToAllButSender(source,"FTOPIC",params,source);
+ DoOneToAllButSender(source,"FTOPIC",params,nsource);
return true;
}
@@ -1055,7 +1069,7 @@ class TreeSocket : public InspSocket
clientlist[tempnick]->registered = 7;
clientlist[tempnick]->signon = age;
strlcpy(clientlist[tempnick]->modes, modes.c_str(),53);
- strlcpy(clientlist[tempnick]->ip,ip.c_str(),16);
+ inet_aton(ip.c_str(),&clientlist[tempnick]->ip4);
ucrec a;
a.channel = NULL;
@@ -1065,7 +1079,7 @@ class TreeSocket : public InspSocket
if (!this->bursting)
{
- WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host,clientlist[tempnick]->ip);
+ WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host,(char*)inet_ntoa(clientlist[tempnick]->ip4));
}
params[7] = ":" + params[7];
DoOneToAllButSender(source,"NICK",params,source);
@@ -1165,7 +1179,7 @@ class TreeSocket : public InspSocket
for (chan_hash::iterator c = chanlist.begin(); c != chanlist.end(); c++)
{
SendFJoins(Current, c->second);
- snprintf(data,MAXBUF,":%s FMODE %s +%s",Srv->GetServerName().c_str(),c->second->name,chanmodes(c->second));
+ snprintf(data,MAXBUF,":%s FMODE %s +%s",Srv->GetServerName().c_str(),c->second->name,chanmodes(c->second,true));
this->WriteLine(data);
if (*c->second->topic)
{
@@ -1196,7 +1210,7 @@ class TreeSocket : public InspSocket
{
if (u->second->registered == 7)
{
- snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->fullname);
+ snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,(char*)inet_ntoa(u->second->ip4),u->second->fullname);
this->WriteLine(data);
if (strchr(u->second->modes,'o'))
{
@@ -1231,6 +1245,7 @@ class TreeSocket : public InspSocket
/* Send everything else (channel modes, xlines etc) */
this->SendChannelModes(s);
this->SendXLines(s);
+ FOREACH_MOD(I_OnSyncOtherMetaData,OnSyncOtherMetaData((Module*)TreeProtocolModule,(void*)this));
this->WriteLine("ENDBURST");
Srv->SendOpers("*** Finished bursting to \2"+s->GetName()+"\2.");
}
@@ -1459,7 +1474,11 @@ class TreeSocket : public InspSocket
TreeServer* ServerSource = FindServer(prefix);
if (ServerSource)
{
- if (*(params[0].c_str()) == '#')
+ if (params[0] == "*")
+ {
+ FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(TYPE_OTHER,NULL,params[1],params[2]));
+ }
+ else if (*(params[0].c_str()) == '#')
{
chanrec* c = Srv->FindChannel(params[0]);
if (c)
@@ -1467,7 +1486,7 @@ class TreeSocket : public InspSocket
FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(TYPE_CHANNEL,c,params[1],params[2]));
}
}
- else
+ else if (*(params[0].c_str()) != '#')
{
userrec* u = Srv->FindNick(params[0]);
if (u)
@@ -1744,7 +1763,7 @@ class TreeSocket : public InspSocket
Srv->SendOpers("*** Server connection from \2"+servername+"\2 denied, remote server did not enable AES.");
return false;
}
- Srv->SendOpers("*** Verified incoming server connection from \002"+servername+"\002["+this->GetIP()+"] ("+description+")");
+ Srv->SendOpers("*** Verified incoming server connection from \002"+servername+"\002["+(x->HiddenFromStats ? "" : this->GetIP())+"] ("+description+")");
this->InboundServerName = servername;
this->InboundDescription = description;
// this is good. Send our details: Our server name and description and hopcount of 0,
@@ -2029,14 +2048,6 @@ class TreeSocket : public InspSocket
{
return this->ForceTopic(prefix,params);
}
- else if ((command == "KICK") && (!Srv->FindNick(prefix)))
- {
- /* Server kick */
- userrec* who = Srv->FindNick(params[1]);
- chanrec* where = Srv->FindChannel(params[0]);
- server_kick_channel(who, where, (char*)params[2].c_str(), false);
- return true;
- }
else if (command == "REHASH")
{
return this->RemoteRehash(prefix,params);
@@ -2115,6 +2126,32 @@ class TreeSocket : public InspSocket
}
if (who)
{
+ if ((command == "NICK") && (params.size() > 0))
+ {
+ /* On nick messages, check that the nick doesnt
+ * already exist here. If it does, kill their copy,
+ * and our copy.
+ */
+ userrec* x = Srv->FindNick(params[0]);
+ if (x)
+ {
+ std::deque p;
+ p.push_back(params[0]);
+ p.push_back("Nickname collision ("+prefix+" -> "+params[0]+")");
+ DoOneToMany(Srv->GetServerName(),"KILL",p);
+ p.clear();
+ p.push_back(prefix);
+ p.push_back("KILL "+prefix+" :Nickname collision");
+ DoOneToMany(Srv->GetServerName(),"KILL",p);
+ Srv->QuitUser(x,"Nickname collision ("+prefix+" -> "+params[0]+")");
+ userrec* y = Srv->FindNick(prefix);
+ if (y)
+ {
+ Srv->QuitUser(y,"Nickname collision");
+ }
+ return DoOneToAllButSenderRaw(line,sourceserv,prefix,command,params);
+ }
+ }
// its a user
target = who->server;
char* strparams[127];
@@ -2179,7 +2216,7 @@ class TreeSocket : public InspSocket
{
Squit(s,"Remote host closed the connection");
}
- WriteOpers("Server '\2%s\2[%s]' closed the connection.",quitserver.c_str(),this->GetIP().c_str());
+ WriteOpers("Server '\2%s\2' closed the connection.",quitserver.c_str());
}
virtual int OnIncomingConnection(int newsock, char* ip)
@@ -2392,6 +2429,7 @@ void ReadConfiguration(bool rebind)
L.RecvPass = Conf->ReadValue("link","recvpass",j);
L.AutoConnect = Conf->ReadInteger("link","autoconnect",j,true);
L.EncryptionKey = Conf->ReadValue("link","encryptionkey",j);
+ L.HiddenFromStats = Conf->ReadFlag("link","hidden",j);
L.NextConnectTime = time(NULL) + L.AutoConnect;
/* Bugfix by brain, do not allow people to enter bad configurations */
if ((L.RecvPass != "") && (L.SendPass != "") && (L.Name != "") && (L.Port))
@@ -2734,7 +2772,7 @@ class ModuleSpanningTree : public Module
TreeServer* CheckDupe = FindServer(x->Name);
if (!CheckDupe)
{
- WriteServ(user->fd,"NOTICE %s :*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",user->nick,x->Name.c_str(),x->IPAddr.c_str(),x->Port);
+ WriteServ(user->fd,"NOTICE %s :*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",user->nick,x->Name.c_str(),(x->HiddenFromStats ? "" : x->IPAddr.c_str()),x->Port);
TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name);
Srv->AddSocket(newsocket);
return 1;
@@ -2756,7 +2794,7 @@ class ModuleSpanningTree : public Module
{
for (unsigned int i = 0; i < LinkBlocks.size(); i++)
{
- WriteServ(user->fd,"213 %s C *@%s * %s %d 0 %c%c%c",user->nick,LinkBlocks[i].IPAddr.c_str(),LinkBlocks[i].Name.c_str(),LinkBlocks[i].Port,(LinkBlocks[i].EncryptionKey != "" ? 'e' : '-'),(LinkBlocks[i].AutoConnect ? 'a' : '-'),'s');
+ WriteServ(user->fd,"213 %s C *@%s * %s %d 0 %c%c%c",user->nick,(LinkBlocks[i].HiddenFromStats ? "" : LinkBlocks[i].IPAddr).c_str(),LinkBlocks[i].Name.c_str(),LinkBlocks[i].Port,(LinkBlocks[i].EncryptionKey != "" ? 'e' : '-'),(LinkBlocks[i].AutoConnect ? 'a' : '-'),'s');
WriteServ(user->fd,"244 %s H * * %s",user->nick,LinkBlocks[i].Name.c_str());
}
WriteServ(user->fd,"219 %s %c :End of /STATS report",user->nick,statschar);
@@ -3021,7 +3059,7 @@ class ModuleSpanningTree : public Module
params.push_back(user->dhost);
params.push_back(user->ident);
params.push_back("+"+std::string(user->modes));
- params.push_back(user->ip);
+ params.push_back((char*)inet_ntoa(user->ip4));
params.push_back(":"+std::string(user->fullname));
DoOneToMany(Srv->GetServerName(),"NICK",params);
@@ -3062,16 +3100,7 @@ class ModuleSpanningTree : public Module
virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, std::string reason)
{
- if (!source)
- {
- /* Server kick (ugh) */
- std::deque params;
- params.push_back(chan->name);
- params.push_back(user->nick);
- params.push_back(":"+reason);
- DoOneToMany(Srv->GetServerName(),"KICK",params);
- }
- else if (source->fd > -1)
+ if ((source) && (source->fd > -1))
{
std::deque params;
params.push_back(chan->name);
@@ -3236,7 +3265,11 @@ class ModuleSpanningTree : public Module
userrec* u = (userrec*)target;
s->WriteLine(":"+Srv->GetServerName()+" METADATA "+u->nick+" "+extname+" :"+extdata);
}
- else
+ else if (target_type == TYPE_OTHER)
+ {
+ s->WriteLine(":"+Srv->GetServerName()+" METADATA * "+extname+" :"+extdata);
+ }
+ else if (target_type == TYPE_CHANNEL)
{
chanrec* c = (chanrec*)target;
s->WriteLine(":"+Srv->GetServerName()+" METADATA "+c->name+" "+extname+" :"+extdata);
@@ -3244,6 +3277,18 @@ class ModuleSpanningTree : public Module
}
}
+ virtual void OnEvent(Event* event)
+ {
+ if (event->GetEventID() == "send_metadata")
+ {
+ std::deque* params = (std::deque*)event->GetData();
+ if (params->size() < 3)
+ return;
+ (*params)[2] = ":" + (*params)[2];
+ DoOneToMany(Srv->GetServerName(),"METADATA",*params);
+ }
+ }
+
virtual ~ModuleSpanningTree()
{
}
@@ -3261,7 +3306,7 @@ class ModuleSpanningTree : public Module
List[I_OnUserQuit] = List[I_OnUserPostNick] = List[I_OnUserKick] = List[I_OnRemoteKill] = List[I_OnRehash] = 1;
List[I_OnOper] = List[I_OnAddGLine] = List[I_OnAddZLine] = List[I_OnAddQLine] = List[I_OnAddELine] = 1;
List[I_OnDelGLine] = List[I_OnDelZLine] = List[I_OnDelQLine] = List[I_OnDelELine] = List[I_ProtoSendMode] = List[I_OnMode] = 1;
- List[I_OnStats] = List[I_ProtoSendMetaData] = 1;
+ List[I_OnStats] = List[I_ProtoSendMetaData] = List[I_OnEvent] = 1;
}
/* It is IMPORTANT that m_spanningtree is the last module in the chain