From 193b540aa750446bf67dcad132773541214c296d Mon Sep 17 00:00:00 2001 From: brain Date: Tue, 31 Oct 2006 20:32:01 +0000 Subject: Socket error state stuff git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@5607 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/dns.cpp | 2 +- src/inspircd.cpp | 2 +- src/inspsocket.cpp | 4 +++- src/socket.cpp | 2 +- src/socketengine_epoll.cpp | 21 +++++++++++++++++++-- src/socketengine_select.cpp | 23 ++++++++++++++--------- src/users.cpp | 2 +- 7 files changed, 40 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/dns.cpp b/src/dns.cpp index fb38a23b9..4248affae 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -944,7 +944,7 @@ int Resolver::GetId() } /** Process a socket read event */ -void DNS::HandleEvent(EventType et) +void DNS::HandleEvent(EventType et, int errornum) { ServerInstance->Log(DEBUG,"Marshall reads: %d",this->GetFd()); /* Fetch the id and result of the next available packet */ diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 53f3bb733..fe8b0b819 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -786,7 +786,7 @@ bool FileLogger::Readable() return false; } -void FileLogger::HandleEvent(EventType et) +void FileLogger::HandleEvent(EventType et, int errornum) { this->WriteLogLine(""); ServerInstance->SE->DelFd(this); diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 9b691fc7f..f8d5109fb 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -475,10 +475,12 @@ InspSocket::~InspSocket() this->Close(); } -void InspSocket::HandleEvent(EventType et) +void InspSocket::HandleEvent(EventType et, int errornum) { switch (et) { + case EVENT_ERROR: + break; case EVENT_READ: if (!this->Poll()) { diff --git a/src/socket.cpp b/src/socket.cpp index 4bf9dc30b..225b27733 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -51,7 +51,7 @@ ListenSocket::ListenSocket(InspIRCd* Instance, int sockfd, insp_sockaddr client, } } -void ListenSocket::HandleEvent(EventType et) +void ListenSocket::HandleEvent(EventType et, int errornum) { insp_sockaddr sock_us; // our port number socklen_t uslen; // length of our port number diff --git a/src/socketengine_epoll.cpp b/src/socketengine_epoll.cpp index c3c0c89a2..618f30592 100644 --- a/src/socketengine_epoll.cpp +++ b/src/socketengine_epoll.cpp @@ -130,10 +130,25 @@ int EPollEngine::GetRemainingFds() int EPollEngine::DispatchEvents() { + socklen_t codesize; + int errcode; int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 150); for (int j = 0; j < i; j++) { ServerInstance->Log(DEBUG,"Handle %s event on fd %d",events[j].events & EPOLLOUT ? "write" : "read", events[j].data.fd); + if (events[j].events & EPOLLHUP) + { + ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, 0); + continue; + } + if (events[j].events & EPOLLERR) + { + /* Get error number */ + if (getsockopt(events[j].data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) + errcode = errno; + ref[events[j].data.fd]->HandleEvent(EVENT_ERROR, errcode); + continue; + } if (events[j].events & EPOLLOUT) { struct epoll_event ev; @@ -144,11 +159,13 @@ int EPollEngine::DispatchEvents() { ServerInstance->Log(DEBUG,"epoll: Could not reset fd %d!", events[j].data.fd); } - ref[events[j].data.fd]->HandleEvent(EVENT_WRITE); + if (ref[events[j].data.fd]) + ref[events[j].data.fd]->HandleEvent(EVENT_WRITE); } else { - ref[events[j].data.fd]->HandleEvent(EVENT_READ); + if (ref[events[j].data.fd]) + ref[events[j].data.fd]->HandleEvent(EVENT_READ); } } diff --git a/src/socketengine_select.cpp b/src/socketengine_select.cpp index 8b0379152..cdd1bdc3c 100644 --- a/src/socketengine_select.cpp +++ b/src/socketengine_select.cpp @@ -134,16 +134,21 @@ int SelectEngine::DispatchEvents() */ for (int i = 0; i < result; i++) { - ServerInstance->Log(DEBUG,"Handle %s event on fd %d",writeable[ev[i]->GetFd()] || !ev[i]->Readable() ? "write" : "read", ev[i]->GetFd()); - if (writeable[ev[i]->GetFd()]) + if (ev[i]) { - ev[i]->HandleEvent(EVENT_WRITE); - writeable[ev[i]->GetFd()] = false; - - } - else - { - ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + ServerInstance->Log(DEBUG,"Handle %s event on fd %d",writeable[ev[i]->GetFd()] || !ev[i]->Readable() ? "write" : "read", ev[i]->GetFd()); + if (writeable[ev[i]->GetFd()]) + { + if (ev[i]) + ev[i]->HandleEvent(EVENT_WRITE); + writeable[ev[i]->GetFd()] = false; + + } + else + { + if (ev[i]) + ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + } } } diff --git a/src/users.cpp b/src/users.cpp index 2c49e1ec7..6acbf137a 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -2026,7 +2026,7 @@ void userrec::ShowRULES() this->WriteServ("NOTICE %s :End of %s rules.",this->nick,ServerInstance->Config->ServerName); } -void userrec::HandleEvent(EventType et) +void userrec::HandleEvent(EventType et, int errornum) { /* WARNING: May delete this user! */ try -- cgit v1.2.3