diff options
-rw-r--r-- | include/inspsocket.h | 16 | ||||
-rw-r--r-- | src/dns.cpp | 2 | ||||
-rw-r--r-- | src/inspsocket.cpp | 32 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 73 |
4 files changed, 79 insertions, 44 deletions
diff --git a/include/inspsocket.h b/include/inspsocket.h index 1b9947ef9..077f20a65 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -27,13 +27,15 @@ /** * States which a socket may be in */ -enum InspSocketState { I_DISCONNECTED, I_RESOLVING, I_CONNECTING, I_CONNECTED, I_LISTENING, I_ERROR }; +enum InspSocketState { I_DISCONNECTED, I_CONNECTING, I_CONNECTED, I_LISTENING, I_ERROR }; /** * Error types which a socket may exhibit */ enum InspSocketError { I_ERR_TIMEOUT, I_ERR_SOCKET, I_ERR_CONNECT, I_ERR_BIND, I_ERR_RESOLVE, I_ERR_WRITE }; +class InspSocket; + /** * InspSocket is an extendable socket class which modules * can use for TCP socket support. It is fully integrated @@ -47,7 +49,7 @@ enum InspSocketError { I_ERR_TIMEOUT, I_ERR_SOCKET, I_ERR_CONNECT, I_ERR_BIND, I */ class InspSocket : public Extensible { -protected: + public: std::deque<std::string> outbuffer; @@ -163,8 +165,6 @@ protected: bool BindAddr(); -public: - /** * The default constructor does nothing * and should not be used. @@ -349,14 +349,6 @@ public: virtual ~InspSocket(); /** - * This method attempts to resolve the hostname, - * if a hostname is given and not an IP, - * before a connection can occur. This method is - * asyncronous. - */ - virtual bool DoResolve(); - - /** * This method attempts to connect to a hostname. * This only occurs on a non-listening socket. This * method is asyncronous. diff --git a/src/dns.cpp b/src/dns.cpp index e0cb3ccaa..753df7cf8 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -578,10 +578,12 @@ Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd { if (forward) { + log(DEBUG,"Resolver: Forward lookup on %s",source.c_str()); this->myid = Res->dns_getip4(source.c_str()); } else { + log(DEBUG,"Resolver: Reverse lookup on %s",source.c_str()); insp_inaddr binip; if (insp_aton(source.c_str(), &binip) > 0) { diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 99ef731c6..f443873e5 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -32,9 +32,11 @@ extern InspIRCd* ServerInstance; extern ServerConfig* Config; extern time_t TIME; +extern Server* MyServer; InspSocket* socket_ref[MAX_DESCRIPTORS]; + InspSocket::InspSocket() { this->state = I_DISCONNECTED; @@ -101,15 +103,13 @@ InspSocket::InspSocket(const std::string &ahost, int aport, bool listening, unsi if (insp_aton(host,&addy) < 1) { - log(DEBUG,"Attempting to resolve %s",this->host); - /* Its not an ip, spawn the resolver */ - - /* TODO: Implement resolver with new Resolver class */ - - timeout_end = time(NULL) + maxtime; - timeout = false; - this->state = I_RESOLVING; - socket_ref[this->fd] = this; + log(DEBUG,"You cannot pass hostnames to InspSocket, resolve them first with Resolver!"); + this->Close(); + this->fd = -1; + this->state = I_ERROR; + this->OnError(I_ERR_RESOLVE); + this->ClosePending = true; + return; } else { @@ -147,14 +147,6 @@ void InspSocket::SetQueues(int nfd) setsockopt(nfd,SOL_SOCKET,SO_RCVBUF,(const void *)&recvbuf,sizeof(sendbuf)); } -bool InspSocket::DoResolve() -{ - log(DEBUG,"In DoResolve(), trying to resolve IP"); - - log(DEBUG,"No result for socket yet!"); - return true; -} - /* Most irc servers require you to specify the ip you want to bind to. * If you dont specify an IP, they rather dumbly bind to the first IP * of the box (e.g. INADDR_ANY). In InspIRCd, we scan thought the IP @@ -399,7 +391,7 @@ bool InspSocket::Timeout(time_t current) return true; } - if (((this->state == I_RESOLVING) || (this->state == I_CONNECTING)) && (current > timeout_end)) + if ((this->state == I_CONNECTING) && (current > timeout_end)) { log(DEBUG,"Timed out, current=%lu timeout_end=%lu"); // for non-listening sockets, the timeout can occur @@ -429,10 +421,6 @@ bool InspSocket::Poll() switch (this->state) { - case I_RESOLVING: - log(DEBUG,"State = I_RESOLVING, calling DoResolve()"); - return this->DoResolve(); - break; case I_CONNECTING: log(DEBUG,"State = I_CONNECTING"); this->SetState(I_CONNECTED); diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 0725d7b51..c91926d98 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -186,6 +186,7 @@ class UserManager : public classbase } }; + /* Each server in the tree is represented by one class of * type TreeServer. A locally connected TreeServer can * have a class of type TreeSocket associated with it, for @@ -3064,6 +3065,36 @@ class TreeSocket : public InspSocket } }; +class ServernameResolver : public Resolver +{ + private: + Link MyLink; + public: + ServernameResolver(const std::string &hostname, Link x) : Resolver(hostname, true), MyLink(x) + { + } + + void OnLookupComplete(const std::string &result) + { + TreeSocket* newsocket = new TreeSocket(result,MyLink.Port,false,10,MyLink.Name.c_str()); + if (newsocket->GetFd() > -1) + { + Srv->AddSocket(newsocket); + } + else + { + WriteOpers("*** CONNECT: Error connecting \002%s\002: %s.",MyLink.Name.c_str(),strerror(errno)); + delete newsocket; + } + } + + void OnError(ResolverError e) + { + WriteOpers("*** CONNECT: Error connecting \002%s\002: Unable to resolve hostname.",MyLink.Name.c_str()); + } +}; + + void AddThisServer(TreeServer* server, std::deque<TreeServer*> &list) { for (unsigned int c = 0; c < list.size(); c++) @@ -3666,16 +3697,28 @@ class ModuleSpanningTree : public Module { // an autoconnected server is not connected. Check if its time to connect it WriteOpers("*** AUTOCONNECT: Auto-connecting server \002%s\002 (%lu seconds until next attempt)",x->Name.c_str(),x->AutoConnect); - TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name.c_str()); - if (newsocket->GetFd() > -1) + + insp_inaddr binip; + + if (insp_aton(x->IPAddr.c_str(), &binip) > 0) { - Srv->AddSocket(newsocket); + TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name.c_str()); + if (newsocket->GetFd() > -1) + { + Srv->AddSocket(newsocket); + } + else + { + WriteOpers("*** AUTOCONNECT: Error autoconnecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); + delete newsocket; + } } else { - WriteOpers("*** AUTOCONNECT: Error autoconnecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); - DELETE(newsocket); + ServernameResolver* snr = new ServernameResolver(x->IPAddr, *x); + Srv->AddResolver(snr); } + } } } @@ -3728,15 +3771,25 @@ class ModuleSpanningTree : public Module if (!CheckDupe) { WriteServ(user->fd,"NOTICE %s :*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",user->nick,x->Name.c_str(),(x->HiddenFromStats ? "<hidden>" : x->IPAddr.c_str()),x->Port); - TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name.c_str()); - if (newsocket->GetFd() > -1) + insp_inaddr binip; + + if (insp_aton(x->IPAddr.c_str(), &binip) > 0) { - Srv->AddSocket(newsocket); + TreeSocket* newsocket = new TreeSocket(x->IPAddr,x->Port,false,10,x->Name.c_str()); + if (newsocket->GetFd() > -1) + { + Srv->AddSocket(newsocket); + } + else + { + WriteOpers("*** CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(),strerror(errno)); + delete newsocket; + } } else { - WriteServ(user->fd,"NOTICE %s :*** CONNECT: Error connecting \002%s\002: %s.",user->nick,x->Name.c_str(),strerror(errno)); - DELETE(newsocket); + ServernameResolver* snr = new ServernameResolver(x->IPAddr, *x); + Srv->AddResolver(snr); } return 1; } |