summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-08-18 01:08:14 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2006-08-18 01:08:14 +0000
commite381b06561228aaea752deda20a62c6dc99a560e (patch)
tree2119fe8bc8895597261935f389004e3c6bafe6a8 /src
parent3c82d2d767186dd6d386dbbe08219ad8612e299e (diff)
EventHandler class, an abstraction for raw i/o
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4941 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/channels.cpp4
-rw-r--r--src/cmd_notice.cpp2
-rw-r--r--src/cmd_privmsg.cpp2
-rw-r--r--src/cmd_quit.cpp9
-rw-r--r--src/dns.cpp133
-rw-r--r--src/inspircd.cpp142
-rw-r--r--src/inspsocket.cpp56
-rw-r--r--src/modules.cpp16
-rw-r--r--src/modules/extra/m_pgsql.cpp7
-rw-r--r--src/modules/m_cgiirc.cpp10
-rw-r--r--src/modules/m_ident.cpp14
-rw-r--r--src/modules/m_samode.cpp2
-rw-r--r--src/modules/m_spanningtree.cpp14
-rw-r--r--src/modules/m_timedbans.cpp2
-rw-r--r--src/socket.cpp128
-rw-r--r--src/socketengine.cpp51
-rw-r--r--src/socketengine_epoll.cpp31
-rw-r--r--src/socketengine_kqueue.cpp24
-rw-r--r--src/socketengine_select.cpp22
-rw-r--r--src/userprocess.cpp19
-rw-r--r--src/users.cpp23
21 files changed, 322 insertions, 389 deletions
diff --git a/src/channels.cpp b/src/channels.cpp
index 29373e906..a89b9b2c4 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -222,7 +222,7 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo
if (!Ptr)
{
- if (user->fd > -1)
+ if (IS_LOCAL(user))
{
MOD_RESULT = 0;
FOREACH_RESULT_I(Instance,I_OnUserPreJoin,OnUserPreJoin(user,NULL,cname));
@@ -654,7 +654,7 @@ void chanrec::WriteChannel(userrec* user, const std::string &text)
for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
{
- if (i->second->fd != FD_MAGIC_NUMBER)
+ if (IS_LOCAL(i->second))
user->WriteTo(i->second,text);
}
}
diff --git a/src/cmd_notice.cpp b/src/cmd_notice.cpp
index 209972400..006036145 100644
--- a/src/cmd_notice.cpp
+++ b/src/cmd_notice.cpp
@@ -118,7 +118,7 @@ void cmd_notice::Handle (const char** parameters, int pcnt, userrec *user)
}
parameters[1] = (char*)temp.c_str();
- if (dest->fd > -1)
+ if (IS_LOCAL(dest))
{
// direct write, same server
user->WriteTo(dest, "NOTICE %s :%s", dest->nick, parameters[1]);
diff --git a/src/cmd_privmsg.cpp b/src/cmd_privmsg.cpp
index 3f9e33652..ce5ece2a2 100644
--- a/src/cmd_privmsg.cpp
+++ b/src/cmd_privmsg.cpp
@@ -120,7 +120,7 @@ void cmd_privmsg::Handle (const char** parameters, int pcnt, userrec *user)
}
parameters[1] = (char*)temp.c_str();
- if (dest->fd > -1)
+ if (IS_LOCAL(dest))
{
// direct write, same server
user->WriteTo(dest, "PRIVMSG %s :%s", dest->nick, parameters[1]);
diff --git a/src/cmd_quit.cpp b/src/cmd_quit.cpp
index 7430e0fd2..c1e73bc84 100644
--- a/src/cmd_quit.cpp
+++ b/src/cmd_quit.cpp
@@ -52,7 +52,7 @@ void cmd_quit::Handle (const char** parameters, int pcnt, userrec *user)
/* We should only prefix the quit for a local user. Remote users have
* already been prefixed, where neccessary, by the upstream server.
*/
- if (user->fd > -1)
+ if (IS_LOCAL(user))
{
user->Write("ERROR :Closing link (%s@%s) [%s%s]",user->ident,user->host,ServerInstance->Config->PrefixQuit,parameters[0]);
ServerInstance->WriteOpers("*** Client exiting: %s!%s@%s [%s%s]",user->nick,user->ident,user->host,ServerInstance->Config->PrefixQuit,parameters[0]);
@@ -80,9 +80,9 @@ void cmd_quit::Handle (const char** parameters, int pcnt, userrec *user)
FOREACH_MOD(I_OnUserDisconnect,OnUserDisconnect(user));
/* push the socket on a stack of sockets due to be closed at the next opportunity */
- if (user->fd > -1)
+ if (IS_LOCAL(user))
{
- ServerInstance->SE->DelFd(user->fd);
+ ServerInstance->SE->DelFd(user);
if (find(ServerInstance->local_users.begin(),ServerInstance->local_users.end(),user) != ServerInstance->local_users.end())
{
ServerInstance->Log(DEBUG,"Delete local user");
@@ -99,7 +99,6 @@ void cmd_quit::Handle (const char** parameters, int pcnt, userrec *user)
if (user->registered == REG_ALL) {
user->PurgeEmptyChannels();
}
- if (user->fd > -1)
- ServerInstance->fd_ref_table[user->fd] = NULL;
DELETE(user);
}
+
diff --git a/src/dns.cpp b/src/dns.cpp
index 50aae9c82..8f23eaa6c 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -50,9 +50,6 @@ using irc::sockets::insp_inaddr;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_aton;
-/* Master file descriptor */
-int DNS::MasterSocket;
-
/* Masks to mask off the responses we get from the DNSRequest methods */
enum QueryInfo
{
@@ -109,9 +106,10 @@ class DNSRequest
unsigned int rr_class; /* Request class */
QueryType type; /* Request type */
insp_inaddr myserver; /* DNS server address*/
+ DNS* dnsobj; /* DNS caller (where we get our FD from) */
/* Allocate the processing buffer */
- DNSRequest(insp_inaddr server)
+ DNSRequest(DNS* dns, insp_inaddr server) : dnsobj(dns)
{
res = new unsigned char[512];
*res = 0;
@@ -193,7 +191,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
addr.sin_family = AF_FAMILY;
addr.sin_port = htons(DNS::QUERY_PORT);
#endif
- if (sendto(DNS::GetMasterSocket(), payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) == -1)
+ if (sendto(dnsobj->GetFd(), payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) == -1)
return -1;
return 0;
@@ -203,7 +201,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
DNSRequest* DNS::AddQuery(DNSHeader *header, int &id)
{
/* Is the DNS connection down? */
- if (MasterSocket == -1)
+ if (this->GetFd() == -1)
return NULL;
/* Are there already the max number of requests on the go? */
@@ -217,7 +215,7 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id)
while (requests.find(id) != requests.end())
id = this->PRNG() & DNS::MAX_REQUEST_ID;
- DNSRequest* req = new DNSRequest(this->myserver);
+ DNSRequest* req = new DNSRequest(this, this->myserver);
header->id[0] = req->id[0] = id >> 8;
header->id[1] = req->id[1] = id & 0xFF;
@@ -237,11 +235,6 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id)
return req;
}
-int DNS::GetMasterSocket()
-{
- return MasterSocket;
-}
-
/* Initialise the DNS UDP socket so that we can send requests */
DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance)
{
@@ -282,16 +275,16 @@ DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance)
}
/* Initialize mastersocket */
- MasterSocket = socket(PF_PROTOCOL, SOCK_DGRAM, 0);
- if (MasterSocket != -1)
+ this->SetFd(socket(PF_PROTOCOL, SOCK_DGRAM, 0));
+ if (this->GetFd() != -1)
{
/* Did it succeed? */
- if (fcntl(MasterSocket, F_SETFL, O_NONBLOCK) != 0)
+ if (fcntl(this->GetFd(), F_SETFL, O_NONBLOCK) != 0)
{
/* Couldn't make the socket nonblocking */
- shutdown(MasterSocket,2);
- close(MasterSocket);
- MasterSocket = -1;
+ shutdown(this->GetFd(),2);
+ close(this->GetFd());
+ this->SetFd(-1);
}
}
else
@@ -299,7 +292,7 @@ DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance)
ServerInstance->Log(DEBUG,"I cant socket() this socket! (%s)",strerror(errno));
}
/* Have we got a socket and is it nonblocking? */
- if (MasterSocket != -1)
+ if (this->GetFd() != -1)
{
#ifdef IPV6
insp_sockaddr addr;
@@ -315,27 +308,27 @@ DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance)
addr.sin_addr.s_addr = INADDR_ANY;
#endif
/* Bind the port */
- if (bind(MasterSocket,(sockaddr *)&addr,sizeof(addr)) != 0)
+ if (bind(this->GetFd(),(sockaddr *)&addr,sizeof(addr)) != 0)
{
/* Failed to bind */
- ServerInstance->Log(DEBUG,"Cant bind DNS::MasterSocket");
- shutdown(MasterSocket,2);
- close(MasterSocket);
- MasterSocket = -1;
+ ServerInstance->Log(DEBUG,"Cant bind DNS fd");
+ shutdown(this->GetFd(),2);
+ close(this->GetFd());
+ this->SetFd(-1);
}
- if (MasterSocket >= 0)
+ if (this->GetFd() >= 0)
{
- ServerInstance->Log(DEBUG,"Add master socket %d",MasterSocket);
+ ServerInstance->Log(DEBUG,"Add master socket %d",this->GetFd());
/* Hook the descriptor into the socket engine */
if (ServerInstance && ServerInstance->SE)
{
- if (!ServerInstance->SE->AddFd(MasterSocket,true,X_ESTAB_DNS))
+ if (!ServerInstance->SE->AddFd(this))
{
ServerInstance->Log(DEFAULT,"Internal error starting DNS - hostnames will NOT resolve.");
- shutdown(MasterSocket,2);
- close(MasterSocket);
- MasterSocket = -1;
+ shutdown(this->GetFd(),2);
+ close(this->GetFd());
+ this->SetFd(-1);
}
}
}
@@ -538,7 +531,7 @@ DNSResult DNS::GetResult()
const char* ipaddr_from = "";
unsigned short int port_from = 0;
- int length = recvfrom(MasterSocket,buffer,sizeof(DNSHeader),0,&from,&x);
+ int length = recvfrom(this->GetFd(),buffer,sizeof(DNSHeader),0,&from,&x);
if (length < 0)
ServerInstance->Log(DEBUG,"Error in recvfrom()! (%s)",strerror(errno));
@@ -594,7 +587,7 @@ DNSResult DNS::GetResult()
if (n_iter == requests.end())
{
/* Somehow we got a DNS response for a request we never made... */
- ServerInstance->Log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d queryid=%d",MasterSocket,this_id);
+ ServerInstance->Log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d queryid=%d",this->GetFd(),this_id);
return std::make_pair(-1,"");
}
else
@@ -832,8 +825,8 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length)
/* Close the master socket */
DNS::~DNS()
{
- shutdown(MasterSocket, 2);
- close(MasterSocket);
+ shutdown(this->GetFd(), 2);
+ close(this->GetFd());
}
/* High level abstraction of dns used by application at large */
@@ -914,53 +907,47 @@ int Resolver::GetId()
}
/* Process a socket read event */
-void DNS::MarshallReads(int fd)
+void DNS::HandleEvent(EventType et)
{
- ServerInstance->Log(DEBUG,"Marshall reads: %d %d",fd,GetMasterSocket());
- /* We are only intrested in our single fd */
- if (fd == GetMasterSocket())
+ ServerInstance->Log(DEBUG,"Marshall reads: %d",this->GetFd());
+ /* Fetch the id and result of the next available packet */
+ DNSResult res = this->GetResult();
+ /* Is there a usable request id? */
+ if (res.first != -1)
{
- /* Fetch the id and result of the next available packet */
- DNSResult res = this->GetResult();
- /* Is there a usable request id? */
- if (res.first != -1)
+ /* Its an error reply */
+ if (res.first & ERROR_MASK)
{
- /* Its an error reply */
- if (res.first & ERROR_MASK)
+ /* Mask off the error bit */
+ res.first -= ERROR_MASK;
+ /* Marshall the error to the correct class */
+ ServerInstance->Log(DEBUG,"Error available, id=%d",res.first);
+ if (Classes[res.first])
{
- /* Mask off the error bit */
- res.first -= ERROR_MASK;
-
- /* Marshall the error to the correct class */
- ServerInstance->Log(DEBUG,"Error available, id=%d",res.first);
- if (Classes[res.first])
- {
- if (ServerInstance && ServerInstance->stats)
- ServerInstance->stats->statsDnsBad++;
- Classes[res.first]->OnError(RESOLVER_NXDOMAIN, res.second);
- delete Classes[res.first];
- Classes[res.first] = NULL;
- }
+ if (ServerInstance && ServerInstance->stats)
+ ServerInstance->stats->statsDnsBad++;
+ Classes[res.first]->OnError(RESOLVER_NXDOMAIN, res.second);
+ delete Classes[res.first];
+ Classes[res.first] = NULL;
}
- else
+ }
+ else
+ {
+ /* It is a non-error result */
+ ServerInstance->Log(DEBUG,"Result available, id=%d",res.first);
+ /* Marshall the result to the correct class */
+ if (Classes[res.first])
{
- /* It is a non-error result */
- ServerInstance->Log(DEBUG,"Result available, id=%d",res.first);
- /* Marshall the result to the correct class */
- if (Classes[res.first])
- {
- if (ServerInstance && ServerInstance->stats)
- ServerInstance->stats->statsDnsGood++;
- Classes[res.first]->OnLookupComplete(res.second);
- delete Classes[res.first];
- Classes[res.first] = NULL;
- }
+ if (ServerInstance && ServerInstance->stats)
+ ServerInstance->stats->statsDnsGood++;
+ Classes[res.first]->OnLookupComplete(res.second);
+ delete Classes[res.first];
+ Classes[res.first] = NULL;
}
-
- if (ServerInstance && ServerInstance->stats)
- ServerInstance->stats->statsDns++;
-
}
+
+ if (ServerInstance && ServerInstance->stats)
+ ServerInstance->stats->statsDns++;
}
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 92c05f557..41e0897b7 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -171,13 +171,9 @@ InspIRCd::InspIRCd(int argc, char** argv)
: ModCount(-1), duration_m(60), duration_h(60*60), duration_d(60*60*24), duration_w(60*60*24*7), duration_y(60*60*24*365)
{
bool SEGVHandler = false;
- //ServerInstance = this;
modules.resize(255);
factory.resize(255);
-
- memset(fd_ref_table, 0, sizeof(fd_ref_table));
- memset(socket_ref, 0, sizeof(socket_ref));
this->Config = new ServerConfig(this);
this->Start();
@@ -294,7 +290,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
if (!stats->BoundPortCount)
{
- printf("\nI couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
+ printf("\nERROR: I couldn't bind any ports! Are you sure you didn't start InspIRCd twice?\n");
Exit(ERROR);
}
@@ -305,7 +301,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
for (unsigned long count = 0; count < stats->BoundPortCount; count++)
{
this->Log(DEBUG,"Add listener: %d",Config->openSockfd[count]);
- if (!SE->AddFd(Config->openSockfd[count],true,X_LISTEN))
+ if (!SE->AddFd(Config->openSockfd[count]))
{
printf("\nEH? Could not add listener to socketengine. You screwed up, aborting.\n");
Exit(ERROR);
@@ -667,15 +663,8 @@ bool InspIRCd::LoadModule(const char* filename)
void InspIRCd::DoOneIteration(bool process_module_sockets)
{
- int activefds[MAX_DESCRIPTORS];
- int incomingSockfd;
- int in_port;
- userrec* cu = NULL;
- InspSocket* s = NULL;
- InspSocket* s_del = NULL;
+ EventHandler* activefds[MAX_DESCRIPTORS];
unsigned int numberactive;
- insp_sockaddr sock_us; // our port number
- socklen_t uslen; // length of our port number
/* time() seems to be a pretty expensive syscall, so avoid calling it too much.
* Once per loop iteration is pleanty.
@@ -728,129 +717,8 @@ void InspIRCd::DoOneIteration(bool process_module_sockets)
for (unsigned int activefd = 0; activefd < numberactive; activefd++)
{
- int socket_type = SE->GetType(activefds[activefd]);
- switch (socket_type)
- {
- case X_ESTAB_CLIENT:
-
- this->Log(DEBUG,"Type: X_ESTAB_CLIENT: fd=%d",activefds[activefd]);
- cu = this->fd_ref_table[activefds[activefd]];
- if (cu)
- this->ProcessUser(cu);
-
- break;
-
- case X_ESTAB_MODULE:
-
- this->Log(DEBUG,"Type: X_ESTAB_MODULE: fd=%d",activefds[activefd]);
-
- if (!process_module_sockets)
- break;
-
- /* Process module-owned sockets.
- * Modules are encouraged to inherit their sockets from
- * InspSocket so we can process them neatly like this.
- */
- s = this->socket_ref[activefds[activefd]];
-
- if ((s) && (!s->Poll()))
- {
- this->Log(DEBUG,"Socket poll returned false, close and bail");
- SE->DelFd(s->GetFd());
- this->socket_ref[activefds[activefd]] = NULL;
- for (std::vector<InspSocket*>::iterator a = module_sockets.begin(); a < module_sockets.end(); a++)
- {
- s_del = *a;
- if ((s_del) && (s_del->GetFd() == activefds[activefd]))
- {
- module_sockets.erase(a);
- break;
- }
- }
- s->Close();
- DELETE(s);
- }
- else if (!s)
- {
- this->Log(DEBUG,"WTF, X_ESTAB_MODULE for nonexistent InspSocket, removed!");
- SE->DelFd(s->GetFd());
- }
- break;
-
- case X_ESTAB_DNS:
- /* Handles instances of the Resolver class,
- * a simple class extended by modules and the core for
- * nonblocking resolving of addresses.
- */
- this->Res->MarshallReads(activefds[activefd]);
- break;
-
- case X_LISTEN:
-
- this->Log(DEBUG,"Type: X_LISTEN: fd=%d",activefds[activefd]);
-
- /* It's a listener */
- uslen = sizeof(sock_us);
- length = sizeof(client);
- incomingSockfd = accept (activefds[activefd],(struct sockaddr*)&client,&length);
-
- if ((incomingSockfd > -1) && (!getsockname(incomingSockfd,(sockaddr*)&sock_us,&uslen)))
- {
-#ifdef IPV6
- in_port = ntohs(sock_us.sin6_port);
-#else
- in_port = ntohs(sock_us.sin_port);
-#endif
- this->Log(DEBUG,"Accepted socket %d",incomingSockfd);
- /* Years and years ago, we used to resolve here
- * using gethostbyaddr(). That is sucky and we
- * don't do that any more...
- */
- NonBlocking(incomingSockfd);
- if (Config->GetIOHook(in_port))
- {
- try
- {
-#ifdef IPV6
- Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin6_addr), in_port);
-#else
- Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin_addr), in_port);
-#endif
- }
- catch (ModuleException& modexcept)
- {
- this->Log(DEBUG,"Module exception cought: %s",modexcept.GetReason());
- }
- }
- stats->statsAccept++;
-#ifdef IPV6
- this->Log(DEBUG,"Add ipv6 client");
- userrec::AddClient(this, incomingSockfd, in_port, false, client.sin6_addr);
-#else
- this->Log(DEBUG,"Add ipv4 client");
- userrec::AddClient(this, incomingSockfd, in_port, false, client.sin_addr);
-#endif
- this->Log(DEBUG,"Adding client on port %d fd=%d",in_port,incomingSockfd);
- }
- else
- {
- this->Log(DEBUG,"Accept failed on fd %d: %s",incomingSockfd,strerror(errno));
- shutdown(incomingSockfd,2);
- close(incomingSockfd);
- stats->statsRefused++;
- }
- break;
-
- default:
- /* Something went wrong if we're in here.
- * In fact, so wrong, im not quite sure
- * what we would do, so for now, its going
- * to safely do bugger all.
- */
- this->Log(DEBUG,"Type: X_WHAT_THE_FUCK_BBQ: fd=%d",activefds[activefd]);
- SE->DelFd(activefds[activefd]);
- break;
- }
+ this->Log(DEBUG,"Handle %s event on fd %d",activefds[activefd]->Readable() ? "read" : "write", activefds[activefd]->GetFd());
+ activefds[activefd]->HandleEvent(activefds[activefd]->Readable() ? EVENT_READ : EVENT_WRITE);
}
}
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 75f8dc250..c44ad130f 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -23,7 +23,6 @@
#include "socket.h"
#include "configreader.h"
#include "inspstring.h"
-
#include "socketengine.h"
#include "inspircd.h"
@@ -31,10 +30,16 @@ using irc::sockets::OpenTCPSocket;
using irc::sockets::insp_inaddr;
using irc::sockets::insp_sockaddr;
+bool InspSocket::Readable()
+{
+ return ((this->state != I_CONNECTING) && (this->WaitingForWriteEvent == false));
+}
+
InspSocket::InspSocket(InspIRCd* SI)
{
this->state = I_DISCONNECTED;
this->fd = -1;
+ this->WaitingForWriteEvent = false;
this->ClosePending = false;
this->Instance = SI;
}
@@ -45,20 +50,21 @@ InspSocket::InspSocket(InspIRCd* SI, int newfd, const char* ip)
this->state = I_CONNECTED;
strlcpy(this->IP,ip,MAXBUF);
this->ClosePending = false;
+ this->WaitingForWriteEvent = false;
this->Instance = SI;
if (this->fd > -1)
- {
- this->ClosePending = (!this->Instance->SE->AddFd(this->fd,true,X_ESTAB_MODULE));
- this->Instance->socket_ref[this->fd] = this;
- }
+ this->ClosePending = (!this->Instance->SE->AddFd(this));
}
-InspSocket::InspSocket(InspIRCd* SI, const std::string &ipaddr, int aport, bool listening, unsigned long maxtime) : fd(-1)
+InspSocket::InspSocket(InspIRCd* SI, const std::string &ipaddr, int aport, bool listening, unsigned long maxtime)
{
+ this->fd = -1;
this->Instance = SI;
strlcpy(host,ipaddr.c_str(),MAXBUF);
this->ClosePending = false;
- if (listening) {
+ this->WaitingForWriteEvent = false;
+ if (listening)
+ {
if ((this->fd = OpenTCPSocket()) == ERROR)
{
this->fd = -1;
@@ -85,14 +91,13 @@ InspSocket::InspSocket(InspIRCd* SI, const std::string &ipaddr, int aport, bool
this->state = I_LISTENING;
if (this->fd > -1)
{
- if (!this->Instance->SE->AddFd(this->fd,true,X_ESTAB_MODULE))
+ if (!this->Instance->SE->AddFd(this))
{
this->Close();
this->state = I_ERROR;
this->OnError(I_ERR_NOMOREFDS);
this->ClosePending = true;
}
- this->Instance->socket_ref[this->fd] = this;
}
this->Instance->Log(DEBUG,"New socket now in I_LISTENING state");
return;
@@ -136,9 +141,9 @@ void InspSocket::WantWrite()
*
* This behaviour may be fixed in a later version.
*/
+ this->Instance->SE->DelFd(this);
this->WaitingForWriteEvent = true;
- this->Instance->SE->DelFd(this->fd);
- if (!this->Instance->SE->AddFd(this->fd,false,X_ESTAB_MODULE))
+ if (!this->Instance->SE->AddFd(this))
{
this->Close();
this->fd = -1;
@@ -263,7 +268,7 @@ bool InspSocket::DoConnect()
this->state = I_CONNECTING;
if (this->fd > -1)
{
- if (!this->Instance->SE->AddFd(this->fd,false,X_ESTAB_MODULE))
+ if (!this->Instance->SE->AddFd(this))
{
this->OnError(I_ERR_NOMOREFDS);
this->Close();
@@ -272,7 +277,6 @@ bool InspSocket::DoConnect()
this->ClosePending = true;
return false;
}
- this->Instance->socket_ref[this->fd] = this;
this->SetQueues(this->fd);
}
this->Instance->Log(DEBUG,"Returning true from InspSocket::DoConnect");
@@ -287,7 +291,6 @@ void InspSocket::Close()
this->OnClose();
shutdown(this->fd,2);
close(this->fd);
- this->Instance->socket_ref[this->fd] = NULL;
this->ClosePending = true;
this->fd = -1;
}
@@ -388,7 +391,7 @@ bool InspSocket::FlushWriteBuffer()
bool InspSocket::Timeout(time_t current)
{
- if (!this->Instance->socket_ref[this->fd] || !this->Instance->SE->HasFd(this->fd))
+ if (this->Instance->SE->GetRef(this->fd) != this)
{
this->Instance->Log(DEBUG,"No FD or socket ref");
return false;
@@ -419,7 +422,7 @@ bool InspSocket::Timeout(time_t current)
bool InspSocket::Poll()
{
- if (!this->Instance->socket_ref[this->fd] || !this->Instance->SE->HasFd(this->fd))
+ if (this->Instance->SE->GetRef(this->fd) != this)
return false;
int incoming = -1;
@@ -432,14 +435,14 @@ bool InspSocket::Poll()
{
case I_CONNECTING:
this->Instance->Log(DEBUG,"State = I_CONNECTING");
- this->SetState(I_CONNECTED);
/* Our socket was in write-state, so delete it and re-add it
* in read-state.
*/
if (this->fd > -1)
{
- this->Instance->SE->DelFd(this->fd);
- if (!this->Instance->SE->AddFd(this->fd,true,X_ESTAB_MODULE))
+ this->Instance->SE->DelFd(this);
+ this->SetState(I_CONNECTED);
+ if (!this->Instance->SE->AddFd(this))
return false;
}
return this->OnConnected();
@@ -460,8 +463,9 @@ bool InspSocket::Poll()
if (this->WaitingForWriteEvent)
{
/* Switch back to read events */
- this->Instance->SE->DelFd(this->fd);
- if (!this->Instance->SE->AddFd(this->fd,true,X_ESTAB_MODULE))
+ this->Instance->SE->DelFd(this);
+ this->WaitingForWriteEvent = false;
+ if (!this->Instance->SE->AddFd(this))
return false;
/* Trigger the write event */
@@ -516,3 +520,13 @@ InspSocket::~InspSocket()
{
this->Close();
}
+
+void InspSocket::HandleEvent(EventType et)
+{
+ if (!this->Poll())
+ {
+ this->Instance->SE->DelFd(this);
+ delete this;
+ }
+}
+
diff --git a/src/modules.cpp b/src/modules.cpp
index b78b84d12..eaff59c2d 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -380,7 +380,7 @@ void InspIRCd::DumpText(userrec* User, const std::string &LinePrefix, stringstre
userrec* InspIRCd::FindDescriptor(int socket)
{
- return ((socket < MAX_DESCRIPTORS && socket > -1) ? this->fd_ref_table[socket] : NULL);
+ return reinterpret_cast<userrec*>(this->SE->GetRef(socket));
}
bool InspIRCd::AddMode(ModeHandler* mh, const unsigned char mode)
@@ -405,18 +405,18 @@ bool InspIRCd::AddResolver(Resolver* r)
bool InspIRCd::UserToPseudo(userrec* user, const std::string &message)
{
- unsigned int old_fd = user->fd;
+ unsigned int old_fd = user->GetFd();
user->Write("ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,message.c_str());
user->FlushWriteBuf();
user->ClearBuffer();
- user->fd = FD_MAGIC_NUMBER;
+ user->SetFd(FD_MAGIC_NUMBER);
if (find(local_users.begin(),local_users.end(),user) != local_users.end())
{
local_users.erase(find(local_users.begin(),local_users.end(),user));
}
- this->SE->DelFd(old_fd);
+ this->SE->DelFd(user);
shutdown(old_fd,2);
close(old_fd);
return true;
@@ -424,9 +424,9 @@ bool InspIRCd::UserToPseudo(userrec* user, const std::string &message)
bool InspIRCd::PseudoToUser(userrec* alive, userrec* zombie, const std::string &message)
{
- zombie->fd = alive->fd;
+ zombie->SetFd(alive->GetFd());
FOREACH_MOD_I(this,I_OnUserQuit,OnUserQuit(alive,message));
- alive->fd = FD_MAGIC_NUMBER;
+ alive->SetFd(FD_MAGIC_NUMBER);
alive->FlushWriteBuf();
alive->ClearBuffer();
// save these for later
@@ -439,7 +439,6 @@ bool InspIRCd::PseudoToUser(userrec* alive, userrec* zombie, const std::string &
local_users.erase(find(local_users.begin(),local_users.end(),alive));
}
// Fix by brain - cant write the user until their fd table entry is updated
- this->fd_ref_table[zombie->fd] = zombie;
zombie->Write(":%s!%s@%s NICK %s",oldnick.c_str(),oldident.c_str(),oldhost.c_str(),zombie->nick);
for (std::vector<ucrec*>::const_iterator i = zombie->chans.begin(); i != zombie->chans.end(); i++)
{
@@ -456,9 +455,8 @@ bool InspIRCd::PseudoToUser(userrec* alive, userrec* zombie, const std::string &
zombie->WriteServ("366 %s %s :End of /NAMES list.", zombie->nick, Ptr->name);
}
}
- if ((find(local_users.begin(),local_users.end(),zombie) == local_users.end()) && (zombie->fd != FD_MAGIC_NUMBER))
+ if ((find(local_users.begin(),local_users.end(),zombie) == local_users.end()) && (zombie->GetFd() != FD_MAGIC_NUMBER))
local_users.push_back(zombie);
-
return true;
}
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index 0a8c1fd11..1790fdfef 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -738,13 +738,12 @@ bool SQLConn::DoConnect()
}
this->state = I_CONNECTING;
- if (!this->Instance->SE->AddFd(this->fd,false,X_ESTAB_MODULE))
+ if (!this->Instance->SE->AddFd(this))
{
Instance->Log(DEBUG, "A PQsocket cant be added to the socket engine!");
Close();
return false;
}
- this->Instance->socket_ref[this->fd] = this;
/* Socket all hooked into the engine, now to tell PgSQL to start connecting */
@@ -754,9 +753,7 @@ bool SQLConn::DoConnect()
void SQLConn::Close()
{
Instance->Log(DEBUG,"SQLConn::Close");
-
- if(this->fd > 01)
- Instance->socket_ref[this->fd] = NULL;
+
this->fd = -1;
this->state = I_ERROR;
this->OnError(I_ERR_SOCKET);
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index 496162877..d70bd9561 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -60,7 +60,7 @@ class CGIResolver : public Resolver
virtual void OnLookupComplete(const std::string &result)
{
/* Check the user still exists */
- if ((them) && (them == ServerInstance->fd_ref_table[theirfd]))
+ if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
{
if (notify)
ServerInstance->WriteOpers("*** Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick, them->host, result.c_str(), typ.c_str());
@@ -73,7 +73,7 @@ class CGIResolver : public Resolver
virtual void OnError(ResolverError e, const std::string &errormessage)
{
- if ((them) && (them == ServerInstance->fd_ref_table[theirfd]))
+ if ((them) && (them == ServerInstance->SE->GetRef(theirfd)))
{
if (notify)
ServerInstance->WriteOpers("*** Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick, them->host,typ.c_str());
@@ -262,7 +262,7 @@ public:
try
{
- CGIResolver* r = new CGIResolver(NotifyOpers, user->password, false, user, user->fd, "PASS");
+ CGIResolver* r = new CGIResolver(NotifyOpers, user->password, false, user, user->GetFd(), "PASS");
ServerInstance->AddResolver(r);
}
catch (ModuleException& e)
@@ -317,8 +317,8 @@ public:
try
{
- ServerInstance->Log(DEBUG,"MAKE RESOLVER: %s %d %s",newip, user->fd, "IDENT");
- CGIResolver* r = new CGIResolver(NotifyOpers, newip, false, user, user->fd, "IDENT");
+ ServerInstance->Log(DEBUG,"MAKE RESOLVER: %s %d %s",newip, user->GetFd(), "IDENT");
+ CGIResolver* r = new CGIResolver(NotifyOpers, newip, false, user, user->GetFd(), "IDENT");
ServerInstance->AddResolver(r);
}
catch (ModuleException& e)
diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp
index 5e842b070..a7ffe6052 100644
--- a/src/modules/m_ident.cpp
+++ b/src/modules/m_ident.cpp
@@ -41,7 +41,7 @@ class RFC1413 : public InspSocket
userrec* u; // user record that the lookup is associated with
int ufd;
- RFC1413(InspIRCd* SI, userrec* user, int maxtime) : InspSocket(SI, user->GetIPString(), 113, false, maxtime), u(user), ufd(user->fd)
+ RFC1413(InspIRCd* SI, userrec* user, int maxtime) : InspSocket(SI, user->GetIPString(), 113, false, maxtime), u(user), ufd(user->GetFd())
{
}
@@ -49,7 +49,7 @@ class RFC1413 : public InspSocket
{
// When we timeout, the connection failed within the allowed timeframe,
// so we just display a notice, and tidy off the ident_data.
- if (u && (Instance->fd_ref_table[ufd] == u))
+ if (u && (Instance->SE->GetRef(ufd) == u))
{
u->Shrink("ident_data");
u->WriteServ("NOTICE "+std::string(u->nick)+" :*** Could not find your ident, using "+std::string(u->ident)+" instead.");
@@ -80,7 +80,7 @@ class RFC1413 : public InspSocket
*j = '\0'; // truncate at invalid chars
if (*section)
{
- if (u && (Instance->fd_ref_table[ufd] == u))
+ if (u && (Instance->SE->GetRef(ufd) == u))
{
if (this->Instance->IsIdent(section))
{
@@ -121,7 +121,7 @@ class RFC1413 : public InspSocket
// descriptor that they were when the lookup began.
//
// Fixes issue reported by webs, 7 Jun 2006
- if (u && (Instance->fd_ref_table[ufd] == u))
+ if (u && (Instance->SE->GetRef(ufd) == u))
{
u->Shrink("ident_data");
}
@@ -129,7 +129,7 @@ class RFC1413 : public InspSocket
virtual void OnError(InspSocketError e)
{
- if (u && (Instance->fd_ref_table[ufd] == u))
+ if (u && (Instance->SE->GetRef(ufd) == u))
{
u->Shrink("ident_data");
}
@@ -137,11 +137,11 @@ class RFC1413 : public InspSocket
virtual bool OnConnected()
{
- if (u && (Instance->fd_ref_table[ufd] == u))
+ if (u && (Instance->SE->GetRef(ufd) == u))
{
uslen = sizeof(sock_us);
themlen = sizeof(sock_them);
- if ((getsockname(this->u->fd,(sockaddr*)&sock_us,&uslen) || getpeername(this->u->fd, (sockaddr*)&sock_them, &themlen)))
+ if ((getsockname(this->u->GetFd(),(sockaddr*)&sock_us,&uslen) || getpeername(this->u->GetFd(), (sockaddr*)&sock_them, &themlen)))
{
Instance->Log(DEBUG,"Ident: failed to get socket names, bailing");
return false;
diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp
index 77d9a756d..2453308d3 100644
--- a/src/modules/m_samode.cpp
+++ b/src/modules/m_samode.cpp
@@ -57,7 +57,7 @@ class cmd_samode : public command_t
std::string result;
ServerInstance->Log(DEBUG,"SAMODE: Being handled");
userrec* n = new userrec(ServerInstance);
- n->fd = FD_MAGIC_NUMBER;
+ n->SetFd(FD_MAGIC_NUMBER);
ServerInstance->SendMode(parameters,pcnt,n);
delete n;
ServerInstance->Log(DEBUG,"SAMODE: Modechange handled");
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index b3cc874bd..fde13ef98 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -309,7 +309,7 @@ class TreeServer : public classbase
for (std::vector<userrec*>::iterator n = time_to_die.begin(); n != time_to_die.end(); n++)
{
userrec* a = (userrec*)*n;
- ServerInstance->Log(DEBUG,"Kill %s fd=%d",a->nick,a->fd);
+ ServerInstance->Log(DEBUG,"Kill %s fd=%d",a->nick,a->GetFd());
if (!IS_LOCAL(a))
userrec::QuitUser(ServerInstance,a,reason_s);
}
@@ -932,7 +932,7 @@ class TreeSocket : public InspSocket
{
/* FMODE from a server, create a fake user to receive mode feedback */
who = new userrec(this->Instance);
- who->fd = FD_MAGIC_NUMBER;
+ who->SetFd(FD_MAGIC_NUMBER);
smode = true; /* Setting this flag tells us we should free the userrec later */
sourceserv = source; /* Set sourceserv to the actual source string */
}
@@ -1542,7 +1542,7 @@ class TreeSocket : public InspSocket
userrec* _new = new userrec(this->Instance);
this->Instance->clientlist[tempnick] = _new;
- _new->fd = FD_MAGIC_NUMBER;
+ _new->SetFd(FD_MAGIC_NUMBER);
strlcpy(_new->nick, tempnick,NICKMAX-1);
strlcpy(_new->host, params[2].c_str(),63);
strlcpy(_new->dhost, params[3].c_str(),63);
@@ -3135,7 +3135,7 @@ void GetListOfServersForChannel(chanrec* c, std::deque<TreeServer*> &list)
CUList *ulist = c->GetUsers();
for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
{
- if (i->second->fd < 0)
+ if (i->second->GetFd() < 0)
{
TreeServer* best = BestRouteTo(i->second->server);
if (best)
@@ -3689,7 +3689,7 @@ class ModuleSpanningTree : public Module
if ((IS_LOCAL(user)) && (pcnt > 1))
{
userrec* remote = ServerInstance->FindNick(parameters[1]);
- if ((remote) && (remote->fd < 0))
+ if ((remote) && (remote->GetFd() < 0))
{
std::deque<std::string> params;
params.push_back(parameters[1]);
@@ -4005,7 +4005,7 @@ class ModuleSpanningTree : public Module
if (target_type == TYPE_USER)
{
userrec* d = (userrec*)dest;
- if ((d->fd < 0) && (IS_LOCAL(user)))
+ if ((d->GetFd() < 0) && (IS_LOCAL(user)))
{
std::deque<std::string> params;
params.clear();
@@ -4053,7 +4053,7 @@ class ModuleSpanningTree : public Module
// route private messages which are targetted at clients only to the server
// which needs to receive them
userrec* d = (userrec*)dest;
- if ((d->fd < 0) && (IS_LOCAL(user)))
+ if ((d->GetFd() < 0) && (IS_LOCAL(user)))
{
std::deque<std::string> params;
params.clear();
diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp
index d933c7f13..8639aa7df 100644
--- a/src/modules/m_timedbans.cpp
+++ b/src/modules/m_timedbans.cpp
@@ -177,7 +177,7 @@ class ModuleTimedBans : public Module
// hash and set its descriptor to FD_MAGIC_NUMBER so the data
// falls into the abyss :p
userrec* temp = new userrec(ServerInstance);
- temp->fd = FD_MAGIC_NUMBER;
+ temp->SetFd(FD_MAGIC_NUMBER);
/* FIX: Send mode remotely*/
std::deque<std::string> n;
n.push_back(setban[0]);
diff --git a/src/socket.cpp b/src/socket.cpp
index d28107f7f..50a4050e0 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -3,13 +3,13 @@
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- * E-mail:
- * <brain@chatspike.net>
- * <Craig@chatspike.net>
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -19,7 +19,6 @@
#include "socket.h"
#include "inspircd.h"
#include "inspstring.h"
-
#include "socketengine.h"
#include "wildcard.h"
@@ -41,6 +40,75 @@ const char inverted_bits[8] = { 0x00, /* 00000000 - 0 bits - never actually used
0xFE /* 11111110 - 7 bits */
};
+
+ListenSocket::ListenSocket(InspIRCd* Instance, int sockfd, insp_sockaddr client, insp_sockaddr server, int port, char* addr) : ServerInstance(Instance)
+{
+ this->SetFd(sockfd);
+ Instance->Log(DEBUG,"Binding to port %s:%d",addr,port);
+ if (!Instance->BindSocket(this->fd,client,server,port,addr))
+ {
+ Instance->Log(DEBUG,"Binding failed!");
+ this->fd = -1;
+ }
+}
+
+void ListenSocket::HandleEvent(EventType et)
+{
+ insp_sockaddr sock_us; // our port number
+ socklen_t uslen; // length of our port number
+ insp_sockaddr client;
+ socklen_t length;
+ int incomingSockfd, in_port;
+
+ ServerInstance->Log(DEBUG,"Handle ListenSocket event");
+
+ uslen = sizeof(sock_us);
+ length = sizeof(client);
+ incomingSockfd = accept (this->GetFd(),(struct sockaddr*)&client, &length);
+
+ if ((incomingSockfd > -1) && (!getsockname(incomingSockfd, (sockaddr*)&sock_us, &uslen)))
+ {
+#ifdef IPV6
+ in_port = ntohs(sock_us.sin6_port);
+#else
+ in_port = ntohs(sock_us.sin_port);
+#endif
+ ServerInstance->Log(DEBUG,"Accepted socket %d",incomingSockfd);
+ NonBlocking(incomingSockfd);
+ if (ServerInstance->Config->GetIOHook(in_port))
+ {
+ try
+ {
+#ifdef IPV6
+ ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin6_addr), in_port);
+#else
+ ServerInstance->Config->GetIOHook(in_port)->OnRawSocketAccept(incomingSockfd, insp_ntoa(client.sin_addr), in_port);
+#endif
+ }
+ catch (ModuleException& modexcept)
+ {
+ ServerInstance->Log(DEBUG,"Module exception cought: %s",modexcept.GetReason());
+ }
+ }
+ ServerInstance->stats->statsAccept++;
+#ifdef IPV6
+ ServerInstance->Log(DEBUG,"Add ipv6 client");
+ userrec::AddClient(ServerInstance, incomingSockfd, in_port, false, client.sin6_addr);
+#else
+ ServerInstance->Log(DEBUG,"Add ipv4 client");
+ userrec::AddClient(ServerInstance, incomingSockfd, in_port, false, client.sin_addr);
+#endif
+ ServerInstance->Log(DEBUG,"Adding client on port %d fd=%d",in_port,incomingSockfd);
+ }
+ else
+ {
+ ServerInstance->Log(DEBUG,"Accept failed on fd %d: %s",incomingSockfd,strerror(errno));
+ shutdown(incomingSockfd,2);
+ close(incomingSockfd);
+ ServerInstance->stats->statsRefused++;
+ }
+}
+
/* Match raw bytes using CIDR bit matching, used by higher level MatchCIDR() */
bool irc::sockets::MatchCIDRBits(unsigned char* address, unsigned char* mask, unsigned int mask_bits)
{
@@ -356,31 +424,30 @@ int InspIRCd::BindPorts(bool bail)
{
for (int count = InitialPortCount; count < InitialPortCount + PortCount; count++)
{
- if ((Config->openSockfd[count] = OpenTCPSocket()) == ERROR)
+ int fd = OpenTCPSocket();
+ if (fd == ERROR)
{
- this->Log(DEBUG,"Bad fd %d binding port [%s:%d]",Config->openSockfd[count],Config->addrs[count],Config->ports[count]);
+ this->Log(DEBUG,"Bad fd %d binding port [%s:%d]",fd,Config->addrs[count],Config->ports[count]);
}
else
{
- if (!BindSocket(Config->openSockfd[count],client,server,Config->ports[count],Config->addrs[count]))
+ Config->openSockfd[count] = new ListenSocket(this,fd,client,server,Config->ports[count],Config->addrs[count]);
+ if (Config->openSockfd[count]->GetFd() > -1)
{
- this->Log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
- }
- else
- {
- /* Associate the new open port with a slot in the socket engine */
- if (Config->openSockfd[count] > -1)
+ if (!SE->AddFd(Config->openSockfd[count]))
{
- if (!SE->AddFd(Config->openSockfd[count],true,X_LISTEN))
- {
- this->Log(DEFAULT,"ERK! Failed to add listening port to socket engine!");
- shutdown(Config->openSockfd[count],2);
- close(Config->openSockfd[count]);
- }
- else
- BoundPortCount++;
+ this->Log(DEFAULT,"ERK! Failed to add listening port to socket engine!");
+ shutdown(Config->openSockfd[count]->GetFd(),2);
+ close(Config->openSockfd[count]->GetFd());
+ delete Config->openSockfd[count];
}
+ else
+ BoundPortCount++;
}
+ /*if (!BindSocket(Config->openSockfd[count],client,server,Config->ports[count],Config->addrs[count]))
+ {
+ this->Log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
+ }*/
}
}
return InitialPortCount + BoundPortCount;
@@ -420,21 +487,22 @@ int InspIRCd::BindPorts(bool bail)
for (int count = 0; count < PortCount; count++)
{
- if ((Config->openSockfd[BoundPortCount] = OpenTCPSocket()) == ERROR)
+ int fd = OpenTCPSocket();
+ if (fd == ERROR)
{
- this->Log(DEBUG,"Bad fd %d binding port [%s:%d]",Config->openSockfd[BoundPortCount],Config->addrs[count],Config->ports[count]);
+ this->Log(DEBUG,"Bad fd %d binding port [%s:%d]",fd,Config->addrs[count],Config->ports[count]);
}
else
{
- if (!BindSocket(Config->openSockfd[BoundPortCount],client,server,Config->ports[count],Config->addrs[count]))
+ Config->openSockfd[count] = new ListenSocket(this,fd,client,server,Config->ports[count],Config->addrs[count]);
+ if (Config->openSockfd[count]->GetFd() > -1)
{
- this->Log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
- }
- else
- {
- /* well we at least bound to one socket so we'll continue */
BoundPortCount++;
}
+ /*if (!BindSocket(Config->openSockfd[BoundPortCount],client,server,Config->ports[count],Config->addrs[count]))
+ {
+ this->Log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
+ }*/
}
}
return BoundPortCount;
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index 3f34d75fb..71ae4fe9b 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -15,21 +15,30 @@
*/
#include "inspircd_config.h"
-#include "globals.h"
#include "inspircd.h"
-#ifdef USE_EPOLL
-#include <sys/epoll.h>
-#endif
-#ifdef USE_KQUEUE
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#endif
#include <vector>
#include <string>
#include "socketengine.h"
-#include "inspircd.h"
+int EventHandler::GetFd()
+{
+ return this->fd;
+}
+
+void EventHandler::SetFd(int FD)
+{
+ this->fd = FD;
+}
+
+bool EventHandler::Readable()
+{
+ return true;
+}
+
+bool EventHandler::Writeable()
+{
+ return false;
+}
SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance)
{
@@ -40,27 +49,26 @@ SocketEngine::~SocketEngine()
{
}
-char SocketEngine::GetType(int fd)
+bool SocketEngine::AddFd(EventHandler* eh)
{
- if ((fd < 0) || (fd > MAX_DESCRIPTORS))
- return X_EMPTY_SLOT;
- /* Mask off the top bit used for 'read/write' state */
- return (ref[fd] & ~0x80);
+ return true;
}
-bool SocketEngine::AddFd(int fd, bool readable, char type)
+bool SocketEngine::HasFd(int fd)
{
- return true;
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ return false;
+ return ref[fd];
}
-bool SocketEngine::HasFd(int fd)
+EventHandler* SocketEngine::GetRef(int fd)
{
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return false;
- return (ref[fd] != 0);
+ return ref[fd];
}
-bool SocketEngine::DelFd(int fd)
+bool SocketEngine::DelFd(EventHandler* eh)
{
return true;
}
@@ -75,7 +83,7 @@ int SocketEngine::GetRemainingFds()
return 0;
}
-int SocketEngine::Wait(int* fdlist)
+int SocketEngine::Wait(EventHandler** fdlist)
{
return 0;
}
@@ -84,3 +92,4 @@ std::string SocketEngine::GetName()
{
return "misconfigured";
}
+
diff --git a/src/socketengine_epoll.cpp b/src/socketengine_epoll.cpp
index 64b1be63d..9057c6d65 100644
--- a/src/socketengine_epoll.cpp
+++ b/src/socketengine_epoll.cpp
@@ -15,15 +15,12 @@
*/
#include "inspircd_config.h"
-#include "globals.h"
#include "inspircd.h"
#include <sys/epoll.h>
#include <vector>
#include <string>
#include "socketengine_epoll.h"
-#include "inspircd.h"
-
EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
EngineHandle = epoll_create(MAX_DESCRIPTORS);
@@ -44,8 +41,9 @@ EPollEngine::~EPollEngine()
close(EngineHandle);
}
-bool EPollEngine::AddFd(int fd, bool readable, char type)
+bool EPollEngine::AddFd(EventHandler* eh)
{
+ int fd = eh->GetFd();
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
{
ServerInstance->Log(DEFAULT,"ERROR: FD of %d added above max of %d",fd,MAX_DESCRIPTORS);
@@ -59,19 +57,14 @@ bool EPollEngine::AddFd(int fd, bool readable, char type)
if (ref[fd])
return false;
- ref[fd] = type;
+ ref[fd] = eh;
- if (readable)
- {
- ServerInstance->Log(DEBUG,"Set readbit");
- ref[fd] |= X_READBIT;
- }
- ServerInstance->Log(DEBUG,"Add socket %d",fd);
+ ServerInstance->Log(DEBUG,"***** Add socket %d",fd);
struct epoll_event ev;
memset(&ev,0,sizeof(struct epoll_event));
ServerInstance->Log(DEBUG,"epoll: Add socket to events, ep=%d socket=%d",EngineHandle,fd);
- readable ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
+ eh->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
ev.data.fd = fd;
int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev);
if (i < 0)
@@ -84,16 +77,17 @@ bool EPollEngine::AddFd(int fd, bool readable, char type)
return true;
}
-bool EPollEngine::DelFd(int fd)
+bool EPollEngine::DelFd(EventHandler* eh)
{
- ServerInstance->Log(DEBUG,"EPollEngine::DelFd(%d)",fd);
+ ServerInstance->Log(DEBUG,"EPollEngine::DelFd(%d)",eh->GetFd());
+ int fd = eh->GetFd();
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return false;
struct epoll_event ev;
memset(&ev,0,sizeof(struct epoll_event));
- ref[fd] && X_READBIT ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
+ ref[fd]->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
ev.data.fd = fd;
int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev);
if (i < 0)
@@ -103,7 +97,7 @@ bool EPollEngine::DelFd(int fd)
}
CurrentSetSize--;
- ref[fd] = 0;
+ ref[fd] = NULL;
return true;
}
@@ -117,13 +111,13 @@ int EPollEngine::GetRemainingFds()
return MAX_DESCRIPTORS - CurrentSetSize;
}
-int EPollEngine::Wait(int* fdlist)
+int EPollEngine::Wait(EventHandler** fdlist)
{
int result = 0;
int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 50);
for (int j = 0; j < i; j++)
- fdlist[result++] = events[j].data.fd;
+ fdlist[result++] = ref[events[j].data.fd];
return result;
}
@@ -132,3 +126,4 @@ std::string EPollEngine::GetName()
{
return "epoll";
}
+
diff --git a/src/socketengine_kqueue.cpp b/src/socketengine_kqueue.cpp
index 0c3226113..14864da79 100644
--- a/src/socketengine_kqueue.cpp
+++ b/src/socketengine_kqueue.cpp
@@ -45,8 +45,9 @@ KQueueEngine::~KQueueEngine()
close(EngineHandle);
}
-bool KQueueEngine::AddFd(int fd, bool readable, char type)
+bool KQueueEngine::AddFd(EventHandler* eh)
{
+ int fd = eh->GetFd();
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
{
ServerInstance->Log(DEFAULT,"ERROR: FD of %d added above max of %d",fd,MAX_DESCRIPTORS);
@@ -61,17 +62,12 @@ bool KQueueEngine::AddFd(int fd, bool readable, char type)
if (ref[fd])
return false;
- ref[fd] = type;
- if (readable)
- {
- ServerInstance->Log(DEBUG,"Set readbit");
- ref[fd] |= X_READBIT;
- }
+ ref[fd] = eh;
ServerInstance->Log(DEBUG,"Add socket %d",fd);
struct kevent ke;
ServerInstance->Log(DEBUG,"kqueue: Add socket to events, kq=%d socket=%d",EngineHandle,fd);
- EV_SET(&ke, fd, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL);
+ EV_SET(&ke, fd, eh->Readable() ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL);
int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
if (i == -1)
{
@@ -83,15 +79,17 @@ bool KQueueEngine::AddFd(int fd, bool readable, char type)
return true;
}
-bool KQueueEngine::DelFd(int fd)
+bool KQueueEngine::DelFd(EventHandler* eh)
{
+ int fd = eh->GetFd();
+
ServerInstance->Log(DEBUG,"KQueueEngine::DelFd(%d)",fd);
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return false;
struct kevent ke;
- EV_SET(&ke, fd, ref[fd] & X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
+ EV_SET(&ke, fd, eh->Readable() ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
if (i == -1)
{
@@ -100,7 +98,7 @@ bool KQueueEngine::DelFd(int fd)
}
CurrentSetSize--;
- ref[fd] = 0;
+ ref[fd] = NULL;
return true;
}
@@ -114,7 +112,7 @@ int KQueueEngine::GetRemainingFds()
return MAX_DESCRIPTORS - CurrentSetSize;
}
-int KQueueEngine::Wait(int* fdlist)
+int KQueueEngine::Wait(EventHandler** fdlist)
{
int result = 0;
@@ -122,7 +120,7 @@ int KQueueEngine::Wait(int* fdlist)
ts.tv_sec = 0;
int i = kevent(EngineHandle, NULL, 0, &ke_list[0], MAX_DESCRIPTORS, &ts);
for (int j = 0; j < i; j++)
- fdlist[result++] = ke_list[j].ident;
+ fdlist[result++] = ref[ke_list[j].ident];
return result;
}
diff --git a/src/socketengine_select.cpp b/src/socketengine_select.cpp
index 4e79dc19b..ec242b76d 100644
--- a/src/socketengine_select.cpp
+++ b/src/socketengine_select.cpp
@@ -35,8 +35,9 @@ SelectEngine::~SelectEngine()
ServerInstance->Log(DEBUG,"SelectEngine::~SelectEngine()");
}
-bool SelectEngine::AddFd(int fd, bool readable, char type)
+bool SelectEngine::AddFd(EventHandler* eh)
{
+ int fd = eh->GetFd();
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
{
ServerInstance->Log(DEFAULT,"ERROR: FD of %d added above max of %d",fd,MAX_DESCRIPTORS);
@@ -53,20 +54,17 @@ bool SelectEngine::AddFd(int fd, bool readable, char type)
if (ref[fd])
return false;
- ref[fd] = type;
- if (readable)
- {
- ServerInstance->Log(DEBUG,"Set readbit");
- ref[fd] |= X_READBIT;
- }
+ ref[fd] = eh;
ServerInstance->Log(DEBUG,"Add socket %d",fd);
CurrentSetSize++;
return true;
}
-bool SelectEngine::DelFd(int fd)
+bool SelectEngine::DelFd(EventHandler* eh)
{
+ int fd = eh->GetFd();
+
ServerInstance->Log(DEBUG,"SelectEngine::DelFd(%d)",fd);
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
@@ -80,7 +78,7 @@ bool SelectEngine::DelFd(int fd)
}
CurrentSetSize--;
- ref[fd] = 0;
+ ref[fd] = NULL;
return true;
}
@@ -94,7 +92,7 @@ int SelectEngine::GetRemainingFds()
return FD_SETSIZE - CurrentSetSize;
}
-int SelectEngine::Wait(int* fdlist)
+int SelectEngine::Wait(EventHandler** fdlist)
{
int result = 0;
@@ -104,7 +102,7 @@ int SelectEngine::Wait(int* fdlist)
int sresult;
for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++)
{
- if (ref[a->second] & X_READBIT)
+ if (ref[a->second]->Readable())
{
FD_SET (a->second, &rfdset);
}
@@ -122,7 +120,7 @@ int SelectEngine::Wait(int* fdlist)
for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++)
{
if ((FD_ISSET (a->second, &rfdset)) || (FD_ISSET (a->second, &wfdset)))
- fdlist[result++] = a->second;
+ fdlist[result++] = ref[a->second];
}
}
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 8c048c760..aa16bd90e 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -55,11 +55,9 @@ void InspIRCd::ProcessUser(userrec* cu)
{
int result = EAGAIN;
- if (cu->fd == FD_MAGIC_NUMBER)
+ if (cu->GetFd() == FD_MAGIC_NUMBER)
return;
- this->Log(DEBUG,"Processing user with fd %d",cu->fd);
-
if (this->Config->GetIOHook(cu->GetPort()))
{
int result2 = 0;
@@ -67,7 +65,7 @@ void InspIRCd::ProcessUser(userrec* cu)
try
{
- MOD_RESULT = this->Config->GetIOHook(cu->GetPort())->OnRawSocketRead(cu->fd,ReadBuffer,sizeof(ReadBuffer),result2);
+ MOD_RESULT = this->Config->GetIOHook(cu->GetPort())->OnRawSocketRead(cu->GetFd(),ReadBuffer,sizeof(ReadBuffer),result2);
this->Log(DEBUG,"Data result returned by module: %d",MOD_RESULT);
}
catch (ModuleException& modexcept)
@@ -115,7 +113,7 @@ void InspIRCd::ProcessUser(userrec* cu)
ReadBuffer[result] = '\0';
current = cu;
- currfd = current->fd;
+ currfd = current->GetFd();
// add the data to the users buffer
if (result > 0)
@@ -216,7 +214,7 @@ void InspIRCd::ProcessUser(userrec* cu)
if (single_line.length() > 512)
single_line.resize(512);
- userrec* old_comp = this->fd_ref_table[currfd];
+ EventHandler* old_comp = this->SE->GetRef(currfd);
this->Parser->ProcessBuffer(single_line,current);
/*
@@ -225,8 +223,8 @@ void InspIRCd::ProcessUser(userrec* cu)
* there used to be an ugly, slow loop here. Now we have a reference
* table, life is much easier (and FASTER)
*/
- userrec* new_comp = this->fd_ref_table[currfd];
- if ((currfd < 0) || (!this->fd_ref_table[currfd]) || (old_comp != new_comp))
+ EventHandler* new_comp = this->SE->GetRef(currfd);
+ if (old_comp != new_comp)
{
return;
}
@@ -270,11 +268,10 @@ void InspIRCd::DoSocketTimeouts(time_t TIME)
{
InspSocket* s = *a;
int fd = s->GetFd();
- if ((s) && (fd >= 0) && (fd < MAX_DESCRIPTORS) && (this->socket_ref[fd] != NULL) && (s->Timeout(TIME)))
+ if ((s) && (fd >= 0) && (fd < MAX_DESCRIPTORS) && (this->SE->GetRef(fd) == s) && (s->Timeout(TIME)))
{
this->Log(DEBUG,"userprocess.cpp: Socket poll returned false, close and bail");
- this->socket_ref[fd] = NULL;
- SE->DelFd(fd);
+ SE->DelFd(s);
this->module_sockets.erase(a);
s->Close();
DELETE(s);
diff --git a/src/users.cpp b/src/users.cpp
index 261ee491e..3953db233 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -138,12 +138,12 @@ UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_res
Resolver(Instance, to_resolve, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE), bound_user(user)
{
this->fwd = forward;
- this->bound_fd = user->fd;
+ this->bound_fd = user->GetFd();
}
void UserResolver::OnLookupComplete(const std::string &result)
{
- if ((!this->fwd) && (ServerInstance->fd_ref_table[this->bound_fd] == this->bound_user))
+ if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
{
ServerInstance->Log(DEBUG,"Commencing forward lookup");
this->bound_user->stored_host = result;
@@ -161,7 +161,7 @@ void UserResolver::OnLookupComplete(const std::string &result)
ServerInstance->Log(DEBUG,"Error in resolver: %s",e.GetReason());
}
}
- else if ((this->fwd) && (ServerInstance->fd_ref_table[this->bound_fd] == this->bound_user))
+ else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user))
{
/* Both lookups completed */
if (this->bound_user->GetIPString() == result)
@@ -196,7 +196,7 @@ void UserResolver::OnLookupComplete(const std::string &result)
void UserResolver::OnError(ResolverError e, const std::string &errormessage)
{
- if (ServerInstance->fd_ref_table[this->bound_fd] == this->bound_user)
+ if (ServerInstance->SE->GetRef(this->bound_fd) == this->bound_user)
{
/* Error message here */
this->bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname, using your IP address (%s) instead.", this->bound_user->GetIPString());
@@ -262,9 +262,10 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance)
*password = *nick = *ident = *host = *dhost = *fullname = *awaymsg = *oper = 0;
server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
reset_due = ServerInstance->Time();
- lines_in = fd = lastping = signon = idle_lastmsg = nping = registered = 0;
+ lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
haspassed = dns_done = false;
+ fd = -1;
recvq = "";
sendq = "";
WriteError = "";
@@ -690,7 +691,7 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user,const std::string &quit
}
}
- Instance->SE->DelFd(user->fd);
+ Instance->SE->DelFd(user);
user->CloseSocket();
}
@@ -714,7 +715,6 @@ void userrec::QuitUser(InspIRCd* Instance, userrec *user,const std::string &quit
Instance->Log(DEBUG,"deleting user hash value %lx",(unsigned long)user);
if (IS_LOCAL(user))
{
- Instance->fd_ref_table[user->fd] = NULL;
if (find(Instance->local_users.begin(),Instance->local_users.end(),user) != Instance->local_users.end())
Instance->local_users.erase(find(Instance->local_users.begin(),Instance->local_users.end(),user));
}
@@ -874,7 +874,6 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached,
_new->sendqmax = class_sqmax;
_new->recvqmax = class_rqmax;
- Instance->fd_ref_table[socket] = _new;
Instance->local_users.push_back(_new);
if (Instance->local_users.size() > Instance->Config->SoftLimit)
@@ -919,7 +918,7 @@ void userrec::AddClient(InspIRCd* Instance, int socket, int port, bool iscached,
if (socket > -1)
{
- if (!Instance->SE->AddFd(socket,true,X_ESTAB_CLIENT))
+ if (!Instance->SE->AddFd(_new))
{
userrec::QuitUser(Instance, _new, "Internal error handling connection");
return;
@@ -1799,3 +1798,9 @@ void userrec::ShowRULES()
this->WriteServ("NOTICE %s :End of %s rules.",this->nick,ServerInstance->Config->ServerName);
}
+void userrec::HandleEvent(EventType et)
+{
+ /* WARNING: May delete this user! */
+ ServerInstance->ProcessUser(this);
+}
+