summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspsocket.h16
-rw-r--r--src/dns.cpp2
-rw-r--r--src/inspsocket.cpp32
-rw-r--r--src/modules/m_spanningtree.cpp73
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;
}