/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd: (C) 2002-2009 InspIRCd Development Team
* See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
/* $Core */
/********* DEFAULTS **********/
/* $ExtraSources: socketengines/socketengine_select.cpp */
/* $ExtraObjects: socketengine_select.o */
/* $If: USE_POLL */
/* $ExtraSources: socketengines/socketengine_poll.cpp */
/* $ExtraObjects: socketengine_poll.o */
/* $EndIf */
/* $If: USE_KQUEUE */
/* $ExtraSources: socketengines/socketengine_kqueue.cpp */
/* $ExtraObjects: socketengine_kqueue.o */
/* $EndIf */
/* $If: USE_EPOLL */
/* $ExtraSources: socketengines/socketengine_epoll.cpp */
/* $ExtraObjects: socketengine_epoll.o */
/* $EndIf */
/* $If: USE_PORTS */
/* $ExtraSources: socketengines/socketengine_ports.cpp */
/* $ExtraObjects: socketengine_ports.o */
/* $EndIf */
#include "inspircd.h"
#include "socketengine.h"
EventHandler::EventHandler()
{
this->IOHook = NULL;
}
bool EventHandler::AddIOHook(Module *IOHooker)
{
if (this->IOHook)
return false;
this->IOHook = IOHooker;
return true;
}
bool EventHandler::DelIOHook()
{
if (!this->IOHook)
return false;
this->IOHook = NULL;
return true;
}
Module *EventHandler::GetIOHook()
{
return this->IOHook;
}
int EventHandler::GetFd()
{
return this->fd;
}
void EventHandler::SetFd(int FD)
{
this->fd = FD;
}
bool EventHandler::Readable()
{
return true;
}
bool EventHandler::Writeable()
{
return false;
}
void SocketEngine::WantWrite(EventHandler* eh)
{
}
SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance)
{
TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0;
lastempty = ServerInstance->Time();
indata = outdata = 0;
}
SocketEngine::~SocketEngine()
{
}
bool SocketEngine::AddFd(EventHandler* eh)
{
return true;
}
bool SocketEngine::HasFd(int fd)
{
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return false;
return ref[fd];
}
EventHandler* SocketEngine::GetRef(int fd)
{
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return 0;
return ref[fd];
}
bool SocketEngine::DelFd(EventHandler* eh, bool force)
{
return true;
}
int SocketEngine::GetMaxFds()
{
return 0;
}
int SocketEngine::GetRemainingFds()
{
return 0;
}
int SocketEngine::DispatchEvents()
{
return 0;
}
std::string SocketEngine::GetName()
{
return "misconfigured";
}
bool SocketEngine::BoundsCheckFd(EventHandler* eh)
{
if (!eh)
return false;
if ((eh->GetFd() < 0) || (eh->GetFd() > MAX_DESCRIPTORS))
return false;
return true;
}
int SocketEngine::Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen)
{
return accept(fd->GetFd(), addr, addrlen);
}
int SocketEngine::Close(EventHandler* fd)
{
#ifdef WINDOWS
return closesocket(fd->GetFd());
#else
return close(fd->GetFd());
#endif
}
int SocketEngine::Close(int fd)
{
#ifdef WINDOWS
return closesocket(fd);
#else
return close(fd);
#endif
}
int SocketEngine::Blocking(int fd)
{
#ifdef WINDOWS
unsigned long opt = 0;
return ioctlsocket(fd, FIONBIO, &opt);
#else
int flags = fcntl(fd, F_GETFL, 0);
return fcntl(fd, F_SETFL, flags ^ O_NONBLOCK);
#endif
}
int SocketEngine::NonBlocking(int fd)
{
#ifdef WINDOWS
unsigned long opt = 1;
return ioctlsocket(fd, FIONBIO, &opt);
#else
int flags = fcntl(fd, F_GETFL, 0);
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#endif
}
int SocketEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
{
return getsockname(fd->GetFd(), name, namelen);
}
int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
{
this->UpdateStats(len, 0);
return recvfrom(fd->GetFd(), (char*)buf, len, flags, from, fromlen);
}
int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
{
this->UpdateStats(0, len);
return send(fd->GetFd(), (const char*)buf, len, flags);
}
int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
{
this->UpdateStats(len, 0);
return recv(fd->GetFd(), (char*)buf, len, flags);
}
int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
{
this->UpdateStats(0, len);
return sendto(fd->GetFd(), (const char*)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::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::Listen(int sockfd, int backlog)
{
return listen(sockfd, backlog);
}
int SocketEngine::Shutdown(int fd, int how)
{
return shutdown(fd, how);
}
void SocketEngine::RecoverFromFork()
{
}
void SocketEngine::UpdateStats(size_t len_in, size_t len_out)
{
if (lastempty != ServerInstance->Time())
{
lastempty = ServerInstance->Time();
indata = outdata = 0;
}
indata += len_in;
outdata += len_out;
}
void SocketEngine::GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total)
{
UpdateStats(0, 0); /* Forces emptying of the values if its been more than a second */
float in_kbit = indata * 8;
float out_kbit = outdata * 8;
kbitpersec_total = ((in_kbit + out_kbit) / 1024);
kbitpersec_in = in_kbit / 1024;
kbitpersec_out = out_kbit / 1024;
}