diff options
-rwxr-xr-x | configure | 15 | ||||
-rw-r--r-- | include/socketengine.h | 51 | ||||
-rw-r--r-- | src/socketengine.cpp | 157 |
3 files changed, 218 insertions, 5 deletions
@@ -975,10 +975,13 @@ CC = im a cheezeball CXXFLAGS = -I../include \${FLAGS} -all: socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o \$(MODULES) inspircd.exe +all: socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o \$(MODULES) inspircd.exe inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/base.h - \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o \$(MODULES) + \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_util.o inspircd_io.o message.o commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o \$(MODULES) + +socketengine.o: socketengine.cpp: ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h + \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp @@ -1053,10 +1056,14 @@ CC = im a cheezeball CXXFLAGS = -I../include \${FLAGS} -all: libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so inspircd +all: libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so inspircd inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h - \$(CC) -I../include \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so + \$(CC) -I../include \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDutil.so libIRCDio.so libIRCDmessage.so libIRCDcommands.so libIRCDdnsqueue.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so + +libIRCDsocketengine.so: socketengine.cpp: ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h + \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp + \$(CC) -shared -o libIRCDsocketengine.so socketengine.o libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp diff --git a/include/socketengine.h b/include/socketengine.h index 9a4610f5f..967c0967b 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -12,7 +12,54 @@ * the file COPYING for details. * * --------------------------------------------------- - */ +*/ + +#ifndef __SOCKETENGINE__ +#define __SOCKETENGINE__ + +#include <vector> +#include <string> + +class SocketEngine { + + std::vector<int> fds; + int EngineHandle; +#ifdef USE_SELECT + fd_set wfdset, rfdset; +#endif +#ifdef USE_KQUEUE + struct kevent ke_list[65535]; + struct timespec ts; +#endif +#ifdef USE_EPOLL + struct epoll_event events[65535]; +#endif + +public: + + SocketEngine(); + ~SocketEngine(); + bool AddFd(int fd, bool readable, bool writeable, char type); + bool DelFd(int fd); + bool Wait(unsigned long millisecs, std::vector<int> &fdlist); + std::string GetName(); +}; + + + + + + + + + + + + + + + + // Fill the engine with client file descriptors pending an action @@ -320,3 +367,5 @@ #define engine_name "epoll" #endif + +#endif diff --git a/src/socketengine.cpp b/src/socketengine.cpp new file mode 100644 index 000000000..d6255e9e3 --- /dev/null +++ b/src/socketengine.cpp @@ -0,0 +1,157 @@ +#ifdef USE_EPOLL +#include <sys/epoll.h> +#define EP_DELAY 5 +#endif +#ifdef USE_KQUEUE +#include <sys/types.h> +#include <sys/event.h> +#include <sys/time.h> +#endif + + +char ref[65535]; + +const char X_LISTEN = 0; +const char X_ESTAB_CLIENT = 1; +const char X_ESTAB_MODULE = 2; +const char X_ESTAB_DNS = 3; + +const char X_READBIT = 0x80; + +SocketEngine::SocketEngine() +{ +#ifdef USE_EPOLL + EngineHandle = epoll_create(65535); +#endif +#ifdef USE_KQUEUE + EngineHandle = kqueue(); +#endif +} + +SocketEngine::~SocketEngine() +{ +#ifdef USE_EPOLL || USE_KQUEUE + close(EngineHandle); +#endif +} + +bool SocketEngine::AddFd(int fd, bool readable, char type) +{ + this->fds.push_back(fd); + if (readable) + ref[fd] |= X_READBIT; +#ifdef USE_EPOLL + struct epoll_event ev; + log(DEBUG,"epoll: Adduser to events, ep=%d socket=%d",EngineHandle,fd); + readable ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET; + ev.data.fd = fd; + int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev); + if (i < 0) + { + log(DEBUG,"epoll: List insertion failure!"); + return false; + } +#endif +#ifdef USE_KQUEUE + struct kevent ke; + log(DEBUG,"kqueue: Add user to events, kq=%d socket=%d",EngineHandle,fd); + EV_SET(&ke, socket, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL); + int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL); + if (i == -1) + { + log(DEBUG,"kqueue: List insertion failure!"); + return false; + } +#endif +return true; +} + +bool SocketEngine::DelFd(int fd) +{ + std::vector<int>::iterator i = this->fds.find(fd); + if (i != this->fds.end()) + this->fds.erase(i); +#ifdef USE_KQUEUE + struct kevent ke; + EV_SET(&ke, fd, ref[fd] && X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL); + if (i == -1) + { + log(DEBUG,"kqueue: Failed to remove user from queue!"); + return false; + } +#endif +#ifdef USE_EPOLL + struct epoll_event ev; + ref[fd] && X_READBIT ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET; + ev.data.fd = fd; + int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev); + if (i < 0) + { + log(DEBUG,"epoll: List deletion failure!"); + return false; + } +#endif + ref[fd] = 0; + return (i != this->fds.end()); +} + +bool SocketEngine::Wait(unsigned long millisecs, std::vector<int> &fdlist) +{ + fdlist.clear(); +#ifdef USE_SELECT + int highest_fd = 0; + timeval tval; + int sresult; + for (unsigned int a = 0; a < fds.size(); a++) + { + if (ref[fds[a]] && X_READBIT) + { + FD_SET (fds[a], &rfdset); + } + else + { + FD_SET (fds[a], &wfdset); + } + + } + tval.tv_sec = 0; + tval.tv_usec = 1000L; + sresult = select(FD_SETSIZE, &rfdset, &wfdset, NULL, &tval); + if (sresult > 0) + { + for (unsigned int a = 0; a < fds.size(); a++) + { + if ((FD_ISSET (fds[a], &rfdset)) || (FD_ISSET (fds[a], &wfdset))) + fdlist.push_back(fds[a]); + } + } +#endif +#ifdef USE_KQUEUE + ts.tv_nsec = 1000L; + ts.tv_sec = 0; + int i = kevent(EngineHandle, NULL, 0, &ke_list, 65535, &ts); + for (int j = 0; j < i; j++) + fdlist.push_back(ke_list[j].ident); +#endif +#ifdef USE_EPOLL + int i = epoll_wait(EngineHandle, events, 65535, 1); + for (int j = 0; j < i; j++) + fdlist.push_back(event[0].data.fd); +#endif + return true; +} + +std::string SocketEngine::GetName() +{ +#ifdef USE_SELECT + return "select"; +#endif +#ifdef USE_KQUEUE + return "kqueue"; +#endif +#ifdef USE_EPOLL + return "epoll"; +#endif + return "misconfigured"; +} |