From 2329d59b09cdc05b0b403f7d313df65492e1813b Mon Sep 17 00:00:00 2001 From: brain Date: Tue, 8 Aug 2006 09:32:57 +0000 Subject: Extra checking that the fd's we pass to SocketEngine::AddFd were added (a lot of assuming was going off, leading to total chaos if we run out of fd's etc) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4780 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/inspsocket.h | 2 +- src/dns.cpp | 14 +++++++++++++- src/inspircd.cpp | 26 +++++++++++++++----------- src/inspsocket.cpp | 36 ++++++++++++++++++++++++++++++------ src/socket.cpp | 10 ++++++++-- src/users.cpp | 7 +++++-- 6 files changed, 72 insertions(+), 23 deletions(-) diff --git a/include/inspsocket.h b/include/inspsocket.h index b644151dc..d2a8ed522 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -32,7 +32,7 @@ enum InspSocketState { I_DISCONNECTED, I_CONNECTING, I_CONNECTED, I_LISTENING, I /** * 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 }; +enum InspSocketError { I_ERR_TIMEOUT, I_ERR_SOCKET, I_ERR_CONNECT, I_ERR_BIND, I_ERR_RESOLVE, I_ERR_WRITE, I_ERR_NOMOREFDS }; class InspSocket; diff --git a/src/dns.cpp b/src/dns.cpp index 0436095b6..cbe56337d 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -202,6 +202,10 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp /* Add a query with a predefined header, and allocate an ID for it. */ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id) { + /* Is the DNS connection down? */ + if (MasterSocket == -1) + return NULL; + /* Are there already the max number of requests on the go? */ if (requests.size() == DNS::MAX_REQUEST_ID + 1) return NULL; @@ -323,7 +327,15 @@ DNS::DNS() log(DEBUG,"Add master socket %d",MasterSocket); /* Hook the descriptor into the socket engine */ if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->AddFd(MasterSocket,true,X_ESTAB_DNS); + { + if (!ServerInstance->SE->AddFd(MasterSocket,true,X_ESTAB_DNS)) + { + log(DEFAULT,"Internal error starting DNS - hostnames will NOT resolve."); + shutdown(MasterSocket,2); + close(MasterSocket); + MasterSocket = -1; + } + } } } } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index c31dbae50..27029a6e4 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -908,7 +908,7 @@ void InspIRCd::DoOneIteration(bool process_module_sockets) int InspIRCd::Run() { /* Until THIS point, ServerInstance == NULL */ - + this->Res = new DNS(); LoadAllModules(this); @@ -916,21 +916,12 @@ int InspIRCd::Run() /* Just in case no modules were loaded - fix for bug #101 */ this->BuildISupport(); - printf("\nInspIRCd is now running!\n"); - if (!stats->BoundPortCount) { printf("\nI couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n"); Exit(ERROR); } - if (!Config->nofork) - { - fclose(stdout); - fclose(stderr); - fclose(stdin); - } - /* Add the listening sockets used for client inbound connections * to the socket engine */ @@ -938,9 +929,22 @@ int InspIRCd::Run() for (unsigned long count = 0; count < stats->BoundPortCount; count++) { log(DEBUG,"Add listener: %d",Config->openSockfd[count]); - SE->AddFd(Config->openSockfd[count],true,X_LISTEN); + if (!SE->AddFd(Config->openSockfd[count],true,X_LISTEN)) + { + printf("\nEH? Could not add listener to socketengine. You screwed up, aborting.\n"); + Exit(ERROR); + } } + if (!Config->nofork) + { + fclose(stdout); + fclose(stderr); + fclose(stdin); + } + + printf("\nInspIRCd is now running!\n"); + this->WritePID(Config->PID); /* main loop, this never returns */ diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 17268dc78..fcd1c3a5a 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -52,7 +52,7 @@ InspSocket::InspSocket(int newfd, const char* ip) this->ClosePending = false; if (this->fd > -1) { - ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE); + this->ClosePending = (!ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE)); socket_ref[this->fd] = this; } } @@ -88,7 +88,13 @@ InspSocket::InspSocket(const std::string &ipaddr, int aport, bool listening, uns this->state = I_LISTENING; if (this->fd > -1) { - ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE); + if (!ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE)) + { + this->Close(); + this->state = I_ERROR; + this->OnError(I_ERR_NOMOREFDS); + this->ClosePending = true; + } socket_ref[this->fd] = this; } log(DEBUG,"New socket now in I_LISTENING state"); @@ -135,7 +141,14 @@ void InspSocket::WantWrite() */ this->WaitingForWriteEvent = true; ServerInstance->SE->DelFd(this->fd); - ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE); + if (!ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE)) + { + this->Close(); + this->fd = -1; + this->state = I_ERROR; + this->OnError(I_ERR_NOMOREFDS); + this->ClosePending = true; + } } void InspSocket::SetQueues(int nfd) @@ -253,7 +266,15 @@ bool InspSocket::DoConnect() this->state = I_CONNECTING; if (this->fd > -1) { - ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE); + if (!ServerInstance->SE->AddFd(this->fd,false,X_ESTAB_MODULE)) + { + this->OnError(I_ERR_NOMOREFDS); + this->Close(); + this->fd = -1; + this->state = I_ERROR; + this->ClosePending = true; + return false; + } socket_ref[this->fd] = this; this->SetQueues(this->fd); } @@ -421,7 +442,8 @@ bool InspSocket::Poll() if (this->fd > -1) { ServerInstance->SE->DelFd(this->fd); - ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE); + if (!ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE)) + return false; } return this->OnConnected(); break; @@ -442,7 +464,9 @@ bool InspSocket::Poll() { /* Switch back to read events */ ServerInstance->SE->DelFd(this->fd); - ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE); + if (!ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_MODULE)) + return false; + /* Trigger the write event */ n = this->OnWriteReady(); } diff --git a/src/socket.cpp b/src/socket.cpp index 04a4f5f15..1916bb555 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -359,8 +359,14 @@ int BindPorts(bool bail) /* Associate the new open port with a slot in the socket engine */ if (Config->openSockfd[count] > -1) { - ServerInstance->SE->AddFd(Config->openSockfd[count],true,X_LISTEN); - BoundPortCount++; + if (!ServerInstance->SE->AddFd(Config->openSockfd[count],true,X_LISTEN)) + { + log(DEFAULT,"ERK! Failed to add listening port to socket engine!"); + shutdown(Config->openSockfd[count],2); + close(Config->openSockfd[count]); + } + else + BoundPortCount++; } } } diff --git a/src/users.cpp b/src/users.cpp index c02dbd4ab..34c347cb9 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -908,10 +908,13 @@ void AddClient(int socket, int port, bool iscached, insp_inaddr ip) if (socket > -1) { - ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT); + if (!ServerInstance->SE->AddFd(socket,true,X_ESTAB_CLIENT)) + { + kill_link(_new, "Internal error handling connection"); + return; + } } - log(DEBUG,"Writing to client %d",_new->fd); WriteServ(_new->fd,"NOTICE Auth :*** Looking up your hostname..."); } -- cgit v1.2.3