summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure15
-rw-r--r--include/socketengine.h51
-rw-r--r--src/socketengine.cpp157
3 files changed, 218 insertions, 5 deletions
diff --git a/configure b/configure
index 2a6296f55..c11ef2aaf 100755
--- a/configure
+++ b/configure
@@ -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";
+}