summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--include/socket.h27
-rw-r--r--include/socketengine.h32
-rw-r--r--include/socketengine_iocp.h12
-rw-r--r--include/socketengine_kqueue.h1
-rw-r--r--src/dns.cpp31
-rw-r--r--src/filelogger.cpp11
-rw-r--r--src/inspircd.cpp14
-rw-r--r--src/inspsocket.cpp35
-rw-r--r--src/modules/extra/m_mysql.cpp2
-rw-r--r--src/socket.cpp41
-rw-r--r--src/socketengine.cpp86
-rw-r--r--src/socketengine_epoll.cpp2
-rw-r--r--src/socketengine_iocp.cpp93
-rw-r--r--src/socketengine_kqueue.cpp12
-rw-r--r--src/socketengine_ports.cpp2
-rw-r--r--src/users.cpp11
-rw-r--r--win/inspircd_win32wrapper.h6
18 files changed, 253 insertions, 167 deletions
diff --git a/configure b/configure
index bc81209d6..8bcfcbe64 100755
--- a/configure
+++ b/configure
@@ -491,7 +491,7 @@ if ($has_epoll) {
{
$kernelv = $1;
# Fix for some retarded libc builds, strip off >> and << etc.
- $kernelv =~ /([0-9\.\-])+/;
+ $kernelv =~ /([0-9\.])+/;
$kernelv = $1;
}
}
diff --git a/include/socket.h b/include/socket.h
index 57725b95f..861acc1f1 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -37,23 +37,6 @@
#include "inspircd_config.h"
#include "socketengine.h"
-/* Accept Define */
-#ifdef CONFIG_USE_IOCP
-/* IOCP wrapper for accept() */
-#define _accept(s, addr, addrlen) __accept_socket(s, addr, addrlen, m_acceptEvent)
-/* IOCP wrapper for getsockname() */
-#define _getsockname(fd, sockptr, socklen) __getsockname(fd, sockptr, socklen, m_acceptEvent)
-/* IOCP wrapper for recvfrom() */
-#define _recvfrom(s, buf, len, flags, from, fromlen) __recvfrom(s, buf, len, flags, from, fromlen, ((IOCPEngine*)ServerInstance->SE)->udp_ov)
-#else
-/* No wrapper for recvfrom() */
-#define _recvfrom recvfrom
-/* No wrapper for accept() */
-#define _accept accept
-/* No wrapper for getsockname() */
-#define _getsockname getsockname
-#endif
-
/* Contains irc-specific definitions */
namespace irc
{
@@ -148,16 +131,6 @@ namespace irc
*/
CoreExport int insp_aton(const char* a, insp_inaddr* n);
- /** Make a socket file descriptor a blocking socket
- * @param s A valid file descriptor
- */
- CoreExport void Blocking(int s);
-
- /** Make a socket file descriptor into a nonblocking socket
- * @param s A valid file descriptor
- */
- CoreExport void NonBlocking(int s);
-
/** Create a new valid file descriptor using socket()
* @return On return this function will return a value >= 0 for success,
* or a negative value upon failure (negative values are invalid file
diff --git a/include/socketengine.h b/include/socketengine.h
index e502a8c04..46a267fb1 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -277,6 +277,38 @@ public:
* which can be handled by the socket engine.
*/
virtual bool BoundsCheckFd(EventHandler* eh);
+
+ virtual int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+
+ virtual int Close(EventHandler* fd);
+
+ virtual int Close(int fd);
+
+ virtual int Send(EventHandler* fd, const void *buf, size_t len, int flags);
+
+ virtual int Recv(EventHandler* fd, void *buf, size_t len, int flags);
+
+ virtual int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
+
+ virtual int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
+
+ virtual int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
+
+ virtual int Blocking(int fd);
+
+ virtual int NonBlocking(int fd);
+
+ virtual int Shutdown(EventHandler* fd, int how);
+
+ virtual int Shutdown(int fd, int how);
+
+ virtual int Bind(int fd, const sockaddr *my_addr, socklen_t addrlen);
+
+ virtual int Listen(int sockfd, int backlog);
+
+ virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen);
+
+ virtual void RecoverFromFork();
};
#endif
diff --git a/include/socketengine_iocp.h b/include/socketengine_iocp.h
index ad3e58157..e45f8e726 100644
--- a/include/socketengine_iocp.h
+++ b/include/socketengine_iocp.h
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -212,6 +212,16 @@ public:
EventHandler* GetIntRef(int fd);
bool BoundsCheckFd(EventHandler* eh);
+
+ virtual int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+
+ virtual int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
+
+ virtual int Blocking(int fd);
+
+ virtual int NonBlocking(int fd);
+
+ virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* name);
};
/** Creates a SocketEngine
diff --git a/include/socketengine_kqueue.h b/include/socketengine_kqueue.h
index e7413d4bb..c34075cd2 100644
--- a/include/socketengine_kqueue.h
+++ b/include/socketengine_kqueue.h
@@ -53,6 +53,7 @@ public:
virtual int DispatchEvents();
virtual std::string GetName();
virtual void WantWrite(EventHandler* eh);
+ virtual void RecoverFromFork();
};
/** Creates a SocketEngine
diff --git a/src/dns.cpp b/src/dns.cpp
index d297260d5..612a47260 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -42,7 +42,6 @@ using irc::sockets::insp_inaddr;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_aton;
using irc::sockets::OpenTCPSocket;
-using irc::sockets::NonBlocking;
/** Masks to mask off the responses we get from the DNSRequest methods
*/
@@ -101,6 +100,7 @@ class DNSRequest
DNS* dnsobj; /* DNS caller (where we get our FD from) */
unsigned long ttl; /* Time to live */
std::string orig; /* Original requested name/ip */
+ InspIRCd* ServerInstance;
DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original);
~DNSRequest();
@@ -152,7 +152,7 @@ class RequestTimeout : public InspTimer
};
/* Allocate the processing buffer */
-DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original) : dnsobj(dns)
+DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original) : dnsobj(dns), ServerInstance(Instance)
{
res = new unsigned char[512];
*res = 0;
@@ -226,7 +226,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
memcpy(&addr.sin6_addr,&dnsobj->myserver6,sizeof(addr.sin6_addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(DNS::QUERY_PORT);
- if (sendto(dnsobj->GetFd(), payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) != length+12)
+ if (ServerInstance->SE->SendTo(dnsobj, payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) != length+12)
return -1;
}
else
@@ -237,7 +237,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
memcpy(&addr.sin_addr.s_addr,&dnsobj->myserver4,sizeof(addr.sin_addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(DNS::QUERY_PORT);
- if (sendto(dnsobj->GetFd(), (const char*)payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) != length+12)
+ if (ServerInstance->SE->SendTo(dnsobj, (const char*)payload, length + 12, 0, (sockaddr *) &addr, sizeof(addr)) != length+12)
return -1;
}
return 0;
@@ -311,8 +311,8 @@ void DNS::Rehash()
{
if (ServerInstance && ServerInstance->SE)
ServerInstance->SE->DelFd(this);
- shutdown(this->GetFd(), 2);
- close(this->GetFd());
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
this->SetFd(-1);
/* Rehash the cache */
@@ -351,7 +351,7 @@ void DNS::Rehash()
/* Initialize mastersocket */
int s = OpenTCPSocket(ServerInstance->Config->DNSServer, SOCK_DGRAM);
this->SetFd(s);
- NonBlocking(s);
+ ServerInstance->SE->NonBlocking(this->GetFd());
/* Have we got a socket and is it nonblocking? */
if (this->GetFd() != -1)
@@ -360,8 +360,8 @@ void DNS::Rehash()
if (!ServerInstance->BindSocket(this->GetFd(), portpass, "", false))
{
/* Failed to bind */
- shutdown(this->GetFd(),2);
- close(this->GetFd());
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
this->SetFd(-1);
}
@@ -373,8 +373,8 @@ void DNS::Rehash()
if (!ServerInstance->SE->AddFd(this))
{
ServerInstance->Log(DEFAULT,"Internal error starting DNS - hostnames will NOT resolve.");
- shutdown(this->GetFd(),2);
- close(this->GetFd());
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
this->SetFd(-1);
}
}
@@ -618,10 +618,7 @@ DNSResult DNS::GetResult(int resultnum)
const char* ipaddr_from;
unsigned short int port_from = 0;
- void* m_readEvent = NULL;
- GetExt("windows_readevent", m_readEvent);
-
- int length = _recvfrom(this->GetFd(),(char*)buffer,sizeof(DNSHeader),0,from,&x);
+ int length = ServerInstance->SE->RecvFrom(this, (char*)buffer, sizeof(DNSHeader), 0, from, &x);
/* Did we get the whole header? */
if (length < 12)
@@ -929,8 +926,8 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length, int result_we_w
/** Close the master socket */
DNS::~DNS()
{
- shutdown(this->GetFd(), 2);
- close(this->GetFd());
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
ServerInstance->Timers->DelTimer(this->PruneTimer);
delete this->PruneTimer;
}
diff --git a/src/filelogger.cpp b/src/filelogger.cpp
index 244b62717..8bd28dde8 100644
--- a/src/filelogger.cpp
+++ b/src/filelogger.cpp
@@ -23,7 +23,7 @@ FileLogger::FileLogger(InspIRCd* Instance, FILE* logfile)
{
if (log)
{
- irc::sockets::NonBlocking(fileno(log));
+ Instance->SE->NonBlocking(fileno(log));
SetFd(fileno(log));
buffer.clear();
}
@@ -79,13 +79,8 @@ void FileLogger::Close()
{
if (log)
{
- /* Burlex: Windows assumes nonblocking on FILE* pointers anyway, and also "file" fd's aren't the same
- * as socket fd's.
- */
-#ifndef WIN32
- int flags = fcntl(fileno(log), F_GETFL, 0);
- fcntl(fileno(log), F_SETFL, flags ^ O_NONBLOCK);
-#endif
+ ServerInstance->SE->Blocking(fileno(log));
+
if (buffer.size())
fprintf(log,"%s",buffer.c_str());
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index f4a9b7e32..5c1835b03 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -41,8 +41,6 @@
#include "exitcodes.h"
#include "caller.h"
-using irc::sockets::NonBlocking;
-using irc::sockets::Blocking;
using irc::sockets::insp_ntoa;
using irc::sockets::insp_inaddr;
using irc::sockets::insp_sockaddr;
@@ -309,6 +307,10 @@ InspIRCd::InspIRCd(int argc, char** argv)
memset(&server, 0, sizeof(server));
memset(&client, 0, sizeof(client));
+ SocketEngineFactory* SEF = new SocketEngineFactory();
+ SE = SEF->Create(this);
+ delete SEF;
+
this->s_signal = 0;
this->unregistered_count = 0;
@@ -454,13 +456,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
}
}
-
- /* Because of limitations in kqueue on freebsd, we must fork BEFORE we
- * initialize the socket engine.
- */
- SocketEngineFactory* SEF = new SocketEngineFactory();
- SE = SEF->Create(this);
- delete SEF;
+ SE->RecoverFromFork();
this->Modes = new ModeParser(this);
this->AddServerName(Config->ServerName);
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 2cfa6fd67..e2a2ab8ee 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -217,7 +217,7 @@ bool InspSocket::BindAddr(const std::string &ip)
}
}
- if (bind(this->fd, s, size) < 0)
+ if (Instance->SE->Bind(this->fd, s, size) < 0)
{
this->state = I_ERROR;
this->OnError(I_ERR_BIND);
@@ -302,14 +302,13 @@ bool InspSocket::DoConnect()
((sockaddr_in*)addr)->sin_port = htons(this->port);
}
}
-#ifndef WIN32
- int flags = fcntl(this->fd, F_GETFL, 0);
- fcntl(this->fd, F_SETFL, flags | O_NONBLOCK);
-#else
- unsigned long flags = 0;
- ioctlsocket(this->fd, FIONBIO, &flags);
+
+#ifdef WIN32
+ /* UGH for the LOVE OF ZOMBIE JESUS SOMEONE FIX THIS!!!!!!!!!!! */
+ Instance->SE->Blocking(this->fd);
#endif
- if (connect(this->fd, (sockaddr*)addr, size) == -1)
+
+ if (Instance->SE->Connect(this, (sockaddr*)addr, size) == -1)
{
if (errno != EINPROGRESS)
{
@@ -323,9 +322,8 @@ bool InspSocket::DoConnect()
this->Instance->Timers->AddTimer(this->Timeout);
}
#ifdef WIN32
- /* Set nonblocking mode after the connect() call */
- flags = 0;
- ioctlsocket(this->fd, FIONBIO, &flags);
+ /* CRAQ SMOKING STUFF TO BE FIXED */
+ Instance->SE->NonBlocking(this->fd);
#endif
this->state = I_CONNECTING;
if (this->fd > -1)
@@ -363,8 +361,8 @@ void InspSocket::Close()
Instance->Log(DEFAULT,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
}
}
- shutdown(this->fd,2);
- if (close(this->fd) != -1)
+ Instance->SE->Shutdown(this, 2);
+ if (Instance->SE->Close(this) != -1)
this->OnClose();
if (Instance->SocketCull.find(this) == Instance->SocketCull.end())
@@ -476,11 +474,8 @@ bool InspSocket::FlushWriteBuffer()
while (outbuffer.size() && (errno != EAGAIN))
{
/* Send a line */
-#ifndef WIN32
- int result = write(this->fd,outbuffer[0].c_str(),outbuffer[0].length());
-#else
- int result = send(this->fd,outbuffer[0].c_str(),outbuffer[0].length(), 0);
-#endif
+ int result = Instance->SE->Send(this, outbuffer[0].c_str(), outbuffer[0].length(), 0);
+
if (result > 0)
{
if ((unsigned int)result >= outbuffer[0].length())
@@ -604,9 +599,7 @@ bool InspSocket::Poll()
if ((!*this->host) || strchr(this->host, ':'))
length = sizeof(sockaddr_in6);
#endif
- void* m_acceptEvent = NULL;
- GetExt("windows_acceptevent", m_acceptEvent);
- incoming = _accept (this->fd, client, &length);
+ incoming = Instance->SE->Accept(this, client, &length);
#ifdef IPV6
if ((!*this->host) || strchr(this->host, ':'))
{
diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp
index 6605bed3c..5d8eeef7d 100644
--- a/src/modules/extra/m_mysql.cpp
+++ b/src/modules/extra/m_mysql.cpp
@@ -676,7 +676,7 @@ class Notifier : public InspSocket
* The function GetCharId translates a single character
* back into an iterator.
*/
- if (read(this->GetFd(), &data, 1) > 0)
+ if (Instance->SE->Recv(this, &data, 1, 0) > 0)
{
ConnMap::iterator iter = GetCharId(data);
if (iter != Connections.end())
diff --git a/src/socket.cpp b/src/socket.cpp
index 976c0585b..3e9db5fd4 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -59,7 +59,7 @@ ListenSocket::~ListenSocket()
{
ServerInstance->SE->DelFd(this);
ServerInstance->Log(DEBUG,"Shut down listener on fd %d", this->fd);
- if (shutdown(this->fd, 2) || close(this->fd))
+ if (ServerInstance->SE->Shutdown(this, 2) || ServerInstance->SE->Close(this))
ServerInstance->Log(DEBUG,"Failed to cancel listener: %s", strerror(errno));
this->fd = -1;
}
@@ -85,11 +85,9 @@ void ListenSocket::HandleEvent(EventType et, int errornum)
length = sizeof(sockaddr_in);
}
- void* m_acceptEvent = NULL;
- GetExt("windows_acceptevent", m_acceptEvent);
- incomingSockfd = _accept (this->GetFd(), (sockaddr*)client, &length);
+ incomingSockfd = ServerInstance->SE->Accept(this, (sockaddr*)client, &length);
- if ((incomingSockfd > -1) && (!_getsockname(incomingSockfd, sock_us, &uslen)))
+ if ((incomingSockfd > -1) && (!ServerInstance->SE->GetSockName(this, sock_us, &uslen)))
{
char buf[MAXBUF];
#ifdef IPV6
@@ -105,7 +103,8 @@ void ListenSocket::HandleEvent(EventType et, int errornum)
in_port = ntohs(((sockaddr_in*)sock_us)->sin_port);
}
- NonBlocking(incomingSockfd);
+ ServerInstance->SE->NonBlocking(incomingSockfd);
+
if (ServerInstance->Config->GetIOHook(in_port))
{
try
@@ -122,7 +121,7 @@ void ListenSocket::HandleEvent(EventType et, int errornum)
}
else
{
- shutdown(incomingSockfd,2);
+ ServerInstance->SE->Shutdown(incomingSockfd, 2);
close(incomingSockfd);
ServerInstance->stats->statsRefused++;
}
@@ -297,28 +296,6 @@ bool irc::sockets::MatchCIDR(const char* address, const char* cidr_mask, bool ma
return MatchCIDRBits(addr_raw, mask_raw, bits);
}
-void irc::sockets::Blocking(int s)
-{
-#ifndef WIN32
- int flags = fcntl(s, F_GETFL, 0);
- fcntl(s, F_SETFL, flags ^ O_NONBLOCK);
-#else
- unsigned long opt = 0;
- ioctlsocket(s, FIONBIO, &opt);
-#endif
-}
-
-void irc::sockets::NonBlocking(int s)
-{
-#ifndef WIN32
- int flags = fcntl(s, F_GETFL, 0);
- fcntl(s, F_SETFL, flags | O_NONBLOCK);
-#else
- unsigned long opt = 1;
- ioctlsocket(s, FIONBIO, &opt);
-#endif
-}
-
/** This will bind a socket to a port. It works for UDP/TCP.
* It can only bind to IP addresses, if you wish to bind to hostnames
* you should first resolve them using class 'Resolver'.
@@ -413,7 +390,7 @@ bool InspIRCd::BindSocket(int sockfd, int port, char* addr, bool dolisten)
((sockaddr_in*)server)->sin_port = htons(port);
size = sizeof(sockaddr_in);
#endif
- ret = bind(sockfd, server, size);
+ ret = SE->Bind(sockfd, server, size);
delete[] server;
if (ret < 0)
@@ -424,7 +401,7 @@ bool InspIRCd::BindSocket(int sockfd, int port, char* addr, bool dolisten)
{
if (dolisten)
{
- if (listen(sockfd, Config->MaxConn) == -1)
+ if (SE->Listen(sockfd, Config->MaxConn) == -1)
{
this->Log(DEFAULT,"ERROR in listen(): %s",strerror(errno));
return false;
@@ -432,7 +409,7 @@ bool InspIRCd::BindSocket(int sockfd, int port, char* addr, bool dolisten)
else
{
this->Log(DEBUG,"New socket binding for %d with listen: %s:%d", sockfd, addr, port);
- NonBlocking(sockfd);
+ SE->NonBlocking(sockfd);
return true;
}
}
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index 28ba8c252..d8291073e 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -100,3 +100,87 @@ bool SocketEngine::BoundsCheckFd(EventHandler* eh)
return true;
}
+
+int SocketEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen)
+{
+ return accept(fd->GetFd(), addr, addrlen);
+}
+
+int SocketEngine::Close(EventHandler* fd)
+{
+ return close(fd->GetFd());
+}
+
+int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
+{
+ return send(fd->GetFd(), buf, len, flags);
+}
+
+int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
+{
+ return recv(fd->GetFd(), buf, len, flags);
+}
+
+int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
+{
+ return recvfrom(fd->GetFd(), buf, len, flags, from, fromlen);
+}
+
+int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
+{
+ return sendto(fd->GetFd(), buf, len, flags, to, tolen);
+}
+
+int SocketEngine::Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen)
+{
+ return connect(fd->GetFd(), serv_addr, addrlen);
+}
+
+int SocketEngine::Blocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL, 0);
+ return fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
+}
+
+int SocketEngine::NonBlocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL, 0);
+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+}
+
+int SocketEngine::Shutdown(EventHandler* fd, int how)
+{
+ return shutdown(fd->GetFd(), how);
+}
+
+
+int SocketEngine::Bind(int fd, const sockaddr *my_addr, socklen_t addrlen)
+{
+ return bind(fd, my_addr, addrlen);
+}
+
+int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
+{
+ return getsockname(fd->GetFd(), name, namelen);
+}
+
+int SocketEngine::Listen(int sockfd, int backlog)
+{
+ return listen(sockfd, backlog);
+}
+
+
+int SocketEngine::Shutdown(int fd, int how)
+{
+ return shutdown(fd, how);
+}
+
+int SocketEngine::Close(int fd)
+{
+ return close(fd);
+}
+
+void SocketEngine::RecoverFromFork()
+{
+}
+
diff --git a/src/socketengine_epoll.cpp b/src/socketengine_epoll.cpp
index 03a3f8f7c..381701093 100644
--- a/src/socketengine_epoll.cpp
+++ b/src/socketengine_epoll.cpp
@@ -33,7 +33,7 @@ EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance)
EPollEngine::~EPollEngine()
{
- close(EngineHandle);
+ this->Close(EngineHandle);
}
bool EPollEngine::AddFd(EventHandler* eh)
diff --git a/src/socketengine_iocp.cpp b/src/socketengine_iocp.cpp
index eb881f280..f1f4f0289 100644
--- a/src/socketengine_iocp.cpp
+++ b/src/socketengine_iocp.cpp
@@ -410,11 +410,51 @@ std::string IOCPEngine::GetName()
return "iocp";
}
-int __accept_socket(SOCKET s, sockaddr * addr, int * addrlen, void * acceptevent)
+EventHandler * IOCPEngine::GetRef(int fd)
{
- Overlapped* ovl = (Overlapped*)acceptevent;
- accept_overlap* ov = (accept_overlap*)ovl->m_params;
+ map<int, EventHandler*>::iterator itr = m_binding.find(fd);
+ return (itr == m_binding.end()) ? 0 : itr->second;
+}
+bool IOCPEngine::HasFd(int fd)
+{
+ return (GetRef(fd) != 0);
+}
+
+bool IOCPEngine::BoundsCheckFd(EventHandler* eh)
+{
+ int * internal_fd;
+ if (!eh || eh->GetFd() < 0)
+ return false;
+
+ if(!eh->GetExt("internal_fd", internal_fd))
+ return false;
+
+ if(*internal_fd > MAX_DESCRIPTORS)
+ return false;
+
+ return true;
+}
+
+EventHandler * IOCPEngine::GetIntRef(int fd)
+{
+ if(fd < 0 || fd > MAX_DESCRIPTORS)
+ return 0;
+ return ref[fd];
+}
+
+int IOCPEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen)
+{
+ SOCKET s = fd->GetFd();
+
+ Overlapped* acceptevent = NULL;
+ if (!fd->GetExt("windows_acceptevent", acceptevent))
+ /* Shit, no accept event on this socket! :( */
+ return -1;
+
+ Overlapped* ovl = acceptevent;
+ accept_overlap* ov = (accept_overlap*)ovl->m_params;
+
sockaddr_in* server_address = (sockaddr_in*)&ov->buf[10];
sockaddr_in* client_address = (sockaddr_in*)&ov->buf[38];
@@ -424,9 +464,13 @@ int __accept_socket(SOCKET s, sockaddr * addr, int * addrlen, void * acceptevent
return ov->socket;
}
-int __getsockname(SOCKET s, sockaddr * name, int * namelen, void * acceptevent)
+int IOCPEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* name)
{
- Overlapped* ovl = (Overlapped*)acceptevent;
+ Overlapped* ovl = NULL;
+
+ if (!fd->GetExt("windows_acceptevent", acceptevent))
+ return -1;
+
accept_overlap* ov = (accept_overlap*)ovl->m_params;
sockaddr_in* server_address = (sockaddr_in*)&ov->buf[10];
@@ -438,43 +482,26 @@ int __getsockname(SOCKET s, sockaddr * name, int * namelen, void * acceptevent)
return 0;
}
-int __recvfrom(SOCKET s, char * buf, int len, int flags, struct sockaddr * from, int * fromlen, udp_overlap * ov)
+int IOCPEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
- memcpy(buf, ov->udp_buffer, ov->udp_len);
+ udp_overlap * ov = NULL;
+ if (!fd->GetExt("windows_readevent", ov))
+ return -1;
+ memcpy(buf, ov->udp_buffer, ov->udp_len);
memcpy(from, ov->udp_sockaddr, *fromlen);
return ov->udp_len;
}
-EventHandler * IOCPEngine::GetRef(int fd)
-{
- map<int, EventHandler*>::iterator itr = m_binding.find(fd);
- return (itr == m_binding.end()) ? 0 : itr->second;
-}
-
-bool IOCPEngine::HasFd(int fd)
+int IOCPEngine::Blocking(int fd)
{
- return (GetRef(fd) != 0);
+ unsigned long opt = 0;
+ ioctlsocket(s, FIONBIO, &opt);
}
-bool IOCPEngine::BoundsCheckFd(EventHandler* eh)
+int IOCPEngine::NonBlocking(int fd)
{
- int * internal_fd;
- if (!eh || eh->GetFd() < 0)
- return false;
-
- if(!eh->GetExt("internal_fd", internal_fd))
- return false;
-
- if(*internal_fd > MAX_DESCRIPTORS)
- return false;
-
- return true;
+ unsigned long opt = 1;
+ ioctlsocket(s, FIONBIO, &opt);
}
-EventHandler * IOCPEngine::GetIntRef(int fd)
-{
- if(fd < 0 || fd > MAX_DESCRIPTORS)
- return 0;
- return ref[fd];
-}
diff --git a/src/socketengine_kqueue.cpp b/src/socketengine_kqueue.cpp
index 246b5e524..e33f9f772 100644
--- a/src/socketengine_kqueue.cpp
+++ b/src/socketengine_kqueue.cpp
@@ -21,6 +21,16 @@
KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance)
{
+ this->RecoverFromFork();
+}
+
+void KQueueEngine::RecoverFromFork()
+{
+ /*
+ * The only bad thing about kqueue is that its fd cant survive a fork and is not inherited.
+ * BUM HATS.
+ *
+ */
EngineHandle = kqueue();
if (EngineHandle == -1)
{
@@ -35,7 +45,7 @@ KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance)
KQueueEngine::~KQueueEngine()
{
- close(EngineHandle);
+ this->Close(EngineHandle);
}
bool KQueueEngine::AddFd(EventHandler* eh)
diff --git a/src/socketengine_ports.cpp b/src/socketengine_ports.cpp
index a0141f79a..352b73062 100644
--- a/src/socketengine_ports.cpp
+++ b/src/socketengine_ports.cpp
@@ -33,7 +33,7 @@ PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance)
PortsEngine::~PortsEngine()
{
- close(EngineHandle);
+ this->Close(EngineHandle);
}
bool PortsEngine::AddFd(EventHandler* eh)
diff --git a/src/users.cpp b/src/users.cpp
index 4854849ad..ccf506697 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -436,8 +436,8 @@ char* userrec::MakeHostIP()
void userrec::CloseSocket()
{
- shutdown(this->fd,2);
- close(this->fd);
+ ServerInstance->SE->Shutdown(this, 2);
+ ServerInstance->SE->Close(this);
}
char* userrec::GetFullHost()
@@ -727,11 +727,8 @@ void userrec::FlushWriteBuf()
if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
{
int old_sendq_length = sendq.length();
-#ifndef WIN32
- int n_sent = write(this->fd, this->sendq.data(), this->sendq.length());
-#else
- int n_sent = send(this->fd, (const char*)this->sendq.data(), this->sendq.length(), 0);
-#endif
+ int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0);
+
if (n_sent == -1)
{
if (errno == EAGAIN)
diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h
index 17c3f5525..a728cf191 100644
--- a/win/inspircd_win32wrapper.h
+++ b/win/inspircd_win32wrapper.h
@@ -121,12 +121,6 @@ struct option
extern char optarg[514];
int getopt_long_only (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind);
-/* Accept Handlers */
-struct udp_overlap;
-CoreExport int __accept_socket(SOCKET s, sockaddr * addr, int * addrlen, void * acceptevent);
-CoreExport int __getsockname(SOCKET s, sockaddr * name, int * namelen, void * acceptevent);
-CoreExport int __recvfrom(SOCKET s, char * buf, int len, int flags, struct sockaddr * from, int * fromlen, udp_overlap * ov);
-
/* Module Loading */
#define dlopen(path, state) (void*)LoadLibrary(path)
#define dlsym(handle, export) (void*)GetProcAddress((HMODULE)handle, export)