diff options
-rw-r--r-- | include/socket.h | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 105 | ||||
-rw-r--r-- | src/socket.cpp | 7 |
3 files changed, 102 insertions, 12 deletions
diff --git a/include/socket.h b/include/socket.h index 4d4b44587..ace21b78f 100644 --- a/include/socket.h +++ b/include/socket.h @@ -40,6 +40,7 @@ private: bool timeout; pollfd polls; char ibuf[1024]; + std::string IP; sockaddr_in client; sockaddr_in server; socklen_t length; @@ -54,6 +55,7 @@ public: virtual void OnTimeout(); virtual void OnClose(); virtual char* Read(); + std::string GetIP(); virtual int Write(std::string data); virtual int OnIncomingConnection(int newfd, char* ip); void SetState(InspSocketState s); diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index ebf65835f..71f3af876 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -107,25 +107,52 @@ class TreeSocket : public InspSocket std::string myhost; std::string in_buffer; ServerState LinkState; + std::string InboundServerName; + std::string InboundDescription; public: TreeSocket(std::string host, int port, bool listening, unsigned long maxtime) : InspSocket(host, port, listening, maxtime) { - Srv->Log(DEBUG,"Create new"); + Srv->Log(DEBUG,"Create new listening"); myhost = host; this->LinkState = LISTENER; } + TreeSocket(std::string host, int port, bool listening, unsigned long maxtime, std::string ServerName) + : InspSocket(host, port, listening, maxtime) + { + Srv->Log(DEBUG,"Create new outbound"); + myhost = ServerName; + this->LinkState = CONNECTING; + } + TreeSocket(int newfd) : InspSocket(newfd) { + Srv->Log(DEBUG,"Associate new inbound"); this->LinkState = WAIT_AUTH_1; } virtual bool OnConnected() { + if (this->LinkState == CONNECTING) + { + // we should send our details here. + // if the other side is satisfied, they send theirs. + // we do not need to change state here. + for (std::vector<Link>::iterator x = LinkBlocks.begin(); x < LinkBlocks.end(); x++) + { + if (x->Name == this->myhost) + { + // found who we're supposed to be connecting to, send the neccessary gubbins. + this->WriteLine("SERVER "+Srv->GetServerName()+" "+x->SendPass+" 0 :"+Srv->GetServerDescription()); + return true; + } + } + } + log(DEBUG,"Outbound connection ERROR: Could not find the right link block!"); return true; } @@ -138,6 +165,13 @@ class TreeSocket : public InspSocket return true; } + void DoBurst(TreeServer* s) + { + log(DEBUG,"Beginning network burst"); + this->WriteLine("BURST"); + this->WriteLine("ENDBURST"); + } + virtual bool OnDataReady() { char* data = this->Read(); @@ -170,6 +204,21 @@ class TreeSocket : public InspSocket return this->Write(line + "\r\n"); } + bool Error(std::deque<std::string> params) + { + if (params.size() < 1) + return false; + std::string Errmsg = params[0]; + std::string SName = myhost; + if (InboundServerName != "") + { + SName = InboundServerName; + } + Srv->SendOpers("*** ERROR from "+SName+": "+Errmsg); + // we will return false to cause the socket to close. + return false; + } + bool Outbound_Reply_Server(std::deque<std::string> params) { if (params.size() < 4) @@ -198,6 +247,7 @@ class TreeSocket : public InspSocket // node. TreeServer* Node = new TreeServer(servername,description,TreeRoot,this); TreeRoot->AddChild(Node); + this->DoBurst(Node); return true; } } @@ -218,11 +268,13 @@ class TreeSocket : public InspSocket return false; } std::string description = params[3]; - Srv->SendToModeMask("o",WM_AND,"inbound-server: name='"+servername+"' pass='"+password+"' description='"+description+"'"); for (std::vector<Link>::iterator x = LinkBlocks.begin(); x < LinkBlocks.end(); x++) { if ((x->Name == servername) && (x->RecvPass == password)) { + Srv->SendOpers("*** Verified incoming server connection from "+servername+"["+this->GetIP()+"] ("+description+")"); + this->InboundServerName = servername; + this->InboundDescription = description; // this is good. Send our details: Our server name and description and hopcount of 0, // along with the sendpass from this block. this->WriteLine("SERVER "+Srv->GetServerName()+" "+x->SendPass+" 0 :"+Srv->GetServerDescription()); @@ -253,6 +305,7 @@ class TreeSocket : public InspSocket std::string append; while (!s.eof()) { + append = ""; s >> append; if (append != "") { @@ -275,17 +328,22 @@ class TreeSocket : public InspSocket std::string prefix = ""; if ((params[0].c_str())[0] == ':') { - prefix = params.pop_front(); - command = params.pop_front(); + prefix = params[0]; + command = params[1]; + params.pop_front(); + params.pop_front(); } else { prefix = ""; - command = params.pop_front(); + command = params[0]; + params.pop_front(); } switch (this->LinkState) { + TreeServer* Node; + case WAIT_AUTH_1: // Waiting for SERVER command from remote server. Server initiating // the connection sends the first SERVER command, listening server @@ -296,6 +354,10 @@ class TreeSocket : public InspSocket { return this->Inbound_Server(params); } + else if (command == "ERROR") + { + return this->Error(params); + } break; case WAIT_AUTH_2: // Waiting for start of other side's netmerge to say they liked our @@ -306,6 +368,17 @@ class TreeSocket : public InspSocket // silently ignore. return true; } + else if (command == "BURST") + { + this->LinkState = CONNECTED; + Node = new TreeServer(InboundServerName,InboundDescription,TreeRoot,this); + TreeRoot->AddChild(Node); + this->DoBurst(Node); + } + else if (command == "ERROR") + { + return this->Error(params); + } break; case LISTENER: @@ -335,6 +408,10 @@ class TreeSocket : public InspSocket virtual void OnTimeout() { + if (this->LinkState = CONNECTING) + { + Srv->SendOpers("*** CONNECT: Connection to "+myhost+" timed out."); + } } virtual void OnClose() @@ -349,13 +426,6 @@ class TreeSocket : public InspSocket } }; -void tree_handle_connect(char **parameters, int pcnt, userrec *user) -{ - std::string addr = parameters[0]; - TreeSocket* sock = new TreeSocket(addr,80,false,10); - Srv->AddSocket(sock); -} - class ModuleSpanningTree : public Module { std::vector<TreeSocket*> Bindings; @@ -440,6 +510,17 @@ class ModuleSpanningTree : public Module int HandleConnect(char** parameters, int pcnt, userrec* user) { + for (std::vector<Link>::iterator x = LinkBlocks.begin(); x < LinkBlocks.end(); x++) + { + if (Srv->MatchText(x->Name.c_str(),parameters[0])) + { + WriteServ(user->fd,"NOTICE %s :*** CONNECT: Connecting to server: %s (%s:%d)",user->nick,x->Name.c_str(),x->IPAddr.c_str(),x->Port); + TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name); + Srv->AddSocket(newsocket); + return 1; + } + } + WriteServ(user->fd,"NOTICE %s :*** CONNECT: No matching server could be found in the config file.",user->nick); return 1; } diff --git a/src/socket.cpp b/src/socket.cpp index 67ff65c70..aa028b8a5 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -94,6 +94,8 @@ InspSocket::InspSocket(std::string host, int port, bool listening, unsigned long ip = inet_ntoa(*ia); } + this->IP = ip; + timeout_end = time(NULL)+maxtime; timeout = false; if ((this->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) @@ -138,6 +140,11 @@ void InspSocket::Close() } } +std::string InspSocket::GetIP() +{ + return this->IP; +} + char* InspSocket::Read() { int n = recv(this->fd,this->ibuf,sizeof(this->ibuf),0); |