diff options
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | include/socket.h | 27 | ||||
-rw-r--r-- | include/socketengine.h | 32 | ||||
-rw-r--r-- | include/socketengine_iocp.h | 12 | ||||
-rw-r--r-- | include/socketengine_kqueue.h | 1 | ||||
-rw-r--r-- | src/dns.cpp | 31 | ||||
-rw-r--r-- | src/filelogger.cpp | 11 | ||||
-rw-r--r-- | src/inspircd.cpp | 14 | ||||
-rw-r--r-- | src/inspsocket.cpp | 35 | ||||
-rw-r--r-- | src/modules/extra/m_mysql.cpp | 2 | ||||
-rw-r--r-- | src/socket.cpp | 41 | ||||
-rw-r--r-- | src/socketengine.cpp | 86 | ||||
-rw-r--r-- | src/socketengine_epoll.cpp | 2 | ||||
-rw-r--r-- | src/socketengine_iocp.cpp | 93 | ||||
-rw-r--r-- | src/socketengine_kqueue.cpp | 12 | ||||
-rw-r--r-- | src/socketengine_ports.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 11 | ||||
-rw-r--r-- | win/inspircd_win32wrapper.h | 6 |
18 files changed, 253 insertions, 167 deletions
@@ -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) |