From bd9b965904651c84690be6d9fe293a4706bd9cb0 Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 2 Feb 2006 16:44:12 +0000 Subject: Nonblocking dns for InspSocket class (used by server to server) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@3018 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/socket.h | 4 ++- src/socket.cpp | 79 +++++++++++++++++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/include/socket.h b/include/socket.h index e8eec405c..dcaca13db 100644 --- a/include/socket.h +++ b/include/socket.h @@ -22,6 +22,7 @@ #include #include #include +#include "dns.h" /** * States which a socket may be in @@ -314,7 +315,8 @@ public: */ virtual ~InspSocket(); - virtual DoResolve(); + virtual bool DoResolve(); + virtual bool DoConnect(); }; #endif diff --git a/src/socket.cpp b/src/socket.cpp index 9c2f5a362..9bc2f09e3 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -87,21 +87,25 @@ InspSocket::InspSocket(std::string host, int port, bool listening, unsigned long return; } } - } else { + } + else + { this->host = host; - if (this->dns.ForwardLookupWithFD(host,fd)) + if (!inet_aton(host.c_str(),&addy)) { + /* Its not an ip, spawn the resolver */ + this->dns.ForwardLookupWithFD(host,fd); timeout_end = time(NULL)+maxtime; timeout = false; this->state = I_RESOLVING; } else { - this->state = I_ERROR; - this->OnError(I_ERR_RESOLVE); - return; + this->IP = host; + this->DoConnect(); } + } } bool InspSocket::DoResolve() @@ -109,49 +113,58 @@ bool InspSocket::DoResolve() if (this->dns.HasResult()) { std::string res_ip = dns.GetResultIP(); - if (res_ip != "") { - this->IP = ip; + this->IP = res_ip; } else { - this->IP = this->host; - } - - if ((this->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - { + this->Close(); this->state = I_ERROR; - this->OnError(I_ERR_SOCKET); + this->OnError(I_ERR_RESOLVE); return false; } - this->port = port; - inet_aton(ip,&addy); - addr.sin_family = AF_INET; - addr.sin_addr = addy; - addr.sin_port = htons(this->port); + return this->DoConnect(); + } + else return true; +} - int flags; - flags = fcntl(this->fd, F_GETFL, 0); - fcntl(this->fd, F_SETFL, flags | O_NONBLOCK); +bool InspSocket::DoConnect() +{ + if ((this->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + this->state = I_ERROR; + this->OnError(I_ERR_SOCKET); + return false; + } + + this->port = port; + inet_aton(this->IP.c_str(),&addy); + addr.sin_family = AF_INET; + addr.sin_addr = addy; + addr.sin_port = htons(this->port); + + int flags; + flags = fcntl(this->fd, F_GETFL, 0); + fcntl(this->fd, F_SETFL, flags | O_NONBLOCK); - if(connect(this->fd, (sockaddr*)&this->addr,sizeof(this->addr)) == -1) + if(connect(this->fd, (sockaddr*)&this->addr,sizeof(this->addr)) == -1) + { + if (errno != EINPROGRESS) { - if (errno != EINPROGRESS) - { - this->Close(); - this->OnError(I_ERR_CONNECT); - this->state = I_ERROR; - return false; - } + this->Close(); + this->OnError(I_ERR_CONNECT); + this->state = I_ERROR; + return false; } - this->state = I_CONNECTING; - ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE); - socket_ref[this->fd] = this; - return true; } + this->state = I_CONNECTING; + ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE); + socket_ref[this->fd] = this; + return true; } + void InspSocket::Close() { if (this->fd != -1) -- cgit v1.2.3